This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Erase main memory while running from RAM

Other Parts Discussed in Thread: MSP430F2112

Hello Everyone,

I am attempting to create firmware which is capable of over writing the main code (in the flash memory) with new code. After doing some research among these forums, I decided to use the method where some code (flash erase/write ect) is copied into the RAM and executed there, in order to erase code memory. Using the example code found here: http://e2e.ti.com/support/microcontrollers/msp430/f/166/p/72156/262251.aspx#262251 I was able to create code which can be executed from RAM. However, when erasing segments of the main memory, the code running in the RAM does not continue to execute. This general idea of the RAM executed code is shown below. The processor used is an MSP430F2112.

// Function which has previously been copied to RAM.
#pragma CODE_SECTION(ram_funct,".FLASHCODE")
void ram_funct(void)
{

// Set test LED1.
P3OUT |= 0x04;

// Erase segments of main code
ram_erase(0xF800);     // Works fine

ram_erase(0xF900);    // Works fine

ram_erase(0xFA00);     // Problem here - debugger cannot continue to step through

// Set Test LED2.

P3OUT |= 0x08;            // Line never reached, LED2 NOT set.

// Since there is now no code in code memory, loop here in RAM forever.

while (1)
{
__no_operation();
}

}

 note: ram_erase is another function located in RAM.

My understanding is that this code should continue to run even after all the flash code is erased, since it is running from RAM, which it does not appear to do.

I also am curious as to how I would execute new code once it is copied into the code memory. Would some sort of reset be needed? Or is it possible to jump to the first line of the new code, at the end of the RAM executed function?

Any insights would be greatly appreciated.
- Jake 

  • Hi Jake,

    Could you post the code of ram_erase? The problem is most likely inside.

    For your questions, you would first need to set the reset vector to the new code start and then jump to it directly ((void (*)())NEW_CODE_ADDRESS)();.

  • Hi Mohamed,

    Thank you for your response, the code used in the ram_erase function is posted below. I did not think it would be a problem since this code has worked elsewhere.

    #pragma CODE_SECTION(ram_erase,".FLASHCODE")
    void ram_erase(uint16_t location)
    {

    // Disable interrupts.
    __bic_SR_register(GIE);
    uint8_t * flashPointer;

    flashPointer = (uint8_t *) location;

    // Clear the lock bit.
    FCTL3 = FWKEY;

    // Set the erase bit.
    FCTL1 = (FWKEY | ERASE);

    // Dummy write to initiate erase.
    *flashPointer = 0;

    __delay_cycles(5000);
    // Clear WRT.
    FCTL1 = FWKEY;

    // Lock the flash from writes.
    FCTL3 = (FWKEY | LOCK);

    // Enable interrupts.

    __bis_SR_register(GIE);
    }

     

    Also, I am not quite sure how to set the reset vector to the new code, is this achieved by altering the interrupt vector table or something similar?

    Thank You,
    Jake 

  • Well, I don't really know how the flash controller work (I mostly worked with FRAM) but here are a few things to check:
    • debug the blocking function call and see exactly at what line you lose debug control
    • also, to be on the safe side check the BUSY flag after the dummy write (to be sure the erase operation is finished)
    • maybe it is because you didn't stop the WDT before?
    • I saw that there is a mass erase instead of a segment erase, this would be easier for you to handle I guess? It would be good to try it out and compare

    You are right for the reset vector, you can directly write to the interrupt vector table. If you don't do it, your reset vector will most likely point to the old code location (which is erased) and thus create a lock condition in case of reset.
  • I have tried each of these methods you suggested and still can't see where the problem is. However, I have noticed that these functions behave correctly if i erase memory which is not running any code on it. For instance, if the code copied to RAM (before it's copied) is located at 0xE000 and the bulk of the code is 0xE100, if i erase 0xE200 it behaves correctly. If I erase 0xE000 or 0xE100 the problem occurs, do you think this could be an issue with the code not actually running from RAM? Is there a way to determine whether it is running from RAM or flash? 

    I attempted what you said for the restarting the code with the reset vector and it appeared to work perfectly, thank you for that!

    Thank You,
    Jake 

  • Jake Verry said:
    If I erase 0xE000 or 0xE100 the problem occurs, do you think this could be an issue with the code not actually running from RAM?

    Very likely. If it executes from flash and you erase the flash where it is executing from, then you can imagine what happens once teh flash content is gone...

    Jake Verry said:
    Is there a way to determine whether it is running from RAM or flash? 

    A breakpoint at the beginning? Or even single-stepping into it (but don't single-step once a write operation starts, as the debugger doesn't like it :) )

  • After paying close attention to the current code address location in the debugger, while stepping through it, I noticed the ram_funct was running from RAM, however the ram_erase function was not. Turns out the erase function did not match the name specified in the pragma (I changed the names before posting here to make it easier to follow, making the mistake unnoticeable). This caused the erase function to run from flash, making it crash while attempting to erase itself - silly mistake by me!

    After placing the erase function into RAM correctly, everything worked exactly as I had hoped!

    I also have one last question, how would I actually get the flash data needed for a firmware update, to be sent the msp430? Would it be necessary to program one with the new updated code, then read/copy its flash and use this data to send to the msp430 being updated? or is there an easier method?

    Thank You,
    Jake 

  • Jake,

    I am not sure what you are asking with this question?  Can you be more specific or give me an example?

    Cheers,
    Darren

    Jake Verry said:

    I also have one last question, how would I actually get the flash data needed for a firmware update, to be sent the msp430? Would it be necessary to program one with the new updated code, then read/copy its flash and use this data to send to the msp430 being updated? or is there an easier method?

  • Hi Daren, 
    Since I am attempting to update firmware via a USCI peripheral (such as UART), I need to send data (the new updated firmware for the msp430) via UART to the msp430, which the msp430 then copies to its flash and executes. I am unsure as to how to get the data needed to send via UART, ie the data to be written to the flash of the msp430 in order to update the firmware. When compiling firmware, only a .out file is produced, is there a method to convert this file into data to be sent to the msp430? or something similar?

    I hope this is a bit a clearer.

    Thank You,
    Jake 

  • Jake,

    You can have CCS to generate binary files.

    http://processors.wiki.ti.com/index.php/Generating_and_Loading_MSP430_Binary_Files

    You may need to write or find a utility to read the binary file and send it a comm port. With a usb-uart module connecting your PC to your target MCU setup.

  • Hi Christopher,

    That was exactly what I needed, worked like a charm!

    Thank You everybody for the help,

    Jake

**Attention** This is a public forum