|
|
View previous topic :: View next topic |
Author |
Message |
allenhuffman
Joined: 17 Jun 2019 Posts: 588 Location: Des Moines, Iowa, USA
|
const data and write_program_memory() on PIC24 |
Posted: Fri Jan 03, 2025 12:41 pm |
|
|
Today I was messing around with some embedded ROM data. CCS help shows two ways to do it, and I am testing the "const" method:
Code: |
#device CONST=ROM // Needed to put tables in ROM.
...
const uint8_t segmentData3[] = // 16 bytes
{
0x00, 0x00, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00,
0x19, 0x83, 0xff, 0x00, 0x4d, 0x3f, 0xff, 0x00
};
|
The compiler allows me to access those bytes like normal:
Code: | for (int idx=0; idx<sizeof(segmentData3); idx++)
{
DEBUG_PRINTF ("%02x ", segmentData3[idx]);
}
DEBUG_PRINTF ("\r\n");
|
But I get a board crash/reset if I try to use that in write_program_memory().
I realize not all things are supported with ROM/const, and maybe memcpy() is one of them, since this crashes as well:
Code: | uint8_t buffer[sizeof(segmentData3)];
memcpy (buffer, segmentData3, sizeof(segmentData3));
for (int idx=0; idx<16; idx++)
{
DEBUG_PRINTF ("%02x ", buffer[idx]);
}
DEBUG_PRINTF ("\r\n");
|
My thought was I could move the const data into a RAM buffer then use the call with that buffer.
I expect there is a real simple solution to this, but the help files are less than helpful when it comes to ROM/const.
Tips appreciated.
have an existing firmware updater system I cannot change. It was based on how a "normal" app .hex file is created -- vector table, application, config bytes.
I created a new program that I want to upload but it has const ROM data which is separated from the code. Is there a way to make the ROM data be directly after the code? In my list file I see this:
Code:
15846: MOV [--W15],W6
15848: MOV [--W15],W5
1584A: RETURN
.................... }
....................
.................... // End of file
Configuration Fuses:
Word 1L: 3F5F WPOSTS16 WDT128 WINDIS NOWDT ICSP1 NODEBUG NOWRT NOPROTECT NOJTAG
H: 0000
Word 2L: 8319 XT IOL1WAY OSCIO CKSFSM PR_PLL IESO
H: 0000
Word 3L: FFFF WPFP WPDIS NOWPCFG WPEND
H: 0000
Word 4L: 0000
H: 0000
ROM data:
028FC2: 0000 0000 0000 0000 0000 00F3 03FF 0000 ................
028FCA: 0200 0000 0000 0004 0000 0000 0002 0000 ................
028FD2: D87B 0003 7800 0027 0000 0000 0044 0000 .{..x..'.....D..
I think if I could get the const ROM data to be right after the "1584A: RETURN" my loader would work with it.
Maybe.
This is the first time I've tried to use const ROM data so I am learning lots of fun new things.
_________________
Allen C. Huffman, Sub-Etha Software (est. 1990) http://www.subethasoftware.com
Embedded C, Arduino, MSP430, ESP8266/32, BASIC Stamp and PIC24 programmer.
http://www.whywouldyouwanttodothat.com ?
Using: 24FJ256GA106, 24EP256GP202 and 24FJ64GA002. _________________ Allen C. Huffman, Sub-Etha Software (est. 1990) http://www.subethasoftware.com
Embedded C, Arduino, MSP430, ESP8266/32, BASIC Stamp and PIC24 programmer.
http://www.whywouldyouwanttodothat.com ?
Using: 24FJ256GA106, 24EP256GP202 and 24FJ64GA002. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19587
|
|
Posted: Sat Jan 04, 2025 4:43 am |
|
|
Big problem you have is the two memories do not have the same layout.
You already know that the PIC24 program memory is not contiguous.
It runs:
byte
byte
byte
N/A
byte
byte
byte
N/A.....
Now the RAM memory doesn't have these gaps. So you cannot just run
bytes from one to the other.
The second problem is addresses. The two memory spaces are _separate_.
There is an address 0, on both spaces. Trying to write to an array
address will write to the wrong memory space. Memcpy writes to RAM.
Historically on the smaller PIC's there was another complexity that the
compiler puts an access routine in front of the actual data.
The way to get where a CONST table actually is, is to use 'label_address'.
Then you would have to modify your data to be written, to have every
fourth byte missing. Then you need to use a write_program_memory
function, not memcpy.
Now fortunately there is a 'trick' in the PIC24, to help with this. PSV.
This allows a window into the program memory to be viewed as if it
is inside RAM. The chip itself handles the 3/4 translation into this.
This thread is about this:
[url]
https://www.ccsinfo.com/forum/viewtopic.php?p=222348
[/url
Seriously, taking this thread, and the other you have launched at the
same time together, why not use ROM, instead of const?.
With ROM, you can specify 'where' the data is to be put. Solves the
address problem and the location one in one go. However you need to
be aware that when writing to program memory a whole page has to
be erased. Not a byte to a word. You need to read the whole page,
change the bytes you want and write the whole page back.
read_program_memory, and write_program_memory are the functions
to talk to the ROM.
I have appended your second port into this thread, since they both are
cross connected. |
|
|
allenhuffman
Joined: 17 Jun 2019 Posts: 588 Location: Des Moines, Iowa, USA
|
|
Posted: Sat Jan 04, 2025 5:52 pm |
|
|
Ttelmah wrote: | Big problem you have is the two memories do not have the same layout.
You already know that the PIC24 program memory is not contiguous.
It runs:
byte
byte
byte
N/A
byte
byte
byte
N/A.....
Now the RAM memory doesn't have these gaps. So you cannot just run
bytes from one to the other. |
The Harvard-architecture stuff I am familiar with from Arduinos, but the PIC24s way of having 2-bytes per address and the "every fourth byte is zero" stuff was a bit odd to me. Makes sense.
I ended up making a buffer of getenv("FLASH_WRITE_SIZE") then copying the const data into the buffer in a loop. (memcpy did not seem to work). Then I'd write those out.
This is not very optimized code, but enabled me to get it working:
Code: | bool WriteSegmentToFlash (uint32_t address, const uint8_t *dataPtr, uint32_t byteCount)
{
uint8_t buffer[getenv("FLASH_WRITE_SIZE")];
uint32_t bytesLeft = byteCount;
uint32_t offset = 0;
uint32_t bytesWritten = 0;
while (bytesLeft >= sizeof(buffer))
{
memset (&buffer[0], 0x0, sizeof(buffer));
for (int idx=0; idx<sizeof(buffer); idx++)
{
buffer[idx] = dataPtr[offset + idx];
}
write_program_memory (address, buffer, sizeof(buffer));
offset = offset + sizeof(buffer);
bytesLeft = bytesLeft - sizeof(buffer);
address = address + sizeof(buffer)/2;
bytesWritten = bytesWritten + sizeof(buffer);
}
if (bytesLeft > 0)
{
memset (&buffer[0], 0x0, sizeof(buffer));
for (int idx=0; idx<bytesLeft; idx++)
{
buffer[idx] = dataPtr[offset + idx];
}
write_program_memory (address, buffer, bytesLeft);
bytesWritten = bytesWritten + bytesLeft;
}
return true; // TODO: error checking.
}
|
As to using ROM, that would make sense. I was able to place const in specific locations using #org, as well, but I do not know which method would be preferred.
Ultimately, I may need to rewrite the firmware uploaded to handle multiple segments. That may be the root problem I should solve. _________________ Allen C. Huffman, Sub-Etha Software (est. 1990) http://www.subethasoftware.com
Embedded C, Arduino, MSP430, ESP8266/32, BASIC Stamp and PIC24 programmer.
http://www.whywouldyouwanttodothat.com ?
Using: 24FJ256GA106, 24EP256GP202 and 24FJ64GA002. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19587
|
|
Posted: Sun Jan 05, 2025 2:21 am |
|
|
Yes, it was a real step 'backwards' on the PIC24/30/33, that they went back
to having gaps in the ROM map.
Have a look at PSV. It really does simplify this stuff, and speeds up the
const accesses.
#DEVICE PSV=16 |
|
|
allenhuffman
Joined: 17 Jun 2019 Posts: 588 Location: Des Moines, Iowa, USA
|
|
Posted: Sun Jan 05, 2025 9:47 am |
|
|
Ttelmah wrote: | Yes, it was a real step 'backwards' on the PIC24/30/33, that they went back
to having gaps in the ROM map.
Have a look at PSV. It really does simplify this stuff, and speeds up the
const accesses.
#DEVICE PSV=16 |
CCS says they are working on an update to their ROM allocation routines, so that gives us something to look forward to.
I will look up PSV. Thanks for your tips, as always. You are appreciated. _________________ Allen C. Huffman, Sub-Etha Software (est. 1990) http://www.subethasoftware.com
Embedded C, Arduino, MSP430, ESP8266/32, BASIC Stamp and PIC24 programmer.
http://www.whywouldyouwanttodothat.com ?
Using: 24FJ256GA106, 24EP256GP202 and 24FJ64GA002. |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|