Fastest way to load a program to an MCU (RISCV)  - Page 1
Forum section: electronics / projects

author: sidereal
author_rank: Contributor
timestamp: October 11, 2024, 12:41:31 am
content: HelloRecently I asked aquestion about HMPin this forum. I have received very good answers. I am very grateful.I am considering (in no particular order):MilkV Duo or MarsSTAR64 Model-A 4GBiPI SMARCThese are my top 3 contenders.I am also considering another approach, where a master SBC can flash a slave MCU. There are several MCUs, with good ADC and Audio in, such as m5stack Stamp, ESP32 C6, etc.What I am thinking, is to inject compiled RISCV code to RAM, and execute it. I do not want to go through "flashing" the MCU, as it degrades the flash memory, and is slow.ESP 32 has ram protection, which need to be manually turned off for this kind of shenanigans, so that you can circumvent writing the Flash, and execute in place.In more details:Let's say, the normal set of flight law is:Fly 1 meter north at constant speedCheck GPSLoopAn alternate set of flight law could be:Fly 1 meter north at a variable speed given by PID parameters a,b, and c, where these are variablesCheck GPSLoopI could have both set of laws in the same code that runs on the MCU, and select them based on a switch statement, but this will go bad as the laws become more complex.I also want the master SBC to calculate the alternate law PID values and update them while the MCU is running the loop.But the question is,what is the fastest way of loading a new routine from a master SBC to a slave MCU?Of course this will be very slow compared to directly interacting with a freeRTOS/Zypher core on a MilkV, but how slow? Of course, this will also depend on the exact SBC and MCU used, but some benchmark information would be nice, showing what speed can be achieved using what combination?Are there some benchmarks and tutorials I can look at?Do I need to go over JTAG?Thank you

author: jbb
author_rank: Super Contributor
timestamp: October 11, 2024, 03:10:22 am
content: So you’d like to keep the code running during this update process?That can be done, but it’s gonna be complex.

author: sidereal
author_rank: Contributor
timestamp: October 11, 2024, 03:17:45 am
content: Well, if i can force ~10mb code update (thinking large for future here) within < 10 ms via DMA or something like that, I will be happy to shut down the currently running code on the MCU. do the update, and trigger the new code execution.

author: pqass
author_rank: Super Contributor
timestamp: October 11, 2024, 03:48:20 am
content: You're assuming that you can you run code from RAM on your chosen MCU.I don't know about ESP32 but not with ATmega; Harvard vs Von Neumann architecture.

author: brucehoult
author_rank: Super Contributor
timestamp: October 11, 2024, 04:23:57 am
content: Quote from: pqass on October 11, 2024, 03:48:20 amIt says "RISC-V" right in the post subject.ESP32 isn't a type of MCU, it's a marketing brand. They used to use Xtensa ISA but recent and all future models will be (according to them) RISC-V.

author: pqass
author_rank: Super Contributor
timestamp: October 11, 2024, 06:30:05 am
content: Quote from: brucehoult on October 11, 2024, 04:23:57 amOkay.But regardless of what machine code it runs yesterday or tomorrow, I was just pointing out if it was even possible to execute it directly out of SRAM (vs FLASH) because some MCUs keep program and data spaces separate. And I'm classifying ESP32 as an MCU because it has FLASH, SRAM, and MCU-ish peripherals in one thumbnail-sized chip. I'm sure you can get RISCV in CPU form, needing external memory and peripherals, but ESP32 isn't that.But a little research answered that question... fromheresection 9.2.2: "In Download Boot mode, users can download code into flash using UART0 or USB interface. It is also possible to load a program into SRAM and execute it from SRAM."Although it does say how to strap certain GPIOs to boot in this mode, it doesn't reference the section explaining exactly how to download to SRAM and execute.

author: Someone
author_rank: Super Contributor
timestamp: October 11, 2024, 06:42:15 am
content: Quote from: brucehoult on October 11, 2024, 04:23:57 amWhich could be Von Neumann or Harvard architectureThe general question of can your [arbitrary choice of] CPU execute from ram? is still valid.OP also seems confused about execution path and how bare metal handles different "programs".As in the thread providing context to this one: The OP should look at the Xilinx MPSoC platform as most of these concepts/ideas are documented and explained with tutorials/demos.

