Statistics
| Branch: | Tag: | Revision:

amiro-blt / Target / Modules / LightRing_1-2 / Boot / hooks.c @ 19d9fea2

History | View | Annotate | Download (21.656 KB)

1 fc7151bb Thomas Schöpping
/************************************************************************************//**
2
* \file         Demo\ARMCM3_STM32_Olimex_STM32P103_GCC\Boot\hooks.c
3
* \brief        Bootloader callback source file.
4
* \ingroup      Boot_ARMCM3_STM32_Olimex_STM32P103_GCC
5
* \internal
6
*----------------------------------------------------------------------------------------
7
*                          C O P Y R I G H T
8
*----------------------------------------------------------------------------------------
9
*   Copyright (c) 2012  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
#if (BOOT_FILE_LOGGING_ENABLE > 0)
39
#include "stm32f10x.h"                           /* STM32 registers                    */
40
#include "stm32f10x_conf.h"                      /* STM32 peripheral drivers           */
41
#endif
42
43
/****************************************************************************************
44
*   B A C K D O O R   E N T R Y   H O O K   F U N C T I O N S
45
****************************************************************************************/
46
47
#if (BOOT_BACKDOOR_HOOKS_ENABLE > 0)
48
49
enum BOOT_STATE {BOOT_FLASH_WAIT,
50
                 BOOT_OS_SYNC,
51
                 BOOT_OS_START
52
                } boot_state;
