Arrow / Mbed OS DAPLink Reset
Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers file_stream.c Source File

file_stream.c

Go to the documentation of this file.
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 }