author: brucehoult
author_rank: Super Contributor
timestamp: October 11, 2024, 08:40:37 am
content: Quote from: pqass on October 11, 2024, 06:30:05 amRISC-V can't do that. ROM/flash, RAM, and peripherals are all located in the same address space. There is no concept in the ISA of multiple address spaces, there are no instructions to read constant data (strings, tables of data) from a special program space. Compilers inherently assume a Von Neumann architecture.For example, constant data is often located in ROM/flash at an offset from the PC. To access it you use theauipcinstruction to add some multiple of 4k to the PC and put the result into a general registers. You then use that register as a base address to load the data. There is no way to distinguish whether the value in a register is a pointer to program space or data space (or not a pointer at all).Simply put: the RISC-V ISA is not compatible with a Harvard architecture.

author: brucehoult
author_rank: Super Contributor
timestamp: October 11, 2024, 08:44:23 am
content: Quote from: Someone on October 11, 2024, 06:42:15 amThe question is answered by "it uses the RISC-V ISA". Which inherently assumes a Von Neumann architecture. As do Arm (both 32 and 64 bit), MIPS, MSP430 and probably every other 16 or 32 or 64 bit ISA.Even if someone somehow built a Harvard implementation it would be pretty useless because you would not be able to use standard compilers or software.

author: SiliconWizard
author_rank: Super Contributor
timestamp: October 11, 2024, 08:53:26 am
content: Except for the oddballs, most modern MCUs can execute code from RAM, so there should be no problem using pretty much any RISC-V or ARM Cortex-M based MCUs.With that said, I'm not sure the idea of updating code on the fly is that good an idea in this case, when only updating some parameters would do.But you can toy with that idea to your heart's content. No need to go the JTAG way. You can just use UART, SPI or whatever, define a protocol to send new code to execute, preferably add a CRC to check for good measure before executing the new code. If anything, that'll be an interesting experience. Although again, I wouldn't necessary recommend doing that, especially in "real-time" on a device that's flying. But that's just my 2 cents.

author: pcprogrammer
author_rank: Super Contributor
timestamp: October 11, 2024, 11:27:33 am
content: It certainly needs a MCU with enough random access memory of any kind to allow for the code to be even loaded into it.A Milk-V duo has plenty so no problem there. For the ESP32 range of devices it depends on the specifications of the chosen device.It also depends on the size of the routines that need to be loaded for sure, but even if expressed in bits and assuming the little m is not intended to mean milli, 1,25 Mega Byte is a lot of code and you have to be writing a lot of code to get up to 10MB.Quote from: sidereal on October 11, 2024, 03:17:45 amThis much random access memory or even FLASH is not that common in the MCU world. On a side note the MCU (CVITEK CV1800B) on the Milk-V duo 64MB does not even have internal FLASH.Like SiliconWizard wrote, it is possible to, during run time, load in code via a UART or other interface and have it executed. It does need a solid setup for sure and be able to interrupt the loaded code at all time to be able to repeat the same process.If the loaded code is an infinite loop and has the ability to disable all interrupts you are basically screwed. So not only checks on code validity with a CRC is needed, making sure there is a recovery path is a must.Edit: corrected a calculation error, and indicated that the MCU on the Milk-V duo does not have FLASH.

author: brucehoult
author_rank: Super Contributor
timestamp: October 11, 2024, 11:47:09 am
content: Quote from: pcprogrammer on October 11, 2024, 11:27:33 amDuo and Duo 256 MB have pads you can solder an SPI NOR flash to, using the same pins as (and replacing) the SD card.

author: pcprogrammer
author_rank: Super Contributor
timestamp: October 11, 2024, 11:59:00 am
content: Quote from: brucehoult on October 11, 2024, 11:47:09 amYes, you are correct. My intention was to say that the CVITEK CV1800B MCU used on the Duo (64MB) does not have internal FLASH.

author: brucehoult
author_rank: Super Contributor
timestamp: October 11, 2024, 12:10:55 pm
content: Quote from: pcprogrammer on October 11, 2024, 11:59:00 amI would hazard a guess that no SoC with a 1 GHz CPU does. Even ~100 MHz chips such as GD32VF103 and RP2040 either use external flash or at least have the flash on a separate die in the same package.

author: tom66
author_rank: Super Contributor
timestamp: October 11, 2024, 12:42:36 pm
content: One big headache with loading code on the fly is if you need to initialise any peripherals, say, PWM peripherals for motor control, those will definitely glitch as you reset the peripherals on init. That initialisation period could easily take as long as the code loading takes.If you truly need customisable logic but do not need to execute it very quickly, then one approach is to have a very simple soft-core CPU that executes some kind of block of instructions and produces an output. You can then stream in new data that way without interrupting the running flow of the program. The obvious downside is this is slow, so if you need to do a lot of DSP it could be an issue.Another option is to load the relevant functions into an area of RAM and replace just that area every time you need to update. You can call these with a function pointer. You would need to relocate the function so that it is in the correct area of code since most linkers assume they can arbitrarily position functions and you may not be able to guarantee the RAM position, that means anything it calls needs to be called via absolute addresses, which is slower.But you also need to evaluate if you really need to replace the actual code, if you are just tweaking PID values and basic behaviour I would go for some kind of state machine / pseudo ISA executed directly by the CPU, as it will be a major headache to get right.

author: sidereal
author_rank: Contributor
timestamp: October 11, 2024, 12:44:37 pm
content: I really do not want to do the Flash, is takes several seconds.I was studying DMA routes, which can be done in milliseconds.I really want to update the code in the sense, that it is a simple way for the master SBC to launch a "thread" in the slave. If there is a sudden storm, e.g. and the UAV is far away, then the master SBC will launch appropriate threads in the real time mcu-s coreThe recovery path idea is great and I have take that into account - all normal alternate flight laws must have a termination rule.Thismaster sbc launches new code every time it is needed on a slave mcuidea is for V1. once i have sufficient experience on this method as a flight control, I will consider integrated solutions. e.g. HMP on fpga, rproc (remote processor API calls on linux) etc

author: sidereal
author_rank: Contributor
timestamp: October 11, 2024, 12:52:30 pm
content: Quote from: tom66 on October 11, 2024, 12:42:36 pmI have considered 8 fixed output pins from the slave to a third mcu. the third MCU is in charge of re-initializing the motors and other peripherals.So, if the newly injected logic itself can be contained in the slave alone, and i can require that all flight laws will produced a predefined set of peripheral commands, then the third mcu can simply treat the slave mcu as a blackbox, and handle the PWM commands as coming from it, without caring for the logicThe exact nature of producing these peripheral commands is still W.I.P.The PWM was just example, so were PID variables. The newly injected logic might need more. I need the flexibility, for future expansion. The slave MCU is a taksed with providing a real time core, to solve real time logic as needed by the uav

author: xvr
author_rank: Frequent Contributor
timestamp: October 11, 2024, 03:53:27 pm
content: ESP32 have a relatively little amount of RAM. It use part of RAM as cache to back up code, executed from external SPI FLASH memory. So, you can execute code directly from internal memory, but size of such code is limited comparing to code in SPI FLASH (up to hundreds of KB in RAM and tenth of MB in SPI FLASH).

author: sidereal
author_rank: Contributor
timestamp: October 11, 2024, 04:59:13 pm
content: Quote from: xvr on October 11, 2024, 03:53:27 pmTrue. The one I am considering is ESP32 P4, has 768 KB SRAM.I said, the speed should be 10 MB in 10 ms, approx, so I if i can push 768 kb ~ 1 MB over dma in about 1 ms - i will be happy about it as well

author: zilp
author_rank: Frequent Contributor
timestamp: October 11, 2024, 05:48:25 pm
content: Quote from: sidereal on October 11, 2024, 04:59:13 pmJust look for an MCU that supports 10 Gb/s Ethernet, that should do the job.

author: sidereal
author_rank: Contributor
timestamp: October 11, 2024, 05:57:31 pm
content: Thank you. I did not consider that.What keyword should i search for to load code via ethernet ?Thanks again

author: pcprogrammer
author_rank: Super Contributor
timestamp: October 11, 2024, 06:02:38 pm
content: Quote from: zilp on October 11, 2024, 05:48:25 pmSure, these are easy to find and also very cheap.

author: pcprogrammer
author_rank: Super Contributor
timestamp: October 11, 2024, 06:10:00 pm
content: Quote from: sidereal on October 11, 2024, 05:57:31 pmTo support uploading via Ethernet you need a lot of code to make it work on proper protocol level. It probably is possible to do it kind of bare metal without a proper protocol stack, but won't be easy. Simple SPI or UART is the easy way to do this. DMA can be used to not load the core, but at some point you would have to know that the new code needs to be started.I think you are better of with the Milk-V duo or other dual core MCU with internal memory where the main core can load the new code to memory and then kick the sub core to do the processing.

author: Sorama
author_rank: Frequent Contributor
timestamp: October 11, 2024, 06:17:19 pm
content: That won’t make a difference.Too much ip overhead.

