53
ARM Programming with GNAT and Ada 2012 Pat Rogers Boston, MA 3-4 November, 2015

Tech Days 2015: ARM Programming with GNAT and Ada 2012

  • Upload
    adacore

  • View
    990

  • Download
    2

Embed Size (px)

Citation preview

ARM Programming with GNAT and Ada 2012

Pat Rogers

Boston, MA

3-4 November, 2015

Goals

• Introduce the target hardware

• Introduce the development environment

– Tools, runtime libraries, etc.

• Show you some “tips and tricks” we use internally

– Switches we apply

– Debugging techniques

– et cetera

• Basically everything you need to get started

• Provide pointers for where to go next

– The AdaCore bare-board community GitHub project

2

Agenda

• The Target Hardware

• The Software Tools

• The Runtime Libraries

• “Hello World”

• Where To Go Next

3

The Target Hardware

“STM32F4 Discovery” Evaluation Board

• 32-bit ARM Cortex-M4F microcontroller at 168 MHz

• 1 MB of Flash memory

• 192 KB of RAM

• On-board USB-JTAG debugger interface

• Four user LEDs: orange, green, red, blue

• Two pushbuttons (user (blue) and system reset (black))

• 3-axis accelerometer

• Timers, DMA, USARTs, others…

5

“STM32F4 Discovery” On-Board Devices

“ST-LINK” USB

Debug Support

User LEDs

Port/Pin Header

Port/Pin Header

Audio Out

Jack

Audio DAC

6

“STM32F429 Discovery” On-Board Devices

“ST-LINK”

USB Debug

Support

User LEDs

2.24” QVGA LCD

with Touch Panel

3-Axis Gyro included

7

The Software Tools

Required Software

• You should already have these installed

• The USB device driver

– Third-party software available publicly

– Install this before you ever connect the board to the host

computer

• The GNAT GPL 2015 release

– Compiler etc.

– GPS

• The “st-link” utilities (“st-util” and “st-flash”)

– Pre-installed with Windows installation of GNAT tools

– Must be built and installed by Linux users

9

Connecting the USB Cable

• Connects the on-board power/debug USB connector to the host

computer

• If it doesn’t fit, that’s the wrong end!

– The other one is Micro-USB and is much thinner

Power/Debug

Mini-USB

Connector

10

Using the “ST-LINK” Utilities

• “st-util” provides a GDB server that talks to the on-board support

• “st-flash” writes apps to memory

• Available on the command line

• Both available via GPS toolbar when the plug-in is active

• You may need to run st-util on the command line if the board is

unresponsive to GPS’ invocation of it

– st-util will “get the board’s attention” when seems hung up

• Sometimes you’ll need to cycle power to the board

11

Flashing & Debugging Within GPS

• Supports STM32F4 boards via st-link utils

• Invoked using toolbar icons

• Visible only if “stm32f4” is used in the gpr file to specify the runtime

library name

Flash to

Board

Load, then

start GDB

12

GNAT Project Files

• Text files with Ada-like syntax

• Also known as “gpr files” due to file extension

• Integrated into command-line tools

– Specified via the –P project-file-name switch

• Integrated into the IDEs

– The fundamental artifact

13

Configurable Properties

• Source directories and specific files’ names

• Output directory for object modules and .ali files

• Switch settings for tools

• Source files for main subprogram(s) to be built

• Source programming languages

– Ada / C / C++ are preconfigured

• Many others…

14

Sample Simple Project File

project Demo is

for Languages use ("Ada");

for Main use ("demo.adb");

for Source_Dirs use ("src");

for Object_Dir use "obj";

package Compiler is

for Switches ("Ada") use

("-g", -- enable debugging

"-gnatwa", -- enable all optional warnings

"-gnata", -- enable pre/postcondition checks

"-gnatQ", -- don’t quit

"-gnatw.X"); -- suppress warnings about exceptions

end Compiler;

package Builder is

for Switches ("Ada") use ("-g"); -- enable debugging

end Builder;

end Demo;

15

Specifying the Remote Connection

• Enables GDB to locate the GDB server

project Demo is…

package Ide is

for Program_Host use "localhost:4242";

for Communication_Protocol use "remote";

end Ide;

end Demo;

16

Removing Unused Data and Object Code

