Closed ellenhp closed 6 months ago
For now I've "solved" this by providing a _pre_init function and doing the remainder of the core setup from cortex_m
there.
core::arch::global_asm!(
"
.text
.globl __pre_init
__pre_init:
ldr sp, =0x20020000
",
// Initialise .bss memory. `__sbss` and `__ebss` come from the linker script.
"ldr r0, =__sbss
ldr r1, =__ebss
movs r2, #0
2:
cmp r1, r0
beq 3f
stm r0!, {{r2}}
b 2b
3:",
// Initialise .data memory. `__sdata`, `__sidata`, and `__edata` come from the linker script.
"ldr r0, =__sdata
ldr r1, =__edata
ldr r2, =__sidata
4:
cmp r1, r0
beq 5f
ldm r2!, {{r3}}
stm r0!, {{r3}}
b 4b
5:",
// Enable the FPU.
// SCB.CPACR is 0xE000_ED88.
// We enable access to CP10 and CP11 from priviliged and unprivileged mode.
"ldr r0, =0xE000ED88
ldr r1, =(0b1111 << 20)
ldr r2, [r0]
orr r2, r2, r1
str r2, [r0]
dsb
isb",
// Jump to user main function.
// `bl` is used for the extended range, but the user main function should not return,
// so trap on any unexpected return.
"bl main
udf #0",
);
Which is kind of evil, but it does mean I can use upstream RTIC. I'm going to leave this open but you can close it if you'd like.
I think the pre-init rout is ok for such special cases
We close it as an acceptable solution, feel free to-reopen if anyone wants to add to this.
This is a pretty goofy feature request and could be an example of the XY problem, but I want to open an issue about it anyway. I'm doing some adversarial firmware development for a TYT MD-UV380 DMR transceiver, which has a bootloader that will refuse to start your firmware unless the initial stack size is exactly 512 bytes. Specifically, it needs to be at address
0x20000200
otherwise the radio will boot into firmware update mode instead of the actual entry point. This is no good for a system like RTIC or Embassy where the main stack is shared. 512 bytes is not a lot to work with.To deal with this, I execute this inline ASM at startup:
Right now I put that at the top the main function macro in
rtic-macros/src/codegen/main.rs
before anything else can run. I (selfishly) don't like that I have to maintain a fork of RTIC to do this so I was wondering if anyone could think of something better or a way for me to hook into the entry point to perform this operation. I'm not an expert on embedded stuff, but I think this is an edge case so I understand if it's outside the scope of what RTIC should be providing.