Page 1 of 1
ESP32-S3 RISC-V memory access
Posted: Mon Dec 16, 2024 5:35 pm
by Mycael_
Hi
I am having problems making the risc-v co-processor to write in the RTC slow memory, outside of it's assigned program memory, I tried accessing it from normal variables using RTC_DATA_ATTR, RTC_SLOW_ATTR, RTC_NOINIT_ATTR, using a pointer to said variable, and using direct memory address, yet I can't seem to write anything on the RTC slow memory.
Am I missing something in accessing it, or is the access restricted to the risc-v program, an not variables outside of it?
Thanks in advance for any feedback!
Re: ESP32-S3 RISC-V memory access
Posted: Tue Dec 17, 2024 12:48 pm
by MicroController
Yeah, I guess that's how it works. The ULP program is not linked against the main application, so it doesn't know of any symbols there.
You can do one of two things: a) define the variables (only) in the ULP program (may be a bit fragile, i.e. wiped/overwritten when a ULP program is loaded), or b) let the main application pass the offset of the respective RTC variable(s) relative to the start of RTC RAM to the ULP at runtime. Could look like this: uint32_t* ulp_pointer = (uint32_t*)((uintptr_t)&main_app_rtc_variable - (uintptr_t)RTC_SLOW_MEM);
Re: ESP32-S3 RISC-V memory access
Posted: Tue Dec 17, 2024 5:34 pm
by Mycael_
Hi, thanks for answering.
Could you elaborate more please on the b) option, I'm more interested in that one?
Are you saying that i can create a pointer in the risc-v program, and the main program passes the offseted address to the pointer in the risc-v? If so, do i need to make anything else on the risc-v program or should I be able to use it directly without any problem?
I tried using them as is, but the variable doesn't seem to have any change, I also tried reseting the address that was passed and it still made no change to the variable's data.
Thanks again.
Re: ESP32-S3 RISC-V memory access
Posted: Tue Dec 17, 2024 6:53 pm
by MicroController
Are you saying that i can create a pointer in the risc-v program, and the main program passes the offseted address to the pointer in the risc-v?
Yes.
The point is that the ULP sees different addresses than the main CPU. For the ULP, memory address 0 is the start of the RTC slow RAM, while the same memory location is at some 0x6000... address to the main CPU.
You can convert a main CPU pointer into a pointer the ULP can use by subtracting the main CPU's RTC slow RAM start address.
Also, you should make all variables shared between the main CPU and the ULP
volatile or either program may miss values written by the other side.
Re: ESP32-S3 RISC-V memory access
Posted: Wed Dec 18, 2024 10:46 am
by Mycael_
Thank you!! It worked.
Even after doing what you were telling me, I couldn't make it work, was already giving up on it, but then i tried passing the offset variable to the pointer AFTER loading and starting the risc-v program, which I wasn't doing before, and it worked. The variable is being updated and nothing wrong is being picked up anymore.
Thank you for helping me!
Re: ESP32-S3 RISC-V memory access
Posted: Wed Dec 18, 2024 1:52 pm
by MicroController
Yes,
1. Load the ULP program
2. write all data/parameters it needs
3. start the ULP.
Not sure if __attribute__((noinit)) also works.
Re: ESP32-S3 RISC-V memory access
Posted: Thu Dec 19, 2024 10:41 am
by Mycael_
One more question, if i have a struct in my main.c, can i make a struct of pointers in the risc-v program to access the original struct variables with the same logic? Or do i need to make use of simple pointers to access the variables in the struct placed in the rtc memory?
If can make a struct of pointers, how do i call them from the main.c? Do I simply do
, assuming that it was declared in the risc-v as
Code: Select all
struct{uint32_t *var1; }my_struct;
, or is it different?
Re: ESP32-S3 RISC-V memory access
Posted: Thu Dec 19, 2024 2:27 pm
by MicroController
Not quite sure what you mean, but you can use the same struct type in both the main and the ULP code, e.g. by typedef'ing it in a header file which both programs #include; then only pass the (ULP-converted) pointer to the struct instance from main to ULP and use in the ULP like any other pointer-to-struct, i.e. my_struct* ptr; ... if( ptr->a != 0 ) { ptr->b = ptr->c + 1;}.
You do not need a dedicated pointer to each struct member.