CCSv11使用280049重定向printf函数到串口输出记录

CCSv11使用280049重定向printf函数到串口输出记录

简单记录一下重定向过程。
根据某博客的说明,首先需要重写fputc等函数,然后因为printf需要的内存比较大,编译会报错,接下来需要去属性里修改堆栈大小(按照原博客说明需要这么做,但是实际上我没有修改也可以用,大概是280049与28335有差异,具体未深究),以及去.cmd 文件给链接器对象字段分配更多的空间。

1.重写printf 相关函数

这里使用的是driverlib函数中的串口发送,串口1,已开启FIFO,未开启中断。

原先以为只需要重写fputc就行,后来发现printf没有按预期打印,可仅打印printf("num=%d",num)中的“num= ”部分,而不会发送需要格式化的变量num的值,经过查询相关博客发现还需要重载fputs等函数。

int fputc(int _c, register FILE *_fp)
{
    
    
        while (SCI_getTxFIFOStatus(mySCI0_BASE) == SCI_FIFO_TX16);
                HWREGH(mySCI0_BASE + SCI_O_TXBUF) = _c;
        return _c;
}

int putc(int _c, register FILE *_fp)
{
    
    
    while (SCI_getTxFIFOStatus(mySCI0_BASE) == SCI_FIFO_TX16);
            HWREGH(mySCI0_BASE + SCI_O_TXBUF) = _c;
    return _c;
}

int putchar(int data)
{
    
    
  while (SCI_getTxFIFOStatus(mySCI0_BASE) == SCI_FIFO_TX16);
  HWREGH(mySCI0_BASE + SCI_O_TXBUF) =data;
  return data;
}

int fputs(const char *_ptr, register FILE *_fp)
{
    
    
    unsigned int i, len;
    len = strlen(_ptr);
    for(i=0 ; i<len ; i++)
    {
    
    
        while (SCI_getTxFIFOStatus(mySCI0_BASE) == SCI_FIFO_TX16);
        HWREGH(mySCI0_BASE + SCI_O_TXBUF) = (uint8_t) _ptr[i];
    }
    return len;
}

以上程序直接复制进去就可以用。

2.修改堆栈大小

位于项目 -> 属性 -> C2000 Linker ->Basic Options
在这里插入图片描述
原博客需要将下面的Heap size与stack size均设置成0x400,但是我没有改动这里。

3.修改.cmd文件

1)在RAM模式下

· 根据报错定位问题

根据报错提示

“…/28004x_generic_ram_lnk.cmd”, line 88: error #10099-D: program will not fit into available memory, or the section contains a call site that requires a trampoline that can’t be generated for this section. run placement with alignment/blocking fails for section “.data” size 0x109 page 1. Available memory ranges:
RAMLS5 size: 0x800 unused: 0x4 max hole: 0x2
“…/28004x_generic_ram_lnk.cmd”, line 76: error #10099-D: program will not fit into available memory, or the section contains a call site that requires a trampoline that can’t be generated for this section. placement with alignment/blocking fails for section “.text” size 0x2d06 page 0. Available memory ranges:
RAMLS0 size: 0x800 unused: 0x0 max hole: 0x0
RAMLS1 size: 0x800 unused: 0x0 max hole: 0x0
RAMLS2 size: 0x800 unused: 0x1 max hole: 0x1
RAMLS3 size: 0x800 unused: 0x0 max hole: 0x0
RAMLS4 size: 0x800 unused: 0x0 max hole: 0x0
error #10010: errors encountered during linking; “empty_driverlib_project.out” not built

说明.const , .text与.data的空间不够,解决办法参考TI的文档:C28x 编译器 - 了解链接

·根据Memory Allocation窗口分析可用空间

可以通过Memory Allocation查看内存的分配,此处是PAGE0的存储空间:
在这里插入图片描述

根据手册,可以看到280049的RAM划分:

  1. 36KB(18KW)的专用RAM以及本地共享RAM。
    (1) 专用RAM:M0/M1: 0x0000 0000-0x000007FF
    (2) 本地共享RAM:LSxRAM:0x0000 8000-0x0000BFFF
  2. 64KB(32KW)的全局共享RAM。
    (1) GSxRAM:0x0000 C000-0x0001 2000

在这里插入图片描述
再对比到cmd文件
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

可以看到PAGE 0使用了RAMLS0-4,而RAMLS 5-7与RAMGS0-3被定义到了PAGE 1,供其他字段使用。
从上面的Memory Allocation中可以得知,其中text字段超出了970 byte,而整个PAGE0之内已经没有多余的空间了。考虑到.text是处于PAGE 0,需要尝试把其他未使用的部分内存分配给PAGE 0。

· 尝试分配Flash来解决

在cmd文件中可以发现在PAGE 0里面有Flash Sactor的说明是这样的:

/* Flash sectors: you can use FLASH for program memory when the RAM is filled up*/
/* Flash 扇区:当 RAM 被填满时,您可以使用 FLASH 作为程序存储器 */

于是尝试在.text字段后面多分配一个未使用过的FLASH_BANK0_SEC 0给.text 字段,
.text : >> RAMLS0 | RAMLS1 | RAMLS2 | RAMLS3 | RAMLS4 | FLASH_BANK0_SEC0 , PAGE = 0
实测过后虽然编译能通过,但是由于需要写入Flash,依然比较占用时间,且浪费Flash的擦写次数,如非必要,还是尽量用别的方法。

· 尝试分配其余的RAM来解决

既然PAGE0已经完全没有空间了,而使用FLASH也不考虑,只能把目光放在PAGE 1了,以下是PAGE1的内存分配:
在这里插入图片描述
可以看到RAMLS6、RAMLS7以及RAMGS0-3是完全空余的,因此可以把这几个空间分配到PAGE0供.text使用。然后考虑到原先的cmd文件中有使用RAMGS0与RAMGS1,故尽量不动这两个存储空间,能下手的只剩下了RAMLS6、RAMLS7、RAMGS2、RAMGS7.
已经使用的RAMGS
由于RAMLS6与RAMLS7和.text使用的其他空间RAMLS0-RAMLS4同属一个存储区,且它们的空间均为2048 byte,大于.text超出的970 byte,足够容纳了,这里选择RAMLS7,将RAMLS7在PAGE 1中的那一行剪切下来,粘贴到PAGE 0中,其地址不做变动。
在这里插入图片描述
随后分配.text。
.text : >> RAMLS0 | RAMLS1 | RAMLS2 | RAMLS3 | RAMLS4 | RAMLS7, PAGE = 0

修改.text完成后接着报错:

“…/28004x_generic_ram_lnk.cmd”, line 90: error #10099-D: program will not fit into available memory, or the section contains a call site that requires a trampoline that can’t be generated for this section. placement with alignment/blocking fails for section “.const” size 0x9c4 page 1. Available memory ranges:
RAMLS5 size: 0x800 unused: 0x800 max hole: 0x800
error #10010: errors encountered during linking; “4th layer test.out” not built

在这里插入图片描述

查看内存分配,现在.text是放下了,还剩下.const不够,接着分配,需要注意.const是PAGE1的空间,这里分配的是RAMLS6。

重点:.const字段是这么写的:.const : > RAMLS5 , PAGE = 1
注意这里使用的是>,可以看到.text字段用到的是>>,这两者有什么区别呢?
根据TI的文档:

在这里插入图片描述
想要把多个内存空间拆分给到链接器,需要使用>>,所以这里需要把.const改成
.const : >> RAMLS5 | RAMLS6, PAGE = 1

再次编译,通过,没有报错,完成对报错的排除。
在这里插入图片描述

以下是配置文件的截图:
在这里插入图片描述

2)在FLASH模式下

其报错与RAM下类似,也是.text字段不够用,同上添加一个存储区域即可。
在这里插入图片描述

4.后记

根据其他博客提及的修改build->c2000 compiler->advanced options中有关printf的部分,我的CCS版本里这里是空的,没有可以选择的项,就没有处理,基本上只需要重写fputc等函数就能实现重载,至于其他的报错处理方法可以根据错误提示进行修改。

参考文献

1.CCS6中printf()的使用——TMS320F28335工程printf()的使用
2.C28x 编译器 - 了解链接

猜你喜欢

转载自blog.csdn.net/hmc_123/article/details/124940913