问题列表(整理中):
1. 获取芯片唯一ID(uniqId)
通过如下方式来获取:
uint32_t id[4];
FLASH_Unlock();
FLASH_GetUniqueID(id);
FLASH_Lock();
芯片内部唯一ID,其实使用的是片内flash的唯一ID。
这里读出来是16个BYTE。
如果这个记录太长,想用1个int型来记录,可以使用读出来的第三个int(即:id[2])。
2. 系统堆栈大小怎么设置
AG32中默认的栈stack大小是0x1000(即:4K)
如果要改变栈的大小,可以在platformio.ini 中加入:
build_flags = -Wl,--defsym=__stack_size=0x1000
而堆的大小,是自动设置的(无须手工设置)。
在128K的sram里,除去静态/全局变量数组的空间,除去栈stack的空间,剩下的都被自动分配为堆heap的空间(就是malloc可以申请到的空间)。
3. 程序异常跑飞怎么定位
如果程序运行中跑飞(进入异常中断函数exception_handler),可以查看几个寄存器帮 助定位:
mepc:进入异常前的pc地址,结合编译map可以定位到是从哪个函数飞掉的;
mcause:是machine cause register,记录进入异常的原因。
异常原因列表如下:
这个列表是risc-v的标准列表,更多信息可以百度获取。
mtval: 机器模式异常值寄存器。当异常发生时,该寄存器将被写入异常的辅助信息。
- 如果是由存储器访问造成的异常,譬如遭遇硬件断点、取指令、存储器读写造成的 异常,则将存储器访问的地址更新到 mtval 寄存器中。
- 如果是由非法指令造成的异常,则将该指令的指令编码更新到 mtval 寄存器中。
通过以上三个寄存器,通常可大致猜测到原因。
更多的信息,可参考网页:https://blog.csdn.net/m0_53157173/article/details/131154336
跑飞的状况,只能在VSCODE下跟踪程序时察觉。
查看mepc,要结合编译出来的map函数列表才能确定具体函数。
map文件位于:工程路径\.pio\build\debug\xxxx.readelf
打开文件后,可以看到函数列表、函数起始地址、函数长度等信息。如下图:
然后查找mepc的值会落在哪个函数段里边。
4. 查看变量的16进制数hex显示
debug跟踪状态下,默认情况下,左边栏看到的是10进制。
如果要查看16进制hex的显示,需要在gdb命令行输入:set output-radix 16
如下:
点开1处的命令行窗口;
在2处输出:set output-radix 16 并回车;
可以看到3处的回显;
同时,在4处watch栏的变量,就变成了16进制输出。
5. 用网口收发数据出现异常(数据量较大)
mac的数据收发(tx/rx),都是dma方式。
在收中断的处理函数(MAC0_isr_agm)中,如果一次中断里,有多条数据到达,也是可以通过for循环逐条处理的。
如果数据量比较大,导致了数据异常,可以尝试修改收发缓存descriptor的数量值:
另外编译要用release方式,debug可能性能不够(debug模式带大量调试信息,执行速度会慢非常多)。
6. 编译时4字节对齐的报错
在risc-v中,要求内存访问时必须4字节对齐。所以,在uint8和uint32两种buff进行数据转换时,经常会报错。
比如,语句:uint32_t u32Data = *((uint32_t*)(&u8_buff[0])); 会报错如下:
那么,常用的解决办法,是指针单独一步赋值(因为指针赋值本身不涉及目标buff的访问,可以避过该检测),如:
这种方法,只是避开了编译器的检测。
但需要自己确保,取数据的那个位置是四字节对齐的,不然运行中还是会进入异常。
如果一定要修改,请参考如下方式:
在platformio.ini中加入:
build_src_flags = -Wno-error=cast-align
这条设置放到 build_src_filter 字段的下边即可。
.