• Requires switches for compiler and linker

package Linker is

for Switches ("Ada") use ("-Wl,--gc-sections", "-Wl,--print-gc-sections");

end Linker;

Optional. Prints

those removed.

Required

package Compiler iscase Build_Mode is

when "debug" =>…

when "production" =>for Switches ("Ada") use (…, "-ffunction-sections", "-fdata-sections");

end case;end Compiler;

RequiredRequired

17

Displaying Percentages Used

• Implemented after GNAT GPL 2015 release

package Linker is

for Switches ("Ada") use ("-Wl,--gc-sections", "-Wl,--print-memory-usage");

end Linker;

18

The Runtime Libraries

The Bare-Board Runtime Libraries

• “SFP” (Small Foot Print”)

– Intended for certification

– A subset of the non-tasking part of the language

• “Full”

– A very large subset of the non-tasking part of the language

• Both provide the Ravenscar tasking subset

• Both are reconfigurable

– You can add or remove functionality and rebuild

• There is also a Zero Footprint “ZFP” runtime

– No tasking

– Almost no object code20

The Runtime Library Names

• Indicate whether Ravenscar is provided

• Indicate the degree of language subset supported

• Indicate the target platform

• Examples

– “zfp-stm32f4”

– “ravenscar-full-stm32f4”

– “ravenscar-sfp-stm32f4”

Ravenscar

tasking

subset

Small

Footprint

subset

Target

Hardware

21

Essential Project File Content

• Specify the runtime library directory path/name

• Specify the platform name

• Both can be specified on the command-line but easier in gpr file

for Runtime ("Ada") use "ravenscar-sfp-stm32f4";

for Target use "arm-eabi";

Basename sufficient

when in default

location

for Runtime ("Ada") use "/path/to/ravenscar-full-stm32f429";

22

The Last Chance Handler (“LCH”)

• Specifies response to unhandled exceptions

– Since exception propagation is not supported in some RTLs

– The last thing executed in that case

• A procedure

• Semantics

– Called automatically by compiled code

– Must never return to caller (loop forever, reset, etc.)

• Default version does nothing but loop

• A user-defined version can override default

23

Lab 1

“Hello World”

“Hello World” of Embedded Systems

• Blinks LEDs, of course!

• Located in the compiler installation tree

– Directory name is “demo_leds-stm32f4”

• In Windows, with default installation choice:

• Contains a GNAT project file

• Located it and invoke GPS with it now

C:\GNAT\2015\share\examples\gnat-cross\demo_leds-stm32f4

demo_leds.gpr

25

26

27

Build Output In Messages View

28

Load Into Flash and Execute

• Load the program into FLASH using toolbar icon

• Program will start automatically after loading

– You may need to reset the board using the black button

– Sometimes you must cycle power to the board

29

Loaded and Running

Plugin loads

the image Push the blue User

button to change the

LED rotation directionUser LEDs

30

Troubleshooting Load/Debug In GPS

• If GPS toolbar icon cannot work for some reason…

• Terminate the debug session in GPS

• Open a command line and invoke st-util there

– It will connect to the board, emit some messages, and wait for

GDB server commands

Command Line st-util for Debugging

• In GPS, start the debugger via the menu

– Apply the “Debug -> Initialize -> demo” menu

32

Additional st-util Messages In Shell

• You will see messages from st-util in the command line console

33

Debugger Then Connects In GPS

34

And You’re Ready To Go…

• You can set breakpoints, etc. if desired

• Then press the debugger toolbar icon to “Continue” (or start) to run

35

Source Files Included

• gnat.adc

• button.adb

• button.ads

• demo.adb

• driver.adb

• driver.ads

• last_chance_handler.adb

• last_chance_handler.ads

• leds.adb

• leds.ads

• registers.ads

• stm32f4.ads

• stm32f4-gpio.ads

• stm32f4-reset_clock_control.ads

• stm32f4-sysconfig_control.ads

pragma Partition_Elaboration_Policy (Sequential);

36

Main Subprogram

with Driver; pragma Unreferenced (Driver);

-- The Driver package contains the task that actually controls the app so-- although it is not referenced directly in the main procedure, we need it-- in the closure of the context clauses so that it will be included in the-- executable.

with Last_Chance_Handler; pragma Unreferenced (Last_Chance_Handler);