53
54
#define SYS_PD_N_PIN      GPIO_Pin_14
55
#define SYS_PD_N_GPIO     GPIOC
56
#define SYS_SYNC_N_PIN    GPIO_Pin_2
57
#define SYS_SYNC_N_GPIO   GPIOD
58
59
/************************************************************************************//**
60
** \brief     Initializes the backdoor entry option.
61
** \return    none.
62
**
63
****************************************************************************************/
64
void BackDoorInitHook(void)
65
{
66
  boot_state = BOOT_FLASH_WAIT;
67
} /*** end of BackDoorInitHook ***/
68
69
70
/************************************************************************************//**
71
** \brief     Checks if it has to stay in backdoor.
72
** \return    BLT_TRUE if the backdoor entry is requested, BLT_FALSE otherwise.
73
**
74
****************************************************************************************/
75
blt_bool BackDoorEntryCheck(void)
76
{
77
  /* evaluate the fsm state */
78
  switch (boot_state) {
79
    case BOOT_FLASH_WAIT:
80
    {
81
      /* wait for the SYS_SYNC_N signal to go up */
82
      GPIO_SetBits(SYS_SYNC_N_GPIO, SYS_SYNC_N_PIN);
83
      if (GPIO_ReadInputDataBit(SYS_SYNC_N_GPIO, SYS_SYNC_N_PIN) == Bit_RESET) {
84
        return BLT_TRUE;
85
      } else {
86
        boot_state = BOOT_OS_SYNC;
87
        return BLT_FALSE;
88
      }
89
      break;
90
    }
91
    default:
92
      return BLT_FALSE;
93
      break;
94
  }
95
  return BLT_FALSE;
96
} /*** end of BackDoorEntryCheck ***/
97
98
/************************************************************************************//**
99
** \brief     Checks if a backdoor entry is requested.
100
** \return    BLT_TRUE if the backdoor entry is requested, BLT_FALSE otherwise.
101
**
102
****************************************************************************************/
103
blt_bool BackDoorEntryHook(void)
104
{
105
  /* default implementation always activates the bootloader after a reset */
106
  return BLT_TRUE;
107
} /*** end of BackDoorEntryHook ***/
108
#endif /* BOOT_BACKDOOR_HOOKS_ENABLE > 0 */
109
110
111
/************************************************************************************//**
112
** \brief     Notice that there is still an open connection over COM 
113
** \return    -
114
**
115
****************************************************************************************/
116
void BackDoorComIsConnected(void)
117
{
118
}
119
120
121
/****************************************************************************************
122
*   C P U   D R I V E R   H O O K   F U N C T I O N S
123
****************************************************************************************/
124
125
#if (BOOT_CPU_USER_PROGRAM_START_HOOK > 0)
126
/************************************************************************************//**
127
** \brief     Callback that gets called when the bootloader is about to exit and
128
**            hand over control to the user program. This is the last moment that
129
**            some final checking can be performed and if necessary prevent the
130
**            bootloader from activiting the user program.
131
** \return    BLT_TRUE if it is okay to start the user program, BLT_FALSE to keep
132
**            keep the bootloader active.
133
**
134
****************************************************************************************/
135
blt_bool CpuUserProgramStartHook(void)
136
{
137
  /* evaluate the fsm state */
138
  switch (boot_state) {
139
    case BOOT_OS_SYNC:
140
    {
141
      /* wait for the SYS_SYNC_N signal to go down */
142
      if (GPIO_ReadInputDataBit(SYS_SYNC_N_GPIO, SYS_SYNC_N_PIN) == Bit_RESET) {
143
        boot_state = BOOT_OS_START;
144
      }
145
      return BLT_FALSE;
146
      break;
147
    }
148
    case BOOT_OS_START:
149
    {
150
      /* pull down SYS_SYNC_N to indicate that the module is busy
151
       * note: This is optional at this point. The OS however MUST pull down SYS_SYNC_N until it is ready */
152
      GPIO_ResetBits(SYS_SYNC_N_GPIO, SYS_SYNC_N_PIN);
153
      return BLT_TRUE;
154
    }
155
    default:
156
      return BLT_FALSE;
157
      break;
158
  }
159
  return BLT_FALSE;
160
} /*** end of CpuUserProgramStartHook ***/
161
#endif /* BOOT_CPU_USER_PROGRAM_START_HOOK > 0 */
162
163
164
/****************************************************************************************
165
*   N O N - V O L A T I L E   M E M O R Y   D R I V E R   H O O K   F U N C T I O N S
166
****************************************************************************************/
167
168
#if (BOOT_NVM_HOOKS_ENABLE > 0)
169
/************************************************************************************//**
170
** \brief     Callback that gets called at the start of the internal NVM driver
171
**            initialization routine. 
172
** \return    none.
173
**
174
****************************************************************************************/
175
void NvmInitHook(void)
176
{
177
} /*** end of NvmInitHook ***/
178
179
180
/************************************************************************************//**
181
** \brief     Callback that gets called at the start of the NVM driver write 
182
**            routine. It allows additional memory to be operated on. If the address
183
**            is not within the range of the additional memory, then 
184
**            BLT_NVM_NOT_IN_RANGE must be returned to indicate that the data hasn't
185
**            been written yet.
186
** \param     addr Start address.
187
** \param     len  Length in bytes.
188
** \param     data Pointer to the data buffer.
189
** \return    BLT_NVM_OKAY if successful, BLT_NVM_NOT_IN_RANGE if the address is
190
**            not within the supported memory range, or BLT_NVM_ERROR is the write
191
**            operation failed.
192
**
193
****************************************************************************************/
194
blt_int8u NvmWriteHook(blt_addr addr, blt_int32u len, blt_int8u *data)
195
{
196
  return BLT_NVM_NOT_IN_RANGE;
197
} /*** end of NvmWriteHook ***/
198
199
200
/************************************************************************************//**
201
** \brief     Callback that gets called at the start of the NVM driver erase 
202
**            routine. It allows additional memory to be operated on. If the address
203
**            is not within the range of the additional memory, then
204
**            BLT_NVM_NOT_IN_RANGE must be returned to indicate that the memory
205
**            hasn't been erased yet.
206
** \param     addr Start address.
207
** \param     len  Length in bytes.
208
** \return    BLT_NVM_OKAY if successful, BLT_NVM_NOT_IN_RANGE if the address is
209
**            not within the supported memory range, or BLT_NVM_ERROR is the erase
210
**            operation failed.
211
**
212
****************************************************************************************/
213
blt_int8u NvmEraseHook(blt_addr addr, blt_int32u len)
214
{
215
  return BLT_NVM_NOT_IN_RANGE;
216
} /*** end of NvmEraseHook ***/
217
218
219
/************************************************************************************//**
220
** \brief     Callback that gets called at the end of the NVM programming session.
221
** \return    BLT_TRUE is successful, BLT_FALSE otherwise.
222
**
223
****************************************************************************************/
224
blt_bool NvmDoneHook(void)
225
{
226
  return BLT_TRUE;
227
} /*** end of NvmDoneHook ***/
228
#endif /* BOOT_NVM_HOOKS_ENABLE > 0 */
229
230
231
#if (BOOT_NVM_CHECKSUM_HOOKS_ENABLE > 0)
232
/************************************************************************************//**
233
** \brief     Verifies the checksum, which indicates that a valid user program is
234
**            present and can be started.
235
** \return    BLT_TRUE if successful, BLT_FALSE otherwise.
236
**
237
****************************************************************************************/
238
blt_bool NvmVerifyChecksumHook(void)
239
{
240
  return BLT_TRUE;
241
} /*** end of NvmVerifyChecksum ***/
242
243
244
/************************************************************************************//**
245
** \brief     Writes a checksum of the user program to non-volatile memory. This is
246
**            performed once the entire user program has been programmed. Through
247
**            the checksum, the bootloader can check if a valid user programming is
248
**            present and can be started.
249
** \return    BLT_TRUE if successful, BLT_FALSE otherwise. 
250
**
251
****************************************************************************************/
252
blt_bool NvmWriteChecksumHook(void)
253
{
254
  return BLT_TRUE;
255
}
256
#endif /* BOOT_NVM_CHECKSUM_HOOKS_ENABLE > 0 */
257
258
259
/****************************************************************************************
260
*   W A T C H D O G   D R I V E R   H O O K   F U N C T I O N S
261
****************************************************************************************/
262
263
#if (BOOT_COP_HOOKS_ENABLE > 0)
264
/************************************************************************************//**
265
** \brief     Callback that gets called at the end of the internal COP driver
266
**            initialization routine. It can be used to configure and enable the
267
**            watchdog.
268
** \return    none.
269
**
270
****************************************************************************************/
271
void CopInitHook(void)
272
{
273
} /*** end of CopInitHook ***/
274
275
276
/************************************************************************************//**
277
** \brief     Callback that gets called at the end of the internal COP driver
278
**            service routine. This gets called upon initialization and during
279
**            potential long lasting loops and routine. It can be used to service
280
**            the watchdog to prevent a watchdog reset.
281
** \return    none.
282
**
283
****************************************************************************************/
284
void CopServiceHook(void)
285
{
286
} /*** end of CopServiceHook ***/
287
#endif /* BOOT_COP_HOOKS_ENABLE > 0 */
288
289
290
/****************************************************************************************
291
*   F I L E   S Y S T E M   I N T E R F A C E   H O O K   F U N C T I O N S
292
****************************************************************************************/
293
294
#if (BOOT_FILE_SYS_ENABLE > 0)
295
296
/****************************************************************************************
297
* Constant data declarations
298
****************************************************************************************/
299
/** \brief Firmware filename. */
300
static const blt_char firmwareFilename[] = "/demoprog_olimex_stm32p103.srec";
301
302
303
/****************************************************************************************
304
* Local data declarations
305
****************************************************************************************/
306
#if (BOOT_FILE_LOGGING_ENABLE > 0)
307
/** \brief Data structure for grouping log-file related information. */
308
static struct 
309
{
310
  FIL      handle;                  /**< FatFS handle to the log-file.                 */
311
  blt_bool canUse;                  /**< Flag to indicate if the log-file can be used. */
312
} logfile;
313
#endif
314
315
316
/************************************************************************************//**
317
** \brief     Callback that gets called to check whether a firmware update from 
318
**            local file storage should be started. This could for example be when
319
**            a switch is pressed, when a certain file is found on the local file 
320
**            storage, etc.
321
** \return    BLT_TRUE if a firmware update is requested, BLT_FALSE otherwise.
322
**
323
****************************************************************************************/
324
blt_bool FileIsFirmwareUpdateRequestedHook(void)
325
{
326
  FILINFO fileInfoObject = { 0 }; /* needs to be zeroed according to f_stat docs */;
327
328
  /* Current example implementation looks for a predetermined firmware file on the 
329
   * SD-card. If the SD-card is accessible and the firmware file was found the firmware
330
   * update is started. When successfully completed, the firmware file is deleted.
331
   * During the firmware update, progress information is written to a file called
332
   * bootlog.txt and additionally outputted on UART @57600 bps for debugging purposes.
333
   */
334
  /* check if firmware file is present and SD-card is accessible */
335
  if (f_stat(firmwareFilename, &fileInfoObject) == FR_OK) 
336
  {
337
    /* check if the filesize is valid and that it is not a directory */
338
    if ( (fileInfoObject.fsize > 0) && (!(fileInfoObject.fattrib & AM_DIR)) )
339
    {
340
      /* all conditions are met to start a firmware update from local file storage */
341
      return BLT_TRUE;
342
    }
343
  }
344
  /* still here so no firmware update request is pending */  
345
  return BLT_FALSE;
346
} /*** end of FileIsFirmwareUpdateRequestedHook ***/
347
348
349
/************************************************************************************//**
350
** \brief     Callback to obtain the filename of the firmware file that should be
351
**            used during the firmware update from the local file storage. This 
352
**            hook function is called at the beginning of the firmware update from
353
**            local storage sequence. 
354
** \return    valid firmware filename with full path or BLT_NULL.
355
**
356
****************************************************************************************/
357
const blt_char *FileGetFirmwareFilenameHook(void)
358
{
359
  return firmwareFilename;
360
} /*** end of FileGetFirmwareFilenameHook ***/
361
362
363
#if (BOOT_FILE_STARTED_HOOK_ENABLE > 0)
364
/************************************************************************************//**
365
** \brief     Callback that gets called to inform the application that a firmware
366
**            update from local storage just started. 
367
** \return    none.
368
**
369
****************************************************************************************/
370
void FileFirmwareUpdateStartedHook(void)
371
{
372
  #if (BOOT_FILE_LOGGING_ENABLE > 0)
373
  /* create/overwrite the logfile */
374
  logfile.canUse = BLT_FALSE;
375
  if (f_open(&logfile.handle, "/bootlog.txt", FA_CREATE_ALWAYS | FA_WRITE) == FR_OK)
376
  {
377
    logfile.canUse = BLT_TRUE;
378
  }
379
  #endif
380
} /*** end of FileFirmwareUpdateStartedHook ***/
381
#endif /* BOOT_FILE_STARTED_HOOK_ENABLE > 0 */
382
383
384
#if (BOOT_FILE_COMPLETED_HOOK_ENABLE > 0)
385
/************************************************************************************//**
386
** \brief     Callback that gets called to inform the application that a firmware
387
**            update was successfully completed.
388
** \return    none.
389
**
390
****************************************************************************************/
391
void FileFirmwareUpdateCompletedHook(void)
392
{
393
  #if (BOOT_FILE_LOGGING_ENABLE > 0)
394
  /* close the log file */
395
  if (logfile.canUse == BLT_TRUE)
396
  {
397
    f_close(&logfile.handle);
398
  }
399
  /* wait for all logging related transmission to complete */
400
  while(USART_GetFlagStatus(USART2, USART_FLAG_TC) == RESET);
401
  #endif
402
  /* now delete the firmware file from the disk since the update was successful */
403
  f_unlink(firmwareFilename);
404
} /*** end of FileFirmwareUpdateCompletedHook ***/
405
#endif /* BOOT_FILE_COMPLETED_HOOK_ENABLE > 0 */
406
407
408
#if (BOOT_FILE_ERROR_HOOK_ENABLE > 0)
409
/************************************************************************************//**
410
** \brief     Callback that gets called in case an error occurred during a firmware
411
**            update. Refer to <file.h> for a list of available error codes.
412
** \return    none.
413
**
414
****************************************************************************************/
415
void FileFirmwareUpdateErrorHook(blt_int8u error_code)
416
{
417
  #if (BOOT_FILE_LOGGING_ENABLE > 0)
418
  /* error detected which stops the firmware update, so close the log file */
419
  if (logfile.canUse == BLT_TRUE)
420
  {
421
    f_close(&logfile.handle);
422
  }
423
  #endif
424
} /*** end of FileFirmwareUpdateErrorHook ***/
425
#endif /* BOOT_FILE_ERROR_HOOK_ENABLE > 0 */
426
427
428
#if (BOOT_FILE_LOGGING_ENABLE > 0)
429
/************************************************************************************//**
430
** \brief     Callback that gets called each time new log information becomes 
431
**            available during a firmware update.
432
** \param     info_string Pointer to a character array with the log entry info.
433
** \return    none.
434
**
435
****************************************************************************************/
436
void FileFirmwareUpdateLogHook(blt_char *info_string)
437
{
438
  /* write the string to the log file */
439
  if (logfile.canUse == BLT_TRUE)
440
  {
441
    if (f_puts(info_string, &logfile.handle) < 0)
442
    {
443
      logfile.canUse = BLT_FALSE;
444
      f_close(&logfile.handle);
445
    }
446
  }
447
  /* echo all characters in the string on UART */
448
  while(*info_string != '\0')
449
  {
450
    /* write character to transmit holding register */
451
    USART_SendData(USART2, *info_string);
452
    /* wait for tx holding register to be empty */
453
    while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET);
454
    /* point to the next character in the string */
455
    info_string++;
456
  }
