SAMV71 how to execute function from ram (harmony 3, xc32 v4.00 compiler) SOLVED - Page 1
Forum section: electronics / general

author: Gabri74
author_rank: Regular Contributor
timestamp: July 08, 2024, 04:40:02 pm
content: Hi all, I could use some help because I'm really struggling hereI've a project based on the SAMV71Q21B, built using MPLAB-X and Harmony 3 for BSP and drivers code generation.The problem is that I can't figure out how to run a function from ram (I need to read the unique ID from flash and the access must be done from ram because whenaccessing that specific flash controller register no code can be fetched from flash).Moreover, all the examples and responses on github or forums that I've found refer to GCC compiler, not XC32, and the linker scripts and startup code are quite different for the two:- in the GCC linker script there is a 'relocate' region defined, but not on the XC32 linker- in the GCC startup code there is the relevant memory initialization code that copies the relocate section to ram, but not on the XC32 startup version- in the XC32 startup version there is a call to a '__pic32c_data_initialization()' which I suspect could be the one that copies the relocatable code, but it's a closed library function so I can't tell.I've started adding this attribute in front of the relevant function:Code:__attribute__ ((ramfunc,section(".ramfunc"),long_call, unique_section,noinline)) void utils_base_unique_id(uint8_t *uid){ [READ ID FROM FLASH CODE] }but when compiling a get a bunch of errors I don't understand, it seems like the linker is moving other unrelated code to the relocate section:Code:/opt/microchip/xc32/v4.00/bin/bin/../../lib/gcc/pic32c/8.3.1/../../../../bin/bin/pic32c-ld: Link Warning: attributes for input section '.RAMFUNC$.__stub' conflict with output section '.RAMFUNC$'/opt/microchip/xc32/v4.00/bin/bin/../../lib/gcc/pic32c/8.3.1/../../../../bin/bin/pic32c-ld: section .text.CLK_MainClockInitialize%449 LMA [004a264c,004a26df] overlaps section .text.sys_init%448 LMA [004a25b4,004a2657]/opt/microchip/xc32/v4.00/bin/bin/../../lib/gcc/pic32c/8.3.1/../../../../bin/bin/pic32c-ld: section .bss.resp.13237%53 VMA [20420e7c,20420f03] overlaps section .RAMFUNC$ VMA [20420dec,20420e8f]Link Error: can't load section .RAMFUNC$ contents/opt/microchip/xc32/v4.00/bin/bin/../../lib/gcc/pic32c/8.3.1/../../../../bin/bin/pic32c-ld: BFD (Microchip xc32 v4.00) 2.32.0.20190703 internal error, aborting at /data01/build/bamboo/xml-data/build-dir/M32DEV-BGT38-JOB1/src/gcc-8-merge/binutils/bfd/elf32-pic32c.c:324 in bfd_pic32_process_data_sectionI've tried to add the missing relocate section to my linker script (copied from the gcc script) but I get a similar but different error:Code:/opt/microchip/xc32/v4.00/bin/bin/../../lib/gcc/pic32c/8.3.1/../../../../bin/bin/pic32c-ld: Please report this bug./opt/microchip/xc32/v4.00/bin/bin/../../lib/gcc/pic32c/8.3.1/../../../../bin/bin/pic32c-ld: Link Warning: attributes for input section '.data.uxCriticalNesting' conflict with output section '.relocate'/opt/microchip/xc32/v4.00/bin/bin/../../lib/gcc/pic32c/8.3.1/../../../../bin/bin/pic32c-ld: Link Warning: attributes for input section '.ramfunc.utils_base_unique_id.__stub' conflict with output section '.relocate'/opt/microchip/xc32/v4.00/bin/bin/../../lib/gcc/pic32c/8.3.1/../../../../bin/bin/pic32c-ld: section .dinit%204 LMA [00485610,0048773f] overlaps section .relocate LMA [00484390,0048561f]/opt/microchip/xc32/v4.00/bin/bin/../../lib/gcc/pic32c/8.3.1/../../../../bin/bin/pic32c-ld: section .text.CLK_MainClockInitialize%414 LMA [004a38cc,004a395f] overlaps section .text.sys_init%413 LMA [004a3834,004a38d7]/opt/microchip/xc32/v4.00/bin/bin/../../lib/gcc/pic32c/8.3.1/../../../../bin/bin/pic32c-ld: section .bss.ucHeap%1 VMA [20401a80,2040ba7f] overlaps section .relocate VMA [20400800,20401a8f]Link Error: can't load section .data.uxCriticalNesting contents/opt/microchip/xc32/v4.00/bin/bin/../../lib/gcc/pic32c/8.3.1/../../../../bin/bin/pic32c-ld: BFD (Microchip xc32 v4.00) 2.32.0.20190703 internal error, aborting at /data01/build/bamboo/xml-data/build-dir/M32DEV-BGT38-JOB1/src/gcc-8-merge/binutils/bfd/elf32-pic32c.c:324 in bfd_pic32_process_data_section/opt/microchip/xc32/v4.00/bin/bin/../../lib/gcc/pic32c/8.3.1/../../../../bin/bin/pic32c-ld: Please report this bug.Does anyone have a sample code for th V71 or another SAM using XC32 and running a function from ram?Any help really appreciatedAttached my startup code (vanilla) and my slightly modified linker script with the ramfunc section added commented out (renamed to TXT because .ld is not allowed)