-- The "last chance handler" is the user-defined routine that is called when-- an exception is propagated. We need it in the executable, therefore it-- must be somewhere in the closure of the context clauses.

with System;

procedure Demo ispragma Priority (System.Priority'First);

beginloop

null;end loop;

end Demo;

37

Setting Tasks’ Stacks and Priorities

• For any task created, set the stack to around 4K

– The default is far too large for these boards

– Can make it larger if necessary

• Can set the priority similarly, as needed

– Remember there is a default applied already

package Driver is

task Controller is

pragma Storage_Size (4 * 1024);

end Controller;

end Driver;

package Driver is

task Controller

with Storage_Size => (4 * 1024);

end Driver;

OR

38

with LEDs; use LEDs;

with Button; use Button;

with Ada.Real_Time; use Ada.Real_Time;

package body Driver is

type Index is mod 4;

Pattern : constant array (Index) of User_LED := (Orange, Red, Blue, Green);

task body Controller isPeriod : constant Time_Span := Milliseconds (75); -- arbitraryNext_Start : Time := Clock;Next_LED : Index := 0;

beginloop

Off (Pattern (Next_LED));

if Button.Current_Direction = Counterclockwise then

Next_LED := Next_LED - 1;

else

Next_LED := Next_LED + 1;

end if;

On (Pattern (Next_LED));

Next_Start := Next_Start + Period;

delay until Next_Start;

end loop;end Controller;

end Driver; 39

package Button ispragma Elaborate_Body;

type Directions is (Clockwise, Counterclockwise);

function Current_Direction return Directions;

end Button;

Button Interface

• Pressing the blue User button changes the value returned by the

“current direction” function

40

with Ada.Interrupts.Names;

with Ada.Real_Time; use Ada.Real_Time;

with Registers; use Registers;

with STM32F4; use STM32F4;

with STM32F4.GPIO; use STM32F4.GPIO;

package body Button is

protected Button is

function Current_Direction return Directions;…

end Button;

protected body Button is

function Current_Direction return Directions is …procedure Interrupt_Handler is …

end Button;

function Current_Direction return Directions isbegin

return User_Button.Current_Direction;end Current_Direction;

procedure Initialize is …

beginInitialize;

end Button;41

protected Button ispragma Interrupt_Priority;

function Current_Direction return Directions;

private

procedure Interrupt_Handler;

pragma Attach_Handler (Interrupt_Handler, Ada.Interrupts.Names.EXTI0_Interrupt);

Direction : Directions := Clockwise; -- arbitrary

Last_Time : Time := Clock;

end Button;

42

Debounce_Time : constant Time_Span := Milliseconds (500); -- semi-arbitrary

protected body Button is

function Current_Direction return Directions isbegin

return Button.Current_Direction;end Current_Direction;

procedure Interrupt_Handler isNow : constant Time := Clock;

begin

-- Clear interrupt

EXTI.PR (0) := 1;

-- Debouncing

if Now - Last_Time >= Debounce_Time then

if Direction = Counterclockwise thenDirection := Clockwise;

elseDirection := Counterclockwise;

end if;

Last_Time := Now;

end if;

end Interrupt_Handler;

end Button;43

with Registers; use Registers;with STM32F4; use STM32F4;with STM32F4.GPIO; use STM32F4.GPIO;

package body Button is …

procedure Initialize isRCC_AHB1ENR_GPIOA : constant Word := 16#01#;

begin-- Enable clock for GPIO-ARCC.AHB1ENR := RCC.AHB1ENR or RCC_AHB1ENR_GPIOA;

-- Configure PA0GPIOA.MODER (0) := Mode_IN;GPIOA.PUPDR (0) := No_Pull;

-- Select PA0 for EXTI0SYSCFG.EXTICR1 (0) := 0;

-- Interrupt on rising edgeEXTI.FTSR (0) := 0;EXTI.RTSR (0) := 1;EXTI.IMR (0) := 1;

end Initialize;

beginInitialize;

end Button; 44

Using the LCH with the Debugger

• Put a breakpoint on the first statement

• If breakpoint is hit, use GPS to examine the memory at Msg.all to

show the designated string

– Use the “Debug->Data->Examine Memory” menu

– Put “msg.all” into the Locations entry pane (no quotes)

package body Last_Chance_Handler is

procedure Last_Chance_Handler (Msg : System.Address; Line : Integer) is

begin

Off (Green);

end Last_Chance_Handler;

end Last_Chance_Handler;

45

Where To Go From Here

STM32F4 Documentation

• For devices across the entire STM32F4 family

– GPIO, Timers, etc.

– “RM0090 Reference manual”

– Subtitled “STM32F405xx/07xx, STM32F415xx/17xx,

STM32F42xxx and STM32F43xxx advanced ARM-based 32-bit

MCUs”

– Also known as file “DM0003120”

• Specific to the STM32F4 Discovery board

– “UM1472 User manual”

– Subtitled “Discovery kit for STM32F407/417 lines”

– Also known as file “DM00039084”

47

GNAT and GPS Documentation

• The GNAT Cross User Guide

– “GNAT User's Guide Supplement for Cross Platforms”

– Especially see the tutorial: “ARM-ELF Topics and Tutorial”

• GPS Users Guide

48

The ARM GitHub Repository

• https://github.com/AdaCore/bareboard

• Makes everything much easier!

• Adds significant functionality

• Contents, currently for STM32F4 products:

– Device drivers

– Complete demonstration projects for drivers

– Components (using drivers) e.g., Gyro and Accelerometer

– Complete demonstration projects for components

– Larger applications

• Trains, and Game of Life, both on STM32F429

• Licensed for both proprietary and Free apps

49

STM32F4_Discovery Package…package STM32F4_Discovery is

subtype User_LED is GPIO_Pin;

Green : User_LED renames Pin_12;Orange : User_LED renames Pin_13;Red : User_LED renames Pin_14;Blue : User_LED renames Pin_15;

All_LEDs : constant GPIO_Pins := LED3 & LED4 & LED5 & LED6;…

procedure Initialize_LEDs;

procedure Turn_On (This : User_LED) with Inline;

procedure Turn_Off (This : User_LED) with Inline;

procedure Toggle (This : User_LED) with Inline;

Accelerometer : Three_Axis_Accelerometer;

GPIO_A : GPIO_Port renames STM32F40xxx.GPIO_A;

GPIO_B : GPIO_Port renames STM32F40xxx.GPIO_B;…

User_Button_Port : GPIO_Port renames GPIO_A; User_Button_Pin : constant GPIO_Pin := Pin_0; User_Button_Interrupt : constant Interrupt_Id := Names.EXTI0_Interrupt;…

Board Additions

Board Addition

Board Specific Number

Board Addition

50

51

STM32F429_Discovery Package…package STM32F429_Discovery is

subtype User_LED is GPIO_Pin;

Green : User_LED renames Pin_13;Red : User_LED renames Pin_14;

All_LEDs : constant GPIO_Pins := LED3 & LED4;

procedure Initialize_LEDs;

procedure Toggle (This : User_LED) with Inline;

Gyro : Three_Axis_Gyroscope;

GPIO_A : GPIO_Port renames STM32F42xxx.GPIO_A;

GPIO_B : GPIO_Port renames STM32F42xxx.GPIO_B;…

GPIO_K : GPIO_Port renames STM32F42xxx.GPIO_K;

Two Fewer User LEDs

Two More

GPIO Ports

Other device differences…

Gyro instead of

accelerometer

Example Driver Library Simplification

procedure Initialize isbegin

Configure_User_Button_GPIO;Connect_External_Interrupt (User_Button_Port, User_Button_Pin);Configure_Trigger (User_Button_Port, User_Button_Pin, Interrupt_Rising_Edge);

end Initialize;

procedure Initialize isRCC_AHB1ENR_GPIOA : constant Word := 16#01#;

begin-- Enable clock for GPIO-ARCC.AHB1ENR := RCC.AHB1ENR or RCC_AHB1ENR_GPIOA;-- Configure PA0GPIOA.MODER (0) := Mode_IN;GPIOA.PUPDR (0) := No_Pull;

-- Select PA0 for EXTI0SYSCFG.EXTICR1 (0) := 0;-- Interrupt on rising edgeEXTI.FTSR (0) := 0;EXTI.RTSR (0) := 1;EXTI.IMR (0) := 1;

end Initialize;

52

Finished!