diff --git a/Target/Demo/_template/Boot/blt_conf.h b/Target/Demo/_template/Boot/blt_conf.h new file mode 100644 index 00000000..210034ae --- /dev/null +++ b/Target/Demo/_template/Boot/blt_conf.h @@ -0,0 +1,164 @@ +/************************************************************************************//** +* \file Demo/_template/Boot/blt_conf.h +* \brief Bootloader configuration header file. +* \ingroup Boot__template +* \internal +*---------------------------------------------------------------------------------------- +* C O P Y R I G H T +*---------------------------------------------------------------------------------------- +* Copyright (c) 2019 by Feaser http://www.feaser.com All rights reserved +* +*---------------------------------------------------------------------------------------- +* L I C E N S E +*---------------------------------------------------------------------------------------- +* This file is part of OpenBLT. OpenBLT is free software: you can redistribute it and/or +* modify it under the terms of the GNU General Public License as published by the Free +* Software Foundation, either version 3 of the License, or (at your option) any later +* version. +* +* OpenBLT is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; +* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +* PURPOSE. See the GNU General Public License for more details. +* +* You have received a copy of the GNU General Public License along with OpenBLT. It +* should be located in ".\Doc\license.html". If not, contact Feaser to obtain a copy. +* +* \endinternal +****************************************************************************************/ +#ifndef BLT_CONF_H +#define BLT_CONF_H + +/**************************************************************************************** +* C P U D R I V E R C O N F I G U R A T I O N +****************************************************************************************/ +/* To properly initialize the baudrate clocks of the communication interface, typically + * the speed of the crystal oscillator and/or the speed at which the system runs is + * needed. Set these through configurables BOOT_CPU_XTAL_SPEED_KHZ and + * BOOT_CPU_SYSTEM_SPEED_KHZ, respectively. To enable data exchange with the host that is + * not dependent on the targets architecture, the byte ordering needs to be known. + * Setting BOOT_CPU_BYTE_ORDER_MOTOROLA to 1 selects big endian mode and 0 selects + * little endian mode. + * + * Set BOOT_CPU_USER_PROGRAM_START_HOOK to 1 if you would like a hook function to be + * called the moment the user program is about to be started. This could be used to + * de-initialize application specific parts, for example to stop blinking an LED, etc. + */ +/** \brief Frequency of the external crystal oscillator. */ +/* TODO ##Boot Set the frequency of the crystal oscillator that provides the clock + * signal that drives the microcontroller. Specify the value in kHz. + */ +#define BOOT_CPU_XTAL_SPEED_KHZ (8000) +/** \brief Desired system speed. */ +/* TODO ##Boot Set the system frequency of the microcontroller system clock. Specify the + * value in kHz. The system clock is typically created by configuring the PLL or FLL + * peripheral of the microcontroller. Note that this macro is only used by the bootloader + * for reference purposes, for example when configuring clock related peripherals. The + * bootloader does not use this macro to actually do the clock configuration for you. + * It is up to you to implement the clock configuration in function Init() in main.c. + */ +#define BOOT_CPU_SYSTEM_SPEED_KHZ (72000) +/** \brief Motorola or Intel style byte ordering. */ +/* TODO ##Boot Configure the CPU's endian mode. This is hardware specific and should be + * defined in the microcontroller's datasheet. + */ +#define BOOT_CPU_BYTE_ORDER_MOTOROLA (0) +/** \brief Enable/disable hook function call right before user program start. */ +#define BOOT_CPU_USER_PROGRAM_START_HOOK (1) + + +/**************************************************************************************** +* C O M M U N I C A T I O N I N T E R F A C E C O N F I G U R A T I O N +****************************************************************************************/ +/* The UART communication interface is selected by setting the BOOT_COM_UART_ENABLE + * configurable to 1. Configurable BOOT_COM_UART_BAUDRATE selects the communication speed + * in bits/second. The maximum amount of data bytes in a message for data transmission + * and reception is set through BOOT_COM_UART_TX_MAX_DATA and BOOT_COM_UART_RX_MAX_DATA, + * respectively. It is common for a microcontroller to have more than 1 UART interface + * on board. The zero-based BOOT_COM_UART_CHANNEL_INDEX selects the UART interface. + * + */ +/** \brief Enable/disable UART transport layer. */ +#define BOOT_COM_UART_ENABLE (1) +/** \brief Configure the desired communication speed. */ +#define BOOT_COM_UART_BAUDRATE (57600) +/** \brief Configure number of bytes in the target->host data packet. */ +#define BOOT_COM_UART_TX_MAX_DATA (64) +/** \brief Configure number of bytes in the host->target data packet. */ +#define BOOT_COM_UART_RX_MAX_DATA (64) +/** \brief Select the desired UART peripheral as a zero based index. */ +#define BOOT_COM_UART_CHANNEL_INDEX (1) + + +/**************************************************************************************** +* B A C K D O O R E N T R Y C O N F I G U R A T I O N +****************************************************************************************/ +/* It is possible to implement an application specific method to force the bootloader to + * stay active after a reset. Such a backdoor entry into the bootloader is desired in + * situations where the user program does not run properly and therefore cannot + * reactivate the bootloader. By enabling these hook functions, the application can + * implement the backdoor, which overrides the default backdoor entry that is programmed + * into the bootloader. When desired for security purposes, these hook functions can + * also be implemented in a way that disables the backdoor entry altogether. + */ +/** \brief Enable/disable the backdoor override hook functions. */ +#define BOOT_BACKDOOR_HOOKS_ENABLE (0) + + +/**************************************************************************************** +* N O N - V O L A T I L E M E M O R Y D R I V E R C O N F I G U R A T I O N +****************************************************************************************/ +/* The NVM driver typically supports erase and program operations of the internal memory + * present on the microcontroller. Through these hook functions the NVM driver can be + * extended to support additional memory types such as external flash memory and serial + * eeproms. The size of the internal memory in kilobytes is specified with configurable + * BOOT_NVM_SIZE_KB. If desired the internal checksum writing and verification method can + * be overridden with a application specific method by enabling configuration switch + * BOOT_NVM_CHECKSUM_HOOKS_ENABLE. + */ +/** \brief Enable/disable the NVM hook function for supporting additional memory devices. */ +#define BOOT_NVM_HOOKS_ENABLE (0) +/** \brief Configure the size of the default memory device (typically flash EEPROM). */ +/* TODO ##Boot Configure the size of the flash memory device on the microcontroller. + * Specify the value in KB. + */ +#define BOOT_NVM_SIZE_KB (128) +/** \brief Enable/disable hooks functions to override the user program checksum handling. */ +#define BOOT_NVM_CHECKSUM_HOOKS_ENABLE (0) + + +/**************************************************************************************** +* W A T C H D O G D R I V E R C O N F I G U R A T I O N +****************************************************************************************/ +/* The COP driver cannot be configured internally in the bootloader, because its use + * and configuration is application specific. The bootloader does need to service the + * watchdog in case it is used. When the application requires the use of a watchdog, + * set BOOT_COP_HOOKS_ENABLE to be able to initialize and service the watchdog through + * hook functions. + */ +/** \brief Enable/disable the hook functions for controlling the watchdog. */ +#define BOOT_COP_HOOKS_ENABLE (1) + + +/**************************************************************************************** +* S E E D / K E Y S E C U R I T Y C O N F I G U R A T I O N +****************************************************************************************/ +/* A security mechanism can be enabled in the bootloader's XCP module by setting configu- + * rable BOOT_XCP_SEED_KEY_ENABLE to 1. Before any memory erase or programming + * operations can be performed, access to this resource need to be unlocked. + * In the Microboot settings on tab "XCP Protection" you need to specify a DLL that + * implements the unlocking algorithm. The demo programs are configured for the (simple) + * algorithm in "libseednkey.dll". The source code for this DLL is available so it can be + * customized to your needs. + * During the unlock sequence, Microboot requests a seed from the bootloader, which is in + * the format of a byte array. Using this seed the unlock algorithm in the DLL computes + * a key, which is also a byte array, and sends this back to the bootloader. The + * bootloader then verifies this key to determine if programming and erase operations are + * permitted. + * After enabling this feature the hook functions XcpGetSeedHook() and XcpVerifyKeyHook() + * are called by the bootloader to obtain the seed and to verify the key, respectively. + */ +#define BOOT_XCP_SEED_KEY_ENABLE (0) + + +#endif /* BLT_CONF_H */ +/*********************************** end of blt_conf.h *********************************/ diff --git a/Target/Demo/_template/Boot/boot.dox b/Target/Demo/_template/Boot/boot.dox new file mode 100644 index 00000000..f2f9c2b7 --- /dev/null +++ b/Target/Demo/_template/Boot/boot.dox @@ -0,0 +1,7 @@ +/** +\defgroup Boot__template Bootloader +\brief Bootloader. +\ingroup Demos_template +*/ + + diff --git a/Target/Demo/_template/Boot/hooks.c b/Target/Demo/_template/Boot/hooks.c new file mode 100644 index 00000000..499264b9 --- /dev/null +++ b/Target/Demo/_template/Boot/hooks.c @@ -0,0 +1,310 @@ +/************************************************************************************//** +* \file Demo/_template/Boot/hooks.c +* \brief Bootloader callback source file. +* \ingroup Boot__template +* \internal +*---------------------------------------------------------------------------------------- +* C O P Y R I G H T +*---------------------------------------------------------------------------------------- +* Copyright (c) 2019 by Feaser http://www.feaser.com All rights reserved +* +*---------------------------------------------------------------------------------------- +* L I C E N S E +*---------------------------------------------------------------------------------------- +* This file is part of OpenBLT. OpenBLT is free software: you can redistribute it and/or +* modify it under the terms of the GNU General Public License as published by the Free +* Software Foundation, either version 3 of the License, or (at your option) any later +* version. +* +* OpenBLT is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; +* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +* PURPOSE. See the GNU General Public License for more details. +* +* You have received a copy of the GNU General Public License along with OpenBLT. It +* should be located in ".\Doc\license.html". If not, contact Feaser to obtain a copy. +* +* \endinternal +****************************************************************************************/ + +/**************************************************************************************** +* Include files +****************************************************************************************/ +#include "boot.h" /* bootloader generic header */ +#include "led.h" /* LED driver header */ + + +/**************************************************************************************** +* 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 +****************************************************************************************/ + +#if (BOOT_BACKDOOR_HOOKS_ENABLE > 0) +/************************************************************************************//** +** \brief Initializes the backdoor entry option. +** \return none. +** +****************************************************************************************/ +void BackDoorInitHook(void) +{ +} /*** end of BackDoorInitHook ***/ + + +/************************************************************************************//** +** \brief Checks if a backdoor entry is requested. +** \return BLT_TRUE if the backdoor entry is requested, BLT_FALSE otherwise. +** +****************************************************************************************/ +blt_bool BackDoorEntryHook(void) +{ + /* default implementation always activates the bootloader after a reset */ + return BLT_TRUE; +} /*** end of BackDoorEntryHook ***/ +#endif /* BOOT_BACKDOOR_HOOKS_ENABLE > 0 */ + + +/**************************************************************************************** +* C P U D R I V E R H O O K F U N C T I O N S +****************************************************************************************/ + +#if (BOOT_CPU_USER_PROGRAM_START_HOOK > 0) +/************************************************************************************//** +** \brief Callback that gets called when the bootloader is about to exit and +** hand over control to the user program. This is the last moment that +** some final checking can be performed and if necessary prevent the +** bootloader from activiting the user program. +** \return BLT_TRUE if it is okay to start the user program, BLT_FALSE to keep +** keep the bootloader active. +** +****************************************************************************************/ +blt_bool CpuUserProgramStartHook(void) +{ + /* additional and optional backdoor entry through the pushbutton on the board. to + * force the bootloader to stay active after reset, keep it pressed during reset. + */ + /* TODO ##Boot Optionally configure an extra backdoor entry to force the bootloader + * to stay active and not start the user program. For example if a digital input is + * in a specific state. + */ + if (1 == 0) + { + /* pushbutton pressed, so do not start the user program and keep the + * bootloader active instead. + */ + return BLT_FALSE; + } + + /* clean up the LED driver */ + LedBlinkExit(); + + /* okay to start the user program */ + return BLT_TRUE; +} /*** end of CpuUserProgramStartHook ***/ +#endif /* BOOT_CPU_USER_PROGRAM_START_HOOK > 0 */ + + +/**************************************************************************************** +* 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 +****************************************************************************************/ + +#if (BOOT_COP_HOOKS_ENABLE > 0) +/************************************************************************************//** +** \brief Callback that gets called at the end of the internal COP driver +** initialization routine. It can be used to configure and enable the +** watchdog. +** \return none. +** +****************************************************************************************/ +void CopInitHook(void) +{ + /* this function is called upon initialization. might as well use it to initialize + * the LED driver. It is kind of a visual watchdog anyways. + */ + LedBlinkInit(100); +} /*** end of CopInitHook ***/ + + +/************************************************************************************//** +** \brief Callback that gets called at the end of the internal COP driver +** service routine. This gets called upon initialization and during +** potential long lasting loops and routine. It can be used to service +** the watchdog to prevent a watchdog reset. +** \return none. +** +****************************************************************************************/ +void CopServiceHook(void) +{ + /* run the LED blink task. this is a better place to do it than in the main() program + * loop. certain operations such as flash erase can take a long time, which would cause + * a blink interval to be skipped. this function is also called during such operations, + * so no blink intervals will be skipped when calling the LED blink task here. + */ + LedBlinkTask(); +} /*** end of CopServiceHook ***/ +#endif /* BOOT_COP_HOOKS_ENABLE > 0 */ + + +/**************************************************************************************** +* 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 +****************************************************************************************/ + +#if (BOOT_NVM_HOOKS_ENABLE > 0) +/************************************************************************************//** +** \brief Callback that gets called at the start of the internal NVM driver +** initialization routine. +** \return none. +** +****************************************************************************************/ +void NvmInitHook(void) +{ +} /*** end of NvmInitHook ***/ + + +/************************************************************************************//** +** \brief Callback that gets called at the start of a firmware update to reinitialize +** the NVM driver. +** \return none. +** +****************************************************************************************/ +void NvmReinitHook(void) +{ +} /*** end of NvmReinitHook ***/ + + +/************************************************************************************//** +** \brief Callback that gets called at the start of the NVM driver write +** routine. It allows additional memory to be operated on. If the address +** is not within the range of the additional memory, then +** BLT_NVM_NOT_IN_RANGE must be returned to indicate that the data hasn't +** been written yet. +** \param addr Start address. +** \param len Length in bytes. +** \param data Pointer to the data buffer. +** \return BLT_NVM_OKAY if successful, BLT_NVM_NOT_IN_RANGE if the address is +** not within the supported memory range, or BLT_NVM_ERROR is the write +** operation failed. +** +****************************************************************************************/ +blt_int8u NvmWriteHook(blt_addr addr, blt_int32u len, blt_int8u *data) +{ + return BLT_NVM_NOT_IN_RANGE; +} /*** end of NvmWriteHook ***/ + + +/************************************************************************************//** +** \brief Callback that gets called at the start of the NVM driver erase +** routine. It allows additional memory to be operated on. If the address +** is not within the range of the additional memory, then +** BLT_NVM_NOT_IN_RANGE must be returned to indicate that the memory +** hasn't been erased yet. +** \param addr Start address. +** \param len Length in bytes. +** \return BLT_NVM_OKAY if successful, BLT_NVM_NOT_IN_RANGE if the address is +** not within the supported memory range, or BLT_NVM_ERROR is the erase +** operation failed. +** +****************************************************************************************/ +blt_int8u NvmEraseHook(blt_addr addr, blt_int32u len) +{ + return BLT_NVM_NOT_IN_RANGE; +} /*** end of NvmEraseHook ***/ + + +/************************************************************************************//** +** \brief Callback that gets called at the end of the NVM programming session. +** \return BLT_TRUE is successful, BLT_FALSE otherwise. +** +****************************************************************************************/ +blt_bool NvmDoneHook(void) +{ + return BLT_TRUE; +} /*** end of NvmDoneHook ***/ +#endif /* BOOT_NVM_HOOKS_ENABLE > 0 */ + + +#if (BOOT_NVM_CHECKSUM_HOOKS_ENABLE > 0) +/************************************************************************************//** +** \brief Verifies the checksum, which indicates that a valid user program is +** present and can be started. +** \return BLT_TRUE if successful, BLT_FALSE otherwise. +** +****************************************************************************************/ +blt_bool NvmVerifyChecksumHook(void) +{ + return BLT_TRUE; +} /*** end of NvmVerifyChecksum ***/ + + +/************************************************************************************//** +** \brief Writes a checksum of the user program to non-volatile memory. This is +** performed once the entire user program has been programmed. Through +** the checksum, the bootloader can check if a valid user programming is +** present and can be started. +** \return BLT_TRUE if successful, BLT_FALSE otherwise. +** +****************************************************************************************/ +blt_bool NvmWriteChecksumHook(void) +{ + return BLT_TRUE; +} +#endif /* BOOT_NVM_CHECKSUM_HOOKS_ENABLE > 0 */ + + +/**************************************************************************************** +* 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 +****************************************************************************************/ + +#if (BOOT_XCP_SEED_KEY_ENABLE > 0) +/************************************************************************************//** +** \brief Provides a seed to the XCP master that will be used for the key +** generation when the master attempts to unlock the specified resource. +** Called by the GET_SEED command. +** \param resource Resource that the seed if requested for (XCP_RES_XXX). +** \param seed Pointer to byte buffer wher the seed will be stored. +** \return Length of the seed in bytes. +** +****************************************************************************************/ +blt_int8u XcpGetSeedHook(blt_int8u resource, blt_int8u *seed) +{ + /* request seed for unlocking ProGraMming resource */ + if ((resource & XCP_RES_PGM) != 0) + { + seed[0] = 0x55; + } + + /* return seed length */ + return 1; +} /*** end of XcpGetSeedHook ***/ + + +/************************************************************************************//** +** \brief Called by the UNLOCK command and checks if the key to unlock the +** specified resource was correct. If so, then the resource protection +** will be removed. +** \param resource resource to unlock (XCP_RES_XXX). +** \param key pointer to the byte buffer holding the key. +** \param len length of the key in bytes. +** \return 1 if the key was correct, 0 otherwise. +** +****************************************************************************************/ +blt_int8u XcpVerifyKeyHook(blt_int8u resource, blt_int8u *key, blt_int8u len) +{ + /* suppress compiler warning for unused parameter */ + len = len; + + /* the example key algorithm in "libseednkey.dll" works as follows: + * - PGM will be unlocked if key = seed - 1 + */ + + /* check key for unlocking ProGraMming resource */ + if ((resource == XCP_RES_PGM) && (key[0] == (0x55-1))) + { + /* correct key received for unlocking PGM resource */ + return 1; + } + + /* still here so key incorrect */ + return 0; +} /*** end of XcpVerifyKeyHook ***/ +#endif /* BOOT_XCP_SEED_KEY_ENABLE > 0 */ + + +/*********************************** end of hooks.c ************************************/ diff --git a/Target/Demo/_template/Boot/led.c b/Target/Demo/_template/Boot/led.c new file mode 100644 index 00000000..1558d9a4 --- /dev/null +++ b/Target/Demo/_template/Boot/led.c @@ -0,0 +1,104 @@ +/************************************************************************************//** +* \file Demo/_template/Boot/led.c +* \brief LED driver source file. +* \ingroup Boot__template +* \internal +*---------------------------------------------------------------------------------------- +* C O P Y R I G H T +*---------------------------------------------------------------------------------------- +* Copyright (c) 2019 by Feaser http://www.feaser.com All rights reserved +* +*---------------------------------------------------------------------------------------- +* L I C E N S E +*---------------------------------------------------------------------------------------- +* This file is part of OpenBLT. OpenBLT is free software: you can redistribute it and/or +* modify it under the terms of the GNU General Public License as published by the Free +* Software Foundation, either version 3 of the License, or (at your option) any later +* version. +* +* OpenBLT is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; +* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +* PURPOSE. See the GNU General Public License for more details. +* +* You have received a copy of the GNU General Public License along with OpenBLT. It +* should be located in ".\Doc\license.html". If not, contact Feaser to obtain a copy. +* +* \endinternal +****************************************************************************************/ + +/**************************************************************************************** +* Include files +****************************************************************************************/ +#include "boot.h" /* bootloader generic header */ +#include "led.h" /* module header */ + + +/**************************************************************************************** +* Local data declarations +****************************************************************************************/ +/** \brief Holds the desired LED blink interval time. */ +static blt_int16u ledBlinkIntervalMs; + + +/************************************************************************************//** +** \brief Initializes the LED blink driver. +** \param interval_ms Specifies the desired LED blink interval time in milliseconds. +** \return none. +** +****************************************************************************************/ +void LedBlinkInit(blt_int16u interval_ms) +{ + /* TODO ##Boot Configure the GPIO pin that the LED is connected to, as a digital output + * and make sure the LED is turned off after this configuration. + */ + + /* store the interval time between LED toggles */ + ledBlinkIntervalMs = interval_ms; +} /*** end of LedBlinkInit ***/ + + +/************************************************************************************//** +** \brief Task function for blinking the LED as a fixed timer interval. +** \return none. +** +****************************************************************************************/ +void LedBlinkTask(void) +{ + static blt_bool ledOn = BLT_FALSE; + static blt_int32u nextBlinkEvent = 0; + + /* check for blink event */ + if (TimerGet() >= nextBlinkEvent) + { + /* toggle the LED state */ + if (ledOn == BLT_FALSE) + { + ledOn = BLT_TRUE; + /* TODO ##Boot Turn the LED on. */ + } + else + { + ledOn = BLT_FALSE; + /* TODO ##Boot Turn the LED off. */ + } + /* schedule the next blink event */ + nextBlinkEvent = TimerGet() + ledBlinkIntervalMs; + } +} /*** end of LedBlinkTask ***/ + + +/************************************************************************************//** +** \brief Cleans up the LED blink driver. This is intended to be used upon program +** exit. +** \return none. +** +****************************************************************************************/ +void LedBlinkExit(void) +{ + /* TODO ##Boot Turn the LED off and reset the GPIO pin configuration that was + * configured to drive the LED. + */ +} /*** end of LedBlinkExit ***/ + + +/*********************************** end of led.c **************************************/ diff --git a/Target/Demo/_template/Boot/led.h b/Target/Demo/_template/Boot/led.h new file mode 100644 index 00000000..b636181c --- /dev/null +++ b/Target/Demo/_template/Boot/led.h @@ -0,0 +1,40 @@ +/************************************************************************************//** +* \file Demo/_template/Boot/led.h +* \brief LED driver header file. +* \ingroup Boot__template +* \internal +*---------------------------------------------------------------------------------------- +* C O P Y R I G H T +*---------------------------------------------------------------------------------------- +* Copyright (c) 2019 by Feaser http://www.feaser.com All rights reserved +* +*---------------------------------------------------------------------------------------- +* L I C E N S E +*---------------------------------------------------------------------------------------- +* This file is part of OpenBLT. OpenBLT is free software: you can redistribute it and/or +* modify it under the terms of the GNU General Public License as published by the Free +* Software Foundation, either version 3 of the License, or (at your option) any later +* version. +* +* OpenBLT is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; +* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +* PURPOSE. See the GNU General Public License for more details. +* +* You have received a copy of the GNU General Public License along with OpenBLT. It +* should be located in ".\Doc\license.html". If not, contact Feaser to obtain a copy. +* +* \endinternal +****************************************************************************************/ +#ifndef LED_H +#define LED_H + +/**************************************************************************************** +* Function prototypes +****************************************************************************************/ +void LedBlinkInit(blt_int16u interval_ms); +void LedBlinkTask(void); +void LedBlinkExit(void); + + +#endif /* LED_H */ +/*********************************** end of led.h **************************************/ diff --git a/Target/Demo/_template/Boot/main.c b/Target/Demo/_template/Boot/main.c new file mode 100644 index 00000000..f9f6840f --- /dev/null +++ b/Target/Demo/_template/Boot/main.c @@ -0,0 +1,80 @@ +/************************************************************************************//** +* \file Demo/_template/Boot/main.c +* \brief Bootloader application source file. +* \ingroup Boot__template +* \internal +*---------------------------------------------------------------------------------------- +* C O P Y R I G H T +*---------------------------------------------------------------------------------------- +* Copyright (c) 2019 by Feaser http://www.feaser.com All rights reserved +* +*---------------------------------------------------------------------------------------- +* L I C E N S E +*---------------------------------------------------------------------------------------- +* This file is part of OpenBLT. OpenBLT is free software: you can redistribute it and/or +* modify it under the terms of the GNU General Public License as published by the Free +* Software Foundation, either version 3 of the License, or (at your option) any later +* version. +* +* OpenBLT is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; +* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +* PURPOSE. See the GNU General Public License for more details. +* +* You have received a copy of the GNU General Public License along with OpenBLT. It +* should be located in ".\Doc\license.html". If not, contact Feaser to obtain a copy. +* +* \endinternal +****************************************************************************************/ + +/**************************************************************************************** +* Include files +****************************************************************************************/ +#include "boot.h" /* bootloader generic header */ + + +/**************************************************************************************** +* Function prototypes +****************************************************************************************/ +static void Init(void); + + +/************************************************************************************//** +** \brief This is the entry point for the bootloader application and is called +** by the reset interrupt vector after the C-startup routines executed. +** \return Program return code. +** +****************************************************************************************/ +int main(void) +{ + /* initialize the microcontroller */ + Init(); + /* initialize the bootloader */ + BootInit(); + + /* start the infinite program loop */ + while (1) + { + /* run the bootloader task */ + BootTask(); + } + + /* program should never get here */ + return 0; +} /*** end of main ***/ + + +/************************************************************************************//** +** \brief Initializes the microcontroller. +** \return none. +** +****************************************************************************************/ +static void Init(void) +{ + /* TODO ##Boot Initialize the microcontroller. This typically consists of configuring + * the microcontroller's system clock and configuring the GPIO for the communication + * peripheral(s) enabled in the bootloader's configuration header file "blt_conf.h". + */ +} /*** end of Init ***/ + + +/*********************************** end of main.c *************************************/ diff --git a/Target/Demo/_template/Boot/makefile b/Target/Demo/_template/Boot/makefile new file mode 100644 index 00000000..1ccfa9e1 --- /dev/null +++ b/Target/Demo/_template/Boot/makefile @@ -0,0 +1,169 @@ +#**************************************************************************************** +#| Description: Makefile for GNU ARM Embedded toolchain. +#| File Name: makefile +#| +#|--------------------------------------------------------------------------------------- +#| C O P Y R I G H T +#|--------------------------------------------------------------------------------------- +#| Copyright (c) 2019 by Feaser http://www.feaser.com All rights reserved +#| +#|--------------------------------------------------------------------------------------- +#| L I C E N S E +#|--------------------------------------------------------------------------------------- +#| This file is part of OpenBLT. OpenBLT is free software: you can redistribute it and/or +#| modify it under the terms of the GNU General Public License as published by the Free +#| Software Foundation, either version 3 of the License, or (at your option) any later +#| version. +#| +#| OpenBLT is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; +#| without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +#| PURPOSE. See the GNU General Public License for more details. +#| +#| You have received a copy of the GNU General Public License along with OpenBLT. It +#| should be located in ".\Doc\license.html". If not, contact Feaser to obtain a copy. +#| +#**************************************************************************************** +SHELL = sh + +#|--------------------------------------------------------------------------------------| +#| Configure project name | +#|--------------------------------------------------------------------------------------| +PROJ_NAME=openblt_template + + +#|--------------------------------------------------------------------------------------| +#| Configure tool path | +#|--------------------------------------------------------------------------------------| +TOOL_PATH= + + +#|--------------------------------------------------------------------------------------| +#| Collect project files | +#|--------------------------------------------------------------------------------------| +# Recursive wildcard function implementation. Example usages: +# $(call rwildcard, , *.c *.h) +# --> Returns all *.c and *.h files in the current directory and below +# $(call rwildcard, /lib/, *.c) +# --> Returns all *.c files in the /lib directory and below +rwildcard = $(strip $(foreach d,$(wildcard $1*),$(call rwildcard,$d/,$2) $(filter $(subst *,%,$2),$d))) + +# Collect all application files in the current directory and its subdirectories, but +# exclude flash-layout.c as this one is directly included in a source file, when used. +PROJ_FILES = $(filter-out flash_layout.c, $(call rwildcard, , *.c *.h *.s)) +# Collect bootloader core files +PROJ_FILES += $(wildcard ../../../Source/*.c) +PROJ_FILES += $(wildcard ../../../Source/*.h) +# Collect bootloader port files +PROJ_FILES += $(wildcard ../../../Source/_template/*.c) +PROJ_FILES += $(wildcard ../../../Source/_template/*.h) +# Collect bootloader port compiler specific files +PROJ_FILES += $(wildcard ../../../Source/_template/GCC/*.c) +PROJ_FILES += $(wildcard ../../../Source/_template/GCC/*.h) + + +#|--------------------------------------------------------------------------------------| +#| Toolchain binaries | +#|--------------------------------------------------------------------------------------| +RM = rm +CC = $(TOOL_PATH)gcc +LN = $(TOOL_PATH)gcc +OC = $(TOOL_PATH)objcopy +OD = $(TOOL_PATH)objdump +AS = $(TOOL_PATH)gcc +SZ = $(TOOL_PATH)size + + +#|--------------------------------------------------------------------------------------| +#| Filter project files +#|--------------------------------------------------------------------------------------| +PROJ_ASRCS = $(filter %.s,$(foreach file,$(PROJ_FILES),$(notdir $(file)))) +PROJ_CSRCS = $(filter %.c,$(foreach file,$(PROJ_FILES),$(notdir $(file)))) +PROJ_CHDRS = $(filter %.h,$(foreach file,$(PROJ_FILES),$(notdir $(file)))) + + +#|--------------------------------------------------------------------------------------| +#| Set important path variables | +#|--------------------------------------------------------------------------------------| +VPATH = $(foreach path,$(sort $(foreach file,$(PROJ_FILES),$(dir $(file)))) $(subst \,/,$(OBJ_PATH)),$(path) :) +OBJ_PATH = obj +BIN_PATH = bin +INC_PATH = $(patsubst %/,%,$(patsubst %,-I%,$(sort $(foreach file,$(filter %.h,$(PROJ_FILES)),$(dir $(file)))))) +LIB_PATH = + + +#|--------------------------------------------------------------------------------------| +#| Options for toolchain binaries | +#|--------------------------------------------------------------------------------------| +STDFLAGS = -fdata-sections -ffunction-sections -Wall -g -Wno-strict-aliasing +STDFLAGS += -Wno-pointer-to-int-cast +OPTFLAGS = -Og +CFLAGS = $(STDFLAGS) $(OPTFLAGS) +CFLAGS += $(INC_PATH) +AFLAGS = $(CFLAGS) +LFLAGS = $(STDFLAGS) $(OPTFLAGS) +LFLAGS += -Wl,-Map=$(BIN_PATH)/$(PROJ_NAME).map +LFLAGS += -Wl,--gc-sections $(LIB_PATH) +OFLAGS = -O srec +ODFLAGS = -x +SZFLAGS = -B -d +RMFLAGS = -f + + +#|--------------------------------------------------------------------------------------| +#| Specify library files | +#|--------------------------------------------------------------------------------------| +LIBS = + + +#|--------------------------------------------------------------------------------------| +#| Define targets | +#|--------------------------------------------------------------------------------------| +AOBJS = $(patsubst %.s,%.o,$(PROJ_ASRCS)) +COBJS = $(patsubst %.c,%.o,$(PROJ_CSRCS)) + + +#|--------------------------------------------------------------------------------------| +#| Make ALL | +#|--------------------------------------------------------------------------------------| +.PHONY: all +all: $(BIN_PATH)/$(PROJ_NAME).srec + + +$(BIN_PATH)/$(PROJ_NAME).srec : $(BIN_PATH)/$(PROJ_NAME).elf + @$(OC) $< $(OFLAGS) $@ + @$(OD) $(ODFLAGS) $< > $(BIN_PATH)/$(PROJ_NAME).map + @echo +++ Summary of memory consumption: + @$(SZ) $(SZFLAGS) $< + @echo +++ Build complete [$(notdir $@)] + +$(BIN_PATH)/$(PROJ_NAME).elf : $(AOBJS) $(COBJS) + @echo +++ Linking [$(notdir $@)] + @$(LN) $(LFLAGS) -o $@ $(patsubst %.o,$(OBJ_PATH)/%.o,$(^F)) $(LIBS) + + +#|--------------------------------------------------------------------------------------| +#| Compile and assemble | +#|--------------------------------------------------------------------------------------| +$(AOBJS): %.o: %.s $(PROJ_CHDRS) + @echo +++ Assembling [$(notdir $<)] + @$(AS) $(AFLAGS) -c $< -o $(OBJ_PATH)/$(@F) + +$(COBJS): %.o: %.c $(PROJ_CHDRS) + @echo +++ Compiling [$(notdir $<)] + @$(CC) $(CFLAGS) -c $< -o $(OBJ_PATH)/$(@F) + + +#|--------------------------------------------------------------------------------------| +#| Make CLEAN | +#|--------------------------------------------------------------------------------------| +.PHONY: clean +clean: + @echo +++ Cleaning build environment + @$(RM) $(RMFLAGS) $(foreach file,$(AOBJS),$(OBJ_PATH)/$(file)) + @$(RM) $(RMFLAGS) $(foreach file,$(COBJS),$(OBJ_PATH)/$(file)) + @$(RM) $(RMFLAGS) $(patsubst %.o,%.lst,$(foreach file,$(COBJS),$(OBJ_PATH)/$(file))) + @$(RM) $(RMFLAGS) $(BIN_PATH)/$(PROJ_NAME).elf $(BIN_PATH)/$(PROJ_NAME).map + @$(RM) $(RMFLAGS) $(BIN_PATH)/$(PROJ_NAME).srec + @echo +++ Clean complete + + diff --git a/Target/Demo/_template/Prog/boot.c b/Target/Demo/_template/Prog/boot.c new file mode 100644 index 00000000..74d62032 --- /dev/null +++ b/Target/Demo/_template/Prog/boot.c @@ -0,0 +1,221 @@ +/************************************************************************************//** +* \file Demo/_template/Prog/boot.c +* \brief Demo program bootloader interface source file. +* \ingroup Prog__template +* \internal +*---------------------------------------------------------------------------------------- +* C O P Y R I G H T +*---------------------------------------------------------------------------------------- +* Copyright (c) 2019 by Feaser http://www.feaser.com All rights reserved +* +*---------------------------------------------------------------------------------------- +* L I C E N S E +*---------------------------------------------------------------------------------------- +* This file is part of OpenBLT. OpenBLT is free software: you can redistribute it and/or +* modify it under the terms of the GNU General Public License as published by the Free +* Software Foundation, either version 3 of the License, or (at your option) any later +* version. +* +* OpenBLT is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; +* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +* PURPOSE. See the GNU General Public License for more details. +* +* You have received a copy of the GNU General Public License along with OpenBLT. It +* should be located in ".\Doc\license.html". If not, contact Feaser to obtain a copy. +* +* \endinternal +****************************************************************************************/ + +/**************************************************************************************** +* Include files +****************************************************************************************/ +#include "header.h" /* generic header */ + + +/**************************************************************************************** +* Function prototypes +****************************************************************************************/ +#if (BOOT_COM_UART_ENABLE > 0) +static void BootComUartInit(void); +static void BootComUartCheckActivationRequest(void); +#endif + + +/************************************************************************************//** +** \brief Initializes the communication interface. +** \return none. +** +****************************************************************************************/ +void BootComInit(void) +{ +#if (BOOT_COM_UART_ENABLE > 0) + BootComUartInit(); +#endif +} /*** end of BootComInit ***/ + + +/************************************************************************************//** +** \brief Receives the CONNECT request from the host, which indicates that the +** bootloader should be activated and, if so, activates it. +** \return none. +** +****************************************************************************************/ +void BootComCheckActivationRequest(void) +{ +#if (BOOT_COM_UART_ENABLE > 0) + BootComUartCheckActivationRequest(); +#endif +} /*** end of BootComCheckActivationRequest ***/ + + +/************************************************************************************//** +** \brief Bootloader activation function. +** \return none. +** +****************************************************************************************/ +void BootActivate(void) +{ + /* TODO ##Prog The bootloader is typically executed by performing a software reset. + * Performing a software reset it typically supported by a microcontroller target. If + * not, then an alternative is to enable the watchdog here and then enter an infinite + * loop, which will trigger a watchdog reset. After a reset event the bootloader always + * runs first, so this is a valid method for activating the bootloader. + */ +} /*** end of BootActivate ***/ + + +#if (BOOT_COM_UART_ENABLE > 0) +/**************************************************************************************** +* U N I V E R S A L A S Y N C H R O N O U S R X T X I N T E R F A C E +****************************************************************************************/ + +/**************************************************************************************** +* Macro definitions +****************************************************************************************/ +/** \brief Timeout time for the reception of a CTO packet. The timer is started upon + * reception of the first packet byte. + */ +#define UART_CTO_RX_PACKET_TIMEOUT_MS (100u) + + +/**************************************************************************************** +* Function prototypes +****************************************************************************************/ +static unsigned char UartReceiveByte(unsigned char *data); + + +/************************************************************************************//** +** \brief Initializes the UART communication interface. +** \return none. +** +****************************************************************************************/ +static void BootComUartInit(void) +{ + /* TODO ##Prog Configure and initialize the UART peripheral for the configured UART + * channel. The communication speed should be set to the value configured with + * BOOT_COM_UART_BAUDRATE in blt_conf.h. Further communication settings are: + * 8 databits, no parity, and 1 stopbit. + */ +} /*** end of BootComUartInit ***/ + + +/************************************************************************************//** +** \brief Receives the CONNECT request from the host, which indicates that the +** bootloader should be activated and, if so, activates it. +** \return none. +** +****************************************************************************************/ +static void BootComUartCheckActivationRequest(void) +{ + static unsigned char xcpCtoReqPacket[BOOT_COM_UART_RX_MAX_DATA+1]; + static unsigned char xcpCtoRxLength; + static unsigned char xcpCtoRxInProgress = 0; + static unsigned long xcpCtoRxStartTime = 0; + + /* start of cto packet received? */ + if (xcpCtoRxInProgress == 0) + { + /* store the message length when received */ + if (UartReceiveByte(&xcpCtoReqPacket[0]) == 1) + { + /* check that the length has a valid value. it should not be 0 */ + if ( (xcpCtoReqPacket[0] > 0) && + (xcpCtoReqPacket[0] <= BOOT_COM_UART_RX_MAX_DATA) ) + { + /* store the start time */ + xcpCtoRxStartTime = TimerGet(); + /* indicate that a cto packet is being received */ + xcpCtoRxInProgress = 1; + /* reset packet data count */ + xcpCtoRxLength = 0; + } + } + } + else + { + /* store the next packet byte */ + if (UartReceiveByte(&xcpCtoReqPacket[xcpCtoRxLength+1]) == 1) + { + /* increment the packet data count */ + xcpCtoRxLength++; + + /* check to see if the entire packet was received */ + if (xcpCtoRxLength == xcpCtoReqPacket[0]) + { + /* done with cto packet reception */ + xcpCtoRxInProgress = 0; + + /* check if this was an XCP CONNECT command */ + if ((xcpCtoReqPacket[1] == 0xff) && (xcpCtoReqPacket[2] == 0x00)) + { + /* connection request received so start the bootloader */ + BootActivate(); + } + } + } + else + { + /* check packet reception timeout */ + if (TimerGet() > (xcpCtoRxStartTime + UART_CTO_RX_PACKET_TIMEOUT_MS)) + { + /* cancel cto packet reception due to timeout. note that this automatically + * discards the already received packet bytes, allowing the host to retry. + */ + xcpCtoRxInProgress = 0; + } + } + } +} /*** end of BootComUartCheckActivationRequest ***/ + + +/************************************************************************************//** +** \brief Receives a communication interface byte if one is present. +** \param data Pointer to byte where the data is to be stored. +** \return 1 if a byte was received, 0 otherwise. +** +****************************************************************************************/ +static unsigned char UartReceiveByte(unsigned char *data) +{ + unsigned char result = 0; + + /* TODO ##Port Check if a new byte was received on the configured channel. This is + * typically done by checking the reception register not empty flag. If a new byte + * was received, read it out and store it in '*data'. Next, clear the reception flag + * such that a new byte can be received again. Finally, set 'result' to 1 to indicate + * to the caller of this function that a new byte was received and stored. + */ + if (1 == 0) + { + /* retrieve and store the newly received byte */ + *data = 0; + /* update the result */ + result = 1; + } + + /* give the result back to the caller */ + return result; +} /*** end of UartReceiveByte ***/ +#endif /* BOOT_COM_UART_ENABLE > 0 */ + + +/*********************************** end of boot.c *************************************/ diff --git a/Target/Demo/_template/Prog/boot.h b/Target/Demo/_template/Prog/boot.h new file mode 100644 index 00000000..59c4b6db --- /dev/null +++ b/Target/Demo/_template/Prog/boot.h @@ -0,0 +1,40 @@ +/************************************************************************************//** +* \file Demo/_template/Prog/boot.h +* \brief Demo program bootloader interface header file. +* \ingroup Prog__template +* \internal +*---------------------------------------------------------------------------------------- +* C O P Y R I G H T +*---------------------------------------------------------------------------------------- +* Copyright (c) 2019 by Feaser http://www.feaser.com All rights reserved +* +*---------------------------------------------------------------------------------------- +* L I C E N S E +*---------------------------------------------------------------------------------------- +* This file is part of OpenBLT. OpenBLT is free software: you can redistribute it and/or +* modify it under the terms of the GNU General Public License as published by the Free +* Software Foundation, either version 3 of the License, or (at your option) any later +* version. +* +* OpenBLT is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; +* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +* PURPOSE. See the GNU General Public License for more details. +* +* You have received a copy of the GNU General Public License along with OpenBLT. It +* should be located in ".\Doc\license.html". If not, contact Feaser to obtain a copy. +* +* \endinternal +****************************************************************************************/ +#ifndef BOOT_H +#define BOOT_H + +/**************************************************************************************** +* Function prototypes +****************************************************************************************/ +void BootComInit(void); +void BootComCheckActivationRequest(void); +void BootActivate(void); + + +#endif /* BOOT_H */ +/*********************************** end of boot.h *************************************/ diff --git a/Target/Demo/_template/Prog/header.h b/Target/Demo/_template/Prog/header.h new file mode 100644 index 00000000..d685babb --- /dev/null +++ b/Target/Demo/_template/Prog/header.h @@ -0,0 +1,41 @@ +/************************************************************************************//** +* \file Demo/_template/Prog/header.h +* \brief Generic header file. +* \ingroup Prog__template +* \internal +*---------------------------------------------------------------------------------------- +* C O P Y R I G H T +*---------------------------------------------------------------------------------------- +* Copyright (c) 2019 by Feaser http://www.feaser.com All rights reserved +* +*---------------------------------------------------------------------------------------- +* L I C E N S E +*---------------------------------------------------------------------------------------- +* This file is part of OpenBLT. OpenBLT is free software: you can redistribute it and/or +* modify it under the terms of the GNU General Public License as published by the Free +* Software Foundation, either version 3 of the License, or (at your option) any later +* version. +* +* OpenBLT is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; +* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +* PURPOSE. See the GNU General Public License for more details. +* +* You have received a copy of the GNU General Public License along with OpenBLT. It +* should be located in ".\Doc\license.html". If not, contact Feaser to obtain a copy. +* +* \endinternal +****************************************************************************************/ +#ifndef HEADER_H +#define HEADER_H + +/**************************************************************************************** +* Include files +****************************************************************************************/ +#include "../Boot/blt_conf.h" /* bootloader configuration */ +#include "boot.h" /* bootloader interface driver */ +#include "led.h" /* LED driver */ +#include "timer.h" /* Timer driver */ + + +#endif /* HEADER_H */ +/*********************************** end of header.h ***********************************/ diff --git a/Target/Demo/_template/Prog/led.c b/Target/Demo/_template/Prog/led.c new file mode 100644 index 00000000..5c38d77a --- /dev/null +++ b/Target/Demo/_template/Prog/led.c @@ -0,0 +1,91 @@ +/************************************************************************************//** +* \file Demo/_template/Prog/led.c +* \brief LED driver source file. +* \ingroup Prog__template +* \internal +*---------------------------------------------------------------------------------------- +* C O P Y R I G H T +*---------------------------------------------------------------------------------------- +* Copyright (c) 2019 by Feaser http://www.feaser.com All rights reserved +* +*---------------------------------------------------------------------------------------- +* L I C E N S E +*---------------------------------------------------------------------------------------- +* This file is part of OpenBLT. OpenBLT is free software: you can redistribute it and/or +* modify it under the terms of the GNU General Public License as published by the Free +* Software Foundation, either version 3 of the License, or (at your option) any later +* version. +* +* OpenBLT is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; +* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +* PURPOSE. See the GNU General Public License for more details. +* +* You have received a copy of the GNU General Public License along with OpenBLT. It +* should be located in ".\Doc\license.html". If not, contact Feaser to obtain a copy. +* +* \endinternal +****************************************************************************************/ + +/**************************************************************************************** +* Include files +****************************************************************************************/ +#include "header.h" /* generic header */ + + +/**************************************************************************************** +* Macro definitions +****************************************************************************************/ +/** \brief Toggle interval time in milliseconds. */ +#define LED_TOGGLE_MS (500) + + +/************************************************************************************//** +** \brief Initializes the LED. +** \return none. +** +****************************************************************************************/ +void LedInit(void) +{ + /* TODO ##Prog Configure the GPIO pin that the LED is connected to, as a digital output + * and make sure the LED is turned off after this configuration. + */ +} /*** end of LedInit ***/ + + +/************************************************************************************//** +** \brief Toggles the LED at a fixed time interval. +** \return none. +** +****************************************************************************************/ +void LedToggle(void) +{ + static unsigned char led_toggle_state = 0; + static unsigned long timer_counter_last = 0; + unsigned long timer_counter_now; + + /* check if toggle interval time passed */ + timer_counter_now = TimerGet(); + if ( (timer_counter_now - timer_counter_last) < LED_TOGGLE_MS) + { + /* not yet time to toggle */ + return; + } + + /* determine toggle action */ + if (led_toggle_state == 0) + { + led_toggle_state = 1; + /* TODO ##Prog Turn the LED on. */ + } + else + { + led_toggle_state = 0; + /* TODO ##Prog Turn the LED off. */ + } + + /* store toggle time to determine next toggle interval */ + timer_counter_last = timer_counter_now; +} /*** end of LedToggle ***/ + + +/*********************************** end of led.c **************************************/ diff --git a/Target/Demo/_template/Prog/led.h b/Target/Demo/_template/Prog/led.h new file mode 100644 index 00000000..afceb9f2 --- /dev/null +++ b/Target/Demo/_template/Prog/led.h @@ -0,0 +1,39 @@ +/************************************************************************************//** +* \file Demo/_template/Prog/led.h +* \brief LED driver header file. +* \ingroup Prog__template +* \internal +*---------------------------------------------------------------------------------------- +* C O P Y R I G H T +*---------------------------------------------------------------------------------------- +* Copyright (c) 2019 by Feaser http://www.feaser.com All rights reserved +* +*---------------------------------------------------------------------------------------- +* L I C E N S E +*---------------------------------------------------------------------------------------- +* This file is part of OpenBLT. OpenBLT is free software: you can redistribute it and/or +* modify it under the terms of the GNU General Public License as published by the Free +* Software Foundation, either version 3 of the License, or (at your option) any later +* version. +* +* OpenBLT is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; +* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +* PURPOSE. See the GNU General Public License for more details. +* +* You have received a copy of the GNU General Public License along with OpenBLT. It +* should be located in ".\Doc\license.html". If not, contact Feaser to obtain a copy. +* +* \endinternal +****************************************************************************************/ +#ifndef LED_H +#define LED_H + +/**************************************************************************************** +* Function prototypes +****************************************************************************************/ +void LedInit(void); +void LedToggle(void); + + +#endif /* LED_H */ +/*********************************** end of led.h **************************************/ diff --git a/Target/Demo/_template/Prog/main.c b/Target/Demo/_template/Prog/main.c new file mode 100644 index 00000000..31159994 --- /dev/null +++ b/Target/Demo/_template/Prog/main.c @@ -0,0 +1,123 @@ +/************************************************************************************//** +* \file Demo/_template/Prog/main.c +* \brief Demo program application source file. +* \ingroup Prog__template +* \internal +*---------------------------------------------------------------------------------------- +* C O P Y R I G H T +*---------------------------------------------------------------------------------------- +* Copyright (c) 2019 by Feaser http://www.feaser.com All rights reserved +* +*---------------------------------------------------------------------------------------- +* L I C E N S E +*---------------------------------------------------------------------------------------- +* This file is part of OpenBLT. OpenBLT is free software: you can redistribute it and/or +* modify it under the terms of the GNU General Public License as published by the Free +* Software Foundation, either version 3 of the License, or (at your option) any later +* version. +* +* OpenBLT is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; +* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +* PURPOSE. See the GNU General Public License for more details. +* +* You have received a copy of the GNU General Public License along with OpenBLT. It +* should be located in ".\Doc\license.html". If not, contact Feaser to obtain a copy. +* +* \endinternal +****************************************************************************************/ + +/**************************************************************************************** +* Include files +****************************************************************************************/ +#include "header.h" /* generic header */ + +/* TODO ##Prog The PC host tools that ship with the OpenBLT bootloader (MicroBoot and + * BootCommander) expect the firmware binary to be in the S-Record format. Make sure to + * configure the project in your IDE or Makefile to generate an S-Record. This is + * typically done in a post-build step. More information about the S-Record format can + * be found here: https://en.wikipedia.org/wiki/SREC_(file_format). + +/* TODO ##Prog Note that the first part of flash memory is reserved for the bootloader. + * To find out exactly how much, have a look at the flashLayout[] array in the + * bootloader's flash.c file. The flash sectors reserved are typically commented out in + * flashLayout[]. This user program's linker descriptor file must be adjusted such that + * the start address is moved forward a number of bytes that equals how many bytes are + * reserved for the bootloader. + */ + +/* TODO ##Prog The bootloader should handle the remapping of the interrupt vector table + * base address such that this user program's vector table is used. This functionality + * is implemented in the bootloader's function CpuStartUserProgram() in file cpu.c. + * Some microcontroller manufacturer provided peripheral driver libraries, which might + * be used in this user program, could unfortunately reset this and map the interrupt + * vector table back to the start of flash. This would be where the bootloader's + * interrupt vector table is located, which is incorrect. In this case the interrupt + * vector table remapping needs to be explicitely implemented here again before the + * interrupts are enabled. + */ + +/* TODO ##Prog Some microcontrollers store the initial value for the stackpointer + * CPU register in the interrupt vector table and the microcontroller automatically loads + * this value into the stackpointer CPU register upon reset. Since this user program is + * not directly started by a microcontroller reset, but by the bootloader, the CPU + * stackpointer register will not be initialized properly. In this case the CPU + * stackpointer register must be explicitly initialized by the startup code. The best + * place to do this is at the start of the reset interrupt handler, which is typically + * located in a file with assembly code. + */ + + +/**************************************************************************************** +* Function prototypes +****************************************************************************************/ +static void Init(void); + + +/************************************************************************************//** +** \brief This is the entry point for the bootloader application and is called +** by the reset interrupt vector after the C-startup routines executed. +** \return Program return code. +** +****************************************************************************************/ +int main(void) +{ + /* initialize the microcontroller */ + Init(); + /* initialize the bootloader interface */ + BootComInit(); + + /* start the infinite program loop */ + while (1) + { + /* toggle LED with a fixed frequency */ + LedToggle(); + /* check for bootloader activation request */ + BootComCheckActivationRequest(); + } + + /* program should never get here */ + return 0; +} /*** end of main ***/ + + +/************************************************************************************//** +** \brief Initializes the microcontroller. +** \return none. +** +****************************************************************************************/ +static void Init(void) +{ + /* TODO ##Prog Initialize the microcontroller. This typically consists of configuring + * the microcontroller's system clock and configuring the GPIO for the communication + * peripheral(s) supported in this user program's boot.c. If the microcontroller does + * not enable interrupts automatically after a reset, the interrupts should be enabled + * here as well. + */ + /* initialize the timer driver */ + TimerInit(); + /* initialize the led driver */ + LedInit(); +} /*** end of Init ***/ + + +/*********************************** end of main.c *************************************/ diff --git a/Target/Demo/_template/Prog/makefile b/Target/Demo/_template/Prog/makefile new file mode 100644 index 00000000..1461e154 --- /dev/null +++ b/Target/Demo/_template/Prog/makefile @@ -0,0 +1,158 @@ +#**************************************************************************************** +#| Description: Makefile for GNU ARM Embedded toolchain. +#| File Name: makefile +#| +#|--------------------------------------------------------------------------------------- +#| C O P Y R I G H T +#|--------------------------------------------------------------------------------------- +#| Copyright (c) 2019 by Feaser http://www.feaser.com All rights reserved +#| +#|--------------------------------------------------------------------------------------- +#| L I C E N S E +#|--------------------------------------------------------------------------------------- +#| This file is part of OpenBLT. OpenBLT is free software: you can redistribute it and/or +#| modify it under the terms of the GNU General Public License as published by the Free +#| Software Foundation, either version 3 of the License, or (at your option) any later +#| version. +#| +#| OpenBLT is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; +#| without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +#| PURPOSE. See the GNU General Public License for more details. +#| +#| You have received a copy of the GNU General Public License along with OpenBLT. It +#| should be located in ".\Doc\license.html". If not, contact Feaser to obtain a copy. +#| +#**************************************************************************************** +SHELL = sh + +#|--------------------------------------------------------------------------------------| +#| Configure project name | +#|--------------------------------------------------------------------------------------| +PROJ_NAME=demoprog_template + + +#|--------------------------------------------------------------------------------------| +#| Configure tool path | +#|--------------------------------------------------------------------------------------| +TOOL_PATH= + + +#|--------------------------------------------------------------------------------------| +#| Collect project files | +#|--------------------------------------------------------------------------------------| +# Recursive wildcard function implementation. Example usages: +# $(call rwildcard, , *.c *.h) +# --> Returns all *.c and *.h files in the current directory and below +# $(call rwildcard, /lib/, *.c) +# --> Returns all *.c files in the /lib directory and below +rwildcard = $(strip $(foreach d,$(wildcard $1*),$(call rwildcard,$d/,$2) $(filter $(subst *,%,$2),$d))) + +# Collect all application files in the current directory and its subdirectories +PROJ_FILES = $(call rwildcard, , *.c *.h *.s) + + +#|--------------------------------------------------------------------------------------| +#| Toolchain binaries | +#|--------------------------------------------------------------------------------------| +RM = rm +CC = $(TOOL_PATH)gcc +LN = $(TOOL_PATH)gcc +OC = $(TOOL_PATH)objcopy +OD = $(TOOL_PATH)objdump +AS = $(TOOL_PATH)gcc +SZ = $(TOOL_PATH)size + + +#|--------------------------------------------------------------------------------------| +#| Filter project files +#|--------------------------------------------------------------------------------------| +PROJ_ASRCS = $(filter %.s,$(foreach file,$(PROJ_FILES),$(notdir $(file)))) +PROJ_CSRCS = $(filter %.c,$(foreach file,$(PROJ_FILES),$(notdir $(file)))) +PROJ_CHDRS = $(filter %.h,$(foreach file,$(PROJ_FILES),$(notdir $(file)))) + + +#|--------------------------------------------------------------------------------------| +#| Set important path variables | +#|--------------------------------------------------------------------------------------| +VPATH = $(foreach path,$(sort $(foreach file,$(PROJ_FILES),$(dir $(file)))) $(subst \,/,$(OBJ_PATH)),$(path) :) +OBJ_PATH = obj +BIN_PATH = bin +INC_PATH = $(patsubst %/,%,$(patsubst %,-I%,$(sort $(foreach file,$(filter %.h,$(PROJ_FILES)),$(dir $(file)))))) +LIB_PATH = + + +#|--------------------------------------------------------------------------------------| +#| Options for toolchain binaries | +#|--------------------------------------------------------------------------------------| +STDFLAGS = -fdata-sections -ffunction-sections -Wall -g -Wno-strict-aliasing +OPTFLAGS = -Og +CFLAGS = $(STDFLAGS) $(OPTFLAGS) +CFLAGS += $(INC_PATH) +AFLAGS = $(CFLAGS) +LFLAGS = $(STDFLAGS) $(OPTFLAGS) +LFLAGS += -Wl,-Map=$(BIN_PATH)/$(PROJ_NAME).map +LFLAGS += -Wl,--gc-sections $(LIB_PATH) +OFLAGS = -O srec +ODFLAGS = -x +SZFLAGS = -B -d +RMFLAGS = -f + + +#|--------------------------------------------------------------------------------------| +#| Specify library files | +#|--------------------------------------------------------------------------------------| +LIBS = + + +#|--------------------------------------------------------------------------------------| +#| Define targets | +#|--------------------------------------------------------------------------------------| +AOBJS = $(patsubst %.s,%.o,$(PROJ_ASRCS)) +COBJS = $(patsubst %.c,%.o,$(PROJ_CSRCS)) + + +#|--------------------------------------------------------------------------------------| +#| Make ALL | +#|--------------------------------------------------------------------------------------| +.PHONY: all +all: $(BIN_PATH)/$(PROJ_NAME).srec + + +$(BIN_PATH)/$(PROJ_NAME).srec : $(BIN_PATH)/$(PROJ_NAME).elf + @$(OC) $< $(OFLAGS) $@ + @$(OD) $(ODFLAGS) $< > $(BIN_PATH)/$(PROJ_NAME).map + @echo +++ Summary of memory consumption: + @$(SZ) $(SZFLAGS) $< + @echo +++ Build complete [$(notdir $@)] + +$(BIN_PATH)/$(PROJ_NAME).elf : $(AOBJS) $(COBJS) + @echo +++ Linking [$(notdir $@)] + @$(LN) $(LFLAGS) -o $@ $(patsubst %.o,$(OBJ_PATH)/%.o,$(^F)) $(LIBS) + + +#|--------------------------------------------------------------------------------------| +#| Compile and assemble | +#|--------------------------------------------------------------------------------------| +$(AOBJS): %.o: %.s $(PROJ_CHDRS) + @echo +++ Assembling [$(notdir $<)] + @$(AS) $(AFLAGS) -c $< -o $(OBJ_PATH)/$(@F) + +$(COBJS): %.o: %.c $(PROJ_CHDRS) + @echo +++ Compiling [$(notdir $<)] + @$(CC) $(CFLAGS) -c $< -o $(OBJ_PATH)/$(@F) + + +#|--------------------------------------------------------------------------------------| +#| Make CLEAN | +#|--------------------------------------------------------------------------------------| +.PHONY: clean +clean: + @echo +++ Cleaning build environment + @$(RM) $(RMFLAGS) $(foreach file,$(AOBJS),$(OBJ_PATH)/$(file)) + @$(RM) $(RMFLAGS) $(foreach file,$(COBJS),$(OBJ_PATH)/$(file)) + @$(RM) $(RMFLAGS) $(patsubst %.o,%.lst,$(foreach file,$(COBJS),$(OBJ_PATH)/$(file))) + @$(RM) $(RMFLAGS) $(BIN_PATH)/$(PROJ_NAME).elf $(BIN_PATH)/$(PROJ_NAME).map + @$(RM) $(RMFLAGS) $(BIN_PATH)/$(PROJ_NAME).srec + @echo +++ Clean complete + + diff --git a/Target/Demo/_template/Prog/prog.dox b/Target/Demo/_template/Prog/prog.dox new file mode 100644 index 00000000..c14daa24 --- /dev/null +++ b/Target/Demo/_template/Prog/prog.dox @@ -0,0 +1,13 @@ +/** +\defgroup Prog__template User Program +\ingroup Demos_template +\brief User Program. +\details The intention of the demo user program is two-fold. (1) To test the + bootloader, you need some sort of firmware to see if you can perform a + firmware update with the bootloader. This program can be used for this + purpose. (2) To make firmware programmable by the bootloader, a few + adjustments to the firmware are required. The demo user program serves as an + example for how these adjustments can be implemented. This demo user program + is a template that can be used as a starting point for creating your own + demo user program. +*/ diff --git a/Target/Demo/_template/Prog/timer.c b/Target/Demo/_template/Prog/timer.c new file mode 100644 index 00000000..26126a71 --- /dev/null +++ b/Target/Demo/_template/Prog/timer.c @@ -0,0 +1,89 @@ +/************************************************************************************//** +* \file Demo/_template/Prog/timer.c +* \brief Timer driver source file. +* \ingroup Prog__template +* \internal +*---------------------------------------------------------------------------------------- +* C O P Y R I G H T +*---------------------------------------------------------------------------------------- +* Copyright (c) 2019 by Feaser http://www.feaser.com All rights reserved +* +*---------------------------------------------------------------------------------------- +* L I C E N S E +*---------------------------------------------------------------------------------------- +* This file is part of OpenBLT. OpenBLT is free software: you can redistribute it and/or +* modify it under the terms of the GNU General Public License as published by the Free +* Software Foundation, either version 3 of the License, or (at your option) any later +* version. +* +* OpenBLT is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; +* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +* PURPOSE. See the GNU General Public License for more details. +* +* You have received a copy of the GNU General Public License along with OpenBLT. It +* should be located in ".\Doc\license.html". If not, contact Feaser to obtain a copy. +* +* \endinternal +****************************************************************************************/ + +/**************************************************************************************** +* Include files +****************************************************************************************/ +#include "header.h" /* generic header */ + + +/**************************************************************************************** +* Local data declarations +****************************************************************************************/ +/** \brief Local variable for storing the number of milliseconds that have elapsed since + * startup. + */ +static unsigned long millisecond_counter; + + +/************************************************************************************//** +** \brief Initializes the timer. +** \return none. +** +****************************************************************************************/ +void TimerInit(void) +{ + /* TODO ##Prog Configure a timer peripheral such that an interrupt is generated every + * 1 millisecond. + */ + + /* Reset the millisecond counter value. */ + millisecond_counter = 0; +} /*** end of TimerInit ***/ + + +/************************************************************************************//** +** \brief Obtains the counter value of the millisecond timer. +** \return Current value of the millisecond timer. +** +****************************************************************************************/ +unsigned long TimerGet(void) +{ + /* Read and return the tick counter value. */ + return millisecond_counter; +} /*** end of TimerGet ***/ + + +/************************************************************************************//** +** \brief Interrupt service routine of the timer. +** \return none. +** +****************************************************************************************/ +void TimerInterrupt(void) +{ + /* Increment the millisecond counter. */ + millisecond_counter++; + + /* TODO ##Prog Clear the timer peripheral's interrupt flag and, if necessary, + * reconfigure the timer peripheral such that another timer interrupt is generated + * in a millisecond after the last timer interrupt event. + */ +} /*** end of TimerInterrupt ***/ + + +/*********************************** end of timer.c ************************************/ diff --git a/Target/Demo/_template/Prog/timer.h b/Target/Demo/_template/Prog/timer.h new file mode 100644 index 00000000..8d45f06f --- /dev/null +++ b/Target/Demo/_template/Prog/timer.h @@ -0,0 +1,38 @@ +/************************************************************************************//** +* \file Demo/_template/Prog/timer.h +* \brief Timer driver header file. +* \ingroup Prog__template +* \internal +*---------------------------------------------------------------------------------------- +* C O P Y R I G H T +*---------------------------------------------------------------------------------------- +* Copyright (c) 2019 by Feaser http://www.feaser.com All rights reserved +* +*---------------------------------------------------------------------------------------- +* L I C E N S E +*---------------------------------------------------------------------------------------- +* This file is part of OpenBLT. OpenBLT is free software: you can redistribute it and/or +* modify it under the terms of the GNU General Public License as published by the Free +* Software Foundation, either version 3 of the License, or (at your option) any later +* version. +* +* OpenBLT is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; +* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +* PURPOSE. See the GNU General Public License for more details. +* +* You have received a copy of the GNU General Public License along with OpenBLT. It +* should be located in ".\Doc\license.html". If not, contact Feaser to obtain a copy. +* +* \endinternal +****************************************************************************************/ +#ifndef TIMER_H +#define TIMER_H + +/**************************************************************************************** +* Function prototypes +****************************************************************************************/ +void TimerInit(void); +unsigned long TimerGet(void); + +#endif /* TIMER_H */ +/*********************************** end of timer.h ************************************/ diff --git a/Target/Demo/_template/demo.dox b/Target/Demo/_template/demo.dox new file mode 100644 index 00000000..2008d56b --- /dev/null +++ b/Target/Demo/_template/demo.dox @@ -0,0 +1,15 @@ +/** +\defgroup Demos_template Template for demo programs +\ingroup Demos +\brief Template for creating OpenBLT demo programs. +\details These template programs for a foundation when creating OpenBLT demo programs. + For compilation testing these template demo programs are preconfigured for + building with GCC and a Makefile. Other already existing demo programs can + serve as a reference when creating OpenBLT demo programs based on this + template. The demo bootloader and demo user program templates contain + instructions in source code comments of what functionality needs to be + implemented where. Search for "TODO ##Boot" and "TODO ##Prog" to find these + comments in the template source files. +*/ + +