陆平

Be water, my friends.

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::

环境: CCS 5.2 ( TI 的 HalCoGen 生成代码)

芯片: TMS570LS3137

现象: 编译正常,下载到芯片后,程序就跑飞了

原因: 程序中定义了长度比较大的缓冲区

 

最近在 TMS570LS3137 的板子上,写了一个 CAN 相关的小程序,主要完成功能为:

将CAN总线上的数据,全部(不过滤)接收下来,然后通过 UART 发送到 PC ,最终由串口助手接收数据。

写这个小程序的初衷就是就是监控 CAN 总线上的数据,最后根据数据内容,对其他板子的调试提供一个参考作用。

需要检测的 CAN 总线有独立的两路,一开始,简单起见,程序的第一个版本只对其中一路 CAN 进行了监控,程序运行良好。

第一版的主体程序为:

 1 #define D_SIZE    8
 2 #define BUF_SIZE 1024
 3 
 4 typedef struct DataBufStr {
 5     uint8 Buffer[BUF_SIZE];
 6     uint8 * Head;
 7     uint8 * Tail;
 8 }DataBuf_t;
 9 
10 uint8 rx_data[D_SIZE] = {0};
11 uint8 rx_done = 0;
12 
13 void main(void)
14 {
15     uint32 i;20     DataBuf_t CanRXBuf;
21     _enable_interrupt_();
22     canInit();
23     gioInit();
24     sciInit();
25     gioSetDirection(gioPORTB, 0xFFFFFFFF);
26     CanRXBuf.Head = CanRXBuf.Buffer;
27     CanRXBuf.Tail = CanRXBuf.Buffer;
28 
29     i = 0;
30 
31     while(1)
32     {
33         if (rx_done == 1) {
34             rx_done = 0;
35             if ((CanRXBuf.Tail + D_SIZE) <= (CanRXBuf.Buffer + BUF_SIZE)) {
36                 memcpy(CanRXBuf.Tail, rx_data, D_SIZE);
37                 CanRXBuf.Tail += D_SIZE;
38             }
39         }
40         if (CanRXBuf.Tail > CanRXBuf.Head) {
41             sciSendByte(scilinREG, *(CanRXBuf.Head));
42             CanRXBuf.Head += 1;
43             if (CanRXBuf.Tail == CanRXBuf.Head) {
44                 CanRXBuf.Tail = CanRXBuf.Buffer;
45                 CanRXBuf.Head = CanRXBuf.Buffer;
46             }
47         }
48         i++;
49         if (i == 0x3FFFFFU) {
50             i = 0U;
51         }
52     }
53 }        

其中的 rx_done 和 rx_data[] 是在中断程序分别进行置位和赋值的。然后于主程序中,将 rx_data[] 中数据复制到长度为 1024 字节的缓冲区中,最后再由 SCI 串口(或者说 UART )依次将缓冲区的数据发送出去。

第二版程序的改进有:增加一路 CAN 接收数据,同时增加一个缓冲区,又考虑到CAN数据发送频率可能会比较高,为了防止缓冲区溢出,所以每个缓冲区的长度增至 8192 字节,相当于两路 CAN 同时监控各自的总线,将接收的数据先存放于各自的缓冲区(长度均为 8192 字节)中,最后这些数据又分别通过不同的串口发送出去。

第二版程序编译没有问题,也生成了可执行代码文件,但是将程序下载到芯片后,执行程序,然后就跑飞了,基本是在  gioSetDirection(gioPORTB, 0xFFFFFFFF); 这一句代码执行完成后就飞了,进入了 sys_intvecs.asm 文件的这个地方:

prefetchEntry
        b   prefetchEntry
        b   _dabort

进入了 _babort() 函数,这个函数应该是链接库中自带的,工程目录中找不到相应的源代码。

调试了很长时间,怀疑过 CAN 或 SCI 的寄存器配置有问题,尝试过几次新的配置都无济于事,看 TMS570 的 System Exception Status Register 寄存器,也只有第3位置1,说明不了问题。所以在这里卡了一段时间。

后来,突然想试一试小一点的缓冲区,试了一下 4096 字节,程序也会跑飞。然后将两个缓冲区改成了 2048 字节,最后编译、下载,程序竟然正常了!这种事情还是第一次遇到,现在貌似可以这样解释,两个缓冲区都是定义在 main() 函数中,而分配给 main 的程序空间可能比较小,已经无法承受高达8K字节的空间分配,最终导致跑飞。当然现在只是一种猜测,毕竟 TMS570LS3137 的片内 Flash 有256K字节呢,后面有时间还需要研究一下 TMS570 对应程序空间、堆、栈的分配。

基本情况就是这样了,总之是代码中定义过大的变量,导致程序跑飞。

posted on 2014-04-18 22:51  陆平  阅读(1754)  评论(0编辑  收藏  举报