最近几天在玩DSP28335板子,在实现printf重定向功能时,遇到很多问题,最终结合网上一些人的经验和个人实践,最终解决了问题。本文做一个简单的总结,以便后续查阅。同时也是希望能对其他人提供一些参考。
问题1 重写了fputc fputs 函数编译报错
fails for section ".stack" size 0x400page 1. Available memory ranges:
RAMM1 size: 0x400 unused: 0x0 max hole: 0x0
该问题一般是由于链接脚本定义数据RAM空间太小所致,修改cmd文件即可,下面修改可以参考
MEMORY
RAML4 : origin = 0x00C000, length = 0x004000 /* on-chip RAM block L1 */
// RAML5 : origin = 0x00D000, length = 0x001000 /* on-chip RAM block L1 */
// RAML6 : origin = 0x00E000, length = 0x001000 /* on-chip RAM block L1 */
// RAML7 : origin = 0x00F000, length = 0x001000 /* on-chip RAM block L1 */
SECTIONS
/* Allocate uninitalized data sections: */
.stack : > RAMM1 PAGE = 1
.ebss : > RAML4 PAGE = 1
.cio : > RAML4, PAGE = 1
.esysmem : > RAML4 PAGE = 1
同时修改CCS工程属性(以CCS V12为例)
!!!建议选择full模式,minimol 模式下某些场景下,打印数字会被过滤。
问题2 编译完成后,printf打印异常
printf 打印异常存在多种情况,需要根据不同情况处理。
1) 打印固定字符串没有问题,打印其他字符串,程序异常;
// 正常
printf("hello world\n") ;
//异常,打印完此行后,程序进入异常中断
printf("hello world %d\n",tick);
//异常 buffer 字符串常量时正常,变量时程序进入异常中断
printf("hello world %s\n",buffer);
// 异常,程序上电跑飞
char buffer[] ="hello world";
sprintf(buffer, "Display %d\r\n",g_u16Display_num);
printf("%s",buffer)
原因 :程序的函数栈空间溢出,若是裸机请检查问题1修改的内容,若是RTOS,请检查线程栈空间是否配置过小
我这里是用的RTOS,调试发现程序卡死在这个钩子函数,说明发生栈溢出,修改任务栈空间大小后,程序正常
2) printf 打印数据缺失
问题1中printf级别选择full模式,minimal 模式下某些场景下,打印数字会被过滤
暂时不清楚这三个级别详细用法,建议使用full 模式
full 模式下打印结果
minimal 模式下打印结果,可以看到printf打印依然正常,但是输入命令后,存在显示不全问题。
最后贴一下fputc ,fputs 实现代码供参考
int fputc(int ch,FILE *fp)
{
while(ScicRegs.SCICTL2.bit.TXRDY == 0);
ScicRegs.SCITXBUF= ch;
return ch;
}
int fputs(const char *_ptr,FILE *_fp)
{
unsigned int i,len;
len = strlen(_ptr);
for(i=0;i<len;i++)
{
while(ScicRegs.SCICTL2.bit.TXRDY == 0);
ScicRegs.SCITXBUF= (uint8_t) _ptr[i];
}
return len;
}
【特别说明】已上仅为个人经验和看法,实际情况可能因为硬件平台及软件架构的不同,以及笔者水平能力所限,有所出入。上述问题若有错误,欢迎评论指针,一起提高!