457
} /*** end of FileFirmwareUpdateLogHook ***/
458
#endif /* BOOT_FILE_LOGGING_ENABLE > 0 */
459
460
461
#endif /* BOOT_FILE_SYS_ENABLE > 0 */
462
463
464
/****************************************************************************************
465
*   S E E D / K E Y   S E C U R I T Y   H O O K   F U N C T I O N S
466
****************************************************************************************/
467
468
#if (BOOT_XCP_SEED_KEY_ENABLE > 0)
469
/************************************************************************************//**
470
** \brief     Provides a seed to the XCP master that will be used for the key 
471
**            generation when the master attempts to unlock the specified resource. 
472
**            Called by the GET_SEED command.
473
** \param     resource  Resource that the seed if requested for (XCP_RES_XXX).
474
** \param     seed      Pointer to byte buffer wher the seed will be stored.
475
** \return    Length of the seed in bytes.
476
**
477
****************************************************************************************/
478
blt_int8u XcpGetSeedHook(blt_int8u resource, blt_int8u *seed)
479
{
480
  /* request seed for unlocking ProGraMming resource */
481
  if ((resource & XCP_RES_PGM) != 0)
482
  {
483
    seed[0] = 0x55;
484
  }
485
486
  /* return seed length */
487
  return 1;
488
} /*** end of XcpGetSeedHook ***/
489
490
491
/************************************************************************************//**
492
** \brief     Called by the UNLOCK command and checks if the key to unlock the 
493
**            specified resource was correct. If so, then the resource protection 
494
**            will be removed.
495
** \param     resource  resource to unlock (XCP_RES_XXX).
496
** \param     key       pointer to the byte buffer holding the key.
497
** \param     len       length of the key in bytes.
498
** \return    1 if the key was correct, 0 otherwise.
499
**
500
****************************************************************************************/
501
blt_int8u XcpVerifyKeyHook(blt_int8u resource, blt_int8u *key, blt_int8u len)
502
{
503
  /* suppress compiler warning for unused parameter */
504
  len = len;
505
506
  /* the example key algorithm in "FeaserKey.dll" works as follows:
507
   *  - PGM will be unlocked if key = seed - 1
508
   */
509
510
  /* check key for unlocking ProGraMming resource */
511
  if ((resource == XCP_RES_PGM) && (key[0] == (0x55-1)))
512
  {
513
    /* correct key received for unlocking PGM resource */
514
    return 1;
515
  }
516
517
  /* still here so key incorrect */
518
  return 0;
519
} /*** end of XcpVerifyKeyHook ***/
520
#endif /* BOOT_XCP_SEED_KEY_ENABLE > 0 */
521
522
523
/*********************************** end of hooks.c ************************************/