Running Ada 2012 on Olimex STM32-E407 (ARM Cortex-M4 / STM32F4)
Almost two years after I got my first ARM Cortex-Mx device, I finally found time to build Ada ARM Cortex-M cross-compiler using FSF GCC/GNAT. But, instead of Atmel SAM3, I used STM32F4 processor found from Olimex STM32-E407 board.
Relevant code pieces are sprinkled into three repositories at Bitbucket:
First repository, embedded-arm-gnat-build, contains the build scripts for GNAT (arm-none-eabi target; the script for binutils is missing, you need to install it manually).
The second repository (embedded-arm-gnat-rts) has simple runtime for GNAT. It is almost direct copy of Lucretia's TAMP RTS. The runtime does not have install script, so after building it you need to install the runtime manually.
The third one (gnat-arm-app-skeleton) contains the actual application. I loaned the startup files from mbed project, in case you wonder why there are so many C and assembler files. They could be optimized to two simple assembler files, but I haven't got that far.
The most interesting parts of the app are here:
-- blink.adb, Ada 2012 code with Interfaces; with STM32F4; procedure Blink is use type Interfaces.Unsigned_32; procedure My_Delay is -- Mark X volatile so that GNAT does not optimize -- the loop. Notice the new Ada 2012 aspect syntax. X : Interfaces.Unsigned_32 := 0 with Volatile; begin loop exit when X = 1000_000; X := X + 1; end loop; end My_Delay; begin STM32F4.RCC_ENABLE := STM32F4.RCC_ENABLE or STM32F4.GPIOC_ENABLE_BIT or STM32F4.GPIOD_ENABLE_BIT; -- 13 c b a 9 8 7 3 STM32F4.GPIOC_MODE := 2#0000_0101_0101_0000_0000_0000_0000_0000#; STM32F4.GPIOC_TYPE := 2#0000_0000_0000_0000_0000_0000_0000_0000#; -- push-pull STM32F4.GPIOC_SPEED := 2#0000_1100_0000_0000_0000_0000_0000_0000#; -- fast STM32F4.GPIOC_PUPD := 2#0000_0000_0000_0000_0000_0000_0000_0000#; -- no pull STM32F4.GPIOD_MODE := 2#0000_0101_0101_0000_0000_0000_0000_0000#; STM32F4.GPIOD_TYPE := 2#0000_0000_0000_0000_0000_0000_0000_0000#; -- push-pull STM32F4.GPIOD_SPEED := 2#0000_1100_0000_0000_0000_0000_0000_0000#; -- fast STM32F4.GPIOD_PUPD := 2#0000_0000_0000_0000_0000_0000_0000_0000#; -- no pull STM32F4.GPIOC_BSRR := 2#0111_1000_0000_0000_0000_0000_0000_0000#; STM32F4.GPIOD_BSRR := 2#0000_0000_0000_0000_0011_1100_0000_0000#; loop STM32F4.GPIOC_BSRR := 2#0111_1000_0000_0000_0000_0000_0000_0000#; STM32F4.GPIOD_BSRR := 2#0111_1000_0000_0000_0000_0000_0000_0000#; My_Delay; STM32F4.GPIOC_BSRR := 2#0000_0000_0000_0000_0111_1000_0000_0000#; STM32F4.GPIOD_BSRR := 2#0000_0000_0000_0000_0111_1000_0000_0000#; My_Delay; end loop; end Blink;
The program blinks various leds at port C and port D.
On Olimex STM32-E407, which I used for testing, the status led is at port C13. If you use the same board, you should see the led blinking.
Note: My build scripts, GNAT runtime for ARM Cortex-Mx, and other Ada code are still very rough. I just wanted to try is it possible to use FSF GNAT for ARM Cortex-Mx development. As my time permits, I will continue to improve things, but it will take some time.