简体   繁体   中英

simultaneous tasks with 8051

Is there any way to run two tasks with the 8051 μC simultaneously? For example,

Task one

Delay 1 sec
P2.B2 = 1
Delay 1 sec
P2.B2 = 0

Task 2

If P1.B0 = 1
P2.B3=1

So at any time, press the switch connected to P2.0 is 1, LED at P2.3=ON, and P2.2 keeps LED at P2.2 blinking.

A task is something what is typically provided by the underlying OS. If you are running on a bare metal system without any OS, you have no tasks at the first point.

But your application can build its own tasks. The job is more or less easy. You have to build a scheduler, typically triggered by a hardware clock for task switching, create stacks for each of the tasks and some control structures for the maintenance of the tasks. As you have no MMU and no memory protection on bare metal systems like 8051, you simply can modify stack pointers to do the task switching.

That is exactly what a library like FreeRTos can do for you. There is a port for 8051 available as I know. Searching on the web returns a lot of links to 8051 FreeRtos. Maybe there are some more libraries which offering tasks for you.

But mostly the overhead of scheduling and all the administration effort is much to high. Running an endless loop which is doing some jobs by reading some kind of queues or flags is much easier and often the more efficient solution. Also running some jobs in interrupt service routines fits well to bare metal requirements.

I assume you are running on bare metal with no battery saving requirements. I assume you can now write a program, load it to your device and run it. What I suggest you do is roughly this.

This program should have a main loop, which in its most simple would be like this:

MAX_TIME is the largest possible value of system clock, should never be reached

task_table is table with 
    next execution time as system clock time (MAX_TIME means disabled)
    function pointer

initialize task-table with the three tasks below

forever
  for each task with time 0
    set task time MAX_TIME (disable)
    call task function (task probably enables itself or other task)

  find a task with lowest non-zero time in task_queue 
  if task time is in past or now
    set task time MAX_TIME (disable)
    call task function (task probably enables itself or other task)

Time 0 tasks are checked separately, and then tasks with time, so that the time 0 tasks don't block each others or the tasks with time from ever being called. Same could be achieved in different ways, this is just an example.

Then your requirements really call for 3 "tasks":

task_p2_b2_0:
  P2.B2 = 0
  enable task task_p2_b2_1 at current_time + 1 second


task_p2_b2_1:
  P2.B2 = 1
  enable task task_p2_b2_0 at current_time + 1 second


task_p1_b0_poll:
  If P1.B0 = 1
    P2.B3=1
  enable task task_p1_b0_poll at time 0 (or current time + 10 ms or whatever)

Future development: Above is for a small number of static tasks. Iterating up to... 5-10 item table is so fast that there is no point trying to optimize it. Once you have more tasks than that, you should consider using a priority heap to store the tasks. Then you could also consider making main loop sleep when it has nothing to do, and use interrupt to wake it up (timer interrupt, serial port interrupt, pin activation interrupt etc). Also, you could have different task types, such as tasks which are activated when there is some IO (button press, byte from serial port, whatever). Etc. At the upper end of this adding features is a complete operating system really, but for simple things what I wrote above is really enough.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM