2812中用printf和puts输出的相关问题

来源:互联网 发布:阿瓦隆之王兵营数据 编辑:程序博客网 时间:2024/04/28 13:32

      今天研究了大半天在2812中用printf和puts输出的相关问题,也在网上找了不少资料,发现没有很具体的讲解相关内容的,最后在实验室师兄弟帮助下解决了这个问题,现在自己做一个小结。

      从http://bbs.21ic.com/icview-125942-1-1.html帖子的相关内容入手开始分析。

      帖子中程序如下:

#include <stdio.h>
void Delay();
int i=0,count=0;
void main()
{
  while(1)
   {
//   puts("hello world!/n"); 就是这里,用puts没事,printf就不能用
     printf("hello world!/n");
     i++;
     Delay(5);
   }
}
void Delay(count)
{
  while(count>0)
  count --;
}
=====================
cmd文件如下:
-l rts2800.lib
-stack 400h
-heap 400H 
MEMORY
{
  PAGE 0 : PROG(R)    :origin=0x3F8000,length=0x1FFF
  PAGE 0 : M0RAM(RW)    :origin=0x000000,length=0x400
  PAGE 1 : M1RAM(RW)    :origin=0x0000400,length=0x400
  PAGE 1 : L0L1RAM(RW):origin=0x008000,length=0x2000
}
SECTIONS
{
      
 
    .stack:>M1RAM,PAGE=1  
   
}

      其中,使用环境为软仿真环境(simulator)。正如程序中注释提到的,使用puts可以在stdout输出窗口中看到相关输出,而用printf则不行。

 

使用printf报错如下:Trouble running Target CPU: Can't read from data memory 0x10000, check memory config [-2185]

 

解决办法:将rts2800.lib改为rts2800_ml.lib,使用大内存模式之前,只能访问程序区的前64K(从错误的提示内存0x1000=64k就可以看出来),而程序区分配的段是以0x3F8000开始,由此可知printf函数寻址时需要访问64K之外存储段,故会产生访问错误。而改为大内存模式之后,就可以访问64k之后的存储段了,故修改之后可以运行。

 

      对于puts而言,不修改相应的库文件至rts2800_ml.lib,程序也可以正常产生输出,因为字符串常量“hello world!/n”是存储在数据段的低64k(const、econst),而puts函数内部访问机制应该和printf不同,它寻址时不需要访问64K之外的数据。将econst分配在高64k时,puts是不能正常输出的,这证明了相关猜想。

 

进一步,可以将cmd文件修改如下:

-l rts2800_ml.lib
-stack 400h
-heap 400h

