Contiki 学习笔记:process_run 解析
来源:互联网 发布:淘宝老兵蜜蜡原石假货 编辑:程序博客网 时间:2024/05/24 05:23
process_run用于处理系统所有needspoll标记为1的进程及处理事件队列的下一个事件。本文深入原码,详细分析,也包括do_poll和do_event函数。
一、运行process_run
- int main()
- {
- dbg_setup_uart();
- usart_puts("Initialising\n");
- clock_init();
- process_init();
- process_start(&etimer_process,NULL);
- autostart_start(autostart_processes);
- while (1)
- {
- /*执行完所有needspoll为1的进程及处理完所有队列*/
- do
- {
- }
- while (process_run()> 0);
- }
- return 0;
- }
二、process_run剖析
process_run处理系统所有needspoll标记为1的进程及处理事件队列的下一个事件,源代码如下:
- static volatile unsignedchar poll_requested;//全局静态变量,标识系统是否有needspoll为1的进程
- int process_run(void)
- {
- if (poll_requested)//进程链表有needspoll为1的进程
- {
- do_poll();//见2.1
- }
- do_event();//见2.2
- return nevents + poll_requested; //若和为0,则表示处理完系统的所有事件,并且没有needspoll为1的进程
- }
透过上述的源代码,可以直观看出needspoll标记为1的进程可以优先执行。并且每执行一次process_run,将处理系统所有needspoll标记为1的进程,而只处理事件队列的一个事件。
2.1 do_poll函数
复位全局变量poll_requested,遍历整个进程链表,将needspoll标记为1的进程投入运行,并将相应的needspoll复位。源代码如下:
- static void do_poll(void)
- {
- struct process*p;
- poll_requested = 0;//复位全局变量
- for (p = process_list; p != NULL; p= p->next)//处理所有needspoll为1的进程
- {
- if (p->needspoll)//将needspoll为1的进程投入执行
- {
- p->state= PROCESS_STATE_RUNNING;
- p->needspoll= 0;
- call_process(p, PROCESS_EVENT_POLL,NULL);
- }
- }
- }
2.2 do_event函数
do_event处理事件队列的一个事件,有两种事件需特殊处理:PROCESS_BROADCAST和PROCESS_EVENT_INIT。前者是广播事件,需处理所有进程,后者是初始化事件,需将进程状态设为PROCESS_STATE_RUNNING。源代码如下:
- static process_num_events_t nevents;/*事件队列的总事件数 */
- static process_num_events_t fevent;/*指向下一个要传递的事件的位置*/
- static struct event_dataevents[PROCESS_CONF_NUMEVENTS];/*事件队列,用数组存储,逻辑上是环形队列*/
- static void do_event(void)
- {
- /*以下3个变量恰为struct event_data的成员,用于暂存即将处理(fevent事件)的值*/
- static process_event_t ev;
- static process_data_t data;
- static structprocess *receiver;
- static structprocess *p;
- if (nevents> 0)
- {
- /*提取将要处理事件的成员变量*/
- ev = events[fevent].ev;
- data = events[fevent].data;
- receiver =events[fevent].p;
- fevent = (fevent+ 1) % PROCESS_CONF_NUMEVENTS; //更新fevent(指向下一个待处理的事件,类型于微机的PC)
- --nevents;//事件队列被组织成环形队列,所以取余数
- if (receiver== PROCESS_BROADCAST)//如果事件是广播事件PROCESS_BROADCAST,则处理所有进程
- {
- for (p = process_list; p != NULL; p= p->next)
- {
- if (poll_requested)
- {
- do_poll();
- }
- call_process(p, ev, data);//jelline note: call the receiver process twice??
- }
- }
- else
- {
- if (ev == PROCESS_EVENT_INIT)//若事件是初始化,设置进程状态,确保进程状态为PROCESS_STATE_RUNNING
- {
- receiver->state= PROCESS_STATE_RUNNING;
- }
- call_process(receiver, ev, data);
- }
- }
- }
1 0
- Contiki 学习笔记:process_run 解析
- contiki学习笔记 spi部分解析
- Contiki学习笔记
- Contiki学习笔记:目录
- Contiki学习笔记:目录
- Contiki学习笔记
- contiki学习笔记-udp-server.c文件详细的解析
- contiki学习笔记之hello_world
- contiki学习笔记 clock部分
- contiki学习笔记 etimer部分
- contiki学习笔记之leds
- Contiki学习笔记3:定时器
- contiki 学习笔记 leds实现部分
- Contiki学习笔记之时钟初始化
- Contiki学习笔记之时钟初始化
- contiki学习笔记——IAR工程合集
- Contiki学习笔记——RPL协议详解
- contiki学习笔记-UDP-Client原厂代码分析
- LeetCode--Minimum Window Substring(最小匹配子串)
- Jboss Server Error:Server already running on localhost
- PostgreSQL postgres_fdw使用
- Java异常机制
- 下拉选框选择
- Contiki 学习笔记:process_run 解析
- 四轴飞行器,炸鸡两次终于起飞了
- C# 数据库操作小结
- shell 脚本笔记
- Step into Redis- 07 - 发布者-订阅者
- 同域jQuery(跨)iframe操作DOM
- 如何生成一个安全的验证码
- HDU-1022-Train Problem I(C++ && 简单堆栈)
- python的input和raw_input