How to write a regular program in ccs

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to support@ccsinfo.com

View previous topic :: View next topic
Author Message
naughty_mark

Joined: 29 Aug 2012
Posts: 97

write_program_memory function and bootloader questions
Posted: Sun Sep 09, 2012 8:09 pm
Hi, guys.

Because last week, with some people help, I know currently ccs doesn't support auxiliary flash memory quite well.
So this week, I just put my bootloader code in main flash memory, and did another main program(LED blinking) demo code. In the demo code I used #org 0x10000 which means I want to compiler generate the code which can only put them after address 0x10000, and once I downloaded my bootloader code which will occupy 0x200 to 0xFFFF, I send the demo code by RS232.
I am using dsPIC33EP256MU814 with CCS v4.133
my question is, once I got lines of hex code such as

Code:

:080000000000040001000000F3
:020000040002F8
:10000000C1E8A8000E2EEF001E2EEF002E2EEF00EE

Joined: 20 Jul 2010
Posts: 1329

Posted: Sun Sep 09, 2012 8:27 pm
Type

Intel hex file format

into Google and do the search and a wikipedia page should pop up that completely describes how the file is formatted.

The big things to watch for are:

1. I think the file gives you addresses formatted at the byte level and PIC24/dsPIC33 are at word level, so you need to make the translation of the address correctly. It's easy to figure out by doing a #org on a line of code, then look at it in the hex file and see the address the hex file produces. I want to say, you need to divide by 2, but I haven't looked in ages.

2. There are a few hex file format lines that change the upper 16 bits part of the address and don't actually have code.

3. Don't assume that the hex file will always give you code in address order. I have had a couple of files where addresses are out of order.

EDIT:
For example, take the excerpt from your hex file:

Code:

:020000040002F8
:10000000C1E8A8000E2EEF001E2EEF002E2EEF00EE

Joined: 29 Aug 2012
Posts: 97

Posted: Sun Sep 09, 2012 8:52 pm
Thanks jeremiah, actually I opened wiki page and check my hex file to see if I can understand. I didn't notice data type 04 too much, I just see type 00, and thought the two byte address is the absolute address that will put in, that's why I got confused. After you explain, I think I can understand, and I will interpret the hex file again and check if my code can also interpret it right when it read that info. Thanks.

Joined: 29 Aug 2012
Posts: 97

Posted: Sun Sep 09, 2012 9:51 pm
Do we have any software which can read out the hex code in micro and display it with alignment of address?
I used the MPLAB bootloader code, it can fit the data type 04 automatically and looks fine. However, after I program in the hex file and read it out, I can not get the same result (only once I got).

Code:

