Statistics
| Branch: | Tag: | Revision:

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

History | View | Annotate | Download (22.186 KB)

1
/************************************************************************************//**
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
      break;
107
    }
108
    default:
109
      return BLT_FALSE;
110
      break;
111
  }
112
  return BLT_FALSE;
113
} /*** end of BackDoorEntryCheck ***/
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
      if (GPIO_ReadInputDataBit(SYS_SYNC_N_GPIO, SYS_SYNC_N_PIN) == Bit_RESET) {
161
        boot_state = BOOT_OS_START;
162
      }
163
      return BLT_FALSE;
164
      break;
165
    }
166
    case BOOT_OS_START:
167
    {
168
      /* pull down SYS_SYNC_N to indicate that the module is busy
169
       * note: This is optional at this point. The OS however MUST pull down SYS_SYNC_N until it is ready */
170
      GPIO_ResetBits(SYS_SYNC_N_GPIO, SYS_SYNC_N_PIN);
171
      return BLT_TRUE;
172
    }
173
    default:
174
      return BLT_FALSE;
175
      break;
176
  }
177
  return BLT_FALSE;
178
} /*** end of CpuUserProgramStartHook ***/
179
#endif /* BOOT_CPU_USER_PROGRAM_START_HOOK > 0 */
180

    
181

    
182
/****************************************************************************************
183
*   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
184
****************************************************************************************/
185

    
186
#if (BOOT_NVM_HOOKS_ENABLE > 0)
187
/************************************************************************************//**
188
** \brief     Callback that gets called at the start of the internal NVM driver
189
**            initialization routine. 
190
** \return    none.
191
**
192
****************************************************************************************/
193
void NvmInitHook(void)
194
{
195
} /*** end of NvmInitHook ***/
196

    
197

    
198
/************************************************************************************//**
199
** \brief     Callback that gets called at the start of the NVM driver write 
200
**            routine. It allows additional memory to be operated on. If the address
201
**            is not within the range of the additional memory, then 
202
**            BLT_NVM_NOT_IN_RANGE must be returned to indicate that the data hasn't
203
**            been written yet.
204
** \param     addr Start address.
205
** \param     len  Length in bytes.
206
** \param     data Pointer to the data buffer.
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 write
209
**            operation failed.
210
**
211
****************************************************************************************/
212
blt_int8u NvmWriteHook(blt_addr addr, blt_int32u len, blt_int8u *data)
213
{
214
  return BLT_NVM_NOT_IN_RANGE;
215
} /*** end of NvmWriteHook ***/
216

    
217

    
218
/************************************************************************************//**
219
** \brief     Callback that gets called at the start of the NVM driver erase 
220
**            routine. It allows additional memory to be operated on. If the address
221
**            is not within the range of the additional memory, then
222
**            BLT_NVM_NOT_IN_RANGE must be returned to indicate that the memory
223
**            hasn't been erased yet.
224
** \param     addr Start address.
225
** \param     len  Length in bytes.
226
** \return    BLT_NVM_OKAY if successful, BLT_NVM_NOT_IN_RANGE if the address is
227
**            not within the supported memory range, or BLT_NVM_ERROR is the erase
228
**            operation failed.
229
**
230
****************************************************************************************/
231
blt_int8u NvmEraseHook(blt_addr addr, blt_int32u len)
232
{
233
  return BLT_NVM_NOT_IN_RANGE;
234
} /*** end of NvmEraseHook ***/
235

    
236

    
237
/************************************************************************************//**
238
** \brief     Callback that gets called at the end of the NVM programming session.
239
** \return    BLT_TRUE is successful, BLT_FALSE otherwise.
240
**
241
****************************************************************************************/
242
blt_bool NvmDoneHook(void)
243
{
244
  return BLT_TRUE;
245
} /*** end of NvmDoneHook ***/
246
#endif /* BOOT_NVM_HOOKS_ENABLE > 0 */
247

    
248

    
249
#if (BOOT_NVM_CHECKSUM_HOOKS_ENABLE > 0)
250
/************************************************************************************//**
251
** \brief     Verifies the checksum, which indicates that a valid user program is
252
**            present and can be started.
253
** \return    BLT_TRUE if successful, BLT_FALSE otherwise.
254
**
255
****************************************************************************************/
256
blt_bool NvmVerifyChecksumHook(void)
257
{
258
  return BLT_TRUE;
259
} /*** end of NvmVerifyChecksum ***/
260

    
261

    
262
/************************************************************************************//**
263
** \brief     Writes a checksum of the user program to non-volatile memory. This is
264
**            performed once the entire user program has been programmed. Through
265
**            the checksum, the bootloader can check if a valid user programming is
266
**            present and can be started.
267
** \return    BLT_TRUE if successful, BLT_FALSE otherwise. 
268
**
269
****************************************************************************************/
270
blt_bool NvmWriteChecksumHook(void)
271
{
272
  return BLT_TRUE;
273
}
274
#endif /* BOOT_NVM_CHECKSUM_HOOKS_ENABLE > 0 */
275

    
276

    
277
/****************************************************************************************
278
*   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
279
****************************************************************************************/
280

    
281
#if (BOOT_COP_HOOKS_ENABLE > 0)
282
/************************************************************************************//**
283
** \brief     Callback that gets called at the end of the internal COP driver
284
**            initialization routine. It can be used to configure and enable the
285
**            watchdog.
286
** \return    none.
287
**
288
****************************************************************************************/
289
void CopInitHook(void)
290
{
291
} /*** end of CopInitHook ***/
292

    
293

    
294
/************************************************************************************//**
295
** \brief     Callback that gets called at the end of the internal COP driver
296
**            service routine. This gets called upon initialization and during
297
**            potential long lasting loops and routine. It can be used to service
298
**            the watchdog to prevent a watchdog reset.
299
** \return    none.
300
**
301
****************************************************************************************/
302
void CopServiceHook(void)
303
{
304
} /*** end of CopServiceHook ***/
305
#endif /* BOOT_COP_HOOKS_ENABLE > 0 */
306

    
307

    
308
/****************************************************************************************
309
*   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
310
****************************************************************************************/
311

    
312
#if (BOOT_FILE_SYS_ENABLE > 0)
313

    
314
/****************************************************************************************
315
* Constant data declarations
316
****************************************************************************************/
317
/** \brief Firmware filename. */
318
static const blt_char firmwareFilename[] = "/demoprog_olimex_stm32p103.srec";
319

    
320

    
321
/****************************************************************************************
322
* Local data declarations
323
****************************************************************************************/
324
#if (BOOT_FILE_LOGGING_ENABLE > 0)
325
/** \brief Data structure for grouping log-file related information. */
326
static struct 
327
{
328
  FIL      handle;                  /**< FatFS handle to the log-file.                 */
329
  blt_bool canUse;                  /**< Flag to indicate if the log-file can be used. */
330
} logfile;
331
#endif
332

    
333

    
334
/************************************************************************************//**
335
** \brief     Callback that gets called to check whether a firmware update from 
336
**            local file storage should be started. This could for example be when
337
**            a switch is pressed, when a certain file is found on the local file 
338
**            storage, etc.
339
** \return    BLT_TRUE if a firmware update is requested, BLT_FALSE otherwise.
340
**
341
****************************************************************************************/
342
blt_bool FileIsFirmwareUpdateRequestedHook(void)
343
{
344
  FILINFO fileInfoObject = { 0 }; /* needs to be zeroed according to f_stat docs */;
345

    
346
  /* Current example implementation looks for a predetermined firmware file on the 
347
   * SD-card. If the SD-card is accessible and the firmware file was found the firmware
348
   * update is started. When successfully completed, the firmware file is deleted.
349
   * During the firmware update, progress information is written to a file called
350
   * bootlog.txt and additionally outputted on UART @57600 bps for debugging purposes.
351
   */
352
  /* check if firmware file is present and SD-card is accessible */
353
  if (f_stat(firmwareFilename, &fileInfoObject) == FR_OK) 
354
  {
355
    /* check if the filesize is valid and that it is not a directory */
356
    if ( (fileInfoObject.fsize > 0) && (!(fileInfoObject.fattrib & AM_DIR)) )
357
    {
358
      /* all conditions are met to start a firmware update from local file storage */
359
      return BLT_TRUE;
360
    }
361
  }
362
  /* still here so no firmware update request is pending */  
363
  return BLT_FALSE;
364
} /*** end of FileIsFirmwareUpdateRequestedHook ***/
365

    
366

    
367
/************************************************************************************//**
368
** \brief     Callback to obtain the filename of the firmware file that should be
369
**            used during the firmware update from the local file storage. This 
370
**            hook function is called at the beginning of the firmware update from
371
**            local storage sequence. 
372
** \return    valid firmware filename with full path or BLT_NULL.
373
**
374
****************************************************************************************/
375
const blt_char *FileGetFirmwareFilenameHook(void)
376
{
377
  return firmwareFilename;
378
} /*** end of FileGetFirmwareFilenameHook ***/
379

    
380

    
381
#if (BOOT_FILE_STARTED_HOOK_ENABLE > 0)
382
/************************************************************************************//**
383
** \brief     Callback that gets called to inform the application that a firmware
384
**            update from local storage just started. 
385
** \return    none.
386
**
387
****************************************************************************************/
388
void FileFirmwareUpdateStartedHook(void)
389
{
390
  #if (BOOT_FILE_LOGGING_ENABLE > 0)
391
  /* create/overwrite the logfile */
392
  logfile.canUse = BLT_FALSE;
393
  if (f_open(&logfile.handle, "/bootlog.txt", FA_CREATE_ALWAYS | FA_WRITE) == FR_OK)
394
  {
395
    logfile.canUse = BLT_TRUE;
396
  }
397
  #endif
398
} /*** end of FileFirmwareUpdateStartedHook ***/
399
#endif /* BOOT_FILE_STARTED_HOOK_ENABLE > 0 */
400

    
401

    
402
#if (BOOT_FILE_COMPLETED_HOOK_ENABLE > 0)
403
/************************************************************************************//**
404
** \brief     Callback that gets called to inform the application that a firmware
405
**            update was successfully completed.
406
** \return    none.
407
**
408
****************************************************************************************/
409
void FileFirmwareUpdateCompletedHook(void)
410
{
411
  #if (BOOT_FILE_LOGGING_ENABLE > 0)
412
  /* close the log file */
413
  if (logfile.canUse == BLT_TRUE)
414
  {
415
    f_close(&logfile.handle);
416
  }
417
  /* wait for all logging related transmission to complete */
418
  while(USART_GetFlagStatus(USART2, USART_FLAG_TC) == RESET);
419
  #endif
420
  /* now delete the firmware file from the disk since the update was successful */
421
  f_unlink(firmwareFilename);
422
} /*** end of FileFirmwareUpdateCompletedHook ***/
423
#endif /* BOOT_FILE_COMPLETED_HOOK_ENABLE > 0 */
424

    
425

    
426
#if (BOOT_FILE_ERROR_HOOK_ENABLE > 0)
427
/************************************************************************************//**
428
** \brief     Callback that gets called in case an error occurred during a firmware
429
**            update. Refer to <file.h> for a list of available error codes.
430
** \return    none.
431
**
432
****************************************************************************************/
433
void FileFirmwareUpdateErrorHook(blt_int8u error_code)
434
{
435
  #if (BOOT_FILE_LOGGING_ENABLE > 0)
436
  /* error detected which stops the firmware update, so close the log file */
437
  if (logfile.canUse == BLT_TRUE)
438
  {
439
    f_close(&logfile.handle);
440
  }
441
  #endif
442
} /*** end of FileFirmwareUpdateErrorHook ***/
443
#endif /* BOOT_FILE_ERROR_HOOK_ENABLE > 0 */
444

    
445

    
446
#if (BOOT_FILE_LOGGING_ENABLE > 0)
447
/************************************************************************************//**
448
** \brief     Callback that gets called each time new log information becomes 
449
**            available during a firmware update.
450
** \param     info_string Pointer to a character array with the log entry info.
451
** \return    none.
452
**
453
****************************************************************************************/
454
void FileFirmwareUpdateLogHook(blt_char *info_string)
455
{
456
  /* write the string to the log file */
457
  if (logfile.canUse == BLT_TRUE)
458
  {
459
    if (f_puts(info_string, &logfile.handle) < 0)
460
    {
461
      logfile.canUse = BLT_FALSE;
462
      f_close(&logfile.handle);
463
    }
464
  }
465
  /* echo all characters in the string on UART */
466
  while(*info_string != '\0')
467
  {
468
    /* write character to transmit holding register */
469
    USART_SendData(USART2, *info_string);
470
    /* wait for tx holding register to be empty */
471
    while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET);
472
    /* point to the next character in the string */
473
    info_string++;
474
  }
475
} /*** end of FileFirmwareUpdateLogHook ***/
476
#endif /* BOOT_FILE_LOGGING_ENABLE > 0 */
477

    
478

    
479
#endif /* BOOT_FILE_SYS_ENABLE > 0 */
480

    
481

    
482
/****************************************************************************************
483
*   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
484
****************************************************************************************/
485

    
486
#if (BOOT_XCP_SEED_KEY_ENABLE > 0)
487
/************************************************************************************//**
488
** \brief     Provides a seed to the XCP master that will be used for the key 
489
**            generation when the master attempts to unlock the specified resource. 
490
**            Called by the GET_SEED command.
491
** \param     resource  Resource that the seed if requested for (XCP_RES_XXX).
492
** \param     seed      Pointer to byte buffer wher the seed will be stored.
493
** \return    Length of the seed in bytes.
494
**
495
****************************************************************************************/
496
blt_int8u XcpGetSeedHook(blt_int8u resource, blt_int8u *seed)
497
{
498
  /* request seed for unlocking ProGraMming resource */
499
  if ((resource & XCP_RES_PGM) != 0)
500
  {
501
    seed[0] = 0x55;
502
  }
503

    
504
  /* return seed length */
505
  return 1;
506
} /*** end of XcpGetSeedHook ***/
507

    
508

    
509
/************************************************************************************//**
510
** \brief     Called by the UNLOCK command and checks if the key to unlock the 
511
**            specified resource was correct. If so, then the resource protection 
512
**            will be removed.
513
** \param     resource  resource to unlock (XCP_RES_XXX).
514
** \param     key       pointer to the byte buffer holding the key.
515
** \param     len       length of the key in bytes.
516
** \return    1 if the key was correct, 0 otherwise.
517
**
518
****************************************************************************************/
519
blt_int8u XcpVerifyKeyHook(blt_int8u resource, blt_int8u *key, blt_int8u len)
520
{
521
  /* suppress compiler warning for unused parameter */
522
  len = len;
523

    
524
  /* the example key algorithm in "FeaserKey.dll" works as follows:
525
   *  - PGM will be unlocked if key = seed - 1
526
   */
527

    
528
  /* check key for unlocking ProGraMming resource */
529
  if ((resource == XCP_RES_PGM) && (key[0] == (0x55-1)))
530
  {
531
    /* correct key received for unlocking PGM resource */
532
    return 1;
533
  }
534

    
535
  /* still here so key incorrect */
536
  return 0;
537
} /*** end of XcpVerifyKeyHook ***/
538
#endif /* BOOT_XCP_SEED_KEY_ENABLE > 0 */
539

    
540

    
541
/*********************************** end of hooks.c ************************************/