图片外链上传网站,美篇app怎么制作,WordPress管理app,网站服务器共享的 vpstitle: 踩坑记 BSS段的初始化 category_bar: true categories:
blog tags:embedded date: 2023-10-20 19:23:05 前言
接手一个项目#xff0c;调试全靠串口日志#xff0c;测试同事测试产品的时候无法拿到日志#xff0c;刚好产品RAM够大#xff0c;且刚好有SD卡。所以就…
title: 踩坑记 BSS段的初始化 category_bar: true categories:
blog tags:embedded date: 2023-10-20 19:23:05 前言
接手一个项目调试全靠串口日志测试同事测试产品的时候无法拿到日志刚好产品RAM够大且刚好有SD卡。所以就诞生了将日志缓存在RAM上在特定条件下将它写到SD卡上的想法。 . . . 开工。 . . . 写完代码之后发现机器偶尔会无法启动无法开机无任何日志。 . 有的时候是烧录完成代码后重启无法启动有些情况下是烧录完成代码后运行正常放置一段时间后无法启动。 . 有时候有些无法启动的机器放置一段时间又成功启动。 . . . 一段一段代码屏蔽编译验证发现一个非常无法理解的事TFCardLogBufferPut函数注释后设备可以正常启动。 . . . 看代码
#define TF_CARD_LOG_BUFFER_SIZE (64*1024ul)
uint8_t tfCardLogBuffer[TF_CARD_LOG_BUFFER_SIZE] {0};
uint32_t tfCardLogBufferIndex 0;void TFCardLogBufferPut(uint8_t data) {tfCardLogBuffer[tfCardLogBufferIndex] data;tfCardLogBufferIndex;if( tfCardLogBufferIndex(sizeof(tfCardLogBuffer)/sizeof(tfCardLogBuffer[0]))-1 ) {tfCardLogBufferIndex 0;}
}. . . 我实在无法理解这段代码是如何导致设备无法启动的后面搁置了一段时间遂归结于小众芯片不完善导致。 . . . 但是后面这个需求实在是过于旺盛遂重新开始验证代码。
当时代码是这样的
// main.c
int main(int argc, char **argv) {hal_uartInit();ax32xx_uart0SendByte(a);ax32xx_uart0SendByte(b);hal_uartSendData(1);hal_uartSendData(2);ax32xx_uart0SendByte(c);hal_sysInit();//.... some code here
}// uart.c
void hal_uartSendData(u8 data)
{ax32xx_uart0SendByte(data);TFCardLogBufferPut(data);
}void ax32xx_uart0SendByte(u8 data)
{R_UART_DATA0 data;while((R_UART_PEND0 0x2)0);R_UART_PEND0 | 1;
}#define TF_CARD_LOG_BUFFER_SIZE (64*1024ul)
uint8_t tfCardLogBuffer[TF_CARD_LOG_BUFFER_SIZE] {0};
uint32_t tfCardLogBufferIndex 0;void TFCardLogBufferPut(uint8_t data) {tfCardLogBuffer[tfCardLogBufferIndex] data;tfCardLogBufferIndex (tfCardLogBufferIndex(sizeof(tfCardLogBuffer)/sizeof(tfCardLogBuffer[0]))-1) ? 0 : tfCardLogBufferIndex1;
}运行后日志是这样的
# 正常运行 的日志
ab12c ...# 无法启动 的日志
ab1. . . 后面我就猜想了很多
这个soc不能支持这么大的数值 64KB这个位置的内存被改写了和冷启动热启动有关芯片异常
. . .
后面我猜想试试把TFCardLogBufferPut函数里面的tfCardLogBufferIndex的数值和data数值输出出来看看。 . .
这一看不得了越界了
代码
输出日志
ab1z31m00327300. . .
这个tfCardLogBufferIndex越界了啊而且初始化赋0并没有成功这就非常坑爹了 . . . 后面尝试在调用这个函数之前再次赋0发现程序运行正常设备也正常启动。
查看map文件这个数组和变量也是存放在BSS段的这就非常令人费解了。 . . . . . 看到这里我直接就怀疑就是这个芯片的锅。
但是别急这还不是让人最震惊的后面还有让人更加鼻血飙升的。 . . . . . . . . . . . . .
最后找FAE排查问题很久最后发现BSS段在hal_sysInit函数内初始化。
看代码
void ax32xx_sysInit(u32 *saddr,u32 *eaddr)
{debg(sys init\n); // 这个debg会调用 hal_uartSendData 函数输出日志//...ax32xx_wdtClear();//-----cache setax32xx_sysIcacheInit();ax32xx_sysDcacheInit();
//-----bss clearax32xx_sysBSSClear();// ...
}. . .
实在是震惊无法理解这个RAM的初始化为什么放在main函数里面实在无法理解进入main函数了c语言环境都没有OK。
最烦的就是这种xx芯片总是会有一些让人血压飙升的操作。
. . . . .
教训
在对数组进行访问的时候一定要先检查范围。
// 原函数
void TFCardLogBufferPut(uint8_t data) {tfCardLogBuffer[tfCardLogBufferIndex] data;tfCardLogBufferIndex (tfCardLogBufferIndex(sizeof(tfCardLogBuffer)/sizeof(tfCardLogBuffer[0]))-1) ? 0 : tfCardLogBufferIndex1;
}// 改后
void TFCardLogBufferPut(uint8_t data) {if( tfCardLogBufferIndex(sizeof(tfCardLogBuffer)/sizeof(tfCardLogBuffer[0]))-1 ) {tfCardLogBufferIndex 0;}tfCardLogBuffer[tfCardLogBufferIndex] data;tfCardLogBufferIndex;
}