contiki-Event Scheduling

Source: Internet
Author: User

Event-driven mechanism is widely used in embedded systems, similar to the interrupt mechanism, when an event arrives (such as a key, data arrives), the system responds to and processes the event. With respect to the polling mechanism, the event mechanism has the advantage of being a star, with low power consumption (the system is in hibernation and is awakened when an event arrives) and MCU utilization is high.

Contiki the event mechanism into the protothreads mechanism, where each event binds to a process (the broadcast event exception), and the messages between processes are passed through events. Signs an event with an unsigned character type. The event structure Body event_data is defined as follows:

struct event_data {  process_event_t ev;  process_data_t data;   struct process *charvoid *        process_data_t;

Identifies an event with an unsigned character type, Contiki defines 10 events (0x80~0x8a), and others are used by the user.

#define Process_event_none            0x80#define process_event_init            0x81#define process_event_poll            0x82#define process_event_exit            0x83#define process_event_service_removed 0x84#define process_event_continue        0x85#define process_event_msg             0x86#define Process_ event_exited          0x87#define process_event_timer           0x88#define process_event_com             0x89#define Process_event_max             0x8a

Each event binds to a process, if p is null, indicating that the event binds all processes (that is, broadcast event Process_broadcast). In addition, events can carry data that can be used to communicate between processes (passing events with data to another process).

Static process_num_events_t nevents, fevent; Static struct Event_data events[process_conf_numevents]; #define Process_conf_numevents 32

Contiki holds events with a global static array, which means that the number of events is specified before the system is run (the user can process_conf_numevents the configuration size) and the array subscript provides quick access to events. The system also defines another two global static variables nevents and fevent, respectively, to record the total number of unhandled events and the next pending location. The event logic consists of a ring queue, stored in an array. Such as:

It can be seen that for Contiki systems, there is no priority for the event, but a first-to-first service strategy, and a global variable fevent records the next subscript for the next event to be processed.

Event generation

Contiki has two ways of generating events, namely, synchronous and asynchronous. Synchronization events are generated by the process_post_synch function, which is processed directly after the event is triggered (calling the call_process function). Asynchronous event generation is generated by Process_post , and is not processed in a timely manner, but into the event queue waiting for processing,process_post flowchart as follows:

1 intProcess_post (structProcess *p, process_event_t ev, process_data_t data)2 {3   Staticprocess_num_events_t Snum;4 5   if(process_current () = =NULL) {6PRINTF ("Process_post:null Process posts event%d to process '%s ', nevents%d\n",7 ev,process_name_string (P), nevents);8   } 9   Else {TenPRINTF ("process_post:process '%s ' posts event%d to process '%s ', nevents%d\n", One process_name_string (Process_current ()), Ev, Ap = = Process_broadcast?"<broadcast>": Process_name_string (P), nevents); -   } -   /*nevents Number of unhandled events, event queue full, return process_err_full*/ the   if(Nevents = =process_conf_numevents) { - #ifDEBUG -     if(p = =process_broadcast) { -printf"Soft panic:event queue is full when broadcast event%d were posted from%s\n", Ev, process_name_string (process_current)); +}Else { -printf"Soft panic:event queue is full if event%d was posted to%s frpm%s\n", Ev, process_name_string (p), process_name_string (process_current)); +     } A #endif/* DEBUG */ at     returnProcess_err_full; -   } -   //Event queue is not full, continue -Snum = (process_num_events_t) (fevent + nevents)% Process_conf_numevents;//get the next idle position in the loop queue -Events[snum].ev = EV;//joining events to a queue -Events[snum].data =data; inEVENTS[SNUM].P =p; -++nevents; to  + #ifProcess_conf_stats -   if(Nevents >process_maxevents) { theProcess_maxevents =nevents; *   } $ #endif/* Process_conf_stats */Panax Notoginseng    -   returnProcess_err_ok; the}

  process_post First determine if the event queue is full, if the full return error, otherwise get the next idle position (because the ring queue, need to do the remainder), and then set the event and the total number of unhandled events plus 1.

Event scheduling

Events do not have a priority, with a first-to-first service policy, and each system poll (Process_run function) handles only one event, and thedo_event function handles the event with the following flowchart:

1 /*2 * Process The next event in the event queue and deliver it to3 * Listening processes.4  */5 /*---------------------------------------------------------------------------*/6 Static void7Do_event (void)8 {9   Staticprocess_event_t ev;Ten   Staticprocess_data_t data; One   Static structProcess *receiver; A   Static structProcess *p; -    -   /* the * If There is any events in the queue, take the first one and walk - * Through the list of processes to see if the event should be - * delivered to any of them. If So, we call the event handler - * function for the process. We only process one event at a time and + * Call the poll handlers inbetween. -    */ +  A   if(Nevents >0) { at      -     /*There is events that we should deliver.*/ -       /*Remove Pending Events*/ -EV =Events[fevent].ev; -      -data =Events[fevent].data; inReceiver =EVENTS[FEVENT].P; -  to     /*Since We have seen the new event, we move pointer upwards + and Decrese the number of events.*/ -       /*update fevent and nevents*/ theFevent = (fevent +1) %process_conf_numevents; *--nevents; $ Panax Notoginseng     /*If This is a broadcast event, we deliver it to all events, in - order of their priority.*/ the       /*whether the event is broadcast*/ +     if(Receiver = =process_broadcast) { A        for(p = process_list; p! = NULL; p = p->next) { the  +         /*If We have been requested to poll a process - between processing the broadcast event.*/ $          /*a high-priority process that runs all high-priority processes*/ $         if(poll_requested) { - Do_poll (); -         } theCall_process (p, Ev, data);//Handling Events -       }Wuyi     }  the     Else { -           /*broadcast event, so we deliver it to the Wu specified process. Not broadcast events, provided to specific processes*/ -           /*If The event is an INIT event, we should also update the About state of the process. If it is an initialization event, set the process status to running*/ $         if(EV = =process_event_init) { -Receiver->state =process_state_running; -       } -  A       /*Make sure, the process actually is running.*/ +Call_process (receiver, Ev, data);//Handling Events the     } -   } $}

  do_event First takes out the event (that is, copies the value of the event to a new variable), updates the total number of unhandled events, and an array subscript for the next pending event (the ring queue, which requires a remainder operation). Then determine whether the event is a broadcast event Process_broadcast, if, considering the processing of broadcast events may take more time, in order to ensure system real-time, first run a high-priority process, and then to handle the event (call call_process function). If the event is an initialization event Process_event_init(This event is triggered when the process is created), the process state needs to be set to process_state_running.

Event handling

The actual event handling is the body threadof the function in the process, as described above,call_process calls the thread function to execute the process. The key code is as follows:

ret = P->thread (&p->pt, Ev, data);

Reference jelline Great God blog: http://jelline.blog.chinaunix.net

contiki-Event Scheduling

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.