Forum Discussion

Altera_Forum's avatar
Altera_Forum
Icon for Honored Contributor rankHonored Contributor
20 years ago

Upgrading Nios Software - external flash

Dear all,

I would like to upgrade my NIOS code by RS232. The NIOS runs from external memory.

This is my procedure:

- I transfer the .elf file to the .flash file by the instruction elf2bin. (bin file for dowloading to the flash)

- I have a RS232 GUI from which I can send the bin file to the flash.

I have written a procedure which is stored in FPGA internal memory. This procedure receives the bin file from the UART and writes the data to flash.

(byte by byte)

Now, what is the problem: my problem is that my NIOS stops working from the moment I erase the flash sector in which the original NIOS code is stored. Nevertheless, the procedure that erases this sector is placed internal. And I keep running my code from internal memory untill the new nios bin file is stored in the flash.

The nios core is placed from 0x00000.

When I declare an instruction to be placed in internal memory.

ex following function is placed in internal memory

void test (void)

{

}

Will the instruction always be in internal memory or will it be placed in internal memory from the moment this instruction is called?

Has someone an idea what the problem is? Has someone experience with how to upgrade a NIOS that is running from external memory.

Regards

28 Replies

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    code for erasing flash sector

    void EraseFlashSector(unsigned int offset)

    {

    unsigned char i = 0;

    volatile char * CommandSeq1 = (char*)(FLASHCTRL_BASE + 0xaaa);

    *CommandSeq1 = 0xaa;

    volatile char * CommandSeq2 = (char*)(FLASHCTRL_BASE + 0x555);

    *CommandSeq2 = 0x55;

    volatile char * CommandSeq3 = (char*)(FLASHCTRL_BASE + 0xaaa);

    *CommandSeq3 = 0x80;

    volatile char * CommandSeq4 = (char*)(FLASHCTRL_BASE + 0xaaa);

    *CommandSeq4 = 0xaa;

    volatile char * CommandSeq5 = (char*)(FLASHCTRL_BASE + 0x555);

    *CommandSeq5 = 0x55;

    volatile char * CommandSeq6 = (char*)(FLASHCTRL_BASE + offset);

    *CommandSeq6 = 0x30;

    // wait for erase completion

    while(*CommandSeq6 != 0xffffffff){}

    }
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Hi Karel,

    Thanks for posting the code.

    Again, Does the nios hang _after_ EraseFlashSector returns, or within EraseFlashSector?

    Also ... <div class='quotetop'>QUOTE </div>

    --- Quote Start ---

    for(FlashAd = 0x0000000; FlashAd < 0x0140000; FlashAd += 0x0020000)

    {

    EraseFlashSector(FlashAd);

    }

    /* here my program fails. I erase the flash sector 0 (sector from which the nios is running from). The instruction "EraseFlashSector" is also placed in internal memory*/[/b]

    --- Quote End ---

    What do you mean by "PROGRAM FAILS"? Doesn&#39;t return? ... locks up? ... jumps to

    a bogus address? Have you looked at this with nios2-console?

    Regards,

    --Scott
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Where the program fails is difficult to define. I have written a routine that

    turns on some debug LEDs on my board. (this routine is also placed in internal memory)

    I can see that the LED instruction isn&#39;t executed after the sector erase.

    The question is: Is the routine always in internal memory or is it placed from external flash to internal memory after the function call.

    Regards

    Karel
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Hi Karel,

    > The question is: Is the routine always in internal memory or is it placed from

    > external flash to internal memory after the function call.

    In an earlier post you said you invoke ALT_LOAD_SECTION_BY_NAME(OnChipMem),

    which copies everything in the ".OnChipMem" section from its LMA to its VMA. So,

    your code should be where it needs to be. However, you should also call:

    alt_dcache_flush_all();

    alt_icache_flush_all();

    after loading the section. Otherwise, it&#39;s possible that some of code you intended to execute is still sitting in the dcache ... or some old code is still in the icache. Either

    way, you&#39;ll execute bogus instructions.

    Regards,

    --Scott
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Hey Scott,

    I indeed use the instructions ALT_LOAD_SECTION_BY_NAME.

    So, I&#39;m sure that my instruction is in internal memory.

    My first idea that the instruction is placed in internal memory after the

    function call by the main program is indeed not correct.

    Scott, you advise me to use also following instructions:

    alt_dcache_flush_all();

    alt_icache_flush_all();

    That&#39;s now for me. So, thanks Scott. I will try this. I will look up info about

    these functions and I hope that gives the solution.

    By the way, I have also posted my question to the Altera Support side. I&#39;m still

    waiting for a reaction of them. It seems to be a difficult problem :-)

    When I have found the solution, I will post it here.

    Karel
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    > By the way, I have also posted my question to the Altera Support side. I&#39;m

    > still waiting for a reaction of them.

    Call me crazy, but I would expect they&#39;ll need more information than you

    provided us here. /o

    > It seems to be a difficult problem

    You might find it less challenging if you use something more advanced than twiddling

    LEDs ... a debugger, perhaps. Regardless, I&#39;ll go out on a limb here (since there&#39;s not

    much to go on) and guess your EraseFlashSector code is broken -- and you&#39;re

    looping forever at:

    while(*CommandSeq6 != 0xffffffff){}

    Anyway, good luck!

    --Scott
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Scott,

    I have off course also used the debugger. I saw that after the sector erase

    the code goes on. So, the instruction after the sector erase is called.

    (also all the other following instructions) The only thing I can learn from

    the debugger is that they have no effect. That why I make use of LEDs, to see that the instructions have any result

    Regards

    Karel
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Maybe you already tried this, but did you checked if there is any exception running because of some unimplemented instruction? ... in that case you&#39;ll jump in flash also if interrupts are disabled...

    PJ