Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
This application contains the example codes to:
1) Connect PFM-M487/PFM-NUC472 boards to Pelion
2) Enable Firmware update
For storage, PFM-M487/PFM-NUC472 support both SPI interface SD and built-in SD bus SD.
For connectivity, PFM-M487/PFM-NUC472 support Ethernet (on-board) by default.
This example supports Ethernet and built-in SD by default.

simple-mbed-cloud-client/mbed-cloud-client/update-client-hub/modules/pal-filesystem/source/arm_uc_pal_linux_extensions.c@0:83caa8fa1d2c, 2018-07-06 (annotated)
- Committer:
- cyliang
- Date:
- Fri Jul 06 04:15:24 2018 +0000
- Revision:
- 0:83caa8fa1d2c
Support cloud client v1.3.3
Who changed what in which revision?
| User | Revision | Line number | New contents of line |
|---|---|---|---|
| cyliang | 0:83caa8fa1d2c | 1 | // ---------------------------------------------------------------------------- |
| cyliang | 0:83caa8fa1d2c | 2 | // Copyright 2016-2017 ARM Ltd. |
| cyliang | 0:83caa8fa1d2c | 3 | // |
| cyliang | 0:83caa8fa1d2c | 4 | // SPDX-License-Identifier: Apache-2.0 |
| cyliang | 0:83caa8fa1d2c | 5 | // |
| cyliang | 0:83caa8fa1d2c | 6 | // Licensed under the Apache License, Version 2.0 (the "License"); |
| cyliang | 0:83caa8fa1d2c | 7 | // you may not use this file except in compliance with the License. |
| cyliang | 0:83caa8fa1d2c | 8 | // You may obtain a copy of the License at |
| cyliang | 0:83caa8fa1d2c | 9 | // |
| cyliang | 0:83caa8fa1d2c | 10 | // http://www.apache.org/licenses/LICENSE-2.0 |
| cyliang | 0:83caa8fa1d2c | 11 | // |
| cyliang | 0:83caa8fa1d2c | 12 | // Unless required by applicable law or agreed to in writing, software |
| cyliang | 0:83caa8fa1d2c | 13 | // distributed under the License is distributed on an "AS IS" BASIS, |
| cyliang | 0:83caa8fa1d2c | 14 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| cyliang | 0:83caa8fa1d2c | 15 | // See the License for the specific language governing permissions and |
| cyliang | 0:83caa8fa1d2c | 16 | // limitations under the License. |
| cyliang | 0:83caa8fa1d2c | 17 | // ---------------------------------------------------------------------------- |
| cyliang | 0:83caa8fa1d2c | 18 | |
| cyliang | 0:83caa8fa1d2c | 19 | #if defined(TARGET_IS_PC_LINUX) |
| cyliang | 0:83caa8fa1d2c | 20 | |
| cyliang | 0:83caa8fa1d2c | 21 | #include "update-client-pal-filesystem/arm_uc_pal_extensions.h" |
| cyliang | 0:83caa8fa1d2c | 22 | |
| cyliang | 0:83caa8fa1d2c | 23 | #include "update-client-common/arm_uc_metadata_header_v2.h" |
| cyliang | 0:83caa8fa1d2c | 24 | #include "update-client-common/arm_uc_types.h" |
| cyliang | 0:83caa8fa1d2c | 25 | #include "update-client-common/arm_uc_utilities.h" |
| cyliang | 0:83caa8fa1d2c | 26 | #include "arm_uc_pal_filesystem_utils.h" |
| cyliang | 0:83caa8fa1d2c | 27 | |
| cyliang | 0:83caa8fa1d2c | 28 | #include "pal.h" |
| cyliang | 0:83caa8fa1d2c | 29 | |
| cyliang | 0:83caa8fa1d2c | 30 | #include "mbed-trace/mbed_trace.h" |
| cyliang | 0:83caa8fa1d2c | 31 | #define TRACE_GROUP "update-client-extensions" |
| cyliang | 0:83caa8fa1d2c | 32 | |
| cyliang | 0:83caa8fa1d2c | 33 | #include <stdlib.h> |
| cyliang | 0:83caa8fa1d2c | 34 | #include <inttypes.h> |
| cyliang | 0:83caa8fa1d2c | 35 | #include <limits.h> |
| cyliang | 0:83caa8fa1d2c | 36 | #include <stdio.h> |
| cyliang | 0:83caa8fa1d2c | 37 | |
| cyliang | 0:83caa8fa1d2c | 38 | #ifndef MBED_CONF_UPDATE_CLIENT_APPLICATION_DETAILS |
| cyliang | 0:83caa8fa1d2c | 39 | #define MBED_CONF_UPDATE_CLIENT_APPLICATION_DETAILS 0 |
| cyliang | 0:83caa8fa1d2c | 40 | #endif |
| cyliang | 0:83caa8fa1d2c | 41 | |
| cyliang | 0:83caa8fa1d2c | 42 | #ifndef MBED_CONF_UPDATE_CLIENT_BOOTLOADER_DETAILS |
| cyliang | 0:83caa8fa1d2c | 43 | #define MBED_CONF_UPDATE_CLIENT_BOOTLOADER_DETAILS 0 |
| cyliang | 0:83caa8fa1d2c | 44 | #endif |
| cyliang | 0:83caa8fa1d2c | 45 | |
| cyliang | 0:83caa8fa1d2c | 46 | static void (*arm_ucex_linux_callback)(uint32_t) = NULL; |
| cyliang | 0:83caa8fa1d2c | 47 | static palImageId_t arm_ucex_activate_image_id; |
| cyliang | 0:83caa8fa1d2c | 48 | |
| cyliang | 0:83caa8fa1d2c | 49 | #ifndef PAL_UPDATE_ACTIVATE_SCRIPT |
| cyliang | 0:83caa8fa1d2c | 50 | #define PAL_UPDATE_ACTIVATE_SCRIPT "./activate_script" |
| cyliang | 0:83caa8fa1d2c | 51 | #endif |
| cyliang | 0:83caa8fa1d2c | 52 | |
| cyliang | 0:83caa8fa1d2c | 53 | arm_uc_error_t pal_ext_imageInitAPI(void (*callback)(uint32_t)) |
| cyliang | 0:83caa8fa1d2c | 54 | { |
| cyliang | 0:83caa8fa1d2c | 55 | arm_uc_error_t result = { .code = ERR_NONE }; |
| cyliang | 0:83caa8fa1d2c | 56 | |
| cyliang | 0:83caa8fa1d2c | 57 | arm_ucex_linux_callback = callback; |
| cyliang | 0:83caa8fa1d2c | 58 | |
| cyliang | 0:83caa8fa1d2c | 59 | return result; |
| cyliang | 0:83caa8fa1d2c | 60 | } |
| cyliang | 0:83caa8fa1d2c | 61 | |
| cyliang | 0:83caa8fa1d2c | 62 | arm_uc_error_t pal_ext_imageGetActiveDetails(arm_uc_firmware_details_t* details) |
| cyliang | 0:83caa8fa1d2c | 63 | { |
| cyliang | 0:83caa8fa1d2c | 64 | arm_uc_error_t result = { .code = ERR_INVALID_PARAMETER }; |
| cyliang | 0:83caa8fa1d2c | 65 | |
| cyliang | 0:83caa8fa1d2c | 66 | if (details) |
| cyliang | 0:83caa8fa1d2c | 67 | { |
| cyliang | 0:83caa8fa1d2c | 68 | /* dummy implementation, return 0 */ |
| cyliang | 0:83caa8fa1d2c | 69 | memset(details, 0, sizeof(arm_uc_firmware_details_t)); |
| cyliang | 0:83caa8fa1d2c | 70 | |
| cyliang | 0:83caa8fa1d2c | 71 | result.code = ERR_NONE; |
| cyliang | 0:83caa8fa1d2c | 72 | |
| cyliang | 0:83caa8fa1d2c | 73 | if (arm_ucex_linux_callback) |
| cyliang | 0:83caa8fa1d2c | 74 | { |
| cyliang | 0:83caa8fa1d2c | 75 | arm_ucex_linux_callback(ARM_UC_PAAL_EVENT_GET_ACTIVE_FIRMWARE_DETAILS_DONE); |
| cyliang | 0:83caa8fa1d2c | 76 | } |
| cyliang | 0:83caa8fa1d2c | 77 | } |
| cyliang | 0:83caa8fa1d2c | 78 | |
| cyliang | 0:83caa8fa1d2c | 79 | return result; |
| cyliang | 0:83caa8fa1d2c | 80 | } |
| cyliang | 0:83caa8fa1d2c | 81 | |
| cyliang | 0:83caa8fa1d2c | 82 | arm_uc_error_t pal_ext_installerGetDetails(arm_uc_installer_details_t* details) |
| cyliang | 0:83caa8fa1d2c | 83 | { |
| cyliang | 0:83caa8fa1d2c | 84 | arm_uc_error_t result = { .code = ERR_INVALID_PARAMETER }; |
| cyliang | 0:83caa8fa1d2c | 85 | |
| cyliang | 0:83caa8fa1d2c | 86 | if (details) |
| cyliang | 0:83caa8fa1d2c | 87 | { |
| cyliang | 0:83caa8fa1d2c | 88 | /* dummy implementation, return 0 */ |
| cyliang | 0:83caa8fa1d2c | 89 | memset(details, 0, sizeof(arm_uc_installer_details_t)); |
| cyliang | 0:83caa8fa1d2c | 90 | |
| cyliang | 0:83caa8fa1d2c | 91 | result.code = ERR_NONE; |
| cyliang | 0:83caa8fa1d2c | 92 | |
| cyliang | 0:83caa8fa1d2c | 93 | if (arm_ucex_linux_callback) |
| cyliang | 0:83caa8fa1d2c | 94 | { |
| cyliang | 0:83caa8fa1d2c | 95 | arm_ucex_linux_callback(ARM_UC_PAAL_EVENT_GET_INSTALLER_DETAILS_DONE); |
| cyliang | 0:83caa8fa1d2c | 96 | } |
| cyliang | 0:83caa8fa1d2c | 97 | } |
| cyliang | 0:83caa8fa1d2c | 98 | |
| cyliang | 0:83caa8fa1d2c | 99 | return result; |
| cyliang | 0:83caa8fa1d2c | 100 | } |
| cyliang | 0:83caa8fa1d2c | 101 | |
| cyliang | 0:83caa8fa1d2c | 102 | static void pal_ext_imageActivationWorker(void* location) |
| cyliang | 0:83caa8fa1d2c | 103 | { |
| cyliang | 0:83caa8fa1d2c | 104 | char cmd_buf[sizeof(PAL_UPDATE_ACTIVATE_SCRIPT) + 1 + PAL_MAX_FILE_AND_FOLDER_LENGTH + 1]; |
| cyliang | 0:83caa8fa1d2c | 105 | char path_buf[PAL_MAX_FILE_AND_FOLDER_LENGTH]; |
| cyliang | 0:83caa8fa1d2c | 106 | |
| cyliang | 0:83caa8fa1d2c | 107 | arm_uc_error_t result = arm_uc_pal_filesystem_get_path(*(palImageId_t*)location, FIRMWARE_IMAGE_ITEM_DATA, |
| cyliang | 0:83caa8fa1d2c | 108 | path_buf, PAL_MAX_FILE_AND_FOLDER_LENGTH); |
| cyliang | 0:83caa8fa1d2c | 109 | palStatus_t rc = PAL_ERR_GENERIC_FAILURE; |
| cyliang | 0:83caa8fa1d2c | 110 | |
| cyliang | 0:83caa8fa1d2c | 111 | if (result.code == ERR_NONE) |
| cyliang | 0:83caa8fa1d2c | 112 | { |
| cyliang | 0:83caa8fa1d2c | 113 | int err = snprintf(cmd_buf, sizeof(cmd_buf), "%s %s", |
| cyliang | 0:83caa8fa1d2c | 114 | PAL_UPDATE_ACTIVATE_SCRIPT, path_buf); |
| cyliang | 0:83caa8fa1d2c | 115 | if (err > 0) |
| cyliang | 0:83caa8fa1d2c | 116 | { |
| cyliang | 0:83caa8fa1d2c | 117 | rc = PAL_SUCCESS; |
| cyliang | 0:83caa8fa1d2c | 118 | } |
| cyliang | 0:83caa8fa1d2c | 119 | else |
| cyliang | 0:83caa8fa1d2c | 120 | { |
| cyliang | 0:83caa8fa1d2c | 121 | tr_err("snprintf failed with err %i", err); |
| cyliang | 0:83caa8fa1d2c | 122 | rc = PAL_ERR_GENERIC_FAILURE; |
| cyliang | 0:83caa8fa1d2c | 123 | } |
| cyliang | 0:83caa8fa1d2c | 124 | } |
| cyliang | 0:83caa8fa1d2c | 125 | |
| cyliang | 0:83caa8fa1d2c | 126 | |
| cyliang | 0:83caa8fa1d2c | 127 | if (rc == PAL_SUCCESS) |
| cyliang | 0:83caa8fa1d2c | 128 | { |
| cyliang | 0:83caa8fa1d2c | 129 | tr_debug("Activate by executing %s", cmd_buf); |
| cyliang | 0:83caa8fa1d2c | 130 | int err = system(cmd_buf); |
| cyliang | 0:83caa8fa1d2c | 131 | err = WEXITSTATUS(err); |
| cyliang | 0:83caa8fa1d2c | 132 | |
| cyliang | 0:83caa8fa1d2c | 133 | if (err != -1) |
| cyliang | 0:83caa8fa1d2c | 134 | { |
| cyliang | 0:83caa8fa1d2c | 135 | tr_debug("Activate completed with %" PRId32, err); |
| cyliang | 0:83caa8fa1d2c | 136 | rc = PAL_SUCCESS; |
| cyliang | 0:83caa8fa1d2c | 137 | } |
| cyliang | 0:83caa8fa1d2c | 138 | else |
| cyliang | 0:83caa8fa1d2c | 139 | { |
| cyliang | 0:83caa8fa1d2c | 140 | tr_err("system call failed with err %" PRId32, err); |
| cyliang | 0:83caa8fa1d2c | 141 | rc = PAL_ERR_GENERIC_FAILURE; |
| cyliang | 0:83caa8fa1d2c | 142 | } |
| cyliang | 0:83caa8fa1d2c | 143 | } |
| cyliang | 0:83caa8fa1d2c | 144 | fflush(stdout); |
| cyliang | 0:83caa8fa1d2c | 145 | sleep(1); |
| cyliang | 0:83caa8fa1d2c | 146 | |
| cyliang | 0:83caa8fa1d2c | 147 | if (arm_ucex_linux_callback) |
| cyliang | 0:83caa8fa1d2c | 148 | { |
| cyliang | 0:83caa8fa1d2c | 149 | uint32_t event = (rc == PAL_SUCCESS? ARM_UC_PAAL_EVENT_ACTIVATE_DONE : ARM_UC_PAAL_EVENT_ACTIVATE_ERROR); |
| cyliang | 0:83caa8fa1d2c | 150 | arm_ucex_linux_callback(event); |
| cyliang | 0:83caa8fa1d2c | 151 | } |
| cyliang | 0:83caa8fa1d2c | 152 | } |
| cyliang | 0:83caa8fa1d2c | 153 | |
| cyliang | 0:83caa8fa1d2c | 154 | arm_uc_error_t pal_ext_imageActivate(uint32_t location) |
| cyliang | 0:83caa8fa1d2c | 155 | { |
| cyliang | 0:83caa8fa1d2c | 156 | arm_uc_error_t err = { .code = ERR_INVALID_PARAMETER }; |
| cyliang | 0:83caa8fa1d2c | 157 | |
| cyliang | 0:83caa8fa1d2c | 158 | memcpy(&arm_ucex_activate_image_id, &location, sizeof(palImageId_t)); |
| cyliang | 0:83caa8fa1d2c | 159 | |
| cyliang | 0:83caa8fa1d2c | 160 | palThreadID_t thread_id = 0; |
| cyliang | 0:83caa8fa1d2c | 161 | palStatus_t rc = pal_osThreadCreateWithAlloc(pal_ext_imageActivationWorker, &arm_ucex_activate_image_id, |
| cyliang | 0:83caa8fa1d2c | 162 | PAL_osPriorityBelowNormal, PTHREAD_STACK_MIN, NULL, &thread_id); |
| cyliang | 0:83caa8fa1d2c | 163 | if (rc != PAL_SUCCESS) |
| cyliang | 0:83caa8fa1d2c | 164 | { |
| cyliang | 0:83caa8fa1d2c | 165 | tr_err("Thread creation failed with %x", rc); |
| cyliang | 0:83caa8fa1d2c | 166 | err.code = ERR_INVALID_PARAMETER; |
| cyliang | 0:83caa8fa1d2c | 167 | } |
| cyliang | 0:83caa8fa1d2c | 168 | else |
| cyliang | 0:83caa8fa1d2c | 169 | { |
| cyliang | 0:83caa8fa1d2c | 170 | tr_debug("Activation thread created, thread ID: %" PRIu32, thread_id); |
| cyliang | 0:83caa8fa1d2c | 171 | err.code = ERR_NONE; |
| cyliang | 0:83caa8fa1d2c | 172 | } |
| cyliang | 0:83caa8fa1d2c | 173 | |
| cyliang | 0:83caa8fa1d2c | 174 | return err; |
| cyliang | 0:83caa8fa1d2c | 175 | } |
| cyliang | 0:83caa8fa1d2c | 176 | |
| cyliang | 0:83caa8fa1d2c | 177 | #endif |