Statistics
| Branch: | Tag: | Revision:

amiro-blt / Target / Modules / DiWheelDrive_1-1 / Boot / hooks.c @ 53ce6fa2

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