MEMORY
{
PAGE 0 :
   PRAMH0     : origin = 0x3f8000, length = 0x002000      
        
PAGE 1 :
   /* SARAM                     */    
   RAMM0    : origin = 0x000000, length = 0x000400
   RAMM1    : origin = 0x000400, length = 0x000400

   /* Peripheral Frame 0:   */
  DEV_EMU    : origin = 0x000880, length = 0x000180
   FLASH_REGS : origin = 0x000A80, length = 0x000060
   CSM        : origin = 0x000AE0, length = 0x000010
   XINTF      : origin = 0x000B20, length = 0x000020
   CPU_TIMER0 : origin = 0x000C00, length = 0x000008
   CPU_TIMER1 : origin = 0x000C08, length = 0x000008  
   CPU_TIMER2 : origin = 0x000C10, length = 0x000008  
   PIE_CTRL   : origin = 0x000CE0, length = 0x000020
   PIE_VECT   : origin = 0x000D00, length = 0x000100

   /* Peripheral Frame 1:   */
   ECAN_A     : origin = 0x006000, length = 0x000100
   ECAN_AMBOX : origin = 0x006100, length = 0x000100

   /* Peripheral Frame 2:   */
   SYSTEM     : origin = 0x007010, length = 0x000020
   SPI_A      : origin = 0x007040, length = 0x000010
   SCI_A      : origin = 0x007050, length = 0x000010
   XINTRUPT   : origin = 0x007070, length = 0x000010
   GPIOMUX    : origin = 0x0070C0, length = 0x000020
   GPIODAT    : origin = 0x0070E0, length = 0x000020
   ADC        : origin = 0x007100, length = 0x000020
   EV_A       : origin = 0x007400, length = 0x000040
   EV_B       : origin = 0x007500, length = 0x000040
   SPI_B      : origin = 0x007740, length = 0x000010
   SCI_B      : origin = 0x007750, length = 0x000010
   MCBSP_A    : origin = 0x007800, length = 0x000040

   /* CSM Password Locations */
   CSM_PWL    : origin = 0x3F7FF8, length = 0x000008

   /* SARAM                    */    
  /* DRAMH0     : origin = 0x3f9800, length = 0x000800 */
   DRAML0     : origin = 0x008000, length = 0x001000
   DRAML1     : origin = 0x009000, length = 0x001000       
}
 
 
SECTIONS
{
   /* Allocate program areas: */
   .reset           : > PRAMH0,      PAGE = 0
   .text            : > PRAMH0,      PAGE = 0
   .cinit           : > PRAMH0,      PAGE = 0
   .cio             : > DRAML1,      PAGE = 1
   //.codestart        : > PRAMH0,      PAGE = 0
   /* Allocate data areas: */
   .stack           : > RAMM0|RAMM1,       PAGE = 1
   .bss             : > DRAML1,      PAGE = 1
   .ebss            : > DRAML0,      PAGE = 1
   .const           : > DRAML0,      PAGE = 1
   .econst          : > DRAML0,      PAGE = 1     
   .sysmem          : > DRAML0,      PAGE = 1
  
   /* Allocate Peripheral Frame 0 Register Structures:   */
   DevEmuRegsFile    : > DEV_EMU,    PAGE = 1
   FlashRegsFile     : > FLASH_REGS, PAGE = 1
   CsmRegsFile       : > CSM,        PAGE = 1
   XintfRegsFile     : > XINTF,      PAGE = 1
   CpuTimer0RegsFile : > CPU_TIMER0, PAGE = 1     
   CpuTimer1RegsFile : > CPU_TIMER1, PAGE = 1     
   CpuTimer2RegsFile : > CPU_TIMER2, PAGE = 1     
   PieCtrlRegsFile   : > PIE_CTRL,   PAGE = 1     
   PieVectTableFile  : > PIE_VECT,   PAGE = 1

   /* Allocate Peripheral Frame 2 Register Structures:   */
   ECanaRegsFile     : > ECAN_A,      PAGE = 1  
   ECanaMboxesFile   : > ECAN_AMBOX   PAGE = 1

   /* Allocate Peripheral Frame 1 Register Structures:   */
   SysCtrlRegsFile   : > SYSTEM,     PAGE = 1
   SpiaRegsFile      : > SPI_A,      PAGE = 1
   SciaRegsFile      : > SCI_A,      PAGE = 1
   XIntruptRegsFile  : > XINTRUPT,   PAGE = 1
   GpioMuxRegsFile   : > GPIOMUX,    PAGE = 1
   GpioDataRegsFile  : > GPIODAT     PAGE = 1
   AdcRegsFile       : > ADC,        PAGE = 1
   EvaRegsFile       : > EV_A,       PAGE = 1
   EvbRegsFile       : > EV_B,       PAGE = 1
   ScibRegsFile      : > SCI_B,      PAGE = 1
   McbspaRegsFile    : > MCBSP_A,    PAGE = 1

   /* CSM Password Locations */
   CsmPwlFile      : > CSM_PWL,     PAGE = 1

}

这样之后,就具有了通用性,在软件仿真和硬件仿真环境下都能运行了,只是在硬件仿真环境下运行printf会占用不少资源,似乎可用性不高。

 

 

原创粉丝点击