cr1901 has quit [Read error: Connection reset by peer]
starblue has quit [Ping timeout: 256 seconds]
starblue has joined #rust-embedded
cr1901 has joined #rust-embedded
cr1901 has quit [Read error: Connection reset by peer]
<re_irc>
<@azerupi> Hi, I have a project where a use a blackpill with an STM32F401CCU6 and I would like to store a setting in flash. To do that I'm required to erase the sector I want to write to and then I can write my setting. All this works, but... The latest sector on this mcu is 128K so it takes a while to erase and this causes a 1 second freeze of the firmware.
<re_irc>
On this mcu the first two sectors are 16K, so I was thinking I could use the second one. But for that I need to modify the linker script to leave a "hole" in the flash at that sector. This repository is an example of what I would like to achieve: https://github.com/maxgerhardt/pio-stm32-reserved-flash-sector
<re_irc>
In the Rust ecosystem I looked around at how I could achieve this and the linker script seems to be defined in "cortex-m-rt", they allow to change the memory areas but as far as I can see it is not possible to change the sections? I'm very unfamiliar with how linker scripts work, maybe someone here with more experience can nudge me in the right direction? π
<re_irc>
<chrysn (@chrysn:matrix.org)> you wouldn't necessarily need to modify the linker script for a hole, we now have a sector for allocated-but-not-programmed memory -- but i don't know in which page are that winds up. 128kB sector ... are you sure? that sounds like half its rom.
<re_irc>
<ryan-summers> You could also just specify some special named link section and place your variable into it
<re_irc>
<ryan-summers> And then link it into the flash sector you care about
<re_irc>
<@azerupi> > 128kB sector ... are you sure? that sounds like half its rom.
<re_irc>
> A main memory block divided into 4 sectors of 16 KBytes, 1 sector of 64 KBytes, 1 sector of 128 KBytes (STM32F401xB/C) or 3 sectors of 128 Kbytes (STM32F401xD/E)
<re_irc>
As far as I can tell from my research online and in the manual, yes.
<re_irc>
<chrysn (@chrysn:matrix.org)> (hm, maybe that approach doesn't even work with non-constant flash page sizes...)
<re_irc>
<chrysn (@chrysn:matrix.org)> My apologies, scratch almost everything I said, I though this was a different channel -- none of it relates.
<re_irc>
<@azerupi> > you could try the FLASH_WRITABLE_INIT macro ... although I'm somewhat curious as to what that'd do with varying flash page sizes
<re_irc>
Yes from what I could read online the stm32f1 and some others seem to have 1K or 2K pages over the whole flash. So in that case it would be easy, I could erase just a 1K page and that would solve the problem. But the STM32f4 seems to be different and only allow whole sectors to be erased.
<re_irc>
<@azerupi> > You could also just specify some special named link section and place your variable into it
<re_irc>
Could I trouble you for some more information? I'm not sure I understand what you mean
<re_irc>
<ryan-summers> In your memory.x, you can specify some special "FLASH_STORAGE" section with a link address range equivalent to your sector-of-interest. Then, in your code, where you have your "const" variable (or buffer), you can do "#[link_section="FLASH_STORAGE"]" or something similar
<re_irc>
<ryan-summers> Then you guarantee that the variable gets put into that flash section, which ensures nothing else is there
<re_irc>
<ryan-summers> I don't know how Rust will work well if you have some "const"variable that could change though...
<re_irc>
<ryan-summers> So maybe just reserve it and don't put any code/vars there
<re_irc>
<ryan-summers> All you really have to do is define your "FLASH" section to not contain that sector and you should be fine
<re_irc>
<@azerupi> Ok, but I think the problem remains the same? The MCU will always start from address 0x08000000 in sector 1. If I understand "cortex-m-rt"'s linker script correctly they put the vector_isr symbols in the FLASH region. And If I want that 16K sector I need to be able to split this vector_isr in the first 16K sector, then a 16K sector where the linker writes nothing and then the actual code in the rest of the flash....
<re_irc>
... Unless there is another way?
<re_irc>
<@azerupi> And if I put the settings in the last sector I have a 128K sector to erase instead of 16K
<re_irc>
<Chris [pwnOrbitals]> sorry if thatβs a dumb question, but do you need to erase the sector ? you canβt simply overwrite the data in the range youβre interested in ?
<re_irc>
<@azerupi> Yes, that is a limitation of flash memory
<re_irc>
By default all bits are set to 1 and you can program them to zero. But to go from zero to 1 again you need to erase the sector
<re_irc>
<adamgreig> @azerupi: yea, it's a nuisance how the flash sectors are laid out, a lot of people use memory.x to move the whole application further back in flash and put a bootloader in the first sector, which could work for you, but in principle it would be convenient to just have a hole in the flash region that the linker leaves alone
<re_irc>
<adamgreig> in general you can add new sections from memory.x without needing to change cortex-m-rt or link.x, but to do what you want might need a change to link.x
<re_irc>
<adamgreig> it's very easy to do this though - just copy link.x.in from cortex-m-rt and name it something like my_link.x or whatever, then change your linker arg (in build.rs or .cargo/config.toml) to point to your linker script instead of link.x
<re_irc>
<adamgreig> then inside the linker script, leave the vector table stuff at flash origin, but don't start .data/.rodata until after the second sector
<re_irc>
<adamgreig> in an ideal world there would be a clever way to do this just from memory.x, but I think you're constrained by how the linker script is going to place both the vector table and .data into the same FLASH memory region
<re_irc>
<@azerupi> Thanks adamgreig !
<re_irc>
This is in line with what understood from digging into "cortex-m-rt" but since I never played much with linkers I got stuck. I will try your solution this evening when I get home. It sounds promising π
<re_irc>
<adamgreig> good luck, feel free to ask here if you get stuck, linker scripts can be pretty annoying
<re_irc>
<adamgreig> ryan-summers: I don't _think_ this would work if the FLASH_STORAGE section entirely overlapped FLASH, right? the idea here is to have FLASH take up the whole flash as usual, because it needs to start at the start for the vector table, but needs to be more than just 16kB big, while the FLASH_STORAGE sector is the second 16kB of flash, so we need the linker to leave a hole in the middle of FLASH
<re_irc>
<@azerupi> adamgreig: Maybe it would be enough to add a fully documented example of overwriting the linker script for this purpose somewhere. I don't think it is a common requirement, but it might be helpful for people to understand the steps involved
<re_irc>
<adamgreig> at the least we could document the steps in the cortex-m-rt readme, next to where we talk about adding new sections to memory.x
<re_irc>
<adamgreig> a new section after that called "Overriding the linker script" or something
<re_irc>
<@azerupi> If I manage to get it working I can look into submitting a PR to get the ball rolling π
<re_irc>
<adamgreig> in my experience it's very rare to need to do, but that might just be because it's hard and a lot of people would like to do exactly what you're doing now
<re_irc>
<adamgreig> it's certainly common to want to store config in flash, and basically all stm32s have this sort of flash layout, so...
<re_irc>
<adamgreig> I think it's only mitigated by also being very common to have a bootloader in this situation, and the bootloader goes at the start of flash, so you don't end up needing a custom linker script
<re_irc>
<adamgreig> thanks!
<re_irc>
<ryan-summers> Honestly the cortex-m-rt linker stuff works great. Once you get into the realm of needing custom sectors or bootloaders, you need to get familiar with the linker anyways
<re_irc>
<ryan-summers> But yeah, having the info of "Copy link.x locally, update .cargo/config to point to new link.x" would be a plus
<re_irc>
<ryan-summers> adamgreig: Yeah, the proposal was to make them intentionally not overlap. Is there any reason that the entry point has to be 0x8000_0000? I thought it loaded the address from the reset vector
<re_irc>
<adamgreig> it does, which is stored at 0x0800_0000
<re_irc>
<adamgreig> cortex-m-rt places the whole vector table at ORIGIN(FLASH)
<re_irc>
<adamgreig> and then places .data and .rodata after it
<re_irc>
<adamgreig> so if you put FLASH _after_ the config sector, nothing would be written to the vector table position and it couldn't boot, but if you put it in the right starting position, FLASH could only be 16kB long and probably not fit the firmware... right?
<re_irc>
<Chris [pwnOrbitals]> anyone knows if itβs possible to have position-independent code for cortex-m ? The linker complains no memory region specified for .got section so I guess thatβs not supported by the linker scripts in cortex-m-rt ?
<re_irc>
<ryan-summers> Ah gotcha, didn't know the default vector table address was the 800 address
<re_irc>
<adamgreig> ryan-summers: technically it's 0x0000_0000 for all cortex-m, they always boot from there, but on stm32 (depending on BOOT pin selection) the flash is normally mapped to address 0
<re_irc>
<adamgreig> so writing the vector table to 0800_0000 means it's present at 0000_0000 at boot time, unless you boot to ram or bootloader instead
<re_irc>
<adamgreig> or on h7 you can use the boot option bytes in flash to change the start address to wherever
<re_irc>
<adamgreig> Chris [pwnOrbitals]: it's not really a limit in cortex-m-rt, it's more that llvm doesn't know how to do the right codegen
<re_irc>
<adamgreig> some stuff would work, but accessing statics and trait methods (anything with vtables) would break horribly
starblue has quit [Ping timeout: 256 seconds]
starblue has joined #rust-embedded
Socke has quit [Ping timeout: 246 seconds]
Socke has joined #rust-embedded
explore has joined #rust-embedded
<re_irc>
<Chris [pwnOrbitals]> ah, got it, thanks for the clarification adamgreig
<re_irc>
<Chris [pwnOrbitals]> Would anyone know any ressources to setup XIPβ―(eXecute In Place) for external QSPIβ―flash on cortex-m ?
cr1901 has joined #rust-embedded
<re_irc>
<James Munns> That's a pretty chip-specific thing Chris [pwnOrbitals]
<re_irc>
<James Munns> which chip are you interested in?
<re_irc>
<James Munns> Usually, the process goes something like:
<re_irc>
- You make sure the chip is in a certain mode, like QSPI, by sending it commands
<re_irc>
- You select where the XIP gets mapped in memory (e.g. 0x1200_0000 for nrf52)
<re_irc>
- You configure your chip's QSPI/XIP peripheral (this is chip/manufacturer specific!)
<re_irc>
- Then you just read from mapped memory, and the hardware takes care of the requests and caching
<re_irc>
<James Munns> but like, the process for the nRF52 is different than the stm32
<re_irc>
<James Munns> So we can't give you a "how to do this for cortex-m" thing, since it's more of a vendor thing, like how a serial port or GPIO works in terms of setting it up.
<re_irc>
But that information should be in the reference manual of your chip! e.g. the STM32H743 or whatever
explore has quit [Quit: Connection closed for inactivity]
<re_irc>
<@azerupi> adamgreig: Hey I got it working! Thank you for your help π
<re_irc>
I had to add the device.x import and define the reserved section in the linker script otherwise I got hard faults. But now it works and it is significantly faster to erase the settings sector!
<re_irc>
<kristoff π§πͺ πͺπΊ> ok .. I'll remove the version of cargo I have now and try again
<re_irc>
<kristoff π§πͺ πͺπΊ> thx :-)
<re_irc>
<newam> NP, hope it helps!
<re_irc>
<kristoff π§πͺ πͺπΊ> newam: yes, it works ... ποΈ thx!
gsalazar has quit [Ping timeout: 256 seconds]
<re_irc>
<halfbit> has there been any effort to run rust on bare zynq or cyclone soc arm cores (cortex-a9/a53)?
<re_irc>
<James Munns> Not specifically! But there have been some bare metal Cortex-A projects before, which might be helpful.
<re_irc>
<James Munns> Unrelated: I'm in need of some poking on 'what docs should I write for my embedded rust OS', so I'm doing sort of a Q&A docs improvement... thing. I'll open it up here too, feel free to poke around, and ask me questions on twitter (if you're on twitter), or here (if you're not). Tweet in question: https://twitter.com/bitshiftmask/status/1514385800779247620