Helpful ReplyHot!bootloader for PIC24FJ128GC010

Page: < 12 Showing page 2 of 2
Author
DPerez
Junior Member
  • Total Posts : 77
  • Reward points : 0
  • Joined: 2014/01/15 00:26:02
  • Location: 0
  • Status: offline
Re: bootloader for PIC24FJ128GC010 2018/04/10 04:02:58 (permalink) ☄ Helpfulby aliaskappa 2018/04/10 04:32:13
5 (1)
Hello aliaskappa,
On the surface, it seems to be right, but deep down I cannot assure you anything, because I am not able to test it by myself, and I normally program dual memory devices which change a little bit the procedure.

The only thing that I saw "bizarre" is that you are trying to write in one address that could be written by your current program, so just try another one further away from the beginning of the memory (i.e., 0x12000)... I do not have many hopes about this will work, but who knows!

Another important thing is to erase before writting, so just keep that in mind.

If these pieces of advice do not work, you have to figure out how to do it on your own (asking anyone else, seeking around the forum), since this step will be a must later!

I hope this helps.
 
Best regards.
Daniel.
post edited by DPerez - 2018/04/10 04:06:13
#21
aliaskappa
New Member
  • Total Posts : 17
  • Reward points : 0
  • Joined: 2017/10/25 06:07:08
  • Location: 0
  • Status: offline
Re: bootloader for PIC24FJ128GC010 2018/04/11 02:23:39 (permalink)
5 (1)
Good news!! I tested this little program to erase, write and read the program memory of my PIC
IT WORKED!!!!

 
/*
* File: BL_main.c
*
*/
 
#include "xc.h"
#include "string.h"
 
#define FCY 8000000UL
#include <libpic30.h>
 
unsigned int readWordL;
unsigned char readByteH;
unsigned int writeWordL=0x0000;
unsigned char writeByteH=0x00;
 
unsigned int count;
 
#define numberofbyte 512
unsigned char read1[numberofbyte];
unsigned char read2[numberofbyte];
unsigned char read3[numberofbyte];
 
//this function erase a block of program memory (512 istruction => 1536 bytes) from the specified address
void erase_program_memory_row(unsigned long progAddr,unsigned int offset){
//for erasing
//Set up pointer to the first memory location to be written
NVMCON = 0x4042; // Initialize NVMCON
TBLPAG = progAddr>>16; // Initialize PM Page Boundary SFR
offset = progAddr & 0xFFFF; // Initialize lower word of address
__builtin_tblwtl(offset, 0x0000); // Set base address of erase block with dummy latch write
__builtin_disi(5); // Block all interrupts with priority <7 for next 5 instructions
__builtin_write_NVM(); // check function to perform unlock sequence and set WR
}
 
//this function read a single istruction (3 bytes) at the specified address
void read_program_memory(unsigned long progADDR){
TBLPAG = ((progADDR & 0x7F0000) >> 16);
int addrOffset = (progADDR & 0x00FFFE);
 
readByteH = __builtin_tblrdh(addrOffset);
readWordL = __builtin_tblrdl(addrOffset);
}
 
//this function write a single istruction (3 bytes) at the specified address
void write_program_memory(unsigned long progAddr,unsigned int offset, unsigned char writeByteH, unsigned int writeWordL){
//for writing
//Set up NVMCON for word programming
NVMCON = 0x4003; // Initialize NVMCON
//Set up pointer to the first memory location to be written
TBLPAG = progAddr>>16; // Initialize PM Page Boundary SFR
offset = progAddr & 0xFFFF; // Initialize lower word of address

__builtin_tblwth(offset,writeByteH); // Write to upper byte
__builtin_tblwtl(offset,writeWordL); // Write to address low word
__builtin_disi(5); // Block all interrupts with priority <7 for next 5 instructions
__builtin_write_NVM(); // check function to perform unlock sequence and set WR

}
 
int main(void){

unsigned long address=0x12000;

//erase selected block
erase_program_memory_row(address,0);

//empty read buffers
memset((char *)&read1,0,sizeof(read1));
memset((char *)&read2,0,sizeof(read1));
memset((char *)&read3,0,sizeof(read1));

//first reading to check that the memory is empty(used with a breakpoint)
for(count=0;count<numberofbyte;count++)
{
read_program_memory(address+(count*2));
read1[count]=readByteH;
read2[count]=readWordL>>8;
read3[count]=(readWordL<<8)>>8;
}

//write the memory
for(count=0;count<numberofbyte;count++)
{
write_program_memory(address+(count*2),0,(writeByteH+count),(writeWordL+count));
// write_program_memory(address+(count*2),0,(writeByteH),(writeWordL)); //to write 512 times a specific istruction
}

count=0;

//empty read buffers
memset((char *)&read1,0,sizeof(read1));
memset((char *)&read2,0,sizeof(read1));
memset((char *)&read3,0,sizeof(read1));

//second reading to read the contents
for(count=0;count<numberofbyte;count++)
{
read_program_memory(address+(count*2));
read1[count]=readByteH;
read2[count]=readWordL>>8;
read3[count]=(readWordL<<8)>>8;
}

while(1){};


return 0;
}
 

 
to be honest it worked in these two cases:
unsigned long address=0x12000;

