|
本帖最后由 regsofweb 于 2025-1-16 14:40 编辑
在ld中,定义了数据段
MEMORY
{
BOOTFLAG (rw) : ORIGIN = 0x00000000, LENGTH = 32
RAM_NOLOAD (xrw) : ORIGIN = 0x00000020, LENGTH = 4064
ITCMRAM (xrw) : ORIGIN = 0x00001000, LENGTH = 60K
DTCMRAM (xrw) : ORIGIN = 0x20000000, LENGTH = 128K
FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 1024K
RAM_D1 (xrw) : ORIGIN = 0x24000000, LENGTH = 320K
RAM_D2 (xrw) : ORIGIN = 0x30000000, LENGTH = 32K
RAM_D3 (xrw) : ORIGIN = 0x38000000, LENGTH = 16K
}
._ram_bootflag (NOLOAD) : /* Space before ':' is critical */
{
. = ALIGN(4);
} >BOOTFLAG
ITCMRAM一共有64K,但是从0x00000000开始的32字节定义为一个段,存放复位标志和运行时间,设置为NOLOAD,避免编译器对其清零。
代码的部分:
//定义一个大数组,占用这32字节的空间
#define BOOTFLAG_UINT32_CNT 8
volatile uint32_t boot_flags[BOOTFLAG_UINT32_CNT] __attribute__((section("._ram_bootflag")));
extern __IO uint32_t uwTick;
// uwTickFreq is 1
// extern HAL_TickFreqTypeDef uwTickFreq;
volatile runningTime_t runningTime;
volatile time_t *psRunningSec = NULL;
#define RUNNING_MAGIC_NUMBER 0x1234567855aa33cc
// 覆盖原来的tick函数
void HAL_IncTick(void)
{
// uwTick += uwTickFreq;
uwTick++;
if (++runningTime.tv_ms == 1000)
{// 每秒更新
runningTime.tv_ms = 0;
runningTime.tv_sec++;
if (psRunningSec != NULL)
{// psRunningSec已经初始化过了
psRunningSec[0] = runningTime.tv_sec; // 运行时间存入
psRunningSec[1] = runningTime.tv_sec;
}
}
}
// 初始化时加载BOOTFLAG_RUNNING_SEC
void RunningInit(uint16_t cnt)
{
ENTER_CRITICAL_pri();
psRunningSec = &boot_flags[BOOTFLAG_RUNNING_SEC];
runningTime.tv_sec = (psRunningSec[0] != psRunningSec[1] ||
psRunningSec[2] != RUNNING_MAGIC_NUMBER ||
psRunningSec[0] < EPOCH_2000 || psRunningSec[0] > EPOCH_2099)
? EPOCH_2000
: psRunningSec[0];
runningTime.boot_cnt = cnt + 1;
psRunningSec[2] = RUNNING_MAGIC_NUMBER;
EXIT_CRITICAL_pri();
}
现象:
系统启动,先运行BOOTFLAG_RUNNING_SEC是否合规。如果正确就加载,如果不正确就从EPOCH_2000开始。
系统运行的时候,在boot_flags[BOOTFLAG_RUNNING_SEC]的位置,有3个变量:
【0】runningTime.tv_sec
【1】runningTime.tv_sec
【2】RUNNING_MAGIC_NUMBER
在tick里面每秒更新运行的秒数
我使用仿真器运行,在任何地方暂停程序,可以看到【0】和【1】是相同的两个数
让程序继续运行,然后复位,无论是软复位,拉低nRST还是使用debug菜单里面的复位。在main的开始处设置断点,可以看到【1】比【0】要小1
这个很是怪异。
如果更改写的顺序:
psRunningSec[1] = runningTime.tv_sec; // 运行时间存入
psRunningSec[0] = runningTime.tv_sec;
就会出现【0】比【1】小1的情况
好像是第二行的写入被复位打断了。
我也试过不同的MPU的配置,无论设成write-through,noncache,device或strongly-ordered都一样
无法理解是哪里出了问题
|
|