Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

[SOLVED] Write/Read a data byte in program memory of PIC using address of the C code saved

Status
Not open for further replies.

Sherry1

Member level 3
Joined
Apr 4, 2013
Messages
61
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,286
Location
Manchester, UK
Activity points
1,810
Hi,

I am using PIC18F27J13 and it does not support internal EEPROM. I need to store a data byte ( basically a simple flag in my C code) into non-volatile memory, so that when microcontroller is switched off, then my flag is retained and i read and edit it during execution. Since I dont have internal EEPROM so I want to store the data in program memory.
So far I know the function that i can use to copy the byte from program memory to data memory ( RAM) is memcpypgm2ram (a,b,c) and string.h extension in my code.
I am using MPLAB IDE v 8.87 and C32 compiler.

Can anybody help me how do I find the addresses in program memory which contain the code. So that I use the unimplemented/unused part of the memory and put my data there? I could not find any guide in MPLAB User guide
 

Your Compiler is C32 or C18?

The addresses will be in the hex file. This might help you. https://www.kanda.com/blog/microcontrollers/pic-microcontrollers/pic-hex-file-format/

Thanks for your reply, It is C32 compiler.
This link shared above says for PIC18 HEX files "User ID: These are bytes for the user to store data,...."
This means I can store my data byte ( my flag byte) at this address since i dont need any code version for now and access it in runtime?
 
Last edited:

You mean you will get the value of flag from that address? Yes, it can be accessed at runtime. How come PIC18F device comes under C32 Compiler?
 

Apart from .HEX file I am also checking .MAP file created by the compiler. And also by going in the main MPLAB window View-> Program memory.
They all list down the instructions and the addresses occupied. Can anybody please help me, how do i make sense from all of these sources?

The link jayanth.devarayanadurga shared refers to addresses which are 3 bytes e.g. 200000h , but in :BBAAAATT[DDDDDDDD]CC format, the [AAAA] part is only 2 bytes. What address does it exactly refer to?
Similarly in Program memory window the address is again 2 byte long but in .MAP file all data is stored and corresponding addresses are mentioned as 3 bytes e.g. 0x000f71

How do i extract information about what place is safe to store my data byte so that it doenst corrupt with the program??
 
Last edited:

What is the purpose of using PIC18F27J13? Can't you change your PIC to a better one with eeprom?

- - - Updated - - -

What is the purpose of using PIC18F27J13? Can't you change your PIC to a better one with eeprom?

See the first line of hex in the link I gave.

:B B AAAAD D D D D D D D D D D D D D D D CC
:100000003C932014BBE0AD7A3EAC4D261FB267A4F2

B B
1000 (Taken as 0X10 = 16 Decimal Bytes)

AAAA = 0x00

D D D D D D D D D D D D D D D D
3C932014BBE0AD7A3EAC4D261FB267A4


No. of Bytes + Address + Data =

0x10 + 0x00 + 0x3C + 0x93 + 0x20 + 0x14 + 0xBB + 0xE0 + 0xAD + 0x7A + 0x3E + 0xAC + 0x4D + 0x26 + 0x1F +

0xB2 + 0x67 + 0xA4

= 0x70E

= 11100001110
00011110001 (invert)
+ 1
CC = F2

Maybe it should be

:B B A A D D D D D D D D D D D D D D D D C
:100000003C932014BBE0AD7A3EAC4D261FB267A4F2

------------------------------------------------------------------------------------------------------------------------------------------------------------------------

address = 0x0000 data bytes = 0x10

:100000003C932014BBE0AD7A3EAC4D261FB267A4F2

address = 0x0001

:100010008121F4C2D641A503B6038C9932A36EBCEC

address = 0x0002

:10002000D204306AE84404FCE8C7452DE0BE3160E4

address = 0x0003

:100030005CC6E94D3F4E62765AC237EAD3C2895157

eeprom extended address

:0200000400F00A

eeprom no. of bytes + data + checksum
0x10 bytes, 0x00 means all data = 0xFF, checksum = 0x00
eeprom address = 0x0000
:10000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00 (checksum should be 1 but shown as 0, maybe checksum not

used for eeprom data)

if there were another line of eeprom data then it would be
address = 0x0003, 0x00 = all data, data = 0xFF (16 bytes) + checksum, like below
:10000300FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00

configuration bytes extended address line

:020000040030CA


:1000000000270F0F0083F500FFC0FFE0FF400000C5

User ID extended address line

:020000040020DA

:080000000102030405060708D4

EOF marker
:00000001FF

address is actually written as 0x000, 0x001, 0x002, 0x003 in the hex data in that link I shared.

This might help you. https://en.wikipedia.org/wiki/Intel_HEX
**broken link removed**
https://www.pjrc.com/tech/8051/pm2_docs/intel-hex.html


Edit: there was a mistake in my explanation of address field. The address are like 0x0000, 0x0010, 0x0020, 0x0030...

address stsrts at 0x0000. 16 bytes = 0x0000 to 0x000F (first line)

address second line 0x0010 to 0x001F :cool:
 

Attachments

  • hex file.txt
    591 bytes · Views: 78
  • hex file 2.txt
    800 bytes · Views: 83
Last edited:

Thanks for the explanantion. yes i too finally figured it out that it is 16 bytes per line.
I cant change the PIC because I am making few modifications in already implemented circuit.

My HEX fle ends like this
:0533D000424200000074
:020000040001F9
:01FFF800BE4A
:01FFFA00DC2A
:00000001FF


This HEX file shows that the code ends at address 0x033D0. This means that from this address to x1FFFF for PIC18F27J13 , all the memory space is free. MAP file of the same project also indicates that only 10% of the program memory is used. Do I need any specific permissions for accessing program memory at run time?

Secondly should i directly address the memory locations and use malloc()function? or memcpyram2pgm () for writing a byte??
 

You will be writing and reading your flag value from Program memory (Flash mem). Find some address which is free according to your hex file then In the code use flash read and write functions to get/set the flag value and use the address you choose as argument for flash read/write function. First write the flag read/write function with dummy address and Compile your code and get the a hex file and then choose your mem address and then use that address in your flash read/write code and then compile your final code. See if that works.


When you use flash read/write function and give some address it will use that address in flash for your purpose then why are you trying to find free address looking at hex file? If you use flash read and write then it will use the program memory (flash) for your purpose.
 
I checked the code of ReadFlash and WriteBytesFlash in flash.h but they write on EEPROM which probably wont work . As a test I tried following code
Code:
rom near unsigned char con_flag;
static byte CheckState;
char *a = &con_flag;
memcpypgm2ram ((void*)&CheckState, (const rom void*)con_flag, sizeof(byte));
if ( CheckState == 0x01){
		return TRUE;
		}
	else {
		return FALSE;
		}
For setting the flag =1 in ROM, I use follwoing sequnce
Code:
CheckState = 0x01;
memcpyram2pgm ((rom void*)con_flag, (void*)&(CheckState), sizeof(byte));

so now when for the very first time the microcontroller reads the byte ( the flag) , its some random value. And so my code returns FALSE, and executes some set of instructions and at the end of it, it sets CheckState=1 , that will be written to con_flag residing in program memory even when the microcontroller is switched off and turned back ON ...

- - - Updated - - -

This is basically my purpose that I want to achieve. There are some configuration settings required for the very first time when the module is used. The microcontroller is supposed to execute some instructions and then at the end, set the flag for itself indicating that the attached module is configured. Every next time when microcontroller is turned On , it will check that flag, and finding that its already set, it will skip those instructions.
That is why I am reading the rom byte first and writing on it later in the code. It is not giving syntax error but not executing the instructions
 

Hey jayanth.. the code didnt work because i realise it will initiate a new variable con_flag everytime when microcontorller is set ON . so i lose my flag that i created before. so now i am trying flash.h functions..
Code:
unsigned char CheckState = 0;
ReadFlash(0x07070, 1,(unsigned char *) CheckState);
		            if ( CheckState != 0x01 ){ // modem NOT_CONFIGURED
					//execute instructions to
		
				//Change Configuration Flag
				CheckState = 0x01;
				WriteBytesFlash ((0x07070, 1, (unsigned char *) CheckState));
This is giving follwoing error : "Error [1203] too few arguments in function call" , Although i am giving right number of arguments and using right conversion (unsigned char*). Is this right implementation?? Please help
Also 0x07070 is far from 0x033D0 so even if i add a couple of lines, this will not overlap with the code. And it is also not towards the end of program memory. This is why i just chose this address. What configuration bits i need for switching off write/read protection??
 

Can you post the document where the Flash library function(s) usage is explained? I think ReadFlash takes only 1 parameter that is address.

**broken link removed**

I think you are using Hi-Tech C Flash functions? Does it work in C32 if flash.h is included?


Code C - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
unsigned char CheckState;
 
 
ReadFlash(0x07070, 1, &CheckState);
 
if ( CheckState != 0x01 ){ // modem NOT_CONFIGURED
               //execute instructions to
        
    //Change Configuration Flag
    CheckState = 0x01;
    WriteBytesFlash(0x07070, 1, &CheckState);
 
}

 
Last edited:
Well i added #include <flash.h> and then right click -> Open file "flash.h" and trusted the explanation given in the header file. I am using pic18 header files and it has been working fine so i guess C32 supports it?

Code:
extern void ReadFlash(unsigned long startaddr, unsigned int num_bytes, unsigned char *flash_array);

#endif

#if defined (FLASH_V1_1) || defined (FLASH_V1_2) || defined (FLASH_V1_3) || defined (FLASH_V1_4) \
	|| defined (FLASH_V1_5) || defined (FLASH_V1_6) || defined (FLASH_V2_1)

extern void EraseFlash(unsigned long startaddr, unsigned long endaddr);

extern void WriteBlockFlash(unsigned long startaddr, unsigned char num_blocks, unsigned char *flash_array);

extern void WriteBytesFlash(unsigned long startaddr, unsigned int num_bytes, unsigned char *flash_array);

#if defined (FLASH_V2_1)
extern void WriteWordFlash(unsigned long startaddr, unsigned int data);
#endif
 
Last edited:

Read my last post. It is updated.

Try this also


Code C - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
unsigned char CheckState;
unsigned char *ptr2CheckState = &CheckState;
 
 
ReadFlash(0x07070, 1, *ptr2CheckState);
 
if ( CheckState != 0x01 ){ // modem NOT_CONFIGURED
               //execute instructions to
        
    //Change Configuration Flag
    CheckState = 0x01;
    WriteBytesFlash(0x07070, 1, *ptr2CheckState);
 
}




Edit:

My second code is wrong and please discard it. You have to use the code in my previous post.

The function prototype clearly shows that the 3rd argument to the functions are a pointer and a pointer expects a left-value. So, you have to pass left-value or address of a variable as the 3rd argument.
 
Last edited:

Its solved!!

Yes the code that you posted first works perfectly well. :) Thanks a bunch :)

I chose 0x07070 address randomly. In MPLAB, after 'Building All', I went to View-> Program Memory and found that last ASM code is written till 0x033D0 which is cognate with the information from the .HEX file of the project. Now I could pick any address after 0x033D0..

Just for the sake of discussion, could I declare a 'rom' variable and then a volatile pointer in the code which points to this non-volatile variable?? Because I thought it was not possible considering that every time the code is executed it will run the following line
Code:
rom near unsigned char CheckState;
and then create a new variable in ROM . Am I correct?

Thanks a lot again!!!
 
Last edited:

Status
Not open for further replies.

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top