Запуск блока кода из оперативной памяти вместо флэш-памяти - PullRequest
0 голосов
/ 11 июня 2018

В следующей программе, что означает строка кода

fnRAM_code((volatile unsigned char *)FLASH_STATUS_REGISTER); // execute the command from SRAM

в следующем разделе кода.У меня есть представление о том, что здесь происходит. Чтобы преодолеть нарушение чтения во время записи, скопируйте код из флэш-памяти в ОЗУ, используя приведенные выше строки кода.Но каков точный смысл этих строк.

static int fnProgram(unsigned long *ptrWord, unsigned long *ptr_ulWord)
{
    while ((FTFL_FSTAT & FTFL_STAT_CCIF) == 0) {}                // wait for previous commands to complete

    if ((FTFL_FSTAT & (FTFL_STAT_ACCERR | FTFL_STAT_FPVIOL | FTFL_STAT_RDCOLERR)) != 0) { // check for errors in previous command 
        FTFL_FSTAT = (FTFL_STAT_ACCERR | FTFL_STAT_FPVIOL | FTFL_STAT_RDCOLERR); // clear old errors
    }

    FTFL_FCCOB0 = FCMD_PROGRAM;                                  // enter the command sequence
    FTFL_FCCOB1 = (unsigned char)(((CAST_POINTER_ARITHMETIC)ptrWord) >> 16); // set address in flash
    FTFL_FCCOB2 = (unsigned char)(((CAST_POINTER_ARITHMETIC)ptrWord) >> 8);
    FTFL_FCCOB3 = (unsigned char)((CAST_POINTER_ARITHMETIC)ptrWord);
    FTFL_FCCOB7_4 = *ptr_ulWord++;                               // enter the long word to be programmed
    FTFL_FCCOBB_8 = *ptr_ulWord;                                 // enter the second long word to be programmed
    uDisable_Interrupt();                                        // protect this region from interrupts
        fnRAM_code((volatile unsigned char *)FLASH_STATUS_REGISTER); // execute the command from SRAM
    uEnable_Interrupt();                                         // safe to accept interrupts again
    return (FTFL_FSTAT & (FTFL_STAT_ACCERR | FTFL_STAT_FPVIOL | FTFL_STAT_MGSTAT0)); // if there was an error this will be non-zero
}

Единственный код, который должен быть в ОЗУ, это:

static void fnFlashRoutineInRam(volatile unsigned char *ptrFTFL_BLOCK)
{
    *ptrFTFL_BLOCK = FTFL_STAT_CCIF;                                     // launch the command - this clears the FTFL_STAT_CCIF flag (register is FTFL_FSTAT)
    while ((*ptrFTFL_BLOCK & FTFL_STAT_CCIF) == 0) {}                    // wait for the command to terminate
}

1 Ответ

0 голосов
/ 11 июня 2018

Это похоже на более старый NXP (бывший Freescale / Motorola) HCS08, HCS12 или Coldfire.На этих устройствах у вас бывают разные случаи написания флеш-драйвера: либо вы можете запустить его из флеш-памяти, либо нет.Это полностью зависит от того, к какому «банку» относится флэш-программа: обычно вы не можете выполнить код на MCU из того же флэш-банка, который она в данный момент программирует.

Так что в идеале вы должны поместить код флэш-программирования в другой банк, но некоторые устройства имеют только один банк флэш-памяти.Затем они предоставляют обходной путь, выполняя код из ОЗУ, что является своего рода быстрым и грязным исправлением.

Обычно они решают эту проблему, предоставляя массив кодов операций с необработанными данными.Этот массив кодов операций копируется в RAM, а затем они устанавливают указатель на функцию, указывающую на адрес RAM.Я подозреваю, fnRAM_code такой указатель на функцию.Часть (volatile unsigned char *)FLASH_STATUS_REGISTER просто передает адрес регистра состояния флэш-памяти.Вероятно, FLASH_STATUS_REGISTER является синонимом FSTAT.

* uDisable_Interrupt(); и uEnable_Interrupt(); должны соответствовать asm SEI и asm CLI соответственно, блокируя все маскируемые прерывания от запуска во время флэш-записи, что потенциально может вызватьзапись для сбоя или зависания программы.

Должны быть доступны заметки приложений, подробно описывающие все это.

Обратите внимание, что этот код очень близок к оборудованию и использует тонныплохо определенного поведения.Я бы не стал рассчитывать на его компиляцию, как ожидалось, ни на что, кроме компилятора Codewarrior.gcc, например, будет выдавать множество ошибок строгого алиасинга.

...