โŒ About FreshRSS

Normal view

There are new articles available, click to refresh the page.
Before yesterdayNews from the Ada programming language world

Writing to a register which may or may not exist in Ada

I have a driver whose codebase is built for several targets, each with its own Registers.ads that defines the register set for that target. The driver needs to write to a register which may or may not exist in Registers.ads (depending on the configuration).

In C, I would do something like this:

#ifdef REG1
    reg_write(REG1, 0x1234);
#endif

In Ada though, there is no preprocessor and I can't do this with a regular if statement:

if REG1_EXISTS then
    reg_write(REG1, 0x1234);
end if;

This fails to compile on targets which do not have the register because REG1 is an undefined symbol.

Is there some way to achieve similar behavior to what the C code does? I could theoretically create a HAL with multiple implementations of a write_reg1 function, and select which one gets compiled based on the target, but I'd like to avoid this since there are a lot of registers like this and it would clutter up the code.

Initializing a record without knowing its exact contents

I have a source file in my project which comes from an external team, and I cannot modify it. It contains a record which defines the contents of a register:

type R_Field is (R_FALSE, R_TRUE) with Size => 1;
for R_Field use (R_FALSE => 16#0#, R_TRUE => 16#1#);
type W_Field is (W_FALSE, W_TRUE) with Size => 1;
for W_Field use (W_FALSE => 16#0#, W_TRUE => 16#1#);
type U_Field is (U_FALSE, U_TRUE) with Size => 1;
for U_Field use (U_FALSE => 16#0#, U_TRUE => 16#1#);
type My_Register is record
        R : R_Field;
        W : W_Field;
        U : U_Field;
end record with Size => 32, Object_Size => 32;

for My_Register use record
        R at 0 range 0 .. 0;
        W at 0 range 1 .. 1;
        U at 0 range 5 .. 5;
end record;

I am writing a driver which will be built against many different targets, each with it's own register file. For some variants of the register file, the My_Register record will not have the U field.

I am trying to initialize a My_Register record in my code in such a way that will set all the fields to 0. I want my code to work in both the case when U is defined and in the case when it is not.

I cannot do reg : My_Register := (R => R_FALSE, W => W_FALSE, U => U_FALSE) because this does not compile in the case when U and U_FALSE are not defined in the register file.

Is there a way to zero-init the entire record, the same way that = {0} would do in C?

Casting a Variable to the same type as another variable in Ada

I have a codebase which is being built for several different targets, each with its own set of register definitions. For a given target, there is a register definition file which will define register contents like this:

type Register1 is record
   field1 : U7;
   field2 : U8;
end record;

The types U7 and U8 are just Unsigned types defined like this:

type U7 is mod 2 ** 7 with Size => 7;
type U8 is mod 2 ** 8 with Size => 8;
...

In my driver, I have a Register_Write function which takes a Register1 as an argument. I've tried calling it like this:

field1_val: U32:= 1;
field2_val: U32:= 2;
...
Register_Write( Register1'(field1 => field1_val, field2 => field2_val ));

But this does not work and I get the error expected type "U7", found type "U32". The issue is that I cannot just make field1_val a U7, because the type of this field is different for different targets. For example, on some targets it may be U7, on some it may be U6, etc.

Is there a way of saying "Cast field1_val to the type of field1" when I create a Register1 record?

โŒ
โŒ