Statistics
| Branch: | Tag: | Revision:

amiro-blt / Target / Source / file.c @ 72294488

History | View | Annotate | Download (32.316 KB)

1 69661903 Thomas Schöpping
/************************************************************************************//**
2
* \file         Source\file.c
3
* \brief        Bootloader file system interface source file.
4
* \ingroup      Core
5
* \internal
6
*----------------------------------------------------------------------------------------
7
*                          C O P Y R I G H T
8
*----------------------------------------------------------------------------------------
9
*   Copyright (c) 2013  by Feaser    http://www.feaser.com    All rights reserved
10
*
11
*----------------------------------------------------------------------------------------
12
*                            L I C E N S E
13
*----------------------------------------------------------------------------------------
14
* This file is part of OpenBLT. OpenBLT is free software: you can redistribute it and/or
15
* modify it under the terms of the GNU General Public License as published by the Free
16
* Software Foundation, either version 3 of the License, or (at your option) any later
17
* version.
18
*
19
* OpenBLT is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
20
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
21
* PURPOSE. See the GNU General Public License for more details.
22
*
23
* You should have received a copy of the GNU General Public License along with OpenBLT.
24
* If not, see <http://www.gnu.org/licenses/>.
25
*
26
* A special exception to the GPL is included to allow you to distribute a combined work 
27
* that includes OpenBLT without being obliged to provide the source code for any 
28
* proprietary components. The exception text is included at the bottom of the license
29
* file <license.html>.
30
* 
31
* \endinternal
32
****************************************************************************************/
33
34
/****************************************************************************************
35
* Include files
36
****************************************************************************************/
37
#include "boot.h"                                     /* bootloader generic header     */
38
#include <string.h>                                   /* for strcpy etc.               */
39
#include <ctype.h>                                    /* for toupper() etc.            */
40
41
42
#if (BOOT_FILE_SYS_ENABLE > 0)
43
/****************************************************************************************
44
* Type definitions
45
****************************************************************************************/
46
/** \brief Enumeration for the different internal module states. */
47
typedef enum 
48
{ 
49
  FIRMWARE_UPDATE_STATE_IDLE,                    /**< idle state                       */
50
  FIRMWARE_UPDATE_STATE_STARTING,                /**< starting state                   */
51
  FIRMWARE_UPDATE_STATE_ERASING,                 /**< erasing state                    */
52
  FIRMWARE_UPDATE_STATE_PROGRAMMING              /**< programming state                */
53
} tFirmwareUpdateState;
54
55
/** \brief Structure type with information for the memory erase opeartion. */
56
typedef struct 
57
{
58
  blt_addr   start_address;                      /**< erase start address              */
59
  blt_int32u total_size;                         /**< total number of bytes to erase   */
60
} tFileEraseInfo;
61
62
/** \brief Structure type for grouping FATFS related objects used by this module. */
63
typedef struct 
64
{
65
  FATFS fs;                                      /**< file system object for mouting   */
66
  FIL   file;                                    /**< file object for firmware file    */
67
} tFatFsObjects;
68
69
/****************************************************************************************
70
* Function prototypes
71
****************************************************************************************/
72
#if (BOOT_FILE_LOGGING_ENABLE > 0)
73
static blt_char      FileLibByteNibbleToChar(blt_int8u nibble);
74
static blt_char     *FileLibByteToHexString(blt_int8u byte_val, blt_char *destination);
75
static blt_char     *FileLibLongToIntString(blt_int32u long_val, blt_char *destination);
76
#endif
77
static blt_int8u     FileLibHexStringToByte(const blt_char *hexstring);
78
79
80
/****************************************************************************************
81
* Hook functions
82
****************************************************************************************/
83
extern blt_bool        FileIsFirmwareUpdateRequestedHook(void);
84
extern const blt_char *FileGetFirmwareFilenameHook(void);
85
extern void            FileFirmwareUpdateStartedHook(void);
86
extern void            FileFirmwareUpdateCompletedHook(void);
87
extern void            FileFirmwareUpdateErrorHook(blt_int8u error_code);
88
extern void            FileFirmwareUpdateLogHook(blt_char *info_string);
89
90
91
/****************************************************************************************
92
* Local data declarations
93
****************************************************************************************/
94
/** \brief Local variable that holds the internal module state. */
95
static tFirmwareUpdateState firmwareUpdateState;
96
/** \brief Local variable for the used FATFS objects in this module. */
97
static tFatFsObjects        fatFsObjects;
98
/** \brief Local variable for storing S-record line parsing results. */
99
static tSrecLineParseObject lineParseObject;
100
/** \brief Local variable for storing information regarding the memory erase operation.*/
101
static tFileEraseInfo       eraseInfo;
102
#if (BOOT_FILE_LOGGING_ENABLE > 0)
103
/** \brief Local character buffer for storing the string with log information. */
104
static blt_char             loggingStr[64];
105
#endif
106
107
108
/***********************************************************************************//**
109
** \brief     Initializes the file system interface module. The initial firmware
110
**            update state is set to idle and the file system is mounted as 
111
**            logical disk 0.
112
** \return    none
113
**
114
****************************************************************************************/
115
void FileInit(void)
116
{
117
  FRESULT fresult;
118
    
119
  /* set the initial state */
120
  firmwareUpdateState = FIRMWARE_UPDATE_STATE_IDLE;
121
  /* mount the file system, using logical disk 0 */
122
  fresult = f_mount(0, &fatFsObjects.fs);
123
  /* mounting does not access the disk and should succeed unless misconfigured */
124
  ASSERT_RT(fresult == FR_OK);
125
} /*** end of FileInit ***/
126
127
128
/***********************************************************************************//**
129
** \brief     This function checks if a firmware update through the locally attached
130
**            storage is in progress or not (idle).
131
** \return    BLT_TRUE when in idle state, BLT_FALSE otherwise.
132
**
133
****************************************************************************************/
134
blt_bool FileIsIdle(void)
135
{
136
  if (firmwareUpdateState == FIRMWARE_UPDATE_STATE_IDLE)
137
  {
138
    return BLT_TRUE;
139
  }
140
  return BLT_FALSE;
141
} /*** end of FileIsIdle ***/
142
143
144
/***********************************************************************************//**
145
** \brief     This function checks if a firmware update through the locally attached
146
**            storage is requested to be started and if so processes this request
147
**            by transitioning from the IDLE to the STARTING state.
148
** \return    BLT_TRUE when a firmware update is requested, BLT_FALSE otherwise.
149
**
150
****************************************************************************************/
151
blt_bool FileHandleFirmwareUpdateRequest(void)
152
{
153
  #if (BOOT_COM_ENABLE > 0)
154
  /* make sure that there is no connection with a remote host to prevent two firmware
155
   * updates happening at the same time
156
   */
157
  if (ComIsConnected() == BLT_TRUE)
158
  {
159
    return BLT_FALSE;
160
  }
161
  #endif
162
  /* a new firmware update request can only be handled if not already busy with one */
163
  if (firmwareUpdateState != FIRMWARE_UPDATE_STATE_IDLE)
164
  {
165
    return BLT_FALSE;
166
  }
167
  /* check if a firmware update is requested */
168
  if (FileIsFirmwareUpdateRequestedHook() == BLT_TRUE)
169
  {
170
    /* transition from IDLE to STARTING state, which kicks off the update sequence */
171
    firmwareUpdateState = FIRMWARE_UPDATE_STATE_STARTING;
172
    return BLT_TRUE;
173
  }
174
  /* still here so no update request pending */
175
  return BLT_FALSE;
176
} /*** end of FileHandleFirmwareUpdateRequest ***/
177
178
179
/***********************************************************************************//**
180
** \brief     File system task function for managing the firmware updates from
181
**                 locally attached storage.
182
** \return    none.
183
**
184
****************************************************************************************/
185
void FileTask(void)
186
{
187
  blt_int16s  parse_result;
188
  blt_char   *read_line_ptr;
189
  
190
  /* ------------------------------- idle -------------------------------------------- */
191
  if (firmwareUpdateState == FIRMWARE_UPDATE_STATE_IDLE)
192
  {
193
    /* currently, nothings need to be done while idling */
194
  }
195
  /* ------------------------------- starting ---------------------------------------- */
196
  else if (firmwareUpdateState == FIRMWARE_UPDATE_STATE_STARTING)
197
  {
198
    #if (BOOT_FILE_STARTED_HOOK_ENABLE > 0)
199
    /* inform application about update started event via hook function */
200
    FileFirmwareUpdateStartedHook();
201
    #endif
202
    #if (BOOT_FILE_LOGGING_ENABLE > 0)
203
    FileFirmwareUpdateLogHook("Firmware update request detected\n\r");
204
    FileFirmwareUpdateLogHook("Opening firmware file for reading...");
205
    #endif
206
    /* attempt to obtain a file object for the firmware file */
207
    if (f_open(&fatFsObjects.file, FileGetFirmwareFilenameHook(), FA_OPEN_EXISTING | FA_READ) != FR_OK)
208
    {
209
      /* can't open file */
210
      #if (BOOT_FILE_LOGGING_ENABLE > 0)
211
      FileFirmwareUpdateLogHook("ERROR\n\r");
212
      #endif
213
      #if (BOOT_FILE_ERROR_HOOK_ENABLE > 0)
214
      FileFirmwareUpdateErrorHook(FILE_ERROR_CANNOT_OPEN_FIRMWARE_FILE);
215
      #endif        
216
      /* nothing left to do now */
217
      return;
218
    }
219
    #if (BOOT_FILE_LOGGING_ENABLE > 0)
220
    FileFirmwareUpdateLogHook("OK\n\r");
221
    FileFirmwareUpdateLogHook("Starting the programming sequence\n\r");
222
    FileFirmwareUpdateLogHook("Parsing firmware file to obtain erase size...");
223
    #endif
224
    /* prepare data objects for the erasing state */
225
    eraseInfo.start_address = 0;
226
    eraseInfo.total_size = 0;
227
    /* transition from idle to erasing state */
228
    firmwareUpdateState = FIRMWARE_UPDATE_STATE_ERASING;
229
  }
230
  /* ------------------------------- erasing ----------------------------------------- */
231
  else if (firmwareUpdateState == FIRMWARE_UPDATE_STATE_ERASING)
232
  {
233
    /* read a line from the file */
234
    read_line_ptr = f_gets(lineParseObject.line, sizeof(lineParseObject.line), &fatFsObjects.file);
235
    /* check if an error occurred */
236
    if (f_error(&fatFsObjects.file) > 0)
237
    {
238
      #if (BOOT_FILE_LOGGING_ENABLE >