author: ataradov
author_rank: Super Contributor
timestamp: July 08, 2024, 05:48:25 pm
content: It is in the XC32 compiler manual. You need to use __ramfunc__ , not just the attribute because XC32 uses a customized linker.

author: SiliconWizard
author_rank: Super Contributor
timestamp: July 08, 2024, 09:29:08 pm
content: Quote from: ataradov on July 08, 2024, 05:48:25 pmWhich I found out the hard way at some point when I was working with PIC32. I was expecting it to just be binutils ld, with the usual parameters. But their customized linker takes additional parameters, from what I remember.

author: ataradov
author_rank: Super Contributor
timestamp: July 08, 2024, 09:31:10 pm
content: It takes a lot of random stuff that arguably does not need to be there. But one thing it has over the standard ld is the flowaround placement. You can fix some functions/variables to some addresses and the rest will be freely placed.

author: Postal2
author_rank: Frequent Contributor
timestamp: July 08, 2024, 10:16:29 pm
content: Quote from: Gabri74 on July 08, 2024, 04:40:02 pmHow do you plan to do this?Code:my_clever_ram_func(){call(interrupts_in_flash);call(readbyte_func_in_flash);call(outstring_func_in_flash);......}

author: ataradov
author_rank: Super Contributor
timestamp: July 08, 2024, 10:33:22 pm
content: What is this code?Reading UID on this device is a pretty standard procedure. A ramfunc with disabled interrupts is a standard way to do that. The only issue here is that XC32 requires a proprietary way of placing things in SRAM instead of a standard section attribute.

author: Postal2
author_rank: Frequent Contributor
timestamp: July 08, 2024, 10:43:29 pm
content: Quote from: ataradov on July 08, 2024, 10:33:22 pmI would be very glad to see your code.I know what needs to be done. But the right advice can turn into long-term training, which I don’t want.

author: ataradov
author_rank: Super Contributor
timestamp: July 08, 2024, 10:46:39 pm
content: Code:__longramfunc__ void read_uid(uint32_t *uid){uint32_t *flash = (uint32_t *)IFLASH_ADDR;__disable_irq();EFC->EEFC_FMR |= EEFC_FMR_SCOD;EFC->EEFC_FCR = EEFC_FCR_FKEY_PASSWD | EEFC_FCR_FCMD_STUI;while (EEFC_FSR_FRDY == (EFC->EEFC_FSR & EEFC_FSR_FRDY));for (int i = 0; i < 4; i++)uid = flash;EFC->EEFC_FCR = EEFC_FCR_FKEY_PASSWD | EEFC_FCR_FCMD_SPUI;while (0 == (EFC->EEFC_FSR & EEFC_FSR_FRDY));EFC->EEFC_FMR &= ~EEFC_FMR_SCOD;__enable_irq();}On 32 bit platforms it must be __longramfunc__. More of the XC32 nonsense.

author: Postal2
author_rank: Frequent Contributor
timestamp: July 08, 2024, 10:52:23 pm
content: Quote from: ataradov on July 08, 2024, 10:46:39 pmOkay. This can be done by loading to flash with labels on begin and end, then dynamically load to predefined rwx-region and run.

author: ataradov
author_rank: Super Contributor
timestamp: July 08, 2024, 11:01:56 pm
content: You would have to somehow generate a position independent code, what is not trivial. You can't take arbitrary code from the flash and copy it into the RAM and just run it.Plus compilers supported ramfuncs since forever, so there is no real point in doing it manually.

author: Postal2
author_rank: Frequent Contributor
timestamp: July 08, 2024, 11:12:51 pm
content: Quote from: ataradov on July 08, 2024, 11:01:56 pmNot right. See my example in topic below, where linker fills data. It can be done from code also by function address.Quote from: ataradov on July 08, 2024, 11:01:56 pmWhy fill the RAM with unnecessary junk that runs once. This is bad form.

author: SiliconWizard
author_rank: Super Contributor
timestamp: July 09, 2024, 12:39:30 am
content: Quote from: ataradov on July 08, 2024, 11:01:56 pmUnless said function is located at a fixed address in RAM, and has been put in the corresponding section in the linker script. Then you don't need PIC?Of course, that requires reserving a fixed area in RAM just for this.Quote from: ataradov on July 08, 2024, 11:01:56 pmWhat does "ramfunc" do exactly?

author: Postal2
author_rank: Frequent Contributor
timestamp: July 09, 2024, 01:01:39 am
content: Quote from: SiliconWizard on July 09, 2024, 12:39:30 amSee above,ataradovkindly showed. Only r/w of registers and store string to RAM. Size of function is several bytes. Possible set label before return to assign size of function from code.

author: ataradov
author_rank: Super Contributor
timestamp: July 09, 2024, 01:13:54 am
content: Quote from: SiliconWizard on July 09, 2024, 12:39:30 amMy comment was about temporarily relocating things to flash. Worrying about a few bytes of RAM on a device with 380K seems silly to me. And then you can also put that function at the bottom of the stack space and call it at the beginning of the program when this area is not used. Later it will be overwritten by the stack, of course.Quote from: ataradov on July 08, 2024, 11:01:56 pmIt physically places the code in the flash, but links it in a way that it could be executed from SRAM. It is placed in the .data section, so it is relocated to SRAM at the same time as initialized variables.Doing that manually does not make any sense to me.

author: Postal2
author_rank: Frequent Contributor
timestamp: July 09, 2024, 01:19:46 am
content: Quote from: ataradov on July 09, 2024, 01:13:54 amAnd if I show how simple it is, will you change your mind?

author: ataradov
author_rank: Super Contributor
timestamp: July 09, 2024, 01:22:36 am
content: Quote from: Postal2 on July 09, 2024, 01:19:46 amNo, why would I? There is a well established method that works perfectly well.

author: Postal2
author_rank: Frequent Contributor
timestamp: July 09, 2024, 01:30:49 am
content: Quote from: ataradov on July 09, 2024, 01:22:36 amThen teach your method to the topic author. This will prove how good this method is, especially for him.

author: ataradov
author_rank: Super Contributor
timestamp: July 09, 2024, 01:40:22 am
content: I already provided everything that is necessary. There is nothing else. All you need to do is put __longramfunc__ in front of the function. Compiler does the rest.

author: Postal2
author_rank: Frequent Contributor
timestamp: July 09, 2024, 01:58:05 am
content: Quote from: ataradov on July 09, 2024, 01:40:22 amYes, it's really simple. Then let's wait for "Hurray, it's working" from the author of the topic.

author: Gabri74
author_rank: Regular Contributor
timestamp: July 10, 2024, 08:24:08 am
content: Quote from: ataradov on July 08, 2024, 10:46:39 pmHi ataradov, thanks a lot for the quick response, apologize for the late reply on my side.This is the exact same code I wrote initially, but I got an error when using __longramfunc__ because it's not defined.Grepping though all the code finally found that it's defined in xc32/v4.00/pic32c/include/newlib/sys/attribs.hI then tried adding 'sys/attrib.h' to the includes and also literally coping the __longramfunc__ definition into my code, but I get the exact same error as my first post:Code:/opt/microchip/xc32/v4.00/bin/bin/../../lib/gcc/pic32c/8.3.1/../../../../bin/bin/pic32c-ld: Link Warning: attributes for input section '.RAMFUNC$.__stub' conflict with output section '.RAMFUNC$'/opt/microchip/xc32/v4.00/bin/bin/../../lib/gcc/pic32c/8.3.1/../../../../bin/bin/pic32c-ld: section .text.CLK_MainClockInitialize%449 LMA [004a264c,004a26df] overlaps section .text.sys_init%448 LMA [004a25b4,004a2657]/opt/microchip/xc32/v4.00/bin/bin/../../lib/gcc/pic32c/8.3.1/../../../../bin/bin/pic32c-ld: section .bss.resp.13237%53 VMA [20420e7c,20420f03] overlaps section .RAMFUNC$ VMA [20420dec,20420e8f]Link Error: can't load section .RAMFUNC$ contents/opt/microchip/xc32/v4.00/bin/bin/../../lib/gcc/pic32c/8.3.1/../../../../bin/bin/pic32c-ld: BFD (Microchip xc32 v4.00) 2.32.0.20190703 internal error, aborting at /data01/build/bamboo/xml-data/build-dir/M32DEV-BGT38-JOB1/src/gcc-8-merge/binutils/bfd/elf32-pic32c.c:324 in bfd_pic32_process_data_sectionCould it be that I need to enable some buried option/flag in the project build options to solve this ?Also I'm not using TCM/ITCM, could it be that not using those memories also (wrongly) disables some relocation linker behavior ?

author: Gabri74
author_rank: Regular Contributor
timestamp: July 10, 2024, 09:19:51 am
content: SOLVED! Thanks everyone for the helpIn the end was a missing option in the project compiler options.I needed to enable'Use indirect calls'Sorry, probably this was obvious for anyone but MPLAB is a relative new environment for me.I'll attach a screenshot for the option for future reference.Maybe a little more helping error message from the linker could have saved me some headache