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.
flash_decoder.c
00001 /** 00002 * @file flash_decoder.c 00003 * @brief Implementation of flash_decoder.h 00004 * 00005 * DAPLink Interface Firmware 00006 * Copyright (c) 2009-2016, ARM Limited, All Rights Reserved 00007 * SPDX-License-Identifier: Apache-2.0 00008 * 00009 * Licensed under the Apache License, Version 2.0 (the "License"); you may 00010 * not use this file except in compliance with the License. 00011 * You may obtain a copy of the License at 00012 * 00013 * http://www.apache.org/licenses/LICENSE-2.0 00014 * 00015 * Unless required by applicable law or agreed to in writing, software 00016 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 00017 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00018 * See the License for the specific language governing permissions and 00019 * limitations under the License. 00020 */ 00021 00022 #include <string.h> 00023 00024 #include "flash_decoder.h" 00025 #include "util.h" 00026 #include "daplink.h" 00027 #include "flash_manager.h" 00028 #include "target_config.h" // for target_device 00029 #include "settings.h" // for config_get_automation_allowed 00030 #include "validation.h" 00031 #include "target_board.h" 00032 00033 // Set to 1 to enable debugging 00034 #define DEBUG_FLASH_DECODER 0 00035 00036 #if DEBUG_FLASH_DECODER 00037 #include "daplink_debug.h" 00038 #define flash_decoder_printf debug_msg 00039 #else 00040 #define flash_decoder_printf(...) 00041 #endif 00042 00043 typedef enum { 00044 DECODER_STATE_CLOSED, 00045 DECODER_STATE_OPEN, 00046 DECODER_STATE_DONE, 00047 DECODER_STATE_ERROR 00048 } decoder_state_t; 00049 00050 static uint8_t flash_buf[FLASH_DECODER_MIN_SIZE]; 00051 static decoder_state_t state = DECODER_STATE_CLOSED; 00052 static flash_decoder_type_t flash_type; 00053 static uint32_t flash_buf_pos; 00054 static uint32_t initial_addr; 00055 static uint32_t current_addr; 00056 static bool flash_initialized; 00057 static bool initial_addr_set; 00058 static bool flash_type_target_bin; 00059 00060 static bool flash_decoder_is_at_end(uint32_t addr, const uint8_t *data, uint32_t size); 00061 00062 flash_decoder_type_t flash_decoder_detect_type(const uint8_t *data, uint32_t size, uint32_t addr, bool addr_valid) 00063 { 00064 daplink_info_t info; 00065 util_assert(size >= FLASH_DECODER_MIN_SIZE); 00066 // Check if this is a daplink image 00067 memcpy(&info, data + DAPLINK_INFO_OFFSET, sizeof(info)); 00068 if(!addr_valid){ //reset until we know the binary type 00069 flash_type_target_bin = false; 00070 } 00071 if (DAPLINK_HIC_ID == info.hic_id) { 00072 if (DAPLINK_BUILD_KEY_IF == info.build_key) { 00073 // Interface update 00074 return FLASH_DECODER_TYPE_INTERFACE; 00075 } else if (DAPLINK_BUILD_KEY_BL == info.build_key) { 00076 // Bootloader update 00077 return FLASH_DECODER_TYPE_BOOTLOADER; 00078 } else { 00079 return FLASH_DECODER_TYPE_UNKNOWN; 00080 } 00081 } 00082 00083 // Check if a valid vector table for the target can be found 00084 if (validate_bin_nvic(data)) { 00085 if(!addr_valid){ //binary is a bin type 00086 flash_type_target_bin = true; 00087 } 00088 return FLASH_DECODER_TYPE_TARGET; 00089 } 00090 00091 // If an address is specified then the data can be decoded 00092 if (addr_valid) { 00093 // TODO - future improvement - make sure address is within target's flash 00094 return FLASH_DECODER_TYPE_TARGET; 00095 } 00096 00097 return FLASH_DECODER_TYPE_UNKNOWN; 00098 } 00099 00100 error_t flash_decoder_get_flash(flash_decoder_type_t type, uint32_t addr, bool addr_valid, uint32_t *start_addr, const flash_intf_t **flash_intf) 00101 { 00102 error_t status = ERROR_SUCCESS; 00103 uint32_t flash_start_local; 00104 const flash_intf_t *flash_intf_local = 0; 00105 00106 if ((0 == start_addr) || (0 == flash_intf)) { 00107 util_assert(0); 00108 return ERROR_INTERNAL; 00109 } 00110 00111 *start_addr = 0; 00112 *flash_intf = 0; 00113 flash_start_local = 0; 00114 flash_intf_local = 0; 00115 00116 if (daplink_is_bootloader()) { 00117 if (FLASH_DECODER_TYPE_INTERFACE == type) { 00118 if (addr_valid && (DAPLINK_ROM_IF_START != addr)) { 00119 // Address is wrong so display error message 00120 status = ERROR_FD_INTF_UPDT_ADDR_WRONG; 00121 } else { 00122 // Setup for update 00123 flash_start_local = DAPLINK_ROM_IF_START; 00124 flash_intf_local = flash_intf_iap_protected; 00125 } 00126 } else if (FLASH_DECODER_TYPE_TARGET == type) { 00127 // "Target" update in this case would be a 3rd party interface application 00128 flash_start_local = DAPLINK_ROM_IF_START; 00129 flash_intf_local = flash_intf_iap_protected; 00130 } else { 00131 status = ERROR_FD_UNSUPPORTED_UPDATE; 00132 } 00133 } else if (daplink_is_interface()) { 00134 if (FLASH_DECODER_TYPE_BOOTLOADER == type) { 00135 if (addr_valid && (DAPLINK_ROM_BL_START != addr)) { 00136 // Address is wrong so display error message 00137 status = ERROR_FD_BL_UPDT_ADDR_WRONG; 00138 } else { 00139 // Setup for update 00140 flash_start_local = DAPLINK_ROM_BL_START; 00141 flash_intf_local = flash_intf_iap_protected; 00142 } 00143 } else if (FLASH_DECODER_TYPE_TARGET == type) { 00144 if (g_board_info.target_cfg) { 00145 region_info_t * region = g_board_info.target_cfg->flash_regions; 00146 for (; region->start != 0 || region->end != 0; ++region) { 00147 if (kRegionIsDefault == region->flags) { 00148 flash_start_local = region->start; 00149 break; 00150 } 00151 } 00152 flash_intf_local = flash_intf_target; 00153 } else { 00154 status = ERROR_FD_UNSUPPORTED_UPDATE; 00155 } 00156 } else { 00157 status = ERROR_FD_UNSUPPORTED_UPDATE; 00158 } 00159 } else { 00160 status = ERROR_FD_UNSUPPORTED_UPDATE; 00161 } 00162 00163 // Don't allow bootloader updates unless automation is allowed 00164 if (!config_get_automation_allowed() && (FLASH_DECODER_TYPE_BOOTLOADER == type)) { 00165 status = ERROR_FD_UNSUPPORTED_UPDATE; 00166 } 00167 00168 if (ERROR_SUCCESS != status) { 00169 return status; 00170 } 00171 00172 if (0 == flash_intf_local) { 00173 util_assert(0); 00174 return ERROR_INTERNAL; 00175 } 00176 00177 *start_addr = flash_start_local; 00178 *flash_intf = flash_intf_local; 00179 return status; 00180 } 00181 00182 error_t flash_decoder_open(void) 00183 { 00184 flash_decoder_printf("flash_decoder_open()\r\n"); 00185 00186 // Stream must not be open already 00187 if (state != DECODER_STATE_CLOSED) { 00188 util_assert(0); 00189 return ERROR_INTERNAL; 00190 } 00191 00192 memset(flash_buf, 0xff, sizeof(flash_buf)); 00193 state = DECODER_STATE_OPEN; 00194 flash_type = FLASH_DECODER_TYPE_UNKNOWN; 00195 flash_buf_pos = 0; 00196 initial_addr = 0; 00197 current_addr = 0; 00198 flash_initialized = false; 00199 initial_addr_set = false; 00200 return ERROR_SUCCESS; 00201 } 00202 00203 error_t flash_decoder_write(uint32_t addr, const uint8_t *data, uint32_t size) 00204 { 00205 error_t status; 00206 flash_decoder_printf("flash_decoder_write(addr=0x%x, size=0x%x)\r\n", addr, size); 00207 00208 if (DECODER_STATE_OPEN != state) { 00209 util_assert(0); 00210 return ERROR_INTERNAL; 00211 } 00212 00213 // Set the initial address the first time through 00214 if (!initial_addr_set) { 00215 initial_addr = addr; 00216 current_addr = initial_addr; 00217 flash_decoder_printf(" initial_addr=0x%x\r\n", initial_addr); 00218 initial_addr_set = true; 00219 } 00220 00221 if (!flash_initialized) { 00222 uint32_t copy_size; 00223 bool flash_type_known = false; 00224 bool sequential; 00225 // Check if the data is sequential 00226 sequential = addr == current_addr; 00227 current_addr += size; 00228 00229 // Buffer data until the flash type is known 00230 if (sequential) { 00231 // Copy data into buffer 00232 copy_size = MIN(size, sizeof(flash_buf) - flash_buf_pos); 00233 memcpy(&flash_buf[flash_buf_pos], data, copy_size); 00234 flash_buf_pos += copy_size; 00235 flash_decoder_printf(" buffering %i bytes\r\n", copy_size); 00236 // Update vars so they no longer include the buffered data 00237 data += copy_size; 00238 size -= copy_size; 00239 addr += copy_size; 00240 00241 // If enough data has been buffered then determine the type 00242 if (flash_buf_pos >= sizeof(flash_buf)) { 00243 util_assert(sizeof(flash_buf) == flash_buf_pos); 00244 // Determine flash type and get info for it 00245 flash_type = flash_decoder_detect_type(flash_buf, flash_buf_pos, initial_addr, true); 00246 flash_decoder_printf(" Buffering complete, setting flash_type=%i\r\n", flash_type); 00247 flash_type_known = true; 00248 } 00249 } else { 00250 flash_type = FLASH_DECODER_TYPE_TARGET; 00251 flash_decoder_printf(" Non sequential addr, setting flash_type=%i\r\n", flash_type); 00252 flash_type_known = true; 00253 } 00254 00255 // If flash type is known initialize the flash manager 00256 if (flash_type_known) { 00257 const flash_intf_t *flash_intf; 00258 uint32_t flash_start_addr; 00259 status = flash_decoder_get_flash(flash_type, initial_addr, true, &flash_start_addr, &flash_intf); 00260 00261 if (ERROR_SUCCESS != status) { 00262 state = DECODER_STATE_ERROR; 00263 return status; 00264 } 00265 00266 flash_decoder_printf(" flash_start_addr=0x%x\r\n", flash_start_addr); 00267 // Initialize flash manager 00268 util_assert(!flash_initialized); 00269 status = flash_manager_init(flash_intf); 00270 flash_decoder_printf(" flash_manager_init ret %i\r\n", status); 00271 00272 if (ERROR_SUCCESS != status) { 00273 state = DECODER_STATE_ERROR; 00274 return status; 00275 } 00276 00277 flash_initialized = true; 00278 } 00279 00280 // If flash has been initalized then write out buffered data 00281 if (flash_initialized) { 00282 status = flash_manager_data(initial_addr, flash_buf, flash_buf_pos); 00283 flash_decoder_printf(" Flushing buffer initial_addr=0x%x, flash_buf_pos=%i, flash_manager_data ret=%i\r\n", 00284 initial_addr, flash_buf_pos, status); 00285 00286 if (ERROR_SUCCESS != status) { 00287 state = DECODER_STATE_ERROR; 00288 return status; 00289 } 00290 } 00291 } 00292 00293 // Write data as normal if flash has been initialized 00294 if (flash_initialized) { 00295 status = flash_manager_data(addr, data, size); 00296 flash_decoder_printf(" Writing data, addr=0x%x, size=0x%x, flash_manager_data ret %i\r\n", 00297 addr, size, status); 00298 00299 if (ERROR_SUCCESS != status) { 00300 state = DECODER_STATE_ERROR; 00301 return status; 00302 } 00303 } 00304 00305 // Check if this is the end of data 00306 if (flash_decoder_is_at_end(addr, data, size)) { 00307 flash_decoder_printf(" End of transfer detected - addr 0x%08x, size 0x%08x\r\n", 00308 addr, size); 00309 state = DECODER_STATE_DONE; 00310 return ERROR_SUCCESS_DONE; 00311 } 00312 00313 return ERROR_SUCCESS; 00314 } 00315 00316 error_t flash_decoder_close(void) 00317 { 00318 error_t status = ERROR_SUCCESS; 00319 decoder_state_t prev_state = state; 00320 flash_decoder_printf("flash_decoder_close()\r\n"); 00321 00322 if (DECODER_STATE_CLOSED == state) { 00323 util_assert(0); 00324 return ERROR_INTERNAL; 00325 } 00326 00327 state = DECODER_STATE_CLOSED; 00328 00329 if (flash_initialized) { 00330 status = flash_manager_uninit(); 00331 flash_decoder_printf(" flash_manager_uninit ret %i\r\n", status); 00332 } 00333 00334 if ((DECODER_STATE_DONE != prev_state) && 00335 (flash_type != FLASH_DECODER_TYPE_TARGET) && 00336 (status == ERROR_SUCCESS)) { 00337 status = ERROR_IAP_UPDT_INCOMPLETE; 00338 } 00339 00340 return status; 00341 } 00342 00343 static bool flash_decoder_is_at_end(uint32_t addr, const uint8_t *data, uint32_t size) 00344 { 00345 uint32_t end_addr=0; 00346 00347 switch (flash_type) { 00348 case FLASH_DECODER_TYPE_BOOTLOADER: 00349 end_addr = DAPLINK_ROM_BL_START + DAPLINK_ROM_BL_SIZE; 00350 break; 00351 00352 case FLASH_DECODER_TYPE_INTERFACE: 00353 end_addr = DAPLINK_ROM_IF_START + DAPLINK_ROM_IF_SIZE; 00354 break; 00355 00356 case FLASH_DECODER_TYPE_TARGET: 00357 //only if we are sure it is a bin for the target; without check unordered hex files will cause to terminate flashing 00358 if (flash_type_target_bin && g_board_info.target_cfg) { 00359 region_info_t * region = g_board_info.target_cfg->flash_regions; 00360 for (; region->start != 0 || region->end != 0; ++region) { 00361 if (addr >= region->start && addr<=region->end) { 00362 end_addr = region->end; 00363 break; 00364 } 00365 } 00366 if(end_addr == 0){ //invalid end_addr 00367 return false; 00368 } 00369 00370 } 00371 else { 00372 return false; 00373 } 00374 break; 00375 00376 default: 00377 return false; 00378 } 00379 00380 if (addr + size >= end_addr) { 00381 return true; 00382 } else { 00383 return false; 00384 } 00385 }
Generated on Tue Jul 12 2022 15:37:16 by
