I am trying to write startup code for a microcontroller (IMXRT1062) in which I have to define an array with u32s that describe my image (IVT, ImageVectorTable, see table 9-37 in the manual), such as where in flash it is stored and how long it is, what the address of the first instruction is etc.
Some of these values are created by the linker through a custom linker script. So in zig I declare them as extern variables:
extern const _flash_img_start: u32;
extern const _flash_img_length: u32;
The linker transfers these values setting the addresses of the variables to the corresponding values. This means that when you take the address of these variables, you get the correct values. In C, this would look like (uint32_t) &_flash_img_start
.
In zig, I would expect it to be almost as easy, like this:
export const boot_data linksection(".boot_data") = [_]u32{
// start Absolute address of the image
@intFromPtr(&_flash_img_start),
// length Size of the program image
@intFromPtr(&_flash_img_length),
// plugin Plugin flag (see Plugin image)
0,
};
But when I do that I get:
startup.zig:17:5: error: unable to evaluate comptime expression
@intFromPtr(&_flash_img_start),
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
startup.zig:17:17: note: operation is runtime due to this operand
@intFromPtr(&_flash_img_start),
^~~~~~~~~~~~~~~~~
I also tried something like this:
fn addr(linker_value: anytype) u32 {
const ptr: *const u8 = @ptrCast(linker_value);
return @bitCast(ptr);
}
...
export const boot_data linksection(".boot_data") = [_]u32{
// start Absolute address of the image
addr(&_flash_img_start),
...
but then I get the error:
startup.zig:10:21: error: cannot @bitCast from '*const u8'
return @bitCast(ptr);
^~~
startup.zig:10:21: note: use @intFromPtr to cast to 'u32'
startup.zig:17:9: note: called from here
addr(&_flash_img_start),
~~~~^~~~~~~~~~~~~~~~~~~
Is this intended behavior? Am I missing something?
I feel like this is something that should be simple…