Loader by CAN Protocol

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Loader by CAN Protocol

2,189 Views
JaimeR
Contributor III
 I am writing a code to reprogram a S08DZ60 by CAN protocol.
 If I send a specific CAN command, the program goes to a function called
 BootLoad where it will stay in order to receive all the bytes from the
 new program. This is the function:
 
 #pragma CODE_SEG DEF_BOOTLOADER
void BootLoad()
{
   int w,k;
   byte buff[]={0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D}; //ES EL ACKNOWLEDGE
   dword messageID = 0x1C; //Necesita ser la direccion de la MASTER CORTEX
   w = 0;
   CanFlag = FALSE;
   CAN1_SendFrameExt(messageID, DATA_FRAME, 1, buff);
   while(1)
   {
      if(CanFlag)
      {
          switch( CanMessage[ 0 ] )
          {
            case (0xB6):
                         IFsh1_EraseSector( MAKE_WORD( CanMessage[1],CanMessage[2] ) );
                         CAN1_SendFrameExt(messageID, DATA_FRAME, 1, buff);
                         CanFlag = FALSE;
                         break;
            case (0xB5):
                        for(k = 0; k < CanMessage[ 1 ] ; w++,k++)
                        {
                           ArrayToWrite[ w ] = CanMessage[k + 2];
                        }
                        CAN1_SendFrameExt(messageID, DATA_FRAME, 8, buff);
                        CanFlag = FALSE;
                        break;
            case (0xB7): WriteS19Line( w, ArrayToWrite, MAKE_WORD( CanMessage[1],CanMessage[2] ) );
                        w = 0 ;
                        CAN1_SendFrameExt(messageID, DATA_FRAME, 8, buff);
                        CanFlag = FALSE;
                        break;
            
          }
                    
      }
   }
}

void WriteS19Line( int Length, byte *Data, word Direccion)
{
    int k;
    for(k = 0; k < Length; k+=2, Direccion+=2)
    {
        IFsh1_SetWordFlash(Direccion, MAKE_WORD(Data[ k ],Data[ k+1 ]) );
    }
    
}

#pragma CODE_SEG DEFAULT
 
 
 The function is located in a protected Flash Memory segment as well as
 the Flash and CAN functions. This is the Memory map for my device:
 SECTIONS
    BOOTLOADER               =  READ_ONLY    0xF400 TO 0xFFAD;
    RELOC_VECT_TAB           =  READ_ONLY    0xF3C0 TO 0xF3FF;
    ROM                      =  READ_ONLY    0x1900 TO 0xF3BF;
    EEPROM                   =  READ_ONLY    0x1400 TO 0x17FF;
    RAM                      =  READ_WRITE   0x00A0 TO 0x107F;
    Z_RAM                    =  READ_WRITE   0x0080 TO 0x009F;
 END

PLACEMENT
    DEFAULT_RAM                         /* non-zero page variables */
                                        INTO  RAM;
    DEFAULT_ROM, ROM_VAR, STRINGS       INTO  ROM;
    _DATA_ZEROPAGE,                     /* zero page variables */
    MY_ZEROPAGE                         INTO  Z_RAM;
    DEF_BOOTLOADER                      INTO  BOOTLOADER;
    DEF_VECT_TAB                        INTO  RELOC_VECT_TAB;
END

 The problem is that the CAN comunication gets lost when I erase sector
 0x1900 to 0x1C00. I am running out of ideas and I really need help with
 this project. I am using Freecale CAN bean and Internal Flash bean. I located
 the code from these beans in DEF_BOOTLOADER using  #pragma CODE_SEG DEF_BOOTLOADER.
 Why is my program failing if I am not writing or erasing CAN or/and Flash Routines
 and those routines are not located in the sectors where I am writing/erasing?
 
Labels (1)
0 Kudos
6 Replies

377 Views
peg
Senior Contributor IV
Hi Jaime,

You can't execute from ANYWHERE in the flash array whilst you are erasing/programming ANYWHERE in the same array. Most devices only have one flash array so this means you must execute from RAM whilst you are actually doing the erase/programme.

There are hundreds of posts about this on this board, do a search for the many solutions available (including the one that has just come in now above yours here.

0 Kudos

377 Views
JaimeR
Contributor III
Thank you for your answer.
I've search and I've read a lot of information about this in the forums, however, only one application uses CAN, is not interrupt based and is not very different to what I'm doing in terms of memory file .prm
The other applications that use RAM  are not using interrupts  and still I believe my code is too long to be placed into RAM. What do you think? Does this mean that I will have to place the Flash code + the CAN code  in RAM?

Thanks in advanced

0 Kudos

377 Views
peg
Senior Contributor IV
Hi again,

Whilst I realise there is probably no CAN examples here the actually erase/programme part is well covered.
You cannot get past the first sentence in my original reply.
This thread shows how little code needs to be in RAM, you only need to switch to execution from RAM while the high programming voltage is connected to the array. Attempting other flash access during this time gives unpredictable results (usually bad). Whether you use interrupts or not is not significant although you must ensure an interrupt will not be triggered during the erase/programme period as it will cause flash accesses (the vector).

If your code is too long too put it in ram then shorten it or bad luck.
Sorry, but there is no way around this restriction except for use the EEPROM in your case or use an external memory device on SPI or I2C.

0 Kudos

377 Views
JaimeR
Contributor III
 Thank you for your time Peg, but as I already mentioned in my first post, I am using Freescale beans for IFlash memory.
 Of course this methods use RAM when writing to flash, therefore this is not the problem since I am never trying to read and write flash at the same time.
 When I said my code was long to place it in RAM I was thinking about the whole loader code. But as I mentioned the part where the loader writes flash is copied into RAM and all of my loader code is place in a
 protected area far from the memory I am erasing and rewriting.
Flash is working fine because when I erase and write memory that was not used by the user program, the loader continue to run fine.
All of the CAN routines are also placed in the same protected area, as well as the Flash routines. However I am missing something, thus I am erasing part of the loader (without knowing). Any helping tips? I'll appreciate any helping ideas. Thanks

Jaime

When deep debugging I found out that the compiler is using RTSHC08.C.o (ansiis.lib) and it is placing these functions into the memory I need to erase. Therefore, the question here is:
Is there any pragma or instruction to avoid jumping to libraries in specific functions?
I mean, can you specify the compiler to copy this instruction into your function instead of jumping to the library?

This is a very dumb example, but I hope it explains what I need to do:
//In ansiis.lib
void Increment(int & P)
{
   P++;
}

//In bootloader.c
void Function()
{
   int A = 1;
   Increment(A); 
}

I want the compiler to to this

void Function()
{
   int P = 1;
   P++; 
}

instead of this

void Function()
{
   int P = 1;
   JMP Increment; 
}



Message Edited by Jaime R on 2009-01-15 05:52 PM
0 Kudos

377 Views
JaimeR
Contributor III
Loader is working fine now. I manage the user application and the loader as different projects, therefore, the calls to ANSII libraries are located where the ROM is defined for each project, thus, avoiding accidental erase of a library used in loader code.
If anyone needs help with an application like this, message me and I will try to help you.

Jaime
0 Kudos

377 Views
TurboBob
Contributor IV
I will be implementing a USB bootloader for a JM60 mcu based on HID mode.  I recently came to the same conclusion:  that the bootloader must be a separate project in order to control the romspace in reasonable fashion.
 
I am working out the details of the interrupt vector redirection and address vectors between the app and boot, as the USB interrupt register will need to be shared.  As a consequence, the main app will need to use the USB code that is within the boot code.
 
I will start a thread when I get the software mostly complete.
 
Bob
0 Kudos