Monday, September 1, 2014

Bootloader for PIC24E

I`m making a bootloader for the PIC24E device. The device I use is an PIC24EP128GP004. The idea is that I will place the bootloader at the end of the flash area, not at the beginning. This way, I avoid remapping all of the interrupt sources and thus very little changes I've to make to the *.GLD file.

The PIC24EP I use, is equipped with two CAN bus controllers on my PCB (So NO on-board CAN). From one of this external CAN controllers, the bootloader must be able to communicate and receive new firmware if available. The CAN bus controller is of the type MCP2515.

About the micro controller

The FLASH area addressing starts from 0x0 to 0x015800 for the 128kb device. This means the total available pages on this device is 42 (1024*3*42=129024 bytes). Please note that these 24EP devices have 0x400 instructions in a single page, not 0x200 like the 24FJ series. This means 3072 bytes or 3kb for a single page for the PIC24EP series.

I will reserve 2 pages for the bootloader. So I will use the following layout;
  • Page 0 to 39 dedicated for user application
  • Page 40 and 41 dedicated for bootloader
  • Page 42 dedicated for configuration fuses
By dedicating the configuration fuses, it will still be possible for the bootloader to change the configuration fuses if needed. e.g. if you want to be able to change the code protection with the bootloader. Please note this is a choice of me, not a requirement of microchip. This choice will come at a price that you will waste 1 entire page since it cannot be used by the bootloader nor user application.

Scratchpad below

Using code:
            nvmAdru = __builtin_tblpage(&myRowData1InFlash[0]);
            nvmAdr = __builtin_tbloffset(&myRowData1InFlash[0]);
            nvmAdrPageAligned = nvmAdr & 0xF800; // Get the Flash Page Aligned address

Declared:

uint16_t myRowData1InFlash[] __attribute__((space(prog), address(0xFC00))) ;

Result

  • nvmAdru = 0x100
  • nvmAdr = 0xFC00
  • nvmAdrPageAligned = 0xF800

Declared

uint16_t myRowData1InFlash[] __attribute__((space(prog), address(0x10400)));

Result
  • nvmAdru = 0x101
  • nvmAdr = 0x400
  • nvmAdrPageAligned = 0x0
Declared

uint16_t myRowData1InFlash[] __attribute__((space(prog), address(0x11200))) ;

Result
  • nvmAdru = 0x101
  • nvmAdr = 0x1200
  • nvmAdrPageAligned = 0x1000
Declared

uint16_t myRowData1InFlash[] __attribute__((space(prog), address(0x200))) = {

  • nvmAdru = 0x100
  • nvmAdr = 0x200
  • nvmAdrPageAligned = 0x0

The microchip PIC24EP simulator, when erasing a page, it only erases 0x100 addresses. In real world test, this is wrong, the same code will erase 0x800 addresses.





























No comments:

Post a Comment