6

I want to write a very simple driver to initialize, write to/read from some peripherals on a microcontroller, the same way I have done it in C. I am using as an example a GPIO peripheral to initialize, write and read.

GPIOA : GPIO_Register with
   Volatile,
   Address => System'To_Address (GPIOA_Base);
   pragma Import (Ada, GPIOA);

If I declare a list to access all the GPIOs:

 type GPIO_Register_ptr is access all GPIO_Register with volatile;

 Gpio_List_Pointers : array (Integer range 1 .. 8) of aliased GPIO_Register_ptr;

And then assign:

  Gpio_List_Pointers(1) := GPIOA'Access;

I get the error :

  142:29 prefix of "ACCESS" attribute must be aliased

Any ideas how to sort it out ?

Elisabeth
  • 111
  • 6

1 Answers1

7

The short answer is:

declare GPIOA as aliased, like this:

GPIOA : aliased GPIO_Register 

EDIT:

A bit longer answer:

GPIOA is declared like this:

GPIOA : aliased GPIO_Register with
   Volatile,
   Address => System'To_Address (GPIOA_Base);

This means that it is a volatile object. The type of the object is still GPIO_Register, which is not volatile. So, when you do

 Gpio_List_Pointers(1) := GPIOA'Access;

The 'Access returns an access to an object of type GPIO_Register, which is not volatile, and the compiler won't let you do that.

To make this legal, GPIO_Register needs to be a volatile type. This is done by changing the type definition to include an aspect specification:

type GPIO_Register is record 
   MODER : Bits_16x2;
   IDR : Word;
   ODR : Word; 
end record
   with Volatile;

Now we have a volatile type, not just a volatile object

egilhh
  • 6,464
  • 1
  • 18
  • 19
  • Then I get the following error: `142:29 access to volatile object cannot yield access-to-non-volatile type ` – Elisabeth Feb 10 '15 at 16:47
  • Then you need to also make `GPIO_Register` a volatile type. – egilhh Feb 10 '15 at 17:00
  • `GPIO_Register` is a platform-dependent record : `type GPIO_Register is record MODER : Bits_16x2; IDR : Word; ODR : Word; end record; ` – Elisabeth Feb 10 '15 at 17:27
  • `GPIOA` is a volatile **object**. If you want to use the `access` attribute on it, the **type** of `GPIOA` must also be volatile. Which means the type definition of `GPIO_Register` needs a volatile aspect – egilhh Feb 10 '15 at 17:32
  • That's done when you declared `GPIOA: GPIO_Register with volatile, ... ` in Ada2012. – Elisabeth Feb 10 '15 at 17:43
  • No, that just says `GPIOA` is a volatile **object**, GPIO_Register needs to be a volatile **type** – egilhh Feb 10 '15 at 17:44
  • Yes. You said that. But you need to add the volatile aspect to it. – egilhh Feb 10 '15 at 17:54
  • Sorry for the bad formatting (missing line breaks) In my case GPIO_Register is a record: `type GPIO_Register is record` `MODER : Bits_16x2;` `IDR : Word;` `ODR : Word;` `end record;` `for GPIO_Register use record` `MODER at 0 range 0 .. 31;` `IDR at 4 range 0 .. 31;` `ODR at 8 range 0 .. 31;` `end record;` – Elisabeth Feb 10 '15 at 18:05
  • Thanks! :) I have applied the changes above for the record and it returns no errors. I'm going to build it and try on my board later. – Elisabeth Feb 10 '15 at 18:21
  • I find that declaring `GPIO_Register` as volatile means I don’t need to declare `GPIOA` as volatile as well. – Simon Wright Jul 30 '15 at 16:59