unsigned long address=0x00800;

and it did not work in these two:
unsigned long address=0x00500;

unsigned long address=0x00600;

I read the program memory before the writing process and it was full up to the address
0x004e8, then at the address 0x00500 the memory was empty...
writing later in the memory is not a problem, better leave some free space,
I was just curious about why it did not work ...
the next step will still be to understand the "Intel Hex" protocol (as recommended by you DPerez)
thanks
Daniele
#22
DPerez
Junior Member
  • Total Posts : 77
  • Reward points : 0
  • Joined: 2014/01/15 00:26:02
  • Location: 0
  • Status: offline
Re: bootloader for PIC24FJ128GC010 2018/04/11 08:28:36 (permalink) ☄ Helpfulby aliaskappa 2018/04/17 23:55:16
0
It seems that the "worst" tip worked after all!!! But you are right, it is weird that you are not able to write on addresses bellow 0x800 if your program is not as big as that length... but there has to be a reason (I do not remember if that happened to me before, I only remember having tons of problems there xD... But I will try to think deeper and report it whether I find out something).

Good job so far!! You are almost finished!! There are only a couple of steps left to end this!!
 
Best regards.
Daniel.
post edited by DPerez - 2018/04/11 12:45:15
#23
aliaskappa
New Member
  • Total Posts : 17
  • Reward points : 0
  • Joined: 2017/10/25 06:07:08
  • Location: 0
  • Status: offline
Re: bootloader for PIC24FJ128GC010 2018/04/17 02:44:56 (permalink)
0
Greetings to all!!!
An update:
I finally studied and understood the "Intel Hex" protocol and I was able to extract
information about the instructions and their respective memory addresses!!!
the bulk of things I understood simply by using wikipedia:
https://en.wikipedia.org/wiki/Intel_HEX
__/\____/\____/\____/\____/\____/\____/\____/\____/\____/\____/\____/\____/\____/\__
substantially each record with record-type=0x00 contains an instruction and its
address (only the lower 16 bits).Example:
:10040000afe020000e7f22000e01880000000000f7
: 10(n° of bytes in the data field) 0400(lower address)
00(Record type=data) afe020000e7f22000e01880000000000(data=the program code) f7(chk)
When the protocol wants to define a complete address it can set the upper bits of the
address by a record with record-type=0x04,in this case the address field is ignored
and the data field contains the upper bits of the address
:020000040002f8
: 02(n° of bytes in the data field) 0000(IGNORED)
04(Record type=Extended Linear Address) 0002(data=upper bits of the address) f8(chk)
the end of fw is identified by a record with record-type = 0x01
:00 0000(IGNORED) 01(Record type=end) FF(chk)
__/\____/\____/\____/\____/\____/\____/\____/\____/\____/\____/\____/\____/\____/\__
I have already implemented the read and write functions of the external FLASH memory,
now I would like to compile a simple fw(with a code offset), write it in the external
memory already "extract" from the intel protocol.
To continue I have to go back to a problem that I have not solved yet...
1)in this discussion it is said: "To get a compiler to generate code for the device,
you will need to tell it to put code at the 0×800 offset, otherwise"
of course...the space required for the bootloader must be left in memory!!! how??????????

