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.

[参考译文] TMS570LS0914:F021闪存 API 会导致预取条目

Guru**** 2535750 points


请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/1022528/tms570ls0914-f021-flashapi-causes-prefetch-entry

器件型号:TMS570LS0914

您好!

我想使用 flashAPI F021 、我正在使用 SafeRTOS 操作系统。

我已经在链接器脚本中添加了 flashAPI 并配置了两个数据段:

flashAPI : RUN_START( FLASHAPI_Start ) RUN_END( FLASHAPI_End )
{
    */library/extern/FlashAPI/Fapi_UserDefinedFunctions.c.obj (.text)
    */library/source/Hardware/flashIf/flashTMS.c.obj (.text)
    --library = */library/extern/FlashAPI/F021_API_CortexR4_BE.lib (.text)
}load = FAPIFLASH, run = FAPIRAM, palign(0x1000), table(BINIT)

MEM_DATA_SEC_0 : START( MEM_DATA_SEC_0_Start ) END( MEM_DATA_SEC_0_End )
{
    --library = */library/extern/FlashAPI/F021_API_CortexR4_BE.lib <
                FlashStateMachine.ScaleFclk.obj
                FlashStateMachine.SetActiveBank.obj > (.data)
} > RAM palign( 0x2000 )

我要在其中使用 flashAPI 的任务在用户模式下运行。

根据 Cortex-R4F 技术参考手册第125和126页(ARM DDI 0363G、ID041111;第125-126/436页)、这两个 memsections 被配置为 MPU 部分

MEM_DATA_SEC_0:AP 位值 b011、XN 位值1、TEX[2:0]值0b000、C 位值0和 B 位值0

flashAPI :AP 位值 b011、XN 位值0、TEX[2:0]值0b000、C 位值0和 B 位值0

 

如果我尝试调试软件、在 RAM 段中执行的第一条指令会导致预取条目。 故障状态寄存器的值为0x0D。 此值为权限故障。

导致权限故障的函数:

Fapi_StatusType Fapi_BlockErase(uint32_t Bank, uint32_t Erase_Start_Address, uint32_t Size_In_Bytes)
{
    Fapi_StatusType error      = Fapi_Status_Success;
    uint8_t ucStartBank        = 0;
    uint8_t ucStartSector      = 0;
    uint8_t ucEndBank          = 0;
    uint32_t* eraseStartAddr0  = (uint32_t*)Erase_Start_Address;
    uint32_t* eraseStartAddr   = (uint32_t*)Erase_Start_Address;
    uint32_t Erase_End_Address = Erase_Start_Address + Size_In_Bytes;

    //Bestimme Startadresse des Sektors, welcher geloescht werden soll.
    for(uint8_t i = 0; i < SECTOR_TABLE_SIZE; i++)  //     for (i = 0; i < NUMBEROFSECTORS - 1; i++) 23.02.2018 mkh
    {
        if(Erase_Start_Address == (uint32_t)(SectorTable[i].dwStartAddr))
        {
            ucStartBank     = SectorTable[i].bankNumber;
            ucStartSector   = SectorTable[i].sectorNumber;
            eraseStartAddr0 = SectorTable[i].dwStartAddr;
            eraseStartAddr  = SectorTable[i].dwStartAddr;
            break;
        }
    }

    //Bestimmt bank des Sektors, welcher geloescht werden soll.
    for(uint8_t j = ucStartSector; j < SECTOR_TABLE_SIZE; j++)
    {
        if(Erase_End_Address < ((uint32_t)(SectorTable[j].dwStartAddr) + SectorTable[j].length))
        {
            ucEndBank = SectorTable[j].bankNumber;
            break;
        }
    }

    if(error == Fapi_Status_Success)
    {
        //F021_CPU0_REGISTER_ADDRESS is defined as 0xfff87000 in FMC.h
        //Fapi_initializeAPI((Fapi_FmcRegistersType *)F021_CPU0_REGISTER_ADDRESS, freqInMHz); /*used for API Rev1.5*/
        error = Fapi_initializeFlashBanks(HCLK_FREQ); /* used for API Rev2.01 */
    }

    for(uint8_t bk = ucStartBank; (bk < (ucEndBank + 1u)) && (error == Fapi_Status_Success); bk++)
    {
        uint8_t k;
        uint32_t remaining;
        error = Fapi_setActiveFlashBank((Fapi_FlashBankType)bk);

        if(bk == 0u)
        {
            k         = ucStartSector;
            remaining = Size_In_Bytes;
        }
        else
        {
            k = 0u;
        }

        error = Fapi_enableMainBankSectors(0xFFFF); /* used for API 2.01*/


        if(!WHILE_SAFE(FAPI_CHECK_FSM_READY_BUSY != Fapi_Status_FsmReady))
        {
            error = Fapi_Status_FsmBusy;
        }

        if(error == Fapi_Status_Success)
        {
            do
            {
                error = Fapi_issueAsyncCommandWithAddress(Fapi_EraseSector,
                                                          eraseStartAddr);

                if(!WHILE_SAFE(FAPI_CHECK_FSM_READY_BUSY == Fapi_Status_FsmBusy))
                {
                    error = Fapi_Status_FsmBusy;
                    break;
                }

                if(!WHILE_SAFE(FAPI_GET_FSM_STATUS != Fapi_Status_Success))
                {
                    error = Fapi_Status_FsmBusy;
                    break;
                }
                remaining -= SectorTable[k++].length;
                if(k < SECTOR_TABLE_SIZE)
                {
                    eraseStartAddr = SectorTable[k].dwStartAddr;
                }

            } while((remaining > 0u) && (k < SECTOR_TABLE_SIZE));
        }
    }

    if(error == Fapi_Status_Success)
    {
        error = Flash_Erase_Check((uint32_t)eraseStartAddr0, Size_In_Bytes);
    }

    return error;
}

从导致权限错误的指令中反汇编:

如您所见、导致权限错误的指令将寄存器压入栈。  

注册内容:

堆栈指针在允许的范围内。

映射文件中的任务堆栈内存范围:
地址   长度
08003000 00001000 safetyTask.c.obj (.bss:safetybuffer_1)

请提供有关如何解决此问题的任何想法?

此致

Aron

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    尊敬的 Aron:

    闪存 API 必须在特权模式(用户以外的模式)下运行、以允许访问闪存存储器控制器寄存器。