公司最近用AB2021A3芯片做彩屏测距仪,开发过程中,发现串口老是出现问题。
设备逻辑是AB2021A3做主控板带按键,自己公司开发的测距模块使用串口通信收发距离数据。在开发过程中,发现程序内部没调用的代码,会影响串口的发送,示波器抓取了波形,tx电平没掉,但是没发出数据。把其他地方的代码注释掉(或者冗余代码,或者没用的代码都行)减小代码体量,或者在把指令写入寄存器之前,printf打印一下准备发送的数据,串口就能正常发送数据了。因为涉及到彩屏的显示,所以里面有很多其他的显示和测距计算函数部分。令我疑惑的是,为什么没调用的代码,会影响串口的发送。由于程序使用code::blocks编译,我对这个编译器不是很熟悉,所以不知道它的优化会不会对代码造成影响。
另一个问题是,由于有时需要语音播报,我需要在只有一个IO脚的情况下,发送数据后,接收语音芯片完成播报的低电平。由于限制我只能不停的转换IO口的输入输出状态。在转换的过程中,串口tx引脚会掉电压,导致后续串口指令发不出去。于是我单独写了个测试main函数,里面只留下串口收发,然后将收到的数据播报出去,这个时候一切正常,串口电平不会往下掉。这让我想到是不是又是和代码大小有关,同样的,注释掉部分代码,也可以解决问题,但是我的代码一直都在改,所以我直接在while(1)里不停初始化串口,来保证我的串口电平不会掉。
这个芯片的开发环境不像stm32那样可以debug,我只能通过串口打印,一步一步排查。一开始出现问题后,我第一反应是,会不会是栈溢出了,导致函数没法压栈。于是我找了RISC-V内核汇编函数查看sp和ra指针,并打印查看
__asm__ volatile("mv %0, sp" : "=r"(sp_ptr)); __asm__ volatile("mv %0, ra" : "=r"(ra_ptr)); printf("%s: sp %lx\n", __func__, sp_ptr); printf("%s: ra %lx\n", __func__, ra_ptr);查看链接脚本文件,栈的位置和我打印输出的位置根本不一样,但是大小我大概可以估计得到,栈应该是没有溢出。因为这个芯片在运行,是将flash内的程序通过spi拷贝到ram内运行(其他芯片了解的不深,不知道是不是都是这样的)。但是对于这个问题,我没有具体的思路,直觉让我认为应该是内存出了问题,但是我不知道用什么方法排查。
关于这款芯片,网上的资料可以说直接没有,芯片内部封装程度很高,基本都是库函数操作,想找寄存器手册,找不到。公司的芯片包里有sdk手册,但是手册写的很笼统,而且不全,另外一些文档的作用也微乎其微。
现在设备看起来挺稳定,但其中的辛酸只有我知道,这个问题不解决,后续量产爆大雷,那就寄了,现实中我不知道能问谁,所以只能在网上问问各位,有没有遇到过类似问题的可以提供一些解决问题的思路,感谢各位不吝赐教。