TMS320F28374S: upgrade issue

Part Number: TMS320F28374S

Tool/software:

I need to develop a requirement for A-side and B-side upgrade. The A-side is the program running area, and the B-side is the program backup area. When the host computer upgrades the chip firmware, it writes the new binary file to the B-side. Then the bootloader copies the content of the B-side to the A-side and jumps to the A-side for execution.

However, I have encountered an unsolvable issue during the copy process from the B-side to the A-side: each time, only approximately 60% of the content is copied. The total size of the binary file is about 157 KB, which means only around 100 KB is copied each time before the process stops, resulting in a failed upgrade. Nevertheless, if I power off the chip and then power it on again, the entire content will be copied successfully, and the chip can jump to the A-side to execute the code.

To resolve this, I have made the following attempts:

  1. Disable global interrupts (DINT) to prevent the copying process from being interrupted by other interrupt tasks.
  2. Feed the watchdog during the copying process to avoid chip reset due to failure to feed the watchdog in time.
  3. Perform the copying before task initialization to prevent interruption by other higher-priority tasks.
  4. Add a communication delay to ensure the chip has sufficient time for the copying process.
  5. Suspect insufficient memory, so declare the array variable used as the buffer as static.

Unfortunately, none of the above measures have worked. Therefore, I would like to consult you: why can a power cycle reset (power off and on again) allow the chip to complete the copying, while a watchdog reset cannot?

Relevant Code

bool flash_copy_region(void)
{
// 定义源地址和目标地址范围
const uint32_t SRC_ADDR_START = 0xA0000;
const uint32_t SRC_ADDR_END = 0xB7FFF;
const uint32_t DST_ADDR_START = 0x88000;
const uint32_t DST_ADDR_END = 0x9FFFF;

// 先擦除目标区域
if (!erase_dest_region(DST_ADDR_START, 0x18000UL))
{
return false;
}

// 检查地址范围大小是否一致
if ((SRC_ADDR_END - SRC_ADDR_START) != (DST_ADDR_END - DST_ADDR_START))
{
// 错误类型:地址范围大小不匹配
return false;
}

// 计算总字节数
const uint32_t TOTAL_BYTES = SRC_ADDR_END - SRC_ADDR_START + 1;

// 使用与原代码相同的缓冲区大小
static uint64_t data_block[256 / sizeof(uint64_t)];
const uint32_t BLOCK_SIZE = sizeof(data_block); // 256字节

// struct
// {
// uint16_t ErrType;
// uint16_t ErrData;
// } err_code = {0, 0};

// 源地址指针(指向Flash区域)
const uint8_t *src_ptr = (const uint8_t *)SRC_ADDR_START;

// 按块复制数据
uint32_t offset;
for (offset = 0; offset < TOTAL_BYTES; offset += BLOCK_SIZE)
{
uint32_t current_block_size = BLOCK_SIZE;

// 处理最后一个可能不完整的块
if (offset + BLOCK_SIZE > TOTAL_BYTES)
{
current_block_size = TOTAL_BYTES - offset;
}

// 计算当前目标地址
uint32_t dst_addr = DST_ADDR_START + offset;

// 通过指针直接从Flash读取数据(不依赖flash_read函数)
memcpy(data_block, &src_ptr[offset], current_block_size);

// 将数据写入目标地址
uint32_t i;
for (i = 0; i < current_block_size / sizeof(uint64_t); i++)
{
uint32_t write_addr = dst_addr + i * sizeof(uint64_t);
uint64_t write_data = data_block[i];

if (!flash_program(write_addr, &write_data))
{
return false;
}
}
}

return true;
}

#ifdef __cplusplus
#pragma CODE_SECTION(".TI.ramfunc");
#else
#pragma CODE_SECTION(flash_program, ".TI.ramfunc");
#endif
bool flash_program(uint32_t addr_align_4, const uint64_t * data)
{
bool ok = false;

EALLOW;
do
{
Fapi_StatusType oReturnCheck;

if(addr_align_4 % 4)
{
break;
}

oReturnCheck = Fapi_issueProgrammingCommand((uint32 *)addr_align_4,
(uint16_t*)data,
4,
0,
0,
Fapi_DataOnly);//Fapi_AutoEccGeneration);

while(Fapi_checkFsmForReady() == Fapi_Status_FsmBusy);

if(oReturnCheck != Fapi_Status_Success)
{
break;
}

ok = true;
}while(0);
EDIS;

return ok;
}

  • Cheng,

    From Reset both the PLL and Flash Waitstates will be at their default; PLL off and Flash WS at max.  Have you confirmed that when you run this during a normal code execution that you have configured the PLL and pass the appropriate CPU clock to the flash API initialization function?  Likewise have you confirmed that the value used in the flash Waitstate register matches to the CPU clock frequency?

    Disabling  ISRs is a good idea(and for debug the WD as well), something that could be occurring is that there is some code that still resides in the same flash bank that is under programmation?  Recall that while programming the flash, no code can run from the same bank as under programmation.

    Best,
    Matthew