a005-software architecture-front and rear structure

Source: Internet
Author: User
Tags define null

Structure of front and rear table


--------------------------------------------------------------------------------------------------------------- ----------------------
Development environment: AVR Studio 4.19 + avr-toolchain-installer-3.4.1.1195-win32.win32.x86
Chip Model: ATMEGA16
Chip Frequency: 8MHz


--------------------------------------------------------------------------------------------------------------- ----------------------

I. Overview 1, front and rear reception: Used to process input and output, generally in the interruption
Backstage: Used to deal with logical judgment, task calculation, etc., generally referred to CPUProcessing
Events: Use events to communicate with each other between the front and back tables to inform the occurrence and end of events, also known as message management
Event/Message management is the core of the pre-background.
For event/message management, refer to this article ( application of message mechanism in software design): http://www.xuebuyuan.com/1777265.html


--------------------------------------------------------------------------------------------------------------- ----------------------

2, before the running process of the background The following example contains three parts: [key input, IR input, digital tube output] + [Event Management] + [numerical calculation and storage]

In this example, the timer 0 will be used OCF0Interrupt timing Detection button and refresh the digital tube, using timer 1 ICP1Interrupts the receiving infrared signal.

If the interrupt is monitored when the key 1 is pressed, the "event _ Key 1 Press" is set to 1, indicating that this event occurred, otherwise 0.
If an infrared code 2 is received in the interrupt, the "event _ Receive Infrared 2" is set to 1, indicating that this event occurred, otherwise 0.
The remaining events are generated in the same way, and all events are saved in the event queue for CPUReal-time queries.
These events do not directly invoke the corresponding task API, but just set the message flag.
To this, the front desk interrupted the end of the task, no longer participate in subsequent operations.
In the background, CPUWill cycle through the message queue, if found "event _ Key 1 Press" flag is 1, the dispatch API"Task _ Show 001" to execute.

At the same time, if the background CPUAfter processing the numerical calculation, and not directly to the foreground of the digital tube display, but set the "event _ Calculate End" Flag is 1, and then this ends.
CPUMonitoring the "event _ Calculation End" Flag is 1 o'clock, the digital tube is dispatched API"Task _ Update Display" To execute, modify the digital tube display data.
In the interrupt, the digital tube in real-time refresh, you can see the results of the numerical calculation.

In other words, the foreground message passes through the message queue, passing the information to CPU
and CPUWith the foreground task associated with the APITo control and transmit data to the foreground task.
The front and rear stations are isolated from each other, but you can also use Message Queuing to contact the front and rear stations.

--------------------------------------------------------------------------------------------------------------- ----------------------

3. Event/message mechanism the benefits of such a design, the various task modules are isolated from each other, forming a loose connection, the software structure is very clear.
Reduce the overall complexity of the system, that is, the system is split into a lot of small modules, they are independent of each other.
Independent modules can easily be individually modified and replaced without affecting other modules.

--------------------------------------------------------------------------------------------------------------- ----------------------

Second, the Code implementation description:
1, the following will be implemented in several steps of the above example:
The first step: the front-time interrupt scheduling module, using the timer 0-time scheduling each scheduled task, including digital tube and key scanning, and give the operation of the task API
The second step: the Event/message management module, as a communication module between the front and rear stations.
The third step: foreground real-time tasks, including infrared reception, and give the operation of the task API
Fourth step: Background numeric calculation task.

