CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

const data and write_program_memory() on PIC24

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
allenhuffman



Joined: 17 Jun 2019
Posts: 588
Location: Des Moines, Iowa, USA

View user's profile Send private message Visit poster's website

const data and write_program_memory() on PIC24
PostPosted: Fri Jan 03, 2025 12:41 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Sat Jan 04, 2025 4:43 am     Reply with quote

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

View user's profile Send private message Visit poster's website

PostPosted: Sat Jan 04, 2025 5:52 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Sun Jan 05, 2025 2:21 am     Reply with quote

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

View user's profile Send private message Visit poster's website

PostPosted: Sun Jan 05, 2025 9:47 am     Reply with quote

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.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
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