从RAM而不是flash运行代码块

时间:2018-06-11 10:18:09

标签: c embedded microcontroller flash-memory nxp-microcontroller

在以下程序中,代码行的含义是什么

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

在下面的代码部分。我对这里发生的事情有一些了解,为了克服读取违反写入,使用上面的代码行将代码从闪存复制到RAM。但这些线的确切含义是什么。

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
}

需要在RAM中的唯一代码是:

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 :(得分:2)

这看起来像旧的恩智浦(前飞思卡尔/摩托罗拉)HCS08,HCS12或Coldfire。在这些设备上,编写闪存驱动程序时有不同的情况:要么可以从闪存执行,要么不能。这完全取决于哪个"银行"程序闪存属于:通常你不能从它当前正在编程的闪存库中执行MCU上的代码。

理想情况下,您将闪存编程代码放在另一个库中,但有些设备只有一个闪存库。然后,他们通过执行RAM中的代码来提供解决方案,这是一种快速和简单的方法。肮脏的修复。

通常他们通过提供一组原始数据操作码来解决这个问题。这个操作码数组被复制到RAM,然后它们设置一个指向RAM地址的函数指针。我怀疑fnRAM_code是一个这样的函数指针。 (volatile unsigned char *)FLASH_STATUS_REGISTER部分只是传递闪存状态寄存器的地址。可能,FLASH_STATUS_REGISTER与FSTAT同义。

uDisable_Interrupt();uEnable_Interrupt();应分别对应asm SEIasm CLI,阻止所有可屏蔽中断在闪存写入期间触发,这可能会导致写入失败或挂断的程序。

应该有应用说明可以详细描述所有这些。

请注意,此代码非常接近硬件,并依赖于大量定义不明确的行为。除了Codewarrior编译器之外,我不会指望它按照预期进行编译。例如,gcc会发出许多严格的别名错误。

相关问题