Blinky.c

This simple program flashes the blue LED on the STM32F0Discovery board. It makes use of the stm32f05xxx.h header file. You can download this file and its support files here
// Blinky.c 
// Author: Frank Duignan 
// Flashes the blue LED on the STM32F0Disovery board 
#include "stm32f05xxx.h"
void delay(int dly)
{
// This is a simple software delay 
  while( dly--);
}
int main()
{
  RCC_AHBENR |= 0x00080000; // Turn on the clock source for GPIO C
  GPIOC_MODER = 0x00010000; // Make bit 8 an output on GPIO C
  while(1)// Repeat the following forever
  {
    GPIOC_ODR = 0x00000100;// set Bit 8 (turn on LED)
    delay(500000);// Hang around for a bit
    GPIOC_ODR = 0x00000000; // clear Bit 8 (turn off LED)
    delay(500000);// Wait for a while again
  }
  return 0;
} 

startup.s

The program above does not include a handler for the reset interrupt that occurs on power up. Traditionally this is supplied in an assembly language file called something like startup.s or similar. This file provides a bare-essential reset handler (it just calls main). More complex startup files will include code to initialize global variables.
		.thumb /*Cortex micros only understand thumb(2) code	*/
		.global Vector_Table, ResetVector	
/* Set up interrupt vector table */
		.text
Vector_Table:    
		.word     0x20002000          /* Top of Stack */
/* The interrupt vectors that follow are manually forced to be aligned along
   odd addresses.  The reason for this is that the address for a Thumb instruction
   must always have its LSB set to 1.  This does not mean that the instruction 
   is stored at an odd number address.  The LSB is used as a flag to indicate
   that an ARM (LSB=0) or a Thumb (LSB=1) instruction is being addressed. */

ResetVector:    .word     Reset_Handler+1     /* Reset Handler */
                .word     Default_Handler+1   /* NMI */
                .word     Default_Handler+1   /* Hard Fault */
                .word     0                   /* Reserved */
                .word     0                   /* Reserved */
                .word     0                   /* Reserved */
                .word     0                   /* Reserved */
                .word     0                   /* Reserved */
                .word     0                   /* Reserved */
                .word     0                   /* Reserved */
                .word     Default_Handler+1   /* SVC */
                .word     0                   /* Reserved */
                .word     0                   /* Reserved */
                .word     Default_Handler+1   /* PendSV */
                .word     Default_Handler+1   /* SysTick */
		
/* External interrupt handlers follow */
		.word	  Default_Handler + 1 /* WWDG */
		.word	  Default_Handler + 1 /* PVD */
		.word	  Default_Handler + 1 /* RTC */
		.word	  Default_Handler + 1 /* FLASH */
 		.word	  Default_Handler + 1 /* RCC */
		.word	  Default_Handler + 1 /* EXTI0_1 */
		.word	  Default_Handler + 1 /* EXTI2_3 */
		.word	  Default_Handler + 1 /* EXTI4_15 */
		.word	  Default_Handler + 1 /* TSC */
		.word	  Default_Handler + 1 /* DMA_CH1 */
		.word	  Default_Handler + 1 /* DMA_CH2_3 */
		.word	  Default_Handler + 1 /* DMA_CH4_5 */
		.word	  Default_Handler + 1 /* ADC_COMP */
		.word	  Default_Handler +1  /* TIM1_BRK_UP_TRG_COM */
		.word	  Default_Handler + 1 /* TIM1_CC */
		.word	  Default_Handler + 1 /* TIM2 */
		.word	  Default_Handler + 1 /* TIM3 */
		.word	  Default_Handler + 1 /* TIM6_DAC */
		.word	  Default_Handler + 1 /* RESERVED */
		.word	  Default_Handler + 1 /* TIM14 */
		.word	  Default_Handler + 1 /* TIM15 */
  		.word	  Default_Handler + 1 /* TIM16 */
		.word	  Default_Handler + 1 /* TIM17 */
		.word	  Default_Handler + 1 /* I2C1 */
		.word	  Default_Handler + 1 /* I2C2 */
		.word	  Default_Handler + 1 /* SPI1 */
		.word	  Default_Handler + 1 /* SPI2 */
		.word	  Default_Handler + 1 /* USART1 */
		.word	  Default_Handler + 1 /* USART2 */
		.word	  Default_Handler + 1 /* RESERVED */
		.word	  Default_Handler + 1 /* CEC */
 		.word	  Default_Handler + 1 /* RESERVED */

/* Reset handler */
		.thumb
Reset_Handler:
	.global Reset_Handler, Default_Handler
    .extern  main
/* Stack pointer is already set to the value at entry 0 in the interrupt vector table  */
/* Clock speed is set by default to the internal factory calibrated 8MHz RC oscillator */
/* The PLL is configured to run at twice the RC clock speed so the default system      */
/* operating speed is 16MHz							       */
/* All that is left to do is to call main					       */
		bl	main
		b	.	/* If main returns enter a loop */
Default_Handler:
		b       .	/* Default handler just enters a loop.  Note the dot */

Makefile

The makefile for this project follows. Just run 'make' on the command line to compile. Typing 'make clean' will remove object and executable files
# Specify the compiler to use
CC=arm-none-eabi-gcc
# Specify the assembler to use
AS=arm-none-eabi-as
# Specity the linker to use
LD=arm-none-eabi-ld

CCFLAGS=-mcpu=cortex-m0 -mthumb -g 
ASFLAGS=-mcpu=cortex-m0 -mthumb -g 
# List the object files involved in this project
OBJS=	startup.o \
	main.o 

# The default 'target' (output) is main.elf and it depends on the object files being there.
# These object files are linked together to create main.elf
main.elf : $(OBJS)
	$(LD) $(OBJS) -T linker_script.ld --cref -Map main.map -nostartfiles -o main.elf
# The object file main.o depends on main.c.  main.c is compiled to make main.o
main.o: main.c
	$(CC) -c $(CCFLAGS) main.c -o main.o

startup.o: startup.s
	$(AS) $(ASFLAGS) startup.s -asghl=startup.lst -o startup.o
# if someone types in 'make clean' then remove all object files and executables
# associated wit this project
clean: 
	rm $(OBJS) 
	rm main.elf 

Linker script

The linker script describes the memory layout of the target system to the linker. In this case, it tells the linker that there is 64k of flash at address 0x08000000 and 8k of RAM at 0x20000000. Constant data and code traditionally are marked with the attribute 'text' by the compiler. These are directed into the flash memory region. Variable data is traditionally marked with the 'data' attribute by the compiler. These are stored in ram.
MEMORY
{
    flash : org = 0x08000000, len = 64k
    ram : org = 0x20000000, len = 8k
}
  
SECTIONS
{
	. = ORIGIN(flash);
        .text : {
        } >flash

	. = ORIGIN(ram);
        .data : {
        } >ram
}