The first step: the front-desk scheduled task scheduling module Description:
1, here will establish a time-sharing scheduling module, used for time-sharing scheduling of 3 scheduled Tasks
Code: config.hSome of the definitions used in:
#ifndef _countof#define _countof (_array) (sizeof (_array)/sizeof (_array[0]) #endif #ifndef null#define NULL    0# endif
sys.timer.cIn the Scheduler module:
#include <avr/interrupt.h> #include "drv_timer.h" #include "sys_timer.h" typedef void (*p_task_funtion) (void);          typedef struct {uint8_t delay;         Task delay count uint8_t period;    Task run interval p_task_funtion task; Task function}t_sys_task, *pt_sys_task;//This array is used to register and manage task queue static T_sys_task sys_task_ctrl[10];static Pt_sys_task p_sys_task_ CTRL = Sys_task_ctrl;//========================================================================================= =================//initializing the System task queue////===============================================================================    ===========================void sys_task_init (void) {uint8_t index = 0;        for (index = 0; index < _countof (Sys_task_ctrl); index++) {(P_sys_task_ctrl + index)->delay = 0;        (P_sys_task_ctrl + index)->period = 0;    (P_sys_task_ctrl + index)->task = NULL; }}// ==========================================================================================================/ /Add Task to Task queue////==========================================================================================================void    Sys_task_add (uint8_t delay, uint8_t period, p_task_funtion Task) {uint8_t index = 0; for (index = 0; index < _countof (Sys_task_ctrl); index++) {if (NULL = = (P_sys_task_ctrl + index)->task) {b Reak;    }} if (Index >= _countof (Sys_task_ctrl)) {return;}    (P_sys_task_ctrl + index)->delay = delay;    (P_sys_task_ctrl + index)->period = period-1; (P_sys_task_ctrl + index)->task = task;} ==========================================================================================================//System Tasks Timer///(1). 1MS markers///==================================================================================== with Timer0 OCF0 interrupt generation ======================void sys_timer_init (void) {///Timer 0 Initialization: CTC mode, OC0 pin not connected, 64 Prescaler drv_timer0_init (T0_WGM_CTC, Com_mo    De_none, t0_clk_source_clk_64); Set initial value: Tcnt0=0, ocr0=122 drv_timer0_set_tcnt0_ocr0 (0, 122); Enable OCF0 interrupt drv_timer0_int_enable (INT_MODE_OCF, enable);} ==========================================================================================================//System Timing Interrupt cycle =1ms)///(1). Use Timer0 's CTC interrupt to schedule each task//(2). Sys_task_add delay is initialized to 0, which means that the 1th time to enter this interrupt, will perform this task///============================================================ ==============================================volatile uint8_t temp2016;    Debug with ISR (timer0_comp_vect) {uint8_t index = 0;        for (index = 0; index < _countof (Sys_task_ctrl); index++) {temp2016 = index;            if (NULL! = (P_sys_task_ctrl + index)->task) {if (0 = = (P_sys_task_ctrl + index)->delay)                {(P_sys_task_ctrl + index)->delay = (P_sys_task_ctrl + index)->period;            (P_sys_task_ctrl + index)->task ();            } else {(P_sys_task_ctrl + index)->delay--; }        }    }}
mod_led_display.cIn the Digital tube task:
==========================================================================================================//Number of LEDs The code tube displays the refresh of the data////(1). Timed refresh in System timer////================================================================================================  ==========void mod_led_display_update (void) {PORTD ^= (1 << PD0); Run time mark//extinguish current digital tube and keep 3 clock cycle off to avoid glow *p_led_display_ctrl->seg_code = Segment_code[_countof (Segment_code)-1]    ;    Switch to the next 1 digital tube p_led_display_ctrl->index++;    if (P_led_display_ctrl->index > (_countof (Segment_index)-1)) {p_led_display_ctrl->index = 0;    }//Modify the bit selection, modify the display *p_led_display_ctrl->seg_index |= segment_index[_countof (Segment_index)-1];    *p_led_display_ctrl->seg_index &= segment_index[p_led_display_ctrl->index]; *p_led_display_ctrl->seg_code = segment_code[p_led_display_ctrl->data[segment_index[p_led_display_ctrl- >index]];}
main.cInitialize 3 tasks in:
==========================================================================================================//main function  ========================================================================================================== #include <avr/io.h> #include "mod_led_displayer.h" #include "sys_timer.h" #include "system.h" #include "config.h" void Mod_  test01 (void) {PORTD ^= (1 << PD1);  Run time marker}void mod_test02 (void) {PORTD ^= (1 << PD2); Run time marker}//==================================================================================================== ======//main function//=============================================================================================== ===========int Main (void) {//-----------------------------------------------------------------------------------    -------------------//Off Global Interrupt cli ();    System initialization sys_init ();    Open Global Interrupt sei (); PD[2:0] initialized to output 0 ddrd |= (1 << DDD0) | (1 << DDD1) |      (1 << DDD2); PORTD &= ~ ((1 << PD0) | (1 << PD1) |    (1 << PD2));  Register 3 Tasks Sys_task_add (0, 3, mod_led_display_update);              Run from moment 0, run once every 3 hours (one moment is 1ms) Sys_task_add (1, 3, mod_test01);              Run from moment 1, ... sys_task_add (2, 3, mod_test02);    Run from time 2, ...//CPU numerical calculation mod_led_display (123456789); ------------------------------------------------------------------------------------------------------while ( 1) {} return 0;}
Operation Result: 1, Task 1: Digital Tube Display 23456789, while PD0Output pulses with a period of 3ms
Task 2
PD1Pin every 3msFlip One level
Task 3PD2Pin every 3msFlip One level
2. 3Each task is a separate 3msBe dispatched once, but they are spaced between each other 1msis dispatched:
Task 1Time of Operation: 0, 3, 6, 9, ...
Task 2
Time of Operation: 1, 4, 7, 10, ...
Task 3
Time of Operation: 2, 5, 8, one, ...
The scheduling time for 3 tasks is as follows:

In other words, the same Ms, only 1 tasks are scheduled to run, which guarantees 1msThere is very little time to run the foreground task, and the remaining time is given to CPUTo do background tasks.
The oscilloscope output is as follows:

CH1Is PD0The output, CH2Is PD1The output, PD1Lag PD0 1ms
This means Task 2Lag Task 1 1msAfter being dispatched, the period is 3ms, stating that 2 tasks are every 3msBe dispatched once.

CH1Is PD0The output, CH2Is PD2The output, PD2Lag PD0 2ms
This means Task 3Lag Task 1 2msAfter being dispatched, i.e., Task 3Lag Task 2 1msAfter being dispatched.
The cycle of task scheduling is consistent with the expected 3ms

This enables scheduled scheduling tasks and supports TenTasks, you can set the time at which each task is scheduled to run.
Two or more tasks can be scheduled at the same time, or they can be dispatched several times apart.
For more time-consuming tasks, it should be placed separately in 1 hours to dispatch.

Test task time is used below PD0A rough measurement of the time spent on a digital tube refresh task
Code:
mod_led_display.cChanges in the digital tube task in PD0As follows:
==========================================================================================================//Number of LEDs The code tube displays the refresh of the data////(1). Timed refresh in System timer////================================================================================================  ==========void mod_led_display_update (void) {PORTD |= (1 << PD0); Run time mark//extinguish current digital tube and keep 3 clock cycle off to avoid glow *p_led_display_ctrl->seg_code = Segment_code[_countof (Segment_code)-1]    ;    Switch to the next 1 digital tube p_led_display_ctrl->index++;    if (P_led_display_ctrl->index > (_countof (Segment_index)-1)) {p_led_display_ctrl->index = 0;    }//Modify the bit selection, modify the display *p_led_display_ctrl->seg_index |= segment_index[_countof (Segment_index)-1];    *p_led_display_ctrl->seg_index &= segment_index[p_led_display_ctrl->index]; *p_led_display_ctrl->seg_code = segment_code[p_led_display_ctrl->data[segment_index[p_led_display_ctrl-    >index]]];  PORTD &= ~ (1 << PD0); Run time Tag}
When Task 1 starts PD0At high level, after Task 1 is finished PD0is low, i.e., PD0The high-level time is the time that task 1 consumes.
This time does not include the time to enter and exit the task function, so the real time will be slightly longer, but not much worse.
The oscilloscope output is as follows:

High-level time is 8.12usIn 8MHzEach instruction below is 0.125us, so here's probably the execution. theInstructions.
While 8.12usRelative to 1ms, it was extremely short, and only accounted for the 8.2%Time, so there's 91.8%The free time can be given to CPUTo handle background tasks.

--------------------------------------------------------------------------------------------------------------- ----------------------
Step two: Message management module


--------------------------------------------------------------------------------------------------------------- ----------------------
Step three: Foreground real-time task (infrared reception)


--------------------------------------------------------------------------------------------------------------- ----------------------
Fourth step: Background numeric calculation task 0
0



000

a005-software architecture-front and rear structure

Related Article

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.