注册 登录
电子工程世界-论坛 返回首页 EEWORLD首页 频道 EE大学堂 下载中心 Datasheet 专题
dan158185的个人空间 https://home.eeworld.com.cn/space-uid-349284.html [收藏] [复制] [分享] [RSS]
日志

CC2538之TinyOS例程实验:2-printf

已有 1889 次阅读2016-1-5 16:05 |个人分类:CC2538之TinyOS例程

上一篇blink的例程使用的外设驱动为GPIO;这一篇继续基本外设驱动串口,串口设置波特率默认115200

例程目录:tinyos-main-release_tinyos_2_1_2\apps\cc2538_Test\TestPrintf

包含文件:

Makefile

TestPrintfAppC.nc----configuration

TestPrintfC.nc---------module

Makefile

  1. COMPONENT=TestPrintfAppC  
  2. CFLAGS += -I$(TOSDIR)/lib/printf  
  3. CFLAGS += -DUSE_TIMER_HANDLER  
  4. CFLAGS += -DUSE_UART_HANDLER  
  5. CFLAGS += -DUART0_TX_INTERRUPT_OFF  
  6. include $(MAKERULES)  
结合第一篇blink nesC语法
Makefile的书写规则COMPONENT应该=[configuration],此处为TestPrintfAppC
结尾处include $(MAKERULES) 为固定写法,旨在使用makerules
CFLAGS += -I$(TOSDIR)/lib/printf 使用printf库的路径
下面的是用户自己的条件编译,
CFLAGS += -DUSE_TIMER_HANDLER     使用Timer中断
CFLAGS += -DUSE_UART_HANDLER      使用UART中断
CFLAGS += -DUART0_TX_INTERRUPT_OFF 关闭UART TX中断


TestPrintfAppC.nc

  1. #define NEW_PRINTF_SEMANTICS  
  2. #include "printf.h"  
  3.   
  4. configuration TestPrintfAppC{  
  5. }  
  6. implementation {  
  7.   components MainC, PrintfC, TestPrintfC;  
  8.   components new TimerMilliC();  
  9.   
  10.   TestPrintfC.Boot -> MainC;  
  11.   TestPrintfC.Timer -> TimerMilliC;  
  12. }  
使用:
components为:MainC,PrintfC, TestPrintfC,TimerMilliC();
interface为:Boot,Timer
#define NEW_PRINTF_SEMANTICS 可以在编译的时候测试一下注释掉,其实就是对应有#warnning一些

TestPrintfC.nc

  1. /*******************************************************************  
  2.  *实验2----串口printf实验,串口(默认波特率115200)  
  3.  *节点需求数1  
  4.  *编译命令make cc2538cb  
  5.  ********************************************************************/  
  6.    
  7.   
  8. #include "printf.h"  
  9. module TestPrintfC @safe() {  
  10.   uses {  
  11.     interface Boot;  
  12.     interface Timer<TMilli>;  
  13.   }  
  14. }  
  15. implementation {  
  16.   
  17.   uint8_t dummyVar1 = 123;  
  18.   uint16_t dummyVar2 = 12345;  
  19.   uint32_t dummyVar3 = 1234567890;  
  20.   /***************************************************  
  21.   *启动事件  
  22.   ****************************************************/  
  23.   event void Boot.booted() {  
  24.         /**开启一秒的周期性定时器(单位毫秒)  Timer**/    
  25.         call Timer.startPeriodic(1000);  
  26.   }  
  27.   
  28.   /***************************************************  
  29.   *Timer定时时间到事件  
  30.   ****************************************************/  
  31.   event void Timer.fired() {  
  32.         /**串口(默认波特率115200)打印*********************************/  
  33.     printf("Hi I am writing to you from my TinyOS application!!\n");  
  34.     printf("Here is a uint8: %u\n", dummyVar1);  
  35.     printf("Here is a uint16: %u\n", dummyVar2);  
  36.     printf("Here is a uint32: %lu\n", dummyVar3);  
  37.     /**启动缓冲区数据送至uart tx************************************/  
  38.     printfflush();  
  39.   }  
  40. }  

可以参考blink的nesC的基础语法阅读代码;不多做介绍,实验结果可以去参考视频


再此之前大家可以通过TestPrintfAppC.nc----configuration发现并没有wire PintfC组件,也可以通过yeti2组件的图形查看会发现没有组件和他有连线,TestPrintfC.nc---------module部分没有使用PintfC的interface,事实上PintfC组件也并没有provides 任何interface,为什么可以使用PintfC/PintfP中的方法呢?
此处可以引申一个nesC的编程技巧,自己去查看tinyos-main-release_tinyos_2_1_2\tos\lib\printf下PrintfC.nc和PrintfP.nc组件源码,在此略过;其实他们的连接是隐藏的,通过printf.h文件,当TestPrintfC.nc中调用printf和printfflush的时候通过printf.h指定到了PintfC提供的函数;这样的写法当然也是不科学的,增加了代码的阅读难度,一般常常用来自己编写printf等覆盖gcc等编译器自带的printf等库函数的实现

下面介绍一下为什么不推荐使用PintfC组件来实现printf函数
1,打印是先放入缓冲区,调用printfflush()函数才操作串口
2,和blip等网络测试的blip_printf.h冲突

那么更加简单的做法呢?直接#include "printf.h",调用printf函数就行了,当然Makefile也要加入 
  1. <span style="font-size:18px;"><strong>CFLAGS += -DNOT_USE_PRINTFC_BUT_USE_PRINT</strong></span>  
这个条件编译宏的含义就在于不使用PintfC组件,直接使用printf函数完成串口打印,再此例程后面的例程都是使用此直接法;

我们得出的结论是TinyOS系统,并不是把所有的代码写成nesC组件就高效,有时候简单的一个c或者一个h头文件就能搞定

printf的意义在于打印结果,调试使用较多!如需修改波特率可以去tinyos-main-release_tinyos_2_1_2\tos\chips\cc2538\usart下找到对应的文件修改就行!

nesC福利:
default-----除去C语言的switch使用,在nesC中常常用来修饰event,表示此事件不做处理
写法1:
  1. event void Timer.fired() {  
  2.          
  3. }  

写法2:
  1. default event void Timer.fired() {  
  2.          
  3. }  
两者是等价的

@safe()---常常用来修饰module,表明该组件内存等是安全的,也即是越界,野指针等是检查过的
如:
  1. module TestPrintfC @safe()  

关键字等的介绍会随着例程出现慢慢补充介绍!
评论 (0 个评论)

facelist doodle 涂鸦板

您需要登录后才可以评论 登录 | 注册

热门文章