Загадочная память защиты от записи - PullRequest
1 голос
/ 11 марта 2020

Я использую последовательный загрузчик на ATSAME51N20A (Cortex-M4). Я читаю в пакетах через UART и записываю их во внутренний fla sh. Для некоторых адресов памяти запись fla sh работает нормально, для других - вообще не работает.

Здесь - это таблица данных. Я проверил все конфигурации регистра, которые я могу найти, и все, кажется, в порядке.

Вот мой код инициализации:

void init(void)
{
     GPIOInit();
     USARTInit();

     NVMCTRL->CTRLA.reg = NVMCTRL_CTRLA_AUTOWS | NVMCTRL_CTRLA_WMODE_AP | NVMCTRL_CTRLA_PRM_MANUAL;
     hri_mclk_set_AHBMASK_NVMCTRL_bit(MCLK);
     hri_mclk_set_APBBMASK_NVMCTRL_bit(MCLK);

     PAC->WRCTRL.reg = PAC_WRCTRL_PERID(ID_DSU) | PAC_WRCTRL_KEY_CLR;
     MCLK->AHBMASK.reg |= MCLK_AHBMASK_DSU;
     MCLK->APBBMASK.reg |= MCLK_APBBMASK_DSU;
}

Вот мое письмо для fla sh code:


#define APPLICATION_START_ADDRESS 0x8000
#define PAGE_SIZE (512U)

void NVMErasePage(uint32_t pageOffset)
{
    // Set the NVM page address that we want to erase
    NVMCTRL->ADDR.reg = (APPLICATION_START_ADDRESS + (pageOffset * PAGE_SIZE));

    // Wait until the NVM controller is ready
    while (0 == NVMCTRL->STATUS.bit.READY);

    // Lock region size is always bigger than the row size
    NVMCTRL->CTRLB.reg = NVMCTRL_CTRLB_CMDEX_KEY | NVMCTRL_CTRLB_CMD_UR;

    while (0 == NVMCTRL->STATUS.bit.READY); // Unlocking is a fast operation

    // Erase the page that contains our address
    NVMCTRL->CTRLB.reg = NVMCTRL_CTRLB_CMDEX_KEY | NVMCTRL_CTRLB_CMD_EP;

    // Wait until the NVM controller is ready
    while (0 == NVMCTRL->STATUS.bit.READY);
}

void programApplicationFlashPage(uint32_t pageOffset)
{
    uint32_t *flash_buf = (uint32_t *) (APPLICATION_START_ADDRESS + (pageOffset * PAGE_SIZE));
    for (int i = 0; i < PAGE_SIZE/4; i++)
    {
        flash_buf[i] = *(uint32_t *) (memoryLocation + (i));
    }
    while (0 == NVMCTRL->STATUS.bit.READY);
}

Я могу написать fla sh страницы с адресов 0x1A00 до 0x1E080 (смещение 145-175), но до и после этого память, в которую предполагалось записать, не изменяется.

Согласно данным таблицы RUNLOCK отвечает за защиту записи NVM, и я проверил, чтобы она была установлена ​​для разблокировки всех секторов NVM (0xFFFFFFFF).

Что еще может помешать мне писать на все NVM?

EDIT

Добавлен код для стирания fla sh и ожидания после прошивки / операции записи. Я вижу, что fla sh все стирается (все биты установлены в высокое значение), но операция записи не работает.

1 Ответ

2 голосов
/ 12 марта 2020

Разобрался. Я выполнял команду Erase Page вместо команды Erase Block. Страница стирания предназначена только для страницы данных пользователя USER FLA sh, а не для основного банка FL sh.

Вот код, который работал для меня:

if((flash_addr % BLOCK_SIZE) == 0)
{
    // Set the NVM block address that we want to erase
    NVMCTRL->ADDR.reg = blockAddress;

    // Unlock the region that contains our address
    NVMCTRL->CTRLB.reg = NVMCTRL_CTRLB_CMDEX_KEY | NVMCTRL_CTRLB_CMD_UR;

    // Wait until the NVM controller is ready
    while (0 == NVMCTRL->STATUS.bit.READY);

    // Erase the block that contains our address
    NVMCTRL->CTRLB.reg = NVMCTRL_CTRLB_CMDEX_KEY | NVMCTRL_CTRLB_CMD_EB;

    // Wait until the NVM controller is ready
    while (0 == NVMCTRL->STATUS.bit.READY);
}

for (int i = 0; i < PAGE_SIZE /4; i++)
{
    flash_buf[i] = *(uint32_t *) (memoryLocation + (i));
}
while (0 == NVMCTRL->STATUS.bit.READY);

...