MSP430 printf函数执行速度太慢

时间:2014-06-13 07:59:36

标签: c embedded printf msp430 contiki

我尝试使用Sky mote(MSP430 F1611 + CC2420)以100Hz采样频率从I2C传感器读取数据,并将数据写入串行端口(USB)。我尝试了几个测试,并意识到总输出数据的采样频率为78Hz。我用rtimer来描述我的采样和打印代码,发现打印功能会减慢整个过程。以下是一些分析输出:

start 50628
15490,f074,20,3b8c,ffab,49,ffcf,fb70
end 51189
start 51293
15491,f0a8,fff4,3ba4,ffc6,24,ffd8,fb90
end 51880
start 51984
15492,f094,20,3b30,ffa7,5b,fff3,fb70
end 52544
start 52647
15493,f118,bc,3ce0,ffab,70,fffc,fb90
end 53207
start 53311
15494,f030,1b0,3b44,ffa9,1f7,1f,fb80
end 53871

rtimer一秒钟有4098 * 8个刻度。在这里,我们可以清楚地看到打印需要大约560个刻度(17毫秒)。如果采样频率为100Hz,则打印功能应在10ms(327刻度)内完成。

我使用的嵌入式系统是Contiki OS,波特率是115200(最大波特率)。传感器样本包含112bytes signed int。

这是我的代码:

mpu_data_union samples;
int m=mpu_sample_all(&samples);
printf("start %u\n",RTIMER_NOW());
printf("%lu,%x,%x,%x,%x,%x,%x,%x\n",
  counterxx,samples.data.accel_x,samples.data.accel_y,
  samples.data.accel_z,samples.data.gyro_x,
  samples.data.gyro_y,samples.data.gyro_z,
  samples.data.temperature);
printf("end %u\n",RTIMER_NOW());

我希望以前有过优化printf或UART经验的人可以提供一些建议。

谢谢!

3 个答案:

答案 0 :(得分:1)

我有一个类似的问题,printf函数对于我使用的MSP变体来说太大了所以我不得不编写我自己的printf函数版本,因为我不需要所有与之相关的行李格式字符串转换器。我写了一组小函数,它们以所需的格式输出一个值,并将字符输出直接发送给usart。

printf("%lu,%x,%x,%x,%x,%x,%x,%x\n", counterxx,samples.data.accel_x,samples.data.accel_y, samples.data.accel_z,samples.data.gyro_x, samples.data.gyro_y,samples.data.gyro_z, samples.data.temperature);

成为

Send_Long_Decimal( counterxx ) ; 
Send_Hex( samples.data.accel_x ) ; 
Send_Hex( samples.data.accel_y ) ;
Send_Hex( samples.data.accel_z ) ;
Send_Hex( samples.data.gyro_x)  ;
Send_Hex( samples.data.gyro_y ) ;
Send_Hex( samples.data.gyro_z ) ;
Send_Hex( samples.data.temperature ) ;
Send_Newline() ;

Morty的答案建议使用非阻塞,中断驱动的串行端口实现。应鼓励这样做,以便串行传输所花费的时间不会超出您的可用处理时间。

查看日志中发送的数据,看起来第一条记录的长度大约为64个字符。以115kbaud发送其中的100个将花费超过0.5秒。然后,您必须从I2C接口读取数据,并在剩余的不到0.5秒内执行一些数据处理/存储。

答案 1 :(得分:0)

虽然printf很慢,但序列甚至更慢(到目前为止)。默认情况下,Contiki使用MSP430 F1xx芯片的阻塞序列(参见1)。通过设置UART0_CONF_TX_WITH_INTERRUPT(将-DUART0_CONF_TX_WITH_INTERRUPT添加到CFLAGS),您可以切换到非阻塞缓冲串行(默认为128字节)。

答案 2 :(得分:0)

C库printf不是为MSP430 16位微控制器设计的。相反,它旨在成为打印到控制台问题的通用解决方案。

如果您需要更高效的解决方案,则应实施自己的自定义打印方法,写出UART。

以下是一些免费提供的解决方案:

  1. http://43oh.com/2011/10/tiny-printf-for-the-space-constrained-msp430/

  2. https://gist.github.com/nicholasjconn/2896369http://www.msp430launchpad.com/2012/06/using-printf.html