__not_in_flash_func() requested around rom_func_lookup() and others. #410
Labels
No labels
bazel
bluetooth
board settings
boot_stage2
bug
build
c++
can't reproduce
clang
clib-interface
cmsis
code cleanliness
code size
compiler version issues
cyw43_driver
debug
discussion
documentation
duplicate
dynamic_clock
elf2uf2
enhancement
errata
filesystem
flash layout
floating point
FreeRTOS
hardware_adc
hardware_claim
hardware_clocks
hardware_dma
hardware_exception
hardware_flash
hardware_gpio
hardware_i2c
hardware_irq
hardware_pio
hardware_pwm
hardware_rcp
hardware_rtc
hardware_spi
hardware_sync
hardware_uart
hardware_vreg
hardware_watchdog
hardware_xosc
help wanted
host
IAR
installation
invalid
linker scripts
lto
lwip
mbedtls
missing API
needs reporter detail
networking
newlib
newlib-multicore
non-c
non-cmake
non-gcc
openocd
orphan PR
OS integration
pico_async_context
pico_base
pico_binary_info
pico_flash
picolibc
pico_lwip
pico_malloc
pico_multicore
pico_printf
pico_runtime
pico_stdio
pico_stdio_usb
pico_sync
pico_time
pico_util
pioasm
port
question
review
review2
rtos interop
runtime init
static library
svd
test
tinyusb
vscode
wifi integration
wontfix
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
gh-raspberrypi/pico-sdk#410
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Hi guys,
I think I'm pushing the boundaries a little here which is why I have created the issue I have.
Here's the background;
So long as all of my apps contain the same code, I can reprogram the device just by putting the UF2 image on the SD card and inserting it.
The issue I seem to have caused myself is that calling the flash routines in the code below causes the app to crash because there are certain dependent functions that are in the flash I'm writing to.
`
for (size_t PageCount = 0; PageCount < NewNumBlocks; PageCount++)
{
uint8_t DataBlock[FLASH_PAGE_SIZE];
`
It appears that flash_range_erase() and flash_range_program() are declared __no_inline_not_in_flash_func, but the dependencies within them are not.
I can fix the problem by changing the declarations of the functions below to be __not_in_flash_func()
My questions are;
P.S. I do have this all working, but I'm after clarification as to whether or not what I am doing to delcare these additional functions as not in flash is correct and should be ported into the standard SDK or not.
Interesting... I dunno how compiler-internals and these function attributes work, but I wonder if any functions marked as
__not_in_flash_funcshould "recursively" be not-in-flash automatically (IYSWIM)? Or perhaps that's simply something that the compiler can't do automatically? 🤷Can't do that
That's not ideal... and perhaps this is an outside use case (since the methods are safe to call from flash unless you are overwriting the binary as you say). it is probably better if they were inline in the header (they are very simple), but they may be called from ASM also. (I'll take a look in a bit)
As a workaround you could certainly just copy the code for all these few functions.
I do see what you mean, and recursiveness was also my thought. Currently seems like it's a manual job to go through your code and seek out all those functions that are called. Wouldn't affect too many users I don't think - after all, erasing the code you are running is not a normal activity!
Note also you could just replace pico_bootrom by setting
SKIP_PICO_BOOTROM=1at the top of your CMakeLists.txt, and adding your own pico_bootrom INTERFACE library which does the same thing but with__not_in_flash_funcYes, that works fine - it just doesn't seem elegant to me - if someone changes any of these functions in future SDK versions I'd have to hunt them down and make sure the changes got applied to my copied functions.....having said that, I'd still have to modify the SDK to put the __not_in_flash_func macros back.
I'm now going to read up on the suggestion of setting SKIP_PICO_BOOTROM and making a new INTERFACE library.
I must be being thick.... I can't find 'SKIP_PICO_BOOTROM' in any of the SDK or any documentation. Can you advise please?
https://github.com/raspberrypi/pico-sdk/blob/develop/src/CMakeLists.txt#L21 ?
I presume you meant set(SKIP_PICO_BOOTROM 1), which is what I have actually done. Thanks for the tip. I'd like to add that I couldn't find any documentation of this nice feature anywhere. It's use might make a nice example for the Pico examples too.
Yes; it isn't currently documented - feel free to make a PR in pico-examples with an example ;-)
Even if its callees are in RAM, the
flash.ccode explicitly does data access on flash on non-NO_FLASHbuilds, when it takes a copy of the second stage bootloader (flash_init_boot2_copyout()).Looking at
flash_range_eraseas an example:The logic of the code is:
So the function is declared as
__no_inline_not_in_flash_funcnot because it is expected to be callable when XIP of the current image is not available, but so that this critical section:Is able to run without flash execution. The code still expects XIP to be available when it is called, and this is the assumption that's broken when you start writing to the program image you called your RAM-resident code from.
Honestly I'm a little surprised that those calls weren't inlined, the function lookups seem like they would benefit from it? Same for
__compiler_memory_barrier, which shouldn't actually produce any code, and was a macro at one point.It's a little unconventional for a program to overwrite its own image. More commonly, this kind of "move the world" operation is a separate, self-contained bootloader. That way you get better linker hygiene between the code that might be in flash and the code that mustn't be.
Like I said - Architect of my own problem 8-)
I might see if I can somehow turn this into a separate bootloader, but I have more pressing project priorities at the moment so this might take a while.
I originally built it as part of my program image since that already had the code for dealing with the SD card filesystem, and I don't have much experience of playing around with linker files/relocating images.
Since there would be SD driver code in both my bootloader image and my program image, that would be rather wasteful of space. Is there a (simple) way I can put the SD card code in "my" bootloader, but then reference the code from within my application?
I'm also very interested in a solution.
@smithps how did you solve the issue?
If you are asking about the __not_in_flash_func() bits - I just added that to the code I needed to and made it all work without disappearing into space.
In terms of the SD card functionality at the moment I have it working, but it relies on the SD card code from my app. That is it isn't a "standalone unit of code" (library) as such, but more of a suite of modules that end up being linked into my executable.
I modified my main() code;
I intend to improve this so that it also uses the LCD screen on my hardware to inform the user what's going on. Once this is complete I might try and turn it into something a bit more elegant, but as its quite hardware specific I'm not sure I can post it to the repository as an example.
I have a similar approach (no sd but field bus) and encountered (among others) the same problem as you did. you may have a look here when you interested, I shared code also: https://www.raspberrypi.org/forums/viewtopic.php?f=144&t=315267&p=1893934#p1893934
for reboot I choose the Watchdog, thats works great. have a look at the forum post of mine.
note that
__compiler_memory_barrieris now __force_inline so shouldn't be an issue - others will be dealt with separatelymerged into develop