I’m working on a Kendryte K210 board (env:sipeed-maix-bit-mic).
I’m trying to put variables at a fixed address in the general-purpose SRAM and tried using a linker script to achieve this. But even if I put the full Path to my linker file in the board.json i get
the following error:
riscv64-unknown-elf-objcopy: error: the input file ‘.pio\build\sipeed-maix-bit-mic\firmware.elf’ has no sections
When I use the standard Kendryte standalone SDK blink example and look at the verbose build output, I see it’s linking against C:\Users\<user>\.platformio\packages\framework-kendryte-standalone-sdk\lds\kendryte.ld. The file already contains a definition for the uncached RAM.
Which has the same origin and length as your definition.
But there’s no section that uses this RAM.
However, as I read it from the datasheet it is the same physical SRAM available through different memory addresses that are either cached or uncached.
int var_allocated_in_nocache_ram1 __attribute__ ((section (".ram_nocache_section")));
int var_allocated_in_nocache_ram2 __attribute__ ((section (".ram_nocache_section")));
per nm tool the variables are allocated in the non-cached RAM
>C:\Users\Max.platformio\packages\toolchain-kendryte210\bin\riscv64-unknown-elf-nm.exe .\.pio\build\sipeed-maix-bit-mic\firmware.elf | grep “var_”
0000000040000000 D var_allocated_in_nocache_ram1
0000000040000004 D var_allocated_in_nocache_ram2
(notice addresses in 0x40000000), but they of course overshadow whatever the linker is placing at 0x80000000.
Now of course we can use a trick that we do not use the same memory cells twice by e.g. decreasing the length of the ram memory by some bytes, and then move the origin of ram_nocache upwards and set the length to what we initially cut off in ram – but this is very hacky.
Thought differently: If you allocate a normal variable in RAM in C-code, and take its address, it will be in the 0x8000000 region. If you subtract 0x4000000 from it (or mask one bit and or another bit…), then that’s the address you need to read from for the uncached access (or write to). Such addresses can be one-time computed at the start of the program and then used. Does that solve your high-level problem?
Otherwise you can also ask in the SDK’s github on how to handle read/writes to the uncached section – maybe there are some convenience functions for it, but I didn’t find any.
Thank you for the detailed help!
I tried the changes to the original linker script and everything compiles and seems to work,
but when I try to flash my board, “the Programming BIN:” is super slow and would need hours to complete, compared to just seconds before. Do you have an idea why this is the case?
Than you for the fast response!
I followed the advice regarding computing the non-cached read/write address for a given RAM variable. I made the additions in the linker file and used the attribute
when defining the variable:
int testval attribute ((section (".ram_nocache_section")));
When building with the changed linkerscript but wihtout using attribute(section) nothing changes and the resulting build folder is 11MB, like before.
With the usage of attribute(section) the resulting build folder is 1.1GB.
Then it’s probably the error you mentioned. Can you tell me how to figure out what’s wrong?