问题列表(整理中):

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: 机器模式异常值寄存器。当异常发生时,该寄存器将被写入异常的辅助信息。

  1. 如果是由存储器访问造成的异常,譬如遭遇硬件断点、取指令、存储器读写造成的 异常,则将存储器访问的地址更新到 mtval 寄存器中。
  2. 如果是由非法指令造成的异常,则将该指令的指令编码更新到 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 字段的下边即可。

.