5
\$\begingroup\$

Wondering if anyone has tried running an entire program on a PIC32 out of RAM? How would one go about doing that. I understand that you can use the ramfunc keyword to move certain functions to RAM however they still require the copy to be on Flash.

What I would like to do is have a loader program on the PIC32 that can accept a hex file over the serial port etc and rather than writing it to flash have it run out of ram directly.

Ideally I was hoping that by modifying the default linker script you could target a program to run from RAM alternatively if anyone knows how we would patch up a program that was linked to run from flash to run from RAM that could work too

Thanks Mike

\$\endgroup\$
3

3 Answers 3

4
\$\begingroup\$

Both the longramfunc and ramfunc attributes place the function in a special area of flash that will be copied to RAM by the startup code. You don't want to use them.

For functions which will be called from flash, you want to use the longcall attribute which specifies that a 32-bit call (JALR) is needed instead of a 28-bit call (JAL), since flash and RAM are located in separate 512MB segments.

You will also need to set up a custom linker file with an executable RAM section, and include that section name on every function that is placed there.

The longramfunc macro also includes the longcall attribute, whereas the ramfunc macro does not, and is intended for calls from one RAM function to another. In your case, for functions called by other RAM functions, you do not want to use the ramfunc attribute because it sets up the copy from flash.

Since you will be copying the functions yourself (e.g. off of an SD card), you will need to include your own loader that interprets the hex code and copies the data to flash as needed.

\$\endgroup\$
2
  • \$\begingroup\$ Would it be possible to load a program into a fixed area in ram and just do a blind jump into the address zero of that range, assuming the hex file will have valid code at that point? \$\endgroup\$
    – captncraig
    Commented May 2, 2012 at 22:52
  • \$\begingroup\$ @CMP, yes you could do that by writing the jump in PIC32 assembly. I think it would be easier though to create a dummy function which would establish the linkage, and then it would be overwritten by the code actually loaded into RAM. \$\endgroup\$
    – tcrosley
    Commented May 2, 2012 at 22:59
1
\$\begingroup\$

You have three basic solutions to your problem of wanting to download programs to run after flashing the part.

  1. Use an interpreted language like Lua, Basic, or Forth. Write (or, more likely, just port) an existing virtual machine that interprets text instructions rather than machine code, and download the program as text. You have to reimplement your program in the interpreted language, but that's quicker and easier (in Lua especially) than writing it in C.
  2. Just get some extra storage and reflash the whole part. You haven't described what you're doing, so I can't know if this is applicable, but it's easy enough to add a serial Flash IC and/or microSD card with plenty of storage to your board and have the bootloader select a profile to run. At a Flash lifetime of 10,000 rewrites, this gives you 27 years of once-per-day reflashes.
  3. Do what you originally intended. This will require some careful programming (see tcrosley's answer for some methods required) and some fancy linker scripts. Good luck.

Largely adapted from my answer to 'Compiling code to run from external RAM'; a similar problem.

\$\endgroup\$
2
  • \$\begingroup\$ I've looked at using Lua on a micro. It's possible, but you do need a lot of RAM. I think they recommend something like at least 256k. \$\endgroup\$ Commented May 3, 2012 at 7:30
  • \$\begingroup\$ @Rocketmagnet - The recommendation is 64k, which is pretty common on the Cortex-M3, ARM7TDMI, and AVR32 platforms that eLua targets. It's also available on the PIC32 (but there's no port for PIC32 yet). It can be fit into 32k, but that doesn't leave you a lot of room for programs - remember that each character in a program is a byte. The actual RAM requirements for the standard libraries that load at startup are about 17k, but that can be reduced to less than 6k with the Lua Tiny RAM patch. \$\endgroup\$ Commented May 3, 2012 at 14:23
0
\$\begingroup\$

The easiest way to make library of DLLs that will be run from RAM one at the time - make a helper project, include in it some functions that will be run from RAM, (debug it on real hardware if needed), then make UART2 subprogram (in this helper project) that saves RAM in hex format from locations indicated by map file (generated by linker). Run this program on emulator and make it save RAM contents to file (it will be UTF8 coded, so convert it back to ascii). Here you are - the memory image of the first DLL is done. Your project may load this image from SD card and call first function (which should be the same i.e. not the body of function is the same but just declaration must be exactly the same, and at the same place in helper and in main project). Then you pass to that function pointer to the table of pointers to functions and other structures that functions in RAM may need to use from main program that resides in flash memory. Proceed with the rest of DLLs you need.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.