author: zilp
author_rank: Frequent Contributor
timestamp: October 11, 2024, 06:30:26 pm
content: Quote from: sidereal on October 11, 2024, 05:57:31 pmThe point was to make you consider how insane your requirements are. You are asking for a microcontroller that can move a gigabyte per second through its I/O. So, that's around eight gigabit serially, or you need a wide bus, at 32 bits wide (so 32 I/O pins plus clock) you still need a 250 MHz clock. That's just so far outside the realm of what microcontrollers can do that you maybe should reconsider what problem you are actually trying to solve.

author: sidereal
author_rank: Contributor
timestamp: October 11, 2024, 07:05:36 pm
content: Quote from: zilp on October 11, 2024, 06:30:26 pmMy aim is 1 MBps. if that is not possible, i am open to finding the fastest DMA approach that is possible.

author: jbb
author_rank: Super Contributor
timestamp: October 11, 2024, 08:12:58 pm
content: It is possible to replacesectionsof code in a running real-time system, but it’s tricky.I speculate that it can be done as follows:MCU runs a Real Time Operating System (RTOs)RTOS runs a number of tasks A, B, C etc.Tasks communicate via message passingHost system wants to update task BHost uploads new binary code N to MCU RAM. Original task B keeps running…Once complete code block has arrived (and CRC checked), RTOS stops execution of task B and replaces it with task N

author: sidereal
author_rank: Contributor
timestamp: October 11, 2024, 09:07:08 pm
content: Quote from: jbb on October 11, 2024, 08:12:58 pmThank you for articulating all these steps. I was thinking like this, but my thought was to completely stop the process B and force the RTOS to copy received binary file from SPI interface in RAM and then launch it as a new process N.But I think your idea would be much better, and that way i will not miss, e.g. a message from the motor controller that might happen during the update process.Could you please offer me more insight, information tutorial, etc using the systems i mentioned?

author: Someone
author_rank: Super Contributor
timestamp: October 11, 2024, 09:39:40 pm
content: Quote from: brucehoult on October 11, 2024, 08:44:23 amhttps://github.com/devindang/dv-cpu-rvOf all the people on this forum I thought you'd be more open minded on that. RISC-V being an instruction set, not an implementation.OP still hasn't motivated why RISC-V is important.Quote from: zilp on October 11, 2024, 06:30:26 pmEverything the OP mentions (original thread was about heterogeneous computing) seems to point to wanting all the features of a Xilinx MPSoC, where they have examples/tutorials of exactly this. Reloading bare metal cores on the fly has a whole bunch of issues which have been solved there.

author: brucehoult
author_rank: Super Contributor
timestamp: October 11, 2024, 11:12:34 pm
content: Quote from: Someone on October 11, 2024, 09:39:40 pmAs I have already said, you *can* do it, and this is often done in student projects because it's much simpler to implement. Or in an FPGA situation where you will be running tiny hand-written programs.But this is only (as that page says itself) "based on RISC-V". It is not actual RISC-V. As I have already said you can't run code generated by compilers because there is no way to access constants/strings stored in the program memory. On an FPGA you could arrange for data memory to be preloaded.No commercial RISC-V core / SoC / SBC would ever be Harvard.

author: Someone
author_rank: Super Contributor
timestamp: October 11, 2024, 11:26:15 pm
content: Quote from: brucehoult on October 11, 2024, 11:12:34 pmAs an expert in the field, how is that example divergent from RISC-V, why do you say it isnot"true" RISC-V ?It does use a standard gcc compiler, what you claimed would be impossible. Yes some programming constructs no longer work, but they are not guaranteed by RISC-V ISA. Various embedded compilers are able to handle data memory init fine. So I do not think a commercial Harvard RISC-V is as implausible as you say, given the well known benefits for low cost low power embedded. Execute in place from FLASH has its place, and Harvard architecture matches that well.Harvard RISC-V in a heterogenous multicore, agree that would be extremely unlikely.

author: brucehoult
author_rank: Super Contributor
timestamp: October 11, 2024, 11:59:09 pm
content: Quote from: Someone on October 11, 2024, 11:26:15 pmBecause everything in the RISC-V ISA and ecosystem assumes that you can write code such as ...Code:.globl mainmain:jal a0,1f.word 421: lw a0,(a0)ret... and on return a0 will contain 42 (and in a *nix environmentecho $?will show that)Harvard architecture breaks suchISA(not implementation) properties.QuoteJust such minor things as e.g. constant strings. No one uses those.QuoteIt's not impossible but I haven't seen any such.If you wanted to print "Hello world!\n" then you'd have to generate code such as:Code:la a0,buf // probably lui/addili a1,'Hell' // actually a lui/addi pairsw a1,(a0)li a1,'o wo'sw a1,4(a0)li a1,'rld!'sw a1,8(a0)li a1,'\n\0'sh a1,12(a0)That's 56 bytes of code  for a 14 byte literal. Not great. You'd better have a lot of program memory.Could you write tooling to do this for everything in.dataand.rodata? Sure. Do standard toolchains support this? No. assuming if you're cutting CPU circuitry so much you won't be implementing the C extension

author: jbb
author_rank: Super Contributor
timestamp: October 12, 2024, 12:19:32 am
content: Quote from: sidereal on October 11, 2024, 09:07:08 pmUnfortunately, no. I’ve never attempted it myself and the above method is half-remembered from a poster in a break room <redacted> years ago. So I know it’s possible, but difficult.Upon further consideration, the Robot Operating System (https://www.ros.org/) may just provide some relevant features. But I know next to nothing about it.

author: SiliconWizard
author_rank: Super Contributor
timestamp: October 12, 2024, 12:40:12 am
content: Yes, true Harvard is pretty inconvenient in practice, and you can get most of its benefits with a MMU.Modern CPUs often have separate instruction and data busses internally anyway, but they usually can access the same memory areas either from caches or through a MMU, or some other kind of "bridge". So that it appears Von Neumann to the user.Using vanilla RISC-V toolchains with a true Harvard CPU, that would require going through some hoops as Bruce mentioned. You'd have to copy all constants to data memory beforehand (with a means of doing that, so probably some extension to the instruction set). And make sure your linker scripts are written appropriately. It's not that hard, but one thing it does is potentially waste a lot of data memory.Making it transparent to the user, even if internally, that's technically "Harvard" to some degree, often makes more sense, which is why it has pretty much become default, except in very niche applications. And you have MMUs for the segregation aspects, and caches for efficient concurrent accesses.

author: brucehoult
author_rank: Super Contributor
timestamp: October 12, 2024, 12:49:01 am
content: Quote from: SiliconWizard on October 12, 2024, 12:40:12 amicache. And a flush instruction (fence.i) if you have self-modifying code / JIT. Or ITIM, in the same address space but maybe with a couple of cycles penalty if accessed as data.

author: Someone
author_rank: Super Contributor
timestamp: October 12, 2024, 01:11:42 am
content: Quote from: brucehoult on October 11, 2024, 11:59:09 pmYes, instructions that move the program counter to a register could be combined in a construct that does not make sense for Harvard Architecture. But that does not mean the ISA prohibits or prevents it, the ISA is neutral to how the memory is arranged and that understanding is for the complier/assembler to abstract away. Those instructions are still useful in Harvard Architecture for subroutines/function call, but loading data would be done in a different way.

author: brucehoult
author_rank: Super Contributor
timestamp: October 12, 2024, 01:41:32 am
content: Quote from: Someone on October 12, 2024, 01:11:42 amIt is really not.The existence and workings ofauipcandjalrimply that addresses in the PC and in general registers are equivalent.In Chapter 3: Machine-Level ISA of the privileged specification, the same virtual memory mechanisms apply to both data and instruction fetches, reinforcing the idea that both the PC and GPRs work within the same address space.Everything about how you handle exceptions with theepcCSR pointing to the faulting instruction implies that you can use standard data load instructions to access and analyse the instruction. For example on a misaligned load/store on a machine that does not handle it in hardware,mtvalwill contain the affected memory address but in order to emulate the load or store the trap handler has to useepcto load and examine the trapping instruction to determine the data size, src or dst register, whether it is integer or FP, and this is done using a normal load instruction.The about to be ratified "semihosting" spec says that the instruction sequence...Code:slli x0, x0, 0x1febreaksrai x0, x0, 7... indicates to the debugger that thisebreakis for the purposes of a simulated OS call which is otherwise identical in specification to Arm semihosting triggered usingSVC #0xABon ARMv7. This, again, implies that the debugger can load and check for the correctslliandsraiNOPs.In short, the spec doesn't explicitly say that there is a single address space because no one writing the spec ever imagined that it might not be true.

author: Someone
author_rank: Super Contributor
timestamp: October 12, 2024, 02:53:47 am
content: Quote from: brucehoult on October 12, 2024, 01:41:32 amWithout an instruction that indirect addresses offset from the program counter there is no implication of data and program counter being intimately linked. Youhaveto bounce through a register if you want that, which is above the ISA.Quote from: brucehoult on October 12, 2024, 01:41:32 amA single address space can have its flatness/symmetry weakened to have sections of ROM (already done in shipped RISC-V processors) so store instructions will obviously fail in those address segments. It's not a radical step to have a design treats RAM and ROM (flash based or not) differently at a hardware level, despite still implementing the RISC-V ISA.Compilers (for C etc) for other architectures exist that handle the asymmetry of Havard architecture, balancing the speed/size trade offs for example various ways to store constants. That could be implemented on RISC-V if there was demand, neither of us know of any examples but it is not prohibited and could remain RISC-V compliant.

author: brucehoult
author_rank: Super Contributor
timestamp: October 12, 2024, 03:23:57 am
content: Quote from: Someone on October 12, 2024, 02:53:47 amThat is a COMPLETELY different characteristic. Yes, of course there can be holes which are not readable or not writable in the SINGLE address space.QuoteThat implementation, not ISA.QuoteThe entire point of sharing an ISA is so you can share tools and code, including assembly language code.If you need custom tools and a custom compilation model and standard code won't run then it's a different ISA. Closely related, sure, but different.I have already made my point of view clear. If you don't agree that's fine, but I think you'll find yourself in a minority.

author: Someone
author_rank: Super Contributor
timestamp: October 12, 2024, 04:03:58 am
content: Quote from: brucehoult on October 12, 2024, 03:23:57 amA single address space could be implemented with disparate data/memory pathways. As we agree that is implementation and could support a RISC-V ISA.A hypothetical RV32E with a linear address space including flash and SRAM is plausible, those being physically separate busses (Harvard architecture) having different access times/performance is plausible. You're an expert in RISC-V ISA and compiler details:https://www.reddit.com/r/RISCV/comments/l91qzu/comment/glg1l84/from my understanding people are doing such things already:https://stackoverflow.com/questions/74401400/linker-script-ram-intialization-in-romNot a significant leap to have a compiler work out intelligent ways to use read only memory (likely already in major compliers from my understanding), and then another small step to have it know the relative access speeds of the different sections to guide optimisation (already in compliers for other processor models and not necessary but nice to have).edit*: looks like there is support for execute only (no data read) floating around:https://github.com/riscv-collab/riscv-gnu-toolchain/issues/668https://github.com/riscv-boom/riscv-boom/issues/703So compliers can be informed there is a ROM with no writeorread access, and a ram region with RW but not initialised. Thats Harvard architecture supported.

author: pcprogrammer
author_rank: Super Contributor
timestamp: October 12, 2024, 06:08:19 am
content: Ok back to the OP's question.I think you are over complicating things. Since it is about flying a drone and changing flight rules on the spot, I assume all the code is already written and available in the "master" FLASH memory. Then all that is needed is using function pointers to select the correct routine and update the datasets as needed.Even when you create a setup with three separate MCU's there is no need to send new code from a master as long as all the code has already been written. Just have the master send the identifier of the new routine that needs to be used for the calculations of the flight control data.If the code has to be written on the fly, the drone is doomed for sure, because that would take way to long in a crisis situation.But with the new information of just 1Mbps as needed data transfer rate, a simple UART will do. Some can reach speeds up to 5Mbps.Still think that there is no need for this all. With a fast MCU it can be done on a single core with proper programming. If it is about redundancy and a more reliable system, then something completely different is needed. For instance a triple processors setup running the same code, sending decisions to an arbitrager circuit that uses the majority vote to take action on.

author: sidereal
author_rank: Contributor
timestamp: October 12, 2024, 01:58:59 pm
content: Yes, all code is written and available on a master flash memory (or other storage medium)But I want to load the code and execute on a real time MCU, along with tuning parameters calculated on the fly.The master storage device has way more code that the real time MCU board has on board. So I can't just save all the code on the real time board itself. What I wanted therefore is the master SBC, which "launches" the proper routine on the MCU (and also manages communication with ground, navigation, swarm rules etc)So basically, if it detect a storm wind suddenly appearing, it will then tell the flight MCU (slave MCU)to load the new "storm flight routine", possibly from a storage managed by the Master SBC, and that once the current loop of the current flight rule ends, go to storm flight routine.e.g.Slave MCU is currently running normal flight loop: move 1 meter north, check gps, loopMaster sbc will load new loop: detect wind speed, calculate correction to fly north, run motors at 40% pwm duty cycle, .......... many other things ... loopThis loading may finish, while, for example, say the slave sbc was in the normal loop, flying 1 meter north. it still has to check gps to finish current loop. Once that is down, instead of returning to the loop, it will go to detecting wind speed of the updated loop and keep doing that loop.The idea is, that the slave sbc should be able to do this mechanism, without ever knowing that such an updated loop existed. To do a hyperbole that illustrates my point, if aliens from mars somehow beamed a new loop, then the slave sbc should be able to follow it. dont worry about security implication.How can I achieve that?

author: pcprogrammer
author_rank: Super Contributor
timestamp: October 12, 2024, 02:24:14 pm
content: I think you are overlooking the fact that a single MCU with enough memory running on for instance 480MHz is as real time as things get, even with some task switching it still will be able to pull the things of that you want. Just don't use an OS like Linux to do the task handling. Write it your self to be as fast as possible. Nothing fancy is needed.But if you really want to have a second processor to do the things you like to do get your self a Milk-v duo and look into how it works with communication between the two cores. I'm sure you will be able to find examples of how it is running Linux on the main core and an Arduino based sketch on the other with inter core communication.Another option is to add a big external SPI based FLASH to the ESP32 you have in mind. Make sure that all the flight law routines are less than half the available random access memory in the ESP32 and have it load the needed code to the free part of the memory while the current code is running in the other part, and switch to the new code when the other one is at the end of its loop.To make this a bit simpler without having to worry about relocatable code just add two versions of each code set. One for the first half of the memory and another for the second half of the memory and choose the needed one based on which part is free.Starting the SPI based loading of the data to memory can be done with the help of DMA.

author: sidereal
author_rank: Contributor
timestamp: October 12, 2024, 03:48:23 pm
content: Yes. my idea is to implement something like that in a discreet architecture, i.e. two cores in two different physical units.If i can do that in my V1, ill learn the details and in v3 or v4 go for an integrated fpga solution, and then later make our own RISCV devices

author: brucehoult
author_rank: Super Contributor
timestamp: October 13, 2024, 01:30:52 am
content: Quote from: sidereal on October 12, 2024, 01:58:59 pmHow do you know that when you haven't yet selected the "real time" device?While some MCUs have only a few KB of RAM there are "real time" devices with access to anything from dozens of MB to a couple of GB of RAM, including ones already mentioned.I highly doubt the "way more code" story. You can simply select a device with enough RAM and storage.Even a modern web browser (Firefox, Chrome, ...) or complete office suite only has a couple of hundred MB of executable code. Less than the RAM size of a $10 Milk-V Duo S.

author: sidereal
author_rank: Contributor
timestamp: October 13, 2024, 03:59:52 pm
content: How do I know?The on board flash is 768 kb according to the datasheetI am reaching few Megabytes already, accounting for crosswind cases, windshear, rain etc.

author: xvr
author_rank: Frequent Contributor
timestamp: October 13, 2024, 05:13:10 pm
content: I guess 768KB is a RAM size, not FLASH (as you noted early). XIP machinery of ESP32 allows using of external SPI FLASH for code storage, and size of this FLASH could be much greater than RAM size. It easily could store 10th MB of code. If you will place code directly to RAM you loose this feature, and your code space will be truncated to available RAM size.

author: pcprogrammer
author_rank: Super Contributor
timestamp: October 13, 2024, 06:38:10 pm
content: I looked at the ESP32-P4 and even thought the specifications are impressive, I would go for the MCU (CV1800B) used on the Milk-v duo. It offers 64MB of memory and one core running on max 1GHz and a second core running at max 700MHz.Twice the speed of the ESP32-P4 and a multiple of the memory found in the ESP32-P4. Sure it is extended on chip with PSRAM, but that does not compare to the DDR2 memory used in the CV1800B.Could not find pricing on a loose SOC, but the development board is expensive, around 60 euros or so.Further more I wonder how it is that your routines for flight control take up so much space?I have no experience in this field, but it feels like way to big for any real time control algorithm that needs to act swiftly on changing circumstances.Edit: as a reference the scope code I wrote for the FNIRSI 1013D that runs on an ARM based F1C100s only takes about 260KB.

author: Someone
author_rank: Super Contributor
timestamp: October 13, 2024, 09:43:10 pm
content: Quote from: pcprogrammer on October 13, 2024, 06:38:10 pmYes, no explanation of why it is impossible to have all the control "laws" in a single program that has parameters/variables/switches/states to take care of the different situations, and why that must be done by loading new executing code.

author: uer166
author_rank: Super Contributor
timestamp: October 13, 2024, 09:46:56 pm
content: Quote from: xvr on October 13, 2024, 05:13:10 pmWhy such a crazy architecture that's prone to failure when you can just put everything in one MCU/memory?Real flight computers running VxWorks can have many GB of program space. In your case just use a MCU with either enough flash memory for XiP, or use an external SRAM or FLASH bus to execute code out of it. It'll be orders of magnitude simpler and more probably reliable that this crazy idea.Edit: I meant to reply to OP but the point still stands.

author: ejeffrey
author_rank: Super Contributor
timestamp: October 13, 2024, 11:17:06 pm
content: Quote from: brucehoult on October 11, 2024, 11:59:09 pmThis is far afield from the original question because it's clear no commercial implementation would do this. However I'm curious because it's not my experience that GCC actually generates code like this. At least on riscv32 with the build options I was using, integer literals use lui/addi while string constants go in the data section. If the linker script places them in their own memory area then that's where they go. Generally they get loaded vias offsets from gp register if possible.This is different from ARM where GCC does use a literal pool in the text area and does PC relative loads. But that's because ARM has single instruction PC relative loads with a short offset which risc-v doesn't have.I definitely haven't studied this extensively so I would be curious if/when compilers actually do this.I was trying this exactly because I wanted to use an FPGA implementation where having unified instruction and data memory would be very costly. FPGA memory blocks are natively dual port. If you connect one to instruction and one to data bus you don't have a port to left load anything. On a system with caches it's no big deal, but if you are going to tightly coupled memory it's a problem. Any solution is going to either take up considerably more memory or cause contention, and probably decrease fmax either way.We ended up using microblaze which specifically supports this because it is intended to target FPGAs, but now I'm curious if we do switch do risc-v if we will have unpredictable tool chain problems unless we eat the cost of providing access to the instruction memory.

author: brucehoult
author_rank: Super Contributor
timestamp: October 14, 2024, 01:07:21 am
content: You're correct that mainstream compilers don't produce code like this. I think for several reasons:1) there is no PC-relative load instruction, so you need additional instructions to get a PC-relative address into a GPR2) it saves space in the icache (and overall) relative to assembling everything with LUI, ADDI, SLLI, and OR, but getting bits of your program code in the dcache is not ideal. You'd want to at least try to put the constant pools in their own cache blocks.GP-relative constants makes sense in an ELF-based system, where everything is copied from disk on startup, regardless, but not so much on a ROM-flash-based system where that would necessitate copying constants from ROM to RAM along with initialised variables. A good idea for speed if random flash access is slow, but bad for RAM usage.I think PC-relative constant pools do make sense in a JIT-based system, and I'm seriously considering it in DotNET for RISC-V, which currently exclusively uses shift-and-add to assemble masses of 64 bit values for every function call or access to a global.

