@20150216
The first contact with asymmetric dual-core MCU, due to a lot of knowledge unfamiliar, these three days encountered a lot of problems. Now finally the event driven on the M0 nuclear run up, send a brief introduction of this event-driven architecture and the 5410x chip learning from these days.
With regard to the event-driven architecture, it is mainly used for low power design and can easily enter sleep mode. General single-chip microcomputer bare Ben are polling, such as:
- void Main ()
- {
- while (1)
- {
- Tesk1 ();
- Tesk2 ();
- Tesk3 ();
- }
- }
Copy Code
In this polling process, it is difficult to determine when to hibernate, how long to sleep, and what level of sleep to use.
The event-driven main function is as follows (take VSF as an example):
- while (1)
- {
- Vsfsm_poll ();
- Vsf_enter_critical ();
- if (!vsfsm_get_event_pending ())
- {
- Vsf_leave_critical ();
- __wfi ();
- }
- Else
- {
- Vsf_leave_critical ();
- }
- }
Copy Code
VSF adds an event queue to the program that sleeps when the event queue is empty. The sleep time is determined by the wake-up timer configured by the program, and of course some external hardware interrupts can also be awakened. If you need to use a different sleep level, you also need to do a sleep level manager, different threads require different sleep levels, and then the manager decides the sleep level. Of course, these fine-grained configuration will be more troublesome ...
In fact, the event-driven capable, in the RTOs are capable, many things rtos can do better, more comfortable. However, the event-driven has one of the biggest advantages: the province of RAM, in many low-power MCU, RAM is generally small, although the RTOs can be cropped, but the allocation of each task stack can not be cropped, when more tasks, RAM allocation is also very annoying. The event driver is still a bare-Ben, just put the thread (a function pointer plus an event state) in the queue for management, one by one call. Each thread only spends more than 10 bytes of RAM.
This time with Simon's event-driven VSF platform, the code is on GitHub, and Github.com/versaloon/vsf,21ic has some introductory posts that are interested to see for themselves.
The following example code caught dead, very very coarse, the code in the post added a Chinese explanation
- Thread 1
- Define an event state
- #define EVENT_1_USER_LOCAL_SCANF (vsfsm_evt_user_local + 1)
- static struct vsfsm_state_t *
- Event_1_handler (struct vsfsm_t *sm, vsfsm_evt_t evt);
- struct vsfsm_t event_1_sm =
- {
- {Event_1_handler},//Initialize Handler
- };
- For generating periodic event timers at intervals of 5 seconds
- static struct vsftimer_timer_t Event_1_timer =
- {
- 5000,//interval is 5 seconds
- &EVENT_1_SM,//corresponding state machine
- EVENT_1_USER_LOCAL_SCANF,//Cycle events
- };
- struct vsfsm_state_t *
- Event_1_handler (struct vsfsm_t *sm, vsfsm_evt_t evt)
- {
- Switch (EVT)
- {
- Case VSFSM_EVT_INIT://Initialize event, default execution
- Vsftimer_register (&event_1_timer);
- Break
- Case EVENT_1_USER_LOCAL_SCANF://Periodic event handling
- Board_uartputstr ("Event 1rn"); Print out "Event 1"
- Print_tick (); Print the current system tick
- Break
- Default
- Break
- }
- return NULL;
- }
- Thread 2, change the thread interval to 3 seconds
- #define EVENT_2_USER_LOCAL_SCANF (vsfsm_evt_user_local + 1)
- static struct vsfsm_state_t *
- Event_2_handler (struct vsfsm_t *sm, vsfsm_evt_t evt);
- struct vsfsm_t event_2_sm =
- {
- {Event_2_handler},
- };
- static struct vsftimer_timer_t Event_2_timer =
- {
- 3000,
- &EVENT_2_SM,
- EVENT_2_USER_LOCAL_SCANF,
- };
- struct vsfsm_state_t *
- Event_2_handler (struct vsfsm_t *sm, vsfsm_evt_t evt)
- {
- Switch (EVT)
- {
- Case Vsfsm_evt_init:
- Vsftimer_register (&event_2_timer);
- Break
- Case EVENT_2_USER_LOCAL_SCANF:
- Board_uartputstr ("event 2rn");
- Print_tick ();
- Break
- Default
- Break
- }
- return NULL;
- }
- int main (void)
- {
- Serial initialization
- Board_uart_init ();
- Wake with Utick interrupt
- Board_utick_init ();
- Vsftimer_init ();
- Board_uartputstr ("Start!rn");
- Vsfsm_init (&EVENT_1_SM);
- Vsfsm_init (&EVENT_2_SM);
- Vsf_leave_critical ();
- while (1)
- {
- Vsfsm_poll (); Polling state machine
- Vsf_enter_critical ();
- if (!vsfsm_get_event_pending ())//Determine if there are unhandled events
- {
- Vsf_leave_critical ();
- __wfi ();
- }
- Else
- {
- Vsf_leave_critical ();
- }
- }
- }
Copy Code
Serial output:
PS: Now the Vsftimer does not do the dynamic management of sleep time, but rather a simple rough timing wake-up once to see if there are any events to deal with. This feature I will be perfected in the back.
There's a lot of fun in Simon's architecture, and it's interesting to study.
"LPC54100" running on M0 event-driven Architecture (i)