老大昨晚喊我过去帮他看看程序出现的奇怪问题, 挺晚才回去, 所以没来得及写, 今天反刍(恶......)了一下记录
下来. 哈哈.......被人需要果然是一种幸福. -_-||
这个 DSP 程序驱动部分几乎全是员工 Z(已离职) 编写的. Y 工呢, 根据这个基础增加实现了一部分 OS 功能, 如内
存管理,消息, 信号. 之后就没在继续了, 可能是升任管理层了. 我在刚来时, Y 工曾让我看了一段时间的代码. 我
觉得叫 OS 真的很扯, 因为已实现的功能在空转, 核心的进程管理功能没有实现. 程序执行方式还是传统的for(;;)
& while(1).所以, 我把他们全精简掉. 事实证明是对的.
本来可以一直搞这个 C6000 的. 奈何核心板硬件问题迟迟没有解决,项目搁置. 我又被分配到了其他项目的单片机编
程填坑. 擦........扯远了.
-----------------------------------------扯蛋分割线---------------------------------------------------
谈正题:
老大 S 本来对这个 DSP 程序不甚了解, 所以在修改网络处理的相关代码时, 可能没有考虑到对其他代码的影响. 这
大概就是程序维护的大坑.
问题呢是如此...........
原本这个结构体是这样的:
typedef struct {
u32 a;
u8 b;
u8 c;
u8 d;
u8 e;
} VHF;
VHF VHF_Channel[15]; // 15 * 8 = 120 Bytes
然后呢, 在结构体里增加了一个成员, 用于表示某个通道是否有效. 所以呢变成了这样:
typedef struct {
u32 a;
u8 b;
u8 c;
u8 d;
u8 e;
u8 f; // 增加的成员
} VHF;
VHF VHF_Channel[15]; // 15 * (8 + 4) = 180 Bytes
然后编译链接, 双零; 运行, 死机!!!
插调试器, 设断点, 单步, 发现在某个函数里的 for 循环 i 在从 0 到 15 的过程中,只增加到 13 然后 i 又回到
1 增加, 如此循环, 死在这了, 而且在变成 12 的时候, 更改了函数内其他 3 个变量的值, 这个是不符合逻辑的.
因为循环体内压根就没对这三个变量进行直接或间接的操作.
开始的时候怀疑是栈溢出的问题, 查阅了手册, 根据编译后的 .map 文件(文后附内容)中得出的 RAM unused 大小修
改了 .cmd 文件中 -statck 的大小, 增加一倍(4KB). 这肯定足够了. 烧写调试还是老错误. 其实原来栈空间就有
4KB 大小了. 这个程序是足够的.
不得已, 重新检查, 挨个单步执行查看, 函数内的局部变量值是否符合预期. 当单步执行到一个长度变量(结构体数
组的长度加上其他值)时, 发现了一个错误, 按照申请的 u32 buf[40] 也就是 160 字节. 而这个长度变量居然是
205(正常值应该是 145), 远超过了缓冲区大小.
找到源头发现是因为增加了结构体成员导致的大小变化. 因为编译器默认是按照 4Bytes 对齐原则(word-alignment)
(查看手册是个好习惯), 所以一个结构体就增加了 4 字节. 而 15 个结构体数组就增加了 60 字节. 远超缓冲区大
小了.
所以, 当 for 循环在操作 0-14 的结构体数组时, 指针已经越界操作. 导致的问题就是修改了不该指向的内存
区域. 所以, 才会有不相干变量值的变化.
其实如果结构体仅仅增加一个字节, 也就多了 15 个字节, 总共刚好侥幸到达 160. 侥幸是侥幸, 后果很严重.
合理的做法还是使用编译器指令来强制结构体字节对齐.如
struct __attribute__ ((__packed__)) packed_struct {
char c1;
int i;
char c2;
};
结束附上参考的编译器手册对应章节:
.map 文件内容(部分), 手册中有介绍:
******************************************************************************
TMS320C6x Linker PC v7.4.1
******************************************************************************
>> Linked Tue Nov 12 10:47:24 2013
OUTPUT FILE NAME: <E:/os_app8023/project/../Debug/project.out>
ENTRY POINT SYMBOL: "_c_int00" address: 10012fc0
MEMORY CONFIGURATION
name origin length used unused attr fill
---------------------- -------- --------- -------- -------- ---- --------
VECTOR_RAM 10000000 00000300 00000200 00000100 RWIX
TEXT_RAM 10000300 00015000 000131fc 00001e04 RWIX
RAM 10015300 0000ad00 00008226 00002ada RWIX
SECTION ALLOCATION MAP
output attributes/
section page origin length input sections
-------- ---- ---------- ---------- ----------------
.pinit 0 10000300 00000000 UNINITIALIZED
..............以下 略