Blinky
Blinky is the “hello world” of embedded computing. The microcontroller comes out of reset and flashes an LED on and off. It is a good initial test of your toolchain and hardware. This little project involves two C source files:
main.c -> This is the main program file consisting of the main function mostly.
init.c -> This file contains startup code and the interrupt vectors for the processor.
The main.c file is shown below:
// include all of the register and macro definitions #include "stm32f05xxx.h" void delay(int dly) { while( dly--); } int main() { RCC_AHBENR |= 0x00080000; // turn on the clock source for GPIOC GPIOC_MODER = 0x00010000; // Make bit 2 an output while(1) // do the following forever { GPIOC_ODR = 0x00000100; // set bit 2 delay(500000); // wait for a period GPIOC_ODR = 0x00000000; // clear bit 2 delay(50000); // wait for a period } return 0; // should never reach here }
The init.c file is shown below. The interrupt vector table consists mostly of default entries however the very first two entries are significant:
Vector[0] -> The address of the top of RAM (0x20002000)
Vector[1] -> The address of the interrupt handler for the Reset interrupt (init)
The job of the init function is to initialize all global and static variables and then call main.
void init(void); void Default_Handler(void); // The following are 'declared' in the linker script extern unsigned char INIT_DATA_VALUES; extern unsigned char INIT_DATA_START; extern unsigned char INIT_DATA_END; extern unsigned char BSS_START; extern unsigned char BSS_END; // the section "vectors" is placed at the beginning of flash // by the linker script const void * Vectors[] __attribute__((section(".vectors"))) ={ (void *)0x20002000, /* Top of stack */ init, /* Reset Handler */ Default_Handler, /* NMI */ Default_Handler, /* Hard Fault */ 0, /* Reserved */ 0, /* Reserved */ 0, /* Reserved */ 0, /* Reserved */ 0, /* Reserved */ 0, /* Reserved */ 0, /* Reserved */ Default_Handler, /* SVC */ 0, /* Reserved */ 0, /* Reserved */ Default_Handler, /* PendSV */ Default_Handler, /* SysTick */ /* External interrupt handlers follow */ Default_Handler, /* WWDG */ Default_Handler, /* PVD */ Default_Handler, /* RTC */ Default_Handler, /* FLASH */ Default_Handler, /* RCC */ Default_Handler, /* EXTI0_1 */ Default_Handler, /* EXTI2_3 */ Default_Handler, /* EXTI4_15 */ Default_Handler, /* TSC */ Default_Handler, /* DMA_CH1 */ Default_Handler, /* DMA_CH2_3 */ Default_Handler, /* DMA_CH4_5 */ Default_Handler, /* ADC_COMP */ Default_Handler , /* TIM1_BRK_UP_TRG_COM */ Default_Handler, /* TIM1_CC */ Default_Handler, /* TIM2 */ Default_Handler, /* TIM3 */ Default_Handler, /* TIM6_DAC */ Default_Handler, /* RESERVED */ Default_Handler, /* TIM14 */ Default_Handler, /* TIM15 */ Default_Handler, /* TIM16 */ Default_Handler, /* TIM17 */ Default_Handler, /* I2C1 */ Default_Handler, /* I2C2 */ Default_Handler, /* SPI1 */ Default_Handler, /* SPI2 */ Default_Handler, /* USART1 */ Default_Handler, /* USART2 */ Default_Handler, /* RESERVED */ Default_Handler, /* CEC */ Default_Handler /* RESERVED */ }; void init() { // do global/static data initialization unsigned char *src; unsigned char *dest; unsigned len; src= &INIT_DATA_VALUES; dest= &INIT_DATA_START; len= &INIT_DATA_END-&INIT_DATA_START; while (len--) *dest++ = *src++; // zero out the uninitialized global/static variables dest = &BSS_START; len = &BSS_END - &BSS_START; while (len--) *dest++=0; // initialization all done, call main main(); } // In the event of an unhandled interrupt the processor will go here and loop forever. // You could choose to flash a 'fault' LED if you find yourself in here. void Default_Handler() { while(1); }
Full source code for blinky is here
To build the program type make. See the openocd usage instructions page for details on how to debug and test the program
The link for the full source goes to a list of the staff at the School of Electrical and Electronic Engineering, not a page with the source.
LikeLike
Thanks Chris, I have updated the link
LikeLike