C6000编译器将每个C源文件编译到一个code section,并且在链接过程中作为一个整体引用。也就是说只要其中有一个函数引用了,整个section都被链接进去。
6.0版编译器可以用--gen_func_subsections选项将每个函数放到一个sub section里,这样不用的函数就不会链接进去,但也会带来一定内存开销,因为每个section/subsection要32字节对齐。
6.1版编译器增加了 --generate_dead_funcs_list和--use_dead_funcs_list这两个参数,也就是生成一个列表,标明哪些函数未使 用,下次链接时引用生成的链接,将调用的函数放到section里,未使用的函数也没删掉,而放到单独的sub-section里,链接时不会链入。
格式:
--gen_func_subsections: 在compiler选项里设置
--generate_dead_funcs_list=feedback.txt :在linker选项里设置,未指定目录时结果保存在项目根目录
--use_dead_funcs_list="$(Proj_dir)\feedback.txt":在compiler选项里设置,必须引用完整路径,否则报错找不到。
TMS320C6000 Optimizing Compiler v6.1 User's Guide里提到的过程比较复杂,研究了一些使用体会。
对于内存并不紧张的项目,用--gen_func_subsectionst就够了。
对于内存紧张的项目:
首次生成feedback.txt时使用--gen_func_subsectionst和--generate_dead_funcs_list,不用–use_dead_funcs_list(用了也没多大事,只不过报warning找不到feedback.txt)。之后再去掉--gen_func_subsectionst,使用–use_dead_funcs_list编译一次。--generate_dead_funcs_list参数可以保留,生成的feedback.txt除了里面的时间戳不一样外,其它内容相同。
之后只要函数调用关系没有变化,用–use_dead_funcs_list就行了,–generate_dead_funcs_list可以一直保留,省得改来改去麻烦。不要用--gen_func_subsectionst,因为只要用了它,–use_dead_funcs_list就是无效的。
如果函数调用关系变化,如一些测试代码没用调用了,用添上--gen_func_subsectionst,–generate_dead_funcs_list也是必须的。–use_dead_funcs_list可以保留,反正此时--gen_func_subsectionst优先。编译一遍,更新feedback.txt。再去掉--gen_func_subsectionst再编译一遍就ok了。
总结:一般--generate_dead_funcs_list和–use_dead_funcs_list参数一直挂着,省得改来改去。需要更新feedback.txt就加上--gen_func_subsectionst,不需要时去掉。
以某项目为例测试,PROG是在内部RAM运行的代码,PROG_SD是在SDRAM中运行的代码。
可以看到程序小了一些了,PROG里省了1k多。并且在.text里不再每个函数一项,而是每个obj一项。可以看到程序小了一些了,PROG里省了1k多。并且在map文件里看到.text里不再每个函数一项,而是每个obj一项。