Statistics
| Branch: | Tag: | Revision:

amiro-blt / Target / Modules / LightRing_1-0 / Boot / hooks.c @ f7d2c786

History | View | Annotate | Download (21.6 KB)

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