CC2538之Contiki3.0实验:3-event
2016-01-11 16:35
204 查看
通过对PEOCESS的一些乱讲,应该有一点可以知道就是我们每编写一个PROCESS_THREAD(...)实际就是弄出了一个 (struct)process;大家可以理解是不是每一个[b]PROCESS_THREAD或者其他的都会在cmpile的时候产生一个全局的struct变量;回忆一下:[/b]
至此我们至少可以CTRL+C/CTRL+V写出自己的小的测试程序,我们不管是学习TinyOS或者Contiki实际并不是只是make然后下载,验证结果就完事了,应该掌握代码的编写;鱼和渔的基本区别是我写这些文档的意义所在;
TinyOS和Contiki都是event驱动;RIOT在Contiki介绍完后会重点去介绍;个人还是比较喜欢他的风格一点;
回忆TinyOS的event是很简单的,采用signal抛出事件,使用者处理;
Contiki的event咱们慢慢来看;我们现在在test_null基础上再编写一次,达到事件处理的目的;
首先在:core/sys/process.h中:
我们这次需要用到的函数为:
process_post
在core/sys/process.c中
下面修改test_null.c文件
看到不认识的家伙了 process_alloc_event();
在core/sys/process.c中:
PROCESS_WAIT_EVENT_UNTIL在core/sys/process.h中:
PT_TIELD_UNTIL在core/sys/pt.h中:
我们的设计思想是,test_null抛出事件,test_event获取该事件后亮灯,编译烧写到板子进行一下测试:
烧写到cc2538cb节点后,contiki-main先将三个led灯fade,流水灯效果;然后咱们发现三个led灯点亮了
说明test_event的leds_on(LEDS_ALL);得到了执行,事件的测试OK;貌似现在也只是最基础的写法测试
在此大家可以再去想一下Contiki的thread模型,PROCESS_WAIT_EVENT_UNTIL到底干了什么?
Contiki是否支持咱们回溯事件的抛出者是谁?
有一个例程我们最好去学习参考,以便以后写出自己的应用,那就是er_timer;可以参考2530的代码或者cc2538cb目录下的blink_hello.c
1;
2;
这些都不重要,那么我们来看一下 PROCESS_EVENT_TIMER这个东东,在core/sys/er_timer.h中
貌似有了PROCESS_EVENT_TIMER的影子,大家可以自己去思考一下,do_poll和do_event
PROCESS_EVENT_TIMER的定义在core/sys/process.h中
在这里我们基本上能够总算接触到了Contiki的event,更多的自己去看代码理解,也许你需要一个sourceinghit来阅读代码,而不用像我一样一个一个文件打开查看;
虽然还是觉得有点模棱两可;只能说再此我并没有感觉到C语言的Contiki的优势!并不是我黑Contiki,我移植TinyOS很多地方也是参考的Contiki;现在能体会到的就是编写应用还是相对要复杂;可以自己结合前面几篇文档对照代码形成自我的理解;现在的作者也只是Contiki的菜鸟;但是应用神马的就得从基础做起;
不得不说的是cc2538dk平台本质是TI的SmartRF06EB板子,我的cc2538cb的代码(驱动部分)主要是参考他修改而来,3.0代码和2.7代码部分在底层变动较大;高手们可以互相印证,至少我比较喜欢2.7的启动文件的写法;
struct process { struct process *next; #if PROCESS_CONF_NO_PROCESS_NAMES #define PROCESS_NAME_STRING(process) "" #else const char *name; #define PROCESS_NAME_STRING(process) (process)->name #endif PT_THREAD((* thread)(struct pt *, process_event_t, process_data_t)); struct pt pt; unsigned char state, needspoll; };
至此我们至少可以CTRL+C/CTRL+V写出自己的小的测试程序,我们不管是学习TinyOS或者Contiki实际并不是只是make然后下载,验证结果就完事了,应该掌握代码的编写;鱼和渔的基本区别是我写这些文档的意义所在;
TinyOS和Contiki都是event驱动;RIOT在Contiki介绍完后会重点去介绍;个人还是比较喜欢他的风格一点;
回忆TinyOS的event是很简单的,采用signal抛出事件,使用者处理;
Contiki的event咱们慢慢来看;我们现在在test_null基础上再编写一次,达到事件处理的目的;
首先在:core/sys/process.h中:
typedef unsigned char process_event_t; typedef void * process_data_t; typedef unsigned char process_num_events_t;
我们这次需要用到的函数为:
process_post
在core/sys/process.c中
int process_post(struct process *p, process_event_t ev, process_data_t data) { static process_num_events_t snum; if(PROCESS_CURRENT() == NULL) { PRINTF("process_post: NULL process posts event %d to process '%s', nevents %d\n", ev,PROCESS_NAME_STRING(p), nevents); } else { PRINTF("process_post: Process '%s' posts event %d to process '%s', nevents %d\n", PROCESS_NAME_STRING(PROCESS_CURRENT()), ev, p == PROCESS_BROADCAST? "<broadcast>": PROCESS_NAME_STRING(p), nevents); } if(nevents == PROCESS_CONF_NUMEVENTS) { #if DEBUG if(p == PROCESS_BROADCAST) { printf("soft panic: event queue is full when broadcast event %d was posted from %s\n", ev, PROCESS_NAME_STRING(process_current)); } else { printf("soft panic: event queue is full when event %d was posted to %s from %s\n", ev, PROCESS_NAME_STRING(p), PROCESS_NAME_STRING(process_current)); } #endif /* DEBUG */ return PROCESS_ERR_FULL; } snum = (process_num_events_t)(fevent + nevents) % PROCESS_CONF_NUMEVENTS; events[snum].ev = ev; events[snum].data = data; events[snum].p = p; ++nevents; #if PROCESS_CONF_STATS if(nevents > process_maxevents) { process_maxevents = nevents; } #endif /* PROCESS_CONF_STATS */ return PROCESS_ERR_OK; }
下面修改test_null.c文件
#include "contiki.h" #include "dev/leds.h" static process_event_t event_xxoo; PROCESS(test_null, "我是菜鸟"); PROCESS(test_event, "我还是菜鸟"); AUTOSTART_PROCESSES(&test_null, &test_event); PROCESS_THREAD(test_null, ev, data) { PROCESS_BEGIN(); event_xxoo = process_alloc_event(); process_post(&test_event, event_xxoo, NULL); PROCESS_END(); } PROCESS_THREAD(test_event, ev, data) { PROCESS_BEGIN(); PROCESS_WAIT_EVENT_UNTIL(ev == event_xxoo); leds_on(LEDS_ALL); PROCESS_END(); }
看到不认识的家伙了 process_alloc_event();
在core/sys/process.c中:
process_event_t process_alloc_event(void) { return lastevent++; }
PROCESS_WAIT_EVENT_UNTIL在core/sys/process.h中:
#define PROCESS_YIELD_UNTIL(c) PT_YIELD_UNTIL(process_pt, c) #define PROCESS_WAIT_EVENT_UNTIL(c) PROCESS_YIELD_UNTIL(c)
PT_TIELD_UNTIL在core/sys/pt.h中:
<pre name="code" class="cpp">#define PT_YIELD_UNTIL(pt, cond) \ do { \ PT_YIELD_FLAG = 0; \ LC_SET((pt)->lc); \ if((PT_YIELD_FLAG == 0) || !(cond)) { \ return PT_YIELDED; \ } \ } while(0)
我们的设计思想是,test_null抛出事件,test_event获取该事件后亮灯,编译烧写到板子进行一下测试:
烧写到cc2538cb节点后,contiki-main先将三个led灯fade,流水灯效果;然后咱们发现三个led灯点亮了
说明test_event的leds_on(LEDS_ALL);得到了执行,事件的测试OK;貌似现在也只是最基础的写法测试
在此大家可以再去想一下Contiki的thread模型,PROCESS_WAIT_EVENT_UNTIL到底干了什么?
Contiki是否支持咱们回溯事件的抛出者是谁?
有一个例程我们最好去学习参考,以便以后写出自己的应用,那就是er_timer;可以参考2530的代码或者cc2538cb目录下的blink_hello.c
#include "contiki.h" #include "dev/leds.h" #include <stdio.h> /* For printf() */ /*---------------------------------------------------------------------------*/ static struct etimer et_hello; static struct etimer et_blink; static uint16_t count; static uint8_t blinks; /*---------------------------------------------------------------------------*/ PROCESS(hello_world_process, "Hello world process"); PROCESS(blink_process, "LED blink process"); AUTOSTART_PROCESSES(&hello_world_process, &blink_process); /*---------------------------------------------------------------------------*/ PROCESS_THREAD(hello_world_process, ev, data) { PROCESS_BEGIN(); etimer_set(&et_hello, CLOCK_SECOND * 4); count = 0; while(1) { PROCESS_WAIT_EVENT(); if(ev == PROCESS_EVENT_TIMER) { printf("Sensor says #%u\n", count); count++; etimer_reset(&et_hello); } } PROCESS_END(); } /*---------------------------------------------------------------------------*/ PROCESS_THREAD(blink_process, ev, data) { PROCESS_BEGIN(); blinks = 0; while(1) { etimer_set(&et_blink, CLOCK_SECOND); PROCESS_WAIT_EVENT_UNTIL(ev == PROCESS_EVENT_TIMER); leds_off(LEDS_ALL); leds_on(blinks & LEDS_ALL); blinks++; printf("Blink... (state %0.2X)\n", leds_get()); } PROCESS_END(); } /*---------------------------------------------------------------------------*/其中的代码可以自己去阅读,参考process阅读;我们看到两种事件等待的写法:
1;
PROCESS_WAIT_EVENT(); if(ev == PROCESS_EVENT_TIMER){
... }
2;
PROCESS_WAIT_EVENT_UNTIL(ev == PROCESS_EVENT_TIMER);
这些都不重要,那么我们来看一下 PROCESS_EVENT_TIMER这个东东,在core/sys/er_timer.h中
PROCESS_THREAD(etimer_process, ev, data) { struct etimer *t, *u; PROCESS_BEGIN(); timerlist = NULL; while(1) { PROCESS_YIELD(); if(ev == PROCESS_EVENT_EXITED) { struct process *p = data; while(timerlist != NULL && timerlist->p == p) { timerlist = timerlist->next; } if(timerlist != NULL) { t = timerlist; while(t->next != NULL) { if(t->next->p == p) { t->next = t->next->next; } else t = t->next; } } continue; } else if(ev != PROCESS_EVENT_POLL) { continue; } again: u = NULL; for(t = timerlist; t != NULL; t = t->next) { if(timer_expired(&t->timer)) { if(process_post(t->p, PROCESS_EVENT_TIMER, t) == PROCESS_ERR_OK) { /* Reset the process ID of the event timer, to signal that the etimer has expired. This is later checked in the etimer_expired() function. */ t->p = PROCESS_NONE; if(u != NULL) { u->next = t->next; } else { timerlist = t->next; } t->next = NULL; update_time(); goto again; } else { etimer_request_poll(); } } u = t; } } PROCESS_END(); }
貌似有了PROCESS_EVENT_TIMER的影子,大家可以自己去思考一下,do_poll和do_event
PROCESS_EVENT_TIMER的定义在core/sys/process.h中
#define PROCESS_EVENT_TIMER 0x88
在这里我们基本上能够总算接触到了Contiki的event,更多的自己去看代码理解,也许你需要一个sourceinghit来阅读代码,而不用像我一样一个一个文件打开查看;
虽然还是觉得有点模棱两可;只能说再此我并没有感觉到C语言的Contiki的优势!并不是我黑Contiki,我移植TinyOS很多地方也是参考的Contiki;现在能体会到的就是编写应用还是相对要复杂;可以自己结合前面几篇文档对照代码形成自我的理解;现在的作者也只是Contiki的菜鸟;但是应用神马的就得从基础做起;
不得不说的是cc2538dk平台本质是TI的SmartRF06EB板子,我的cc2538cb的代码(驱动部分)主要是参考他修改而来,3.0代码和2.7代码部分在底层变动较大;高手们可以互相印证,至少我比较喜欢2.7的启动文件的写法;
相关文章推荐
- 如何在Mac OS X上安装 Ruby运行环境
- 在vim上实现跳转到定义处的方法
- Hbase原理、基本概念、基本架构
- 基于Selenium2和TestNG的自动化测试
- Android九点图(Nine-Patch)制作及应用
- 自定义圆角图片控件(Xfermode方式)
- VS2012发布网站详细步骤
- 每天一个设计模式: 桥模式(Bridge)
- Android自定义ProgressDialog进度等待框
- PreparedStatement与SQL批处理
- android TouchImageView 初级篇
- 86、交换机安全MAC层攻击配置实验之Static CAM
- 自定义状态栏
- 面试题9:斐波那契数列
- CSS样式随笔总结
- caffe添加layer层
- iOS APP之本地数据存储(译)
- 1.11考核数组中有字典
- WEB扫描类产品测试--AppScan-WVS-WebRavor(8)
- fatal error LNK1112: module machine type 'x64' conflicts with target machine type 'X86'