`
hulianwang2014
  • 浏览: 690058 次
文章分类
社区版块
存档分类
最新评论
  • bcworld: 排版成这样,一点看的欲望都没有了
    jfinal

contiki 学习笔记 leds实现部分

 
阅读更多
1.前言
contiki是一款小型开源,易于移植的多任务操作系统,专门为无线传感网设计,适合内存受限制的网络系统。国内的研究和应用还处于初级阶段,甚至还不知道这个contiki如何发音,也没有那么响亮的中文名称。如果还没有中文名称的话,就干脆叫它“康提基”(来自wifi百科)。
本从分析最简单基础的led驱动部分。contiki的led驱动可简单分为抽象接口和具体实现两部分。由于contiki需要适应多种平台,所以contiki提供了控制LED的三大接口,分别是:
voidleds_arch_init(void) LED初始化函数
unsigned charleds_arch_get(void) LED状态获取函数
voidleds_arch_set(unsigned char leds) LED状态设置函数
各LED状态按位排列,例如最低位为LED1的状态,最低位为1则LED点亮,最低位为0则LED熄灭。以此类推。
平台说明
硬件平台:CC2530
软件平台:IAR EW8051
2.相关文件
2.1 leds.c和leds.h
该文件为led驱动代码的抽象接口,具体代码如下:

void leds_init(void);
void leds_blink(void);
unsigned char leds_get(void);
void leds_on(unsigned char leds);
void leds_off(unsigned char leds);
void leds_toggle(unsigned char leds);
void leds_invert(unsigned char leds);

而另外三个函数便是以上抽象接口的具体实现,具体代码如下:

void leds_arch_init(void);
unsigned char leds_arch_get(void);
void leds_arch_set(unsigned char leds);

2.2 leds-arch.c
以-arch结尾的一般都是接口实现的代码,再如rime-arch.h。该部分代码可位于contiki/cpu/cc253x,也可以位于contiki/platform/cc2530dk。该文件在哪不重要,重要的该文件本质为led的驱动。(学习contiki的过程中,我总是纠结哪些文件应该在哪个文件夹,其实这并不重要,重要的是看懂这些文件到底有什么功能)
虽然代码接口部分显得非常简单,但是如果认真查看leds中的具体代码,还是颇费功夫。contiki具备能量消耗统计功能,任何LED的操作都会被统计分析。个人认为这种能量统计机制非常有特色,有时间可以深入研究。
3.具体实现
LED初始化和控制程序,难不倒任何有经验的嵌入式工程师,理解代码还不如理解contiki的结构。如果LED不在同一个端口上,那么可以使用switch-case结构,总之该部分容易实现。甚至可以比下面的代码写的更优美。
具体代码如下:

/* H/W Connections */
#define LED1_PIN    P1_0
#define LED2_PIN    P1_1
#define LED3_PIN    P1_4

/* P0DIR and P0SEL masks */
#define LED1_MASK   0x01
#define LED2_MASK   0x02
#define LED3_MASK   0x10
#define LED4_MASK   0x02
/*---------------------------------------------------------------------------*/
void
leds_arch_init(void)
{
  P1SEL &= ~(LED1_MASK | LED2_MASK | LED3_MASK);
  P1DIR |= (LED1_MASK | LED2_MASK | LED3_MASK);
}
/*---------------------------------------------------------------------------*/
unsigned char
leds_arch_get(void)
{
  unsigned char v;

  v = (unsigned char) (LED1_PIN | (LED2_PIN << 1) | (LED3_PIN << 2));

  return v;
}
/*---------------------------------------------------------------------------*/
void
leds_arch_set(unsigned char leds)
{
  LED1_PIN = leds & 0x01;
  LED2_PIN = (leds & 0x02) >> 1;
  LED3_PIN = (leds & 0x04) >> 2;
}
/*---------------------------------------------------------------------------*/

4.范例
在main开始的部分,可初始化LED即调用leds_init()。定义一个任务,该任务实现LED闪烁,间隔时间为1s。在这个任务中还涉及contiki任务的基本结构,etimer的使用,这里暂不详细分析,因为分析这些的博文很多我就不重复劳动了。具体代码如下:

#include "contiki.h"
#include "dev/leds.h"
/*---------------------------------------------------------------------------*/
PROCESS(blink_process, "Blink");
AUTOSTART_PROCESSES(&blink_process);
/*---------------------------------------------------------------------------*/
PROCESS_THREAD(blink_process, ev, data)
{
  static struct etimer et;
  PROCESS_BEGIN();

  while(1) {
    etimer_set(&et, CLOCK_SECOND);                    // etimer溢出周期为1s
    PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et));
    leds_on(1);                                       // 打开LED1
    etimer_set(&et, CLOCK_SECOND);
    PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et));
    leds_off(1);
  }

  PROCESS_END();
}

5.总结
leds部分实现还算简单易懂,写这些东西主要为了理解contiki的具体结构,理解contiki的设计思路。那么接下来便可切入rtimer部分。请注意rtimer为一种定时器而rime则是一种协议栈,两者都是contiki的一个部分,相差一个字母t,但是完全不同。
PS:写博客真TMD的痛苦,但是我还是“逼着”自己多写写。第一,文字总结的东西比自己心里默想要踏实的多,很多细节问题会在书写的过程中重新暴露出来。第二,写博客或许还可以找到志同道合的人,虽然国内搞contiki的人太少了!
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics