Improve a code program that implements multitasking operation meters

At the beginning of 2002, the author wrote a working procedure for an IC card prepaid meter. The meter uses Philips' 8-bit 51 extended-type single-chip 87LPC764, which requires many functions, including display-off, load calculation and control, indicator flicker, and various meters. Parameter query, etc. In short, there are many units to use time. The author used ASM51 to complete the preparation of this program. The number of programs after completion is a little more than 2KB. Later, for various reasons, this program was not actually used, but was used for timing and load calculations on an aging device after making some changes. About a year later, the author rewrote the code.

Improve a code program that implements multitasking operation meters

1 system improvement

It can be said that the code implemented by ASM51 is not organized. What features are added to the function, and the structure of the program is very loose. In fact, this is the reason why the author finally decided to rewrite the code. As we all know, the 87LPC764 has 4KB of Flash ROM, and the program size of the author is only 2KB, so the first idea is to use C language as the main development language, which should not lead to insufficient code space. Secondly, considering the modules (or tasks, hereinafter referred to as tasks) that require timing functions, it is necessary to manage these tasks in an orderly manner. The author considers the use of the time slice polling method, that is, for each task that requires time management, the time interval is reached, that is, the code is run to achieve the purpose of rational use of the system timer resource. In the case of the 51 system, generally at least one timer can be used for polling of time slices. Based on the above ideas, the following data types are constructed.

Typedef unsigned char uInt8

Typedef struct {

Void (*proc)( void ); /* handler */

uInt8 ms_count; /* Time slice size*/

} _op_;

After the data structure is defined, the implementation code is followed by three parts, namely initialization data, time slice refresh and time to execution.

Initialization data. #define proc_cnt 0x08 //Define the number of processes or tasks

/ / Task stack initialization

Code _op_ Op[proc_cnt] = { { ic_check 10 } { disp_loop 100 }

{ calc_power 150 } { set_led 2 } ... };

/ / Set the time slice initial value

Data uInt8 time_val[proc_cnt]={10,100,150,2,...};

The time slice is refreshed.

Void time_int1( void ) interrupt 3

{

uInt8 cnt;

Time_Counter: = Time_Unit;

For ( cnt = 0; cnt < proc_cnt; cnt++ )

{

Time_val[cnt]--;

}

}

The execution of the task.

Void main( void )

{

uInt8 cnt;

Init(); /* program initialization */

Interrupt_on(); /* Open interrupt*/

Do

{

For ( cnt = 0; cnt < proc_cnt; cnt++ )

{

If ( !time_val[cnt] )

{

Time_val[cnt] = Op[cnt].ms_count;

Op[cnt].proc();

}

}

}

While ( 1 );

}

In the above structure definition, proc can not take parameters, communication between tasks can define a parameter memory block, through a mechanism for data information interaction, such as defining a global variable. For small-capacity single-chip microcomputer systems, there are not many tasks that need to be done, and the total amount of tasks is not too much, so this coordination is not too difficult to handle. Perhaps everyone has the understanding that in a real-time system, almost all specific tasks have time attributes, even if there is no need for a timed process or task, it is not necessary to query and refresh from time to time. For example, IC card media detection is guaranteed to be sufficient once per second. Therefore, these tasks can also be included in this structure. In the above program code, considering the RAM limitation of the microcontroller system, the task stack cannot be built in RAM like some real-time OS. The author builds the task stack in the code space, so it can't dynamically join the task when the program is running. Therefore, the task stack needs to be determined when the program is compiled. At the same time, a set of count value flags time_val is defined, the amount of time when the program is running is recorded, and it is refreshed in a timer interrupt. Changing the Time_Unit in the time slice refresh interrupt process statement Time_Counter:=Time_Unit; can change the refresh granularity of the system time slice. Generally, this value is determined by the minimum time metric of the system. At the same time, it can be seen from the execution flow of the task that the system configuration does not change the nature of its front/backstage system, but only the background logic operation sequence is effectively managed. At the same time, if you make some changes to the task execution process and ensure that the time slice is small, the program is as follows.

Do

{

For ( cnt = 0; cnt < proc_cnt; cnt++ )

{

If ( !time_val[cnt] )

{

Time_val[cnt] = Op[cnt].ms_count;

Op[cnt].proc();

Break; /* After the execution is completed, re-prioritize the schedule */

}

}

}

While ( 1 );

Then the system becomes a task scheduling system with priority of execution frequency. Of course, this method is very careful, and pay attention to the allocation of time slices. If the time slice is too small, it may cause the task with lower execution frequency to be difficult to be executed; if there are two identical time slices, it is more dangerous. , may result in the second task with the same time slice not being executed, therefore, the allocation of time slices should be reasonable and guarantee its uniqueness.

2 performance analysis and task splitting

In the above two task management modes, the former is scheduled in the order of the task stack and the size of the time slice, and is temporarily referred to as pipeline job scheduling; and the latter is called frequency priority scheduling. Both methods have advantages and disadvantages. Each task of the pipeline job scheduling has the same priority. The time slice will be called in order, and the order and uniqueness of the time slice size are not required. The disadvantage is that the time slice is small, that is, the task requiring faster execution is required. Waiting for too long. Each task of frequency-prioritized scheduling divides the priority according to the size of its time slice, that is, the execution frequency, and the task with small time slice has high execution frequency and always has higher priority, but the allocation of time slices is coordinated, otherwise it may be This will cause the task with low execution frequency to wait for a long time. It is important to note that both methods may cause some tasks to wait for a long time. The time set by the time slice cannot be used as the basis for accurate time. According to the requirements or needs of the system, even during the execution of the task. Some protection work, such as interrupt shielding, should be taken into account when planning tasks. If a task is cumbersome or may have to wait for a long time, you should consider splitting the task, refine a larger task into smaller tasks, and divide a time-consuming task into multiple time-consuming tasks. Collaborate to complete its functions. For example, if the waiting time is long, a timed task may be attached, and when the timed task arrives, a message flag is sent, and the main process returns without detecting the message flag, otherwise the execution continues. The following is the sample code, assuming that the task will wait for a long time, now split it into two tasks proc1 and proc2 work together to complete the original work, proc1 is executed every 100 time units, and proc2 is executed every 200 time units .

/* Defines two tasks and adds them to the task stack. */

Code _op_Op[proc_cnt] = { ...{ proc1 100 } { proc2 200 } };

Data inttime1_Seg; /* Define a global flag */

/* Task implementation*/

Void proc1( void )

{

If ( time1_Seg )

Exit;

Else

time1_Seg = const_Time1; /* If the time is up, restore the initial value and */

/* Then execute the following code. */

... /* task actual execution code */

}

Void proc2( void )

{

If ( time1_Seg )

time1_Seg--;

}

As can be seen from the above example, after the task is split, it hardly takes up too much CPU time, which makes the waiting time of the task greatly reduced, so that the CPU has enough time for task management and scheduling. It also greatly enhances the structure and readability of the program.

2835 Single Color Led Strip

2835 Single Color Led Strip,Single Red Led Light,Single Color Led,Single Blue Led Light

NINGBO SENTU ART AND CRAFT CO.,LTD. , https://www.lightworld-sentu.com