Many tasks, one CPU, no operating system. Each task does a little and steps aside. Muchas tareas, una CPU, sin sistema operativo. Cada tarea hace un poco y cede el paso.
Santi Scagliusi, PhD
Two LEDs, two rhythms, one sleeping CPU.Dos LEDs, dos ritmos, una CPU dormida.
superbucle call #tareaA
call #tareaB
bis.w #LPM3|GIE, SR ; dormir
jmp superbucle
tareaA mov.w &tick, R12
sub.w &dueA, R12
jn finA ; aún no
add.w #2, &dueA
xor.b #BIT0, &P1OUT
finA ret
LED1 toggles every 2 ticks, LED2 every 3. No delay loops anywhere.LED1 conmuta cada 2 ticks, LED2 cada 3. Ningún bucle de retardo.
Why is the sign of tick − due enough?¿Por qué basta con el signo de tick − due?
No OS. Just one loop in main that calls each task in turn, forever.Sin SO. Un solo bucle en main que llama a cada tarea por turno, para siempre.
The whole module is about honoring that one contract. Todo el módulo trata de honrar ese único contrato.
One task spins in a wait loop. The CPU is busy, so no other task runs.Una tarea gira en un bucle de espera. La CPU está ocupada, así que ninguna otra tarea corre.
B and C wait the whole delay before they get a turn. B y C esperan todo el retardo antes de tener turno.
LED2 should copy S1. Does it?LED2 debería copiar S1. ¿Lo hace?
superbucle xor.b #BIT0, &P1OUT
call #retardo ; 300 vueltas
bit.b #BIT1, &P1IN ; S1
jz pulsado
bic.b #BIT7, &P9OUT
jmp superbucle
pulsado bis.b #BIT7, &P9OUT
jmp superbucle
Tap S1 briefly: nothing. R15 is busy counting down inside retardo.Pulsa S1 un instante: nada. R15 está ocupado contando hacia abajo en retardo.
How long can a press last and still be missed?¿Cuánto puede durar una pulsación y aun así perderse?
Instead of waiting inside the task, the task remembers a state and returns.En vez de esperar dentro de la tarea, la tarea recuerda un estado y retorna.
Each call checks the trigger, maybe changes state, then returns. No spinning. Cada llamada comprueba el disparo, quizás cambia de estado, y retorna. Sin girar.
Not time yet: return. Time: run the code of the current state.¿Aún no? Retorna. ¿Ya? Ejecuta el código del estado actual.
br jumps there.Estado × 2 indexa una tabla de palabras. br salta allí.
Do not burn cycles counting down. Compare the clock against a deadline.No quemes ciclos contando hacia atrás. Compara el reloj contra un plazo.
CPU held the whole wait. B and C never get a turn.CPU retenida toda la espera. B y C no tienen turno.
A checks the clock and returns. B and C run every pass; A acts only when the deadline arrives.A mira el reloj y retorna. B y C corren en cada vuelta; A actúa solo cuando llega el plazo.
Every CCR0 interrupt adds one to a 32-bit SystemTimer.Cada interrupción de CCR0 suma uno a un SystemTimer de 32 bits.
TA2 in continuous mode, clocked by ACLK so it keeps ticking in LPM3.TA2 en modo continuo, con ACLK para que siga contando en LPM3.
Keep the interrupt short. The real work happens in the cooperative loop.Mantén la interrupción breve. El trabajo real ocurre en el bucle cooperativo.
The ISR never waits for main, and main never blocks the ISR. La ISR nunca espera a main, y main nunca bloquea a la ISR.
Round-robin: call each task once, in order, every pass of the loop.Round-robin: llama a cada tarea una vez, en orden, en cada vuelta del bucle.
No priorities, no preemption. Order in the list is the whole policy. Sin prioridades, sin expropiación. El orden en la lista es toda la política.
After one pass, the loop sleeps in LPM3. The tick interrupt wakes it.Tras una vuelta, el bucle duerme en LPM3. La interrupción del tick lo despierta.
bis.w #LPM3+GIE, sr.Bucle: ejecuta cada tarea, luego bis.w #LPM3+GIE, sr.bic.w #LPM4, 0(sp).ISR: borra los bits LPM en el SR apilado con bic.w #LPM4, 0(sp).The amber line is the tick. Between ticks the CPU draws almost nothing.La línea ámbar es el tick. Entre ticks la CPU consume casi nada.
blinkLed toggles the LED every ledPeriod ticks, scheduled by the SystemTimer.blinkLed conmuta el LED cada ledPeriod ticks, planificado por el SystemTimer.
One task that refuses to return on time blocks every other task.Una tarea que se niega a retornar a tiempo bloquea a todas las demás.
Short slices. Each task waits one quick lap for its turn.Rebanadas cortas. Cada tarea espera una vuelta rápida su turno.
For those 10 ms nothing else runs, no matter how urgent.Durante esos 10 ms nada más corre, por urgente que sea.
There is no kernel to step in. Timing is a shared responsibility of every task. No hay un kernel que intervenga. El tiempo es una responsabilidad compartida de cada tarea.
When tasks cannot be trusted to yield, a kernel takes the CPU by force.Cuando no se confía en que las tareas cedan, un kernel toma la CPU por la fuerza.
Switches land at task boundaries. No kernel, tiny RAM, but one bad task freezes the rest.Los cambios caen en los bordes de tarea. Sin kernel, poca RAM, pero una mala tarea congela al resto.
The tick cuts any task. Costs RAM, but no task can starve the rest.El tick corta cualquier tarea. Cuesta RAM, pero ninguna tarea deja sin CPU al resto.
Structuring firmware without an operating system.Estructurar firmware sin sistema operativo.
Model each task as an FSM. Check, maybe change state, return.Modela cada tarea como una FSM. Comprueba, quizás cambia de estado, retorna.
Compare against a deadline. The ISR produces, the loop consumes.Compara contra un plazo. La ISR produce, el bucle consume.
LPM3 between passes. Cooperation only works if every task yields.LPM3 entre vueltas. La cooperación solo funciona si toda tarea cede.