author: JoeyG
author_rank: Regular Contributor
timestamp: October 14, 2024, 01:35:35 am
content: Not RISC-V based but some mcu's have "live flash update"https://ww1.microchip.com/downloads/en/DeviceDoc/60001193B.pdfhttps://www.microchip.com/en-us/about/media-center/videos/Y7cOUCQ5yEM

author: brucehoult
author_rank: Super Contributor
timestamp: October 14, 2024, 03:24:28 am
content: If a regular debugger/OpenOCD can write a program into the flash (which they do by first uploading a small program into RAM and then running it) then it stands to reason that any regular program can also write to flash, it it wants to. You'll generally need to copy the flash writing code into RAM and temporarily turn off XIP, but that's no big deal.Assuming you're not running on some wacky Harvard architecture, of course.

author: bson
author_rank: Unknown
timestamp: October 14, 2024, 07:59:19 pm
content: Quote from: sidereal on October 11, 2024, 05:57:31 pmIf you want to do this I'd consider getting U-Boot up and running on it, directly out of flash. It can load binaries from just about anywhere into RAM to execute them, including tftpboot, SD/MMC cards, raw JEDEC NAND flash (binary, JFFS2 etc etc), knows many file systems and is just a good item. I'm sure it already runs on some RV boards, has support for most SoC peripherals already - and maybe even binaries for the board(s) you're considering. Its size depends on what's enabled, but 256k should be sufficient and 512k more than adequate, which should be no problem.However, you can edit-compile-load into NOR flash all day for years and years without wearing it out. It's really not a problem. Usually development is short enough that the wear is trivial.