void WriteHexRecord2Flash(/*unsigned int8 * HexRecord, */unsigned int8 totalHexRecLen)
{
static T_HEX_RECORD HexRecordSt;
unsigned int8 Checksum = 0;
unsigned int8 i;
unsigned int32 WrData;
unsigned int32 ProgAddress;
unsigned int8 Result;
unsigned int32 nextRecStartPt = 0;


while(totalHexRecLen>=5) // A hex record must be atleast 5 bytes. (1 Data Len byte + 1 rec type byte+ 2 address bytes + 1 crc)
{
// HexRecord = &HexRecord[nextRecStartPt];
HexRecordSt.RecDataLen = uartRecvInfo[1];//HexRecord[0 + 1];
HexRecordSt.RecType = uartRecvInfo[4];//HexRecord[3 + 1];
HexRecordSt.Hex_Data = &uartRecvInfo[5];//&HexRecord[4 + 1];

//Determine next record starting point.
nextRecStartPt = HexRecordSt.RecDataLen + 5;

// Decrement total hex record length by length of current record.
totalHexRecLen = totalHexRecLen - nextRecStartPt;

// Hex Record checksum check.
Checksum = 0;
// for(i = 1/*0*/; i < HexRecordSt.RecDataLen + 5; i++)
// {
// Checksum += uartRecvInfo[i];//HexRecord[i];
// }
//
// if(Checksum != 0)
// {
// //Error. Hex record Checksum mismatch.
// }
// else

// Hex record checksum OK.
switch(HexRecordSt.RecType)
{
case DATA_RECORD: //Record Type 00, data record.
HexRecordSt.Address.byte_dw.MB = 0;
HexRecordSt.Address.byte_dw.UB = 0;
HexRecordSt.Address.byte_dw.HB = uartRecvInfo[2];//HexRecord[1];
HexRecordSt.Address.byte_dw.LB = uartRecvInfo[3];//HexRecord[2];

// Derive the address.
HexRecordSt.Address.Val = HexRecordSt.Address.Val + HexRecordSt.ExtLinAddress.Val + HexRecordSt.ExtSegAddress.Val;

while(HexRecordSt.RecDataLen) // Loop till all bytes are done.
{

// Convert the Physical address to Virtual address.
ProgAddress = (HexRecordSt.Address.Val/2);
// ProgAddress = (HexRecordSt.Address.Val);

// Make sure we are not writing boot area and device configuration bits.
if(((ProgAddress < AUX_FLASH_BASE_ADRS)
else
{
memcpy(&WrData, HexRecordSt.Hex_Data, 4);
}
// Write the data into flash.
// Result = NVMemWriteWord(ProgAddress, WrData);
write_program_memory(ProgAddress,WrData,4);
// Assert on error. This must be caught during debug phase.
// ASSERT(Result==0);
}

// Increment the address.
HexRecordSt.Address.Val += 4;
// Increment the data pointer.
HexRecordSt.Hex_Data += 4;
// Decrement data len.
if(HexRecordSt.RecDataLen > 3)
{
HexRecordSt.RecDataLen -= 4;
}
else
{
HexRecordSt.RecDataLen = 0;
}
}
break;

case EXT_SEG_ADRS_RECORD: // Record Type 02, defines 4th to 19th bits of the data address.
HexRecordSt.ExtSegAddress.byte_dw.MB = 0;
HexRecordSt.ExtSegAddress.byte_dw.UB = HexRecordSt.Hex_Data[0];
HexRecordSt.ExtSegAddress.byte_dw.HB = HexRecordSt.Hex_Data[1];
HexRecordSt.ExtSegAddress.byte_dw.LB = 0;
// Reset linear address.
HexRecordSt.ExtLinAddress.Val = 0;
break;

case EXT_LIN_ADRS_RECORD: // Record Type 04, defines 16th to 31st bits of the data address.
HexRecordSt.ExtLinAddress.byte_dw.MB = HexRecordSt.Hex_Data[0];
HexRecordSt.ExtLinAddress.byte_dw.UB = HexRecordSt.Hex_Data[1];
HexRecordSt.ExtLinAddress.byte_dw.HB = 0;
HexRecordSt.ExtLinAddress.byte_dw.LB = 0;
// Reset segment address.
HexRecordSt.ExtSegAddress.Val = 0;
break;

Joined: 20 Jul 2010
Posts: 1329

Posted: Sun Sep 09, 2012 10:02 pm
If you mean just read the hex file aligned, then the CCS IDE does that. If you mean read the data off of the micro itself after being programmed, then CCSLoad does, but it is for the programmers from CCS. If you are using a different programmer, you might see if they have an option to read code from a PIC.

Joined: 29 Aug 2012
Posts: 97

jeremiah wrote:
If you mean just read the hex file aligned, then the CCS IDE does that. If you mean read the data off of the micro itself after being programmed, then CCSLoad does, but it is for the programmers from CCS. If you are using a different programmer, you might see if they have an option to read code from a PIC.

Thanks, Jeremiah.
I just tried a simply code below

Code:

s = "1234";
iniBootloader();

Joined: 20 Jul 2010
Posts: 1329

Posted: Mon Sep 10, 2012 6:30 am
A call to read_program_memory() and then print it out could help show if the data got written.

Joined: 29 Aug 2012
Posts: 97

jeremiah wrote:
A call to read_program_memory() and then print it out could help show if the data got written.


Thanks Jeremiah, I tried the way you suggest, by popping out the data in the memory via LCD or RS232, both of them are failed, I can not get correctly result. (if the string just contains four bytes, then it looks ok, but if more, looks not good. ) I even tried to use MPLAB example which is using its built_in function "tblwtl" (I write with asm for those operation, not sure if they are correct), and it doesn't work. feel really bad.
The code below is using ccs built in function ,write it and read back, I just tried write one byte, it failed. The content displayed on screen via RS232 is "the result" even the word "is" is not showed!

Code:

unsigned int32 WrData;
s= "abcd";
memcpy(&WrData, s, 4);

Joined: 29 Aug 2012
Posts: 97

Code:

unsigned int32 WrData,RdData;
s="abcdefg";
s1 = "zyxwvu";
//memcpy(&WrData, s, 4);

Joined: 20 Jul 2010
Posts: 1329

Posted: Mon Sep 10, 2012 4:55 pm
you still have string size issues. You are writing / reading 7 characters but not adding a null terminator to what you read back. Though I would expect plain garbage instead of all FFs

Code:

erase_program_memory(0x00010000);

before your write_program_memory() call. Maybe it isn't calling the erase for some reason.


I know write_program_memory() works fine on PIC24 and at least some of the dsPIC33Fs that I have at work. I just tested it today. For your particular pic I am unsure. I don't have one to test against with my normal test program.

Joined: 06 Sep 2003
Posts: 21708

Posted: Mon Sep 10, 2012 4:59 pm
You never answered Jeremiah's question about 's' and 's1'.

I don't see that you have legal code in your program.
Do it like this. Then it's legal:

Code:

void main(void)
{
int8 s[8] = "abcdefg";
int8 s1[8] = "zyxwvu";

Joined: 20 Jul 2010
Posts: 1329

Posted: Mon Sep 10, 2012 5:03 pm
Also, you aren't writing/reading in multiples of 4, and you aren't making every 4th byte 0x00. So the write_program_memory() might not be executing at all.

EDIT:
Try this test program. Don't use a bootloader, just load this directly to the PIC. I tried using the settings you provided from your previous thread, but change the fuses, pin_select, use delay(), and use rs232() to fit your current configuration.

Code:

#case
#include

#use delay(clock=20000000) // Actual crystal is 20M
#pin_select U1TX = PIN_D0
#pin_select U1RX = PIN_D1
#use RS232(UART1, STREAM=GSM, BAUD=9600, BITS=8, STOP=1, PARITY=N, ERRORS)


void main(){
unsigned int8 data_to_write[] = {0x01,0x02,0x03,0x00};
unsigned int8 data_read[sizeof(data_to_write)];

//erase_program_memory(0x00010000); //shouldn't need this line
write_program_memory(0x00010000,data_to_write,4);
delay_ms(1000);
read_program_memory(0x00010000,data_read,4);

Joined: 29 Aug 2012
Posts: 97

PCM programmer wrote:
You never answered Jeremiah's question about 's' and 's1'.

I don't see that you have legal code in your program.
Do it like this. Then it's legal:

Code:

void main(void)
{
int8 s[8] = "abcdefg";
int8 s1[8] = "zyxwvu";

s and s1 are defined like

Joined: 20 Jul 2010
Posts: 1329

Posted: Mon Sep 10, 2012 5:40 pm
While
Code:

s="abcdefg";

will compile (at least it does in 4.135), it is bad code and will probably corrupt memory. You are essentially telling it to reassign your memory array pointer to the location of the constant string "abcdefg" and to no longer point to your buffer of 50 characters. I don't believe it is legal C to reassign an array name like a pointer to a new string (as PCM Programmer was pointing out), so that may be part of the issue.

Joined: 29 Aug 2012
Posts: 97

jeremiah wrote:
Also, you aren't writing/reading in multiples of 4, and you aren't making every 4th byte 0x00. So the write_program_memory() might not be executing at all.

EDIT:
Try this test program. Don't use a bootloader, just load this directly to the PIC. I tried using the settings you provided from your previous thread, but change the fuses, pin_select, use delay(), and use rs232() to fit your current configuration.

Code:

#case
#include

#use delay(clock=20000000) // Actual crystal is 20M
#pin_select U1TX = PIN_D0
#pin_select U1RX = PIN_D1
#use RS232(UART1, STREAM=GSM, BAUD=9600, BITS=8, STOP=1, PARITY=N, ERRORS)

Thanks for your great help, jeremiah. I put your test code in the main function, and comment out my code. The result is same:
Program Start
Write: 1 2 3 0
Read: ff ff ff 0

I know that the most significant byte should be 00, but I just want to test this built_in function, if I write in , then the first three bytes should be ok, the fourth will be 0x00 or 0xFF, however, my code or you code gives the same result that even the first three bytes are not written correctly~

By the way, is there any written protection in software config or hardware config?(except NVMKEY sequence).
I just add erase program before the write in your test code, same result

And because auxiliary flash memory can not be compiled by ccs, so my "bootloader" code actually is the normal code, put into the main flash memory. Just my demo main program(blink LED) code will be compiled from 0x10000 address. So my "bootloader" code actually is normal

CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Goto page 1, 2 Next
Page 1 of 2