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.
file_stream.c
00001 /** 00002 * @file file_stream.c 00003 * @brief Implementation of file_stream.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 "file_stream.h" 00025 #include "util.h" 00026 #include "intelhex.h" 00027 #include "flash_decoder.h" 00028 #include "error.h" 00029 #include "cmsis_os2.h" 00030 #include "compiler.h" 00031 #include "validation.h" 00032 00033 typedef enum { 00034 STREAM_STATE_CLOSED, 00035 STREAM_STATE_OPEN, 00036 STREAM_STATE_END, 00037 STREAM_STATE_ERROR 00038 } stream_state_t; 00039 00040 typedef bool (*stream_detect_cb_t)(const uint8_t *data, uint32_t size); 00041 typedef error_t (*stream_open_cb_t)(void *state); 00042 typedef error_t (*stream_write_cb_t)(void *state, const uint8_t *data, uint32_t size); 00043 typedef error_t (*stream_close_cb_t)(void *state); 00044 00045 typedef struct { 00046 stream_detect_cb_t detect; 00047 stream_open_cb_t open; 00048 stream_write_cb_t write; 00049 stream_close_cb_t close; 00050 } stream_t; 00051 00052 typedef struct { 00053 uint8_t vector_buf[FLASH_DECODER_MIN_SIZE]; 00054 uint8_t buf_pos; 00055 uint32_t flash_addr; 00056 } bin_state_t; 00057 00058 typedef struct { 00059 bool parsing_complete; 00060 uint8_t bin_buffer[256]; 00061 } hex_state_t; 00062 00063 typedef union { 00064 bin_state_t bin; 00065 hex_state_t hex; 00066 } shared_state_t; 00067 00068 static bool detect_bin(const uint8_t *data, uint32_t size); 00069 static error_t open_bin(void *state); 00070 static error_t write_bin(void *state, const uint8_t *data, uint32_t size); 00071 static error_t close_bin(void *state); 00072 00073 static bool detect_hex(const uint8_t *data, uint32_t size); 00074 static error_t open_hex(void *state); 00075 static error_t write_hex(void *state, const uint8_t *data, uint32_t size); 00076 static error_t close_hex(void *state); 00077 00078 stream_t stream[] = { 00079 {detect_bin, open_bin, write_bin, close_bin}, // STREAM_TYPE_BIN 00080 {detect_hex, open_hex, write_hex, close_hex}, // STREAM_TYPE_HEX 00081 }; 00082 COMPILER_ASSERT(ARRAY_SIZE(stream) == STREAM_TYPE_COUNT); 00083 // STREAM_TYPE_NONE must not be included in count 00084 COMPILER_ASSERT(STREAM_TYPE_NONE > STREAM_TYPE_COUNT); 00085 00086 static shared_state_t shared_state; 00087 static stream_state_t state = STREAM_STATE_CLOSED; 00088 static stream_t *current_stream = 0; 00089 00090 // Thread variables (STUB these if RTX is not used) 00091 static osThreadId_t stream_thread_tid = 0; 00092 static void stream_thread_set(void) 00093 { 00094 stream_thread_tid = osThreadGetId(); 00095 } 00096 static void stream_thread_assert(void) 00097 { 00098 util_assert(osThreadGetId() == stream_thread_tid); 00099 } 00100 00101 stream_type_t stream_start_identify(const uint8_t *data, uint32_t size) 00102 { 00103 stream_type_t i; 00104 00105 for (i = STREAM_TYPE_START; i < STREAM_TYPE_COUNT; i++) { 00106 if (stream[i].detect(data, size)) { 00107 return i; 00108 } 00109 } 00110 00111 return STREAM_TYPE_NONE; 00112 } 00113 00114 // Identify the file type from its extension 00115 stream_type_t stream_type_from_name(const vfs_filename_t filename) 00116 { 00117 // 8.3 file names must be in upper case 00118 if (0 == strncmp("BIN", &filename[8], 3)) { 00119 return STREAM_TYPE_BIN; 00120 } else if (0 == strncmp("HEX", &filename[8], 3)) { 00121 return STREAM_TYPE_HEX; 00122 } else { 00123 return STREAM_TYPE_NONE; 00124 } 00125 } 00126 00127 error_t stream_open(stream_type_t stream_type) 00128 { 00129 error_t status; 00130 00131 // Stream must not be open already 00132 if (state != STREAM_STATE_CLOSED) { 00133 util_assert(0); 00134 return ERROR_INTERNAL; 00135 } 00136 00137 // Stream must be of a supported type 00138 if (stream_type >= STREAM_TYPE_COUNT) { 00139 util_assert(0); 00140 return ERROR_INTERNAL; 00141 } 00142 00143 stream_thread_set(); 00144 // Initialize all variables 00145 memset(&shared_state, 0, sizeof(shared_state)); 00146 state = STREAM_STATE_OPEN; 00147 current_stream = &stream[stream_type]; 00148 // Initialize the specified stream 00149 status = current_stream->open(&shared_state); 00150 00151 if (ERROR_SUCCESS != status) { 00152 state = STREAM_STATE_ERROR; 00153 } 00154 00155 return status; 00156 } 00157 00158 error_t stream_write(const uint8_t *data, uint32_t size) 00159 { 00160 error_t status; 00161 00162 // Stream must be open already 00163 if (state != STREAM_STATE_OPEN) { 00164 util_assert(0); 00165 return ERROR_INTERNAL; 00166 } 00167 00168 // Check thread after checking state since the stream thread is 00169 // set only if stream_open has been called 00170 stream_thread_assert(); 00171 // Write to stream 00172 status = current_stream->write(&shared_state, data, size); 00173 00174 if (ERROR_SUCCESS_DONE == status) { 00175 state = STREAM_STATE_END; 00176 } else if ((ERROR_SUCCESS_DONE_OR_CONTINUE == status) || (ERROR_SUCCESS == status)) { 00177 // Stream should remain in the open state 00178 util_assert(STREAM_STATE_OPEN == state); 00179 } else { 00180 state = STREAM_STATE_ERROR; 00181 } 00182 00183 return status; 00184 } 00185 00186 error_t stream_close(void) 00187 { 00188 error_t status; 00189 00190 // Stream must not be closed already 00191 if (STREAM_STATE_CLOSED == state) { 00192 util_assert(0); 00193 return ERROR_INTERNAL; 00194 } 00195 00196 // Check thread after checking state since the stream thread is 00197 // set only if stream_open has been called 00198 stream_thread_assert(); 00199 // Close stream 00200 status = current_stream->close(&shared_state); 00201 state = STREAM_STATE_CLOSED; 00202 return status; 00203 } 00204 00205 /* Binary file processing */ 00206 00207 static bool detect_bin(const uint8_t *data, uint32_t size) 00208 { 00209 return FLASH_DECODER_TYPE_UNKNOWN != flash_decoder_detect_type(data, size, 0, false); 00210 } 00211 00212 static error_t open_bin(void *state) 00213 { 00214 error_t status; 00215 status = flash_decoder_open(); 00216 return status; 00217 } 00218 00219 static error_t write_bin(void *state, const uint8_t *data, uint32_t size) 00220 { 00221 error_t status; 00222 bin_state_t *bin_state = (bin_state_t *)state; 00223 00224 if (bin_state->buf_pos < FLASH_DECODER_MIN_SIZE) { 00225 flash_decoder_type_t flash_type; 00226 uint32_t size_left; 00227 uint32_t copy_size; 00228 uint32_t start_addr; 00229 const flash_intf_t *flash_intf; 00230 // Buffer Data 00231 size_left = FLASH_DECODER_MIN_SIZE - bin_state->buf_pos; 00232 copy_size = MIN(size_left, size); 00233 memcpy(bin_state->vector_buf + bin_state->buf_pos, data, copy_size); 00234 bin_state->buf_pos += copy_size; 00235 00236 if (bin_state->buf_pos < FLASH_DECODER_MIN_SIZE) { 00237 // Not enough data to determine type 00238 return ERROR_SUCCESS; 00239 } 00240 00241 data += copy_size; 00242 size -= copy_size; 00243 // Determine type 00244 flash_type = flash_decoder_detect_type(bin_state->vector_buf, bin_state->buf_pos, 0, false); 00245 00246 if (FLASH_DECODER_TYPE_UNKNOWN == flash_type) { 00247 return ERROR_FD_UNSUPPORTED_UPDATE; 00248 } 00249 00250 // Determine flash addresss 00251 status = flash_decoder_get_flash(flash_type, 0, false, &start_addr, &flash_intf); 00252 00253 if (ERROR_SUCCESS != status) { 00254 return status; 00255 } 00256 00257 bin_state->flash_addr = start_addr; 00258 // Pass on data to the decoder 00259 status = flash_decoder_write(bin_state->flash_addr, bin_state->vector_buf, bin_state->buf_pos); 00260 00261 if (ERROR_SUCCESS != status) { 00262 return status; 00263 } 00264 00265 bin_state->flash_addr += bin_state->buf_pos; 00266 } 00267 00268 // Write data 00269 status = flash_decoder_write(bin_state->flash_addr, data, size); 00270 00271 if (ERROR_SUCCESS != status) { 00272 return status; 00273 } 00274 00275 bin_state->flash_addr += size; 00276 // There is no way to determine the end of a binary 00277 // file so any point could be the end 00278 return ERROR_SUCCESS_DONE_OR_CONTINUE; 00279 } 00280 00281 static error_t close_bin(void *state) 00282 { 00283 error_t status; 00284 status = flash_decoder_close(); 00285 return status; 00286 } 00287 00288 /* Hex file processing */ 00289 00290 static bool detect_hex(const uint8_t *data, uint32_t size) 00291 { 00292 return 1 == validate_hexfile(data); 00293 } 00294 00295 static error_t open_hex(void *state) 00296 { 00297 error_t status; 00298 hex_state_t *hex_state = (hex_state_t *)state; 00299 memset(hex_state, 0, sizeof(*hex_state)); 00300 reset_hex_parser(); 00301 hex_state->parsing_complete = false; 00302 status = flash_decoder_open(); 00303 return status; 00304 } 00305 00306 static error_t write_hex(void *state, const uint8_t *data, uint32_t size) 00307 { 00308 error_t status = ERROR_SUCCESS; 00309 hex_state_t *hex_state = (hex_state_t *)state; 00310 hexfile_parse_status_t parse_status = HEX_PARSE_UNINIT ; 00311 uint32_t bin_start_address = 0; // Decoded from the hex file, the binary buffer data starts at this address 00312 uint32_t bin_buf_written = 0; // The amount of data in the binary buffer starting at address above 00313 uint32_t block_amt_parsed = 0; // amount of data parsed in the block on the last call 00314 00315 while (1) { 00316 // try to decode a block of hex data into bin data 00317 parse_status = parse_hex_blob(data, size, &block_amt_parsed, hex_state->bin_buffer, sizeof(hex_state->bin_buffer), &bin_start_address, &bin_buf_written); 00318 00319 // the entire block of hex was decoded. This is a simple state 00320 if (HEX_PARSE_OK == parse_status) { 00321 if (bin_buf_written > 0) { 00322 status = flash_decoder_write(bin_start_address, hex_state->bin_buffer, bin_buf_written); 00323 } 00324 00325 break; 00326 } else if (HEX_PARSE_UNALIGNED == parse_status) { 00327 if (bin_buf_written > 0) { 00328 status = flash_decoder_write(bin_start_address, hex_state->bin_buffer, bin_buf_written); 00329 00330 if (ERROR_SUCCESS != status) { 00331 break; 00332 } 00333 } 00334 00335 // incrememntal offset to finish the block 00336 size -= block_amt_parsed; 00337 data += block_amt_parsed; 00338 } else if (HEX_PARSE_EOF == parse_status) { 00339 if (bin_buf_written > 0) { 00340 status = flash_decoder_write(bin_start_address, hex_state->bin_buffer, bin_buf_written); 00341 } 00342 00343 if (ERROR_SUCCESS == status) { 00344 status = ERROR_SUCCESS_DONE; 00345 } 00346 00347 break; 00348 } else if (HEX_PARSE_CKSUM_FAIL == parse_status) { 00349 status = ERROR_HEX_CKSUM; 00350 break; 00351 } else if ((HEX_PARSE_UNINIT == parse_status) || (HEX_PARSE_FAILURE == parse_status)) { 00352 util_assert(HEX_PARSE_UNINIT != parse_status); 00353 status = ERROR_HEX_PARSER; 00354 break; 00355 } 00356 } 00357 00358 return status; 00359 } 00360 00361 static error_t close_hex(void *state) 00362 { 00363 error_t status; 00364 status = flash_decoder_close(); 00365 return status; 00366 }
Generated on Tue Jul 12 2022 15:37:16 by
1.7.2