I tried to use some linker's options... I tried to configure PICkit 3 for manual memory
and range selection (http://microchipdeveloper.com/pickit3:select-memory-to-program)...
I believe that I'm missing something...sad: sad
 
Daniele
#24
DPerez
Junior Member
  • Total Posts : 77
  • Reward points : 0
  • Joined: 2014/01/15 00:26:02
  • Location: 0
  • Status: offline
Re: bootloader for PIC24FJ128GC010 2018/04/17 07:03:45 (permalink) ☄ Helpfulby aliaskappa 2018/04/17 23:54:56
0
Hello aliaskappa,

Perhaps the last piece you need to complete the puzzle are the GLD files, which are meant to define the microcontroller's memory distribution. I am attaching one from one specific PIC24FJ, because I have not found any for yours (something that does not really matter, you will see why). Read it carefully, and keep in mind the "#ifdef __BOOTLOADER" label, which is actually the key to achieve two memory allocations.

This should be the solution to your standoff, and if not, here I will be in order to try to help you as well as I can.

Best regards.
Daniel.
post edited by DPerez - 2018/04/17 07:05:00
#25
aliaskappa
New Member
  • Total Posts : 17
  • Reward points : 0
  • Joined: 2017/10/25 06:07:08
  • Location: 0
  • Status: offline
Re: bootloader for PIC24FJ128GC010 2018/04/17 23:54:51 (permalink)
0
Thank you so much Dperez!!
I will look at the GLD files even if I would have preferred other methods, such as directives for the linker...
the Gld files, in fact, seem to be a more convenient and quick method!
For now I am content to succeed, one day I will think a more custom solutionmr green: mr green
I also promised myself that, when I will be successful in my purpose, I will write a small guide on how to take the first steps in the bootloder...but first I have to finish !!!mr green: mr green
#26
aliaskappa
New Member
  • Total Posts : 17
  • Reward points : 0
  • Joined: 2017/10/25 06:07:08
  • Location: 0
  • Status: offline
Re: bootloader for PIC24FJ128GC010 2018/04/18 03:58:03 (permalink)
0
the first part was a success!
I recovered from mla libraries the  hid_boot_p24FJ128GC010.gld and by modifying 
program (xr)   : ORIGIN = 0x1938,         LENGTH = 0x13EBE
I added an offset to the program memory which now starts at address 0x1938
(I have also changed the address by being careful to change the length)
finish of the first part....
 
I noticed something strange with IVT addresses...
with the gld file they had disappeared!!!!!!!
 
I did another (strange) attempt...I captured the original gld file while the compiler was compiling, and 
by modifying the same program (xr)   : ORIGIN = 0x1938,         LENGTH = 0x13EBE
I still managed to get the same offset and the IVT was still there (I attached the file) but I haven't been able to move  the IVT (or AIVT) in any way. IT's possible?
 
what about these?
ivt              : ORIGIN = 0x4,    LENGTH = 0xFC
_reserved   : ORIGIN = 0x100, LENGTH = 0x4
aivt            : ORIGIN = 0x104, LENGTH = 0xFC
__CODE_BASE = 0x200;
__CODE_LENGTH = 0x155F8;
__IVT_BASE = 0x4;
__AIVT_BASE = 0x104;
 
Daniele
 
post edited by aliaskappa - 2018/04/18 05:42:56
#27
DPerez
Junior Member
  • Total Posts : 77
  • Reward points : 0
  • Joined: 2014/01/15 00:26:02
  • Location: 0
  • Status: offline
Re: bootloader for PIC24FJ128GC010 2018/04/18 07:39:20 (permalink) ☄ Helpfulby aliaskappa 2018/04/19 05:49:14
0
Hello aliaskappa,
It is much easier... or I understood wrongly your explanation, that I believe so.

Anyway, I have just downloaded the latest version of the MLA so that I could be able to help you better, and I found the GLD that ought to be modified in order to achieve the new memory allocations (see the attached gld file).

Once you have selected your blocks (both bootloader and application), by including this file to your own project, the original one which is taken from the compiler route will be ignored (see the attached picture).

Another tip that could be useful is that I always avoid using interrupts on the bootloader side, just because remapping them is trully a pain in the neck.

I hope these clues could help!
 
Best regards.
Daniel.
post edited by DPerez - 2018/04/18 07:48:39

Attached Image(s)

#28
aliaskappa
New Member
  • Total Posts : 17
  • Reward points : 0
  • Joined: 2017/10/25 06:07:08
  • Location: 0
  • Status: offline
Re: bootloader for PIC24FJ128GC010 2018/04/19 05:47:14 (permalink)
0
good morning DPerez,
mmmmm I think I didn't understand ...
 
do I simply have to compile separately the bootloader using the gld you posted with a "#define  __BOOTLOADER" and my application using the gld you posted without a "#define  __BOOTLOADER"?
 
Daniele
post edited by aliaskappa - 2018/04/19 05:59:25
#29
DPerez
Junior Member
  • Total Posts : 77
  • Reward points : 0
  • Joined: 2014/01/15 00:26:02
  • Location: 0
  • Status: offline
Re: bootloader for PIC24FJ128GC010 2018/04/19 23:33:32 (permalink)
0
Hello aliaskappa,
Exactly, but apart from the "#define  __BOOTLOADER", you will have also to customize the memory referred to the "program (xr)" label for both bootloader and user application (according to your specifications). Once you finishes this, you will have to come back to old replies, where you attached already a link to preserve memory.
 
If you do not do that, the "Make and Program Device Main Project" button will erase the whole device, and the bootloader part will not exist anymore causing serious consequences in the device behaviour. Later, after ending this (programming bootloader and the application preserving memory), you will be able to update the device by your own user applicacion as many times as you want to!
 
I hope this helps.
 
Best regards.
Daniel.
 
post edited by DPerez - 2018/04/19 23:36:20
#30
Page: < 12 Showing page 2 of 2
Jump to:
© 2018 APG vNext Commercial Version 4.5