Polling Method in Embedded Programming
Polling operation in embedded programming refers to actively sampling the status of an external device. Polling is most often used in terms of input/output (I/O), and it is the process where the embedded system waits for an external device to check for its readiness or status. For example, we have a simple microcontroller device with a one-push button and LED. When we press the button, the LED will be lit. If we press the button again, then the LED is turned off. The pseudocode code would look something like this:
loop:
if button pressed, toggle LED
repeat
In this program, you can see that the microcontroller always checks the status of the button and then decides the condition for the LED.
A real-life example of the polling method can be when you are working on your homework in your room, and you are waiting for the mailman to deliver an important package. The polling method will be when you go to the front door at set intervals (maybe every 5 minutes) to check whether your package has arrived.
Polling Cycle
Polling basically means that the embedded system will check all status for each device at set intervals, which is called a polling cycle. For example, the embedded system may check the state of a switch every 5 ms, detect any obstacles every 20 ms, and read the room temperature every 5 sec. The optimal polling cycle will vary according to several factors, including the desired speed of response and the overhead (e.g. processor time and bandwidth) of the polling.
Implementation of Polling Method in a Single Task
A simple embedded system, it is usually designed to execute multiple jobs in a single task, such as in the main() function. There are three types of polling methods that can be used in the code, as shown below. Assume that the latency time on each job can be ignored.
Same Polling Cycle
Same Polling Cycle
Figure 1: Multi-Jobs with Same Polling Cycle
It is easy to implement If all the jobs have the same polling cycle. The following code uses a simple delay function for the polling interval.
loop:
execute Job_A
execute Job_B
execute Job_C
delay for 20 ms
repeat
The following code may use SysTick to get a more accurate time interval:
loop:
get the SysTick value to time1
execute Job_A
execute Job_B
execute Job_C
loop until ( time1 - SysTick) greater than or equal to 20 ms
repeat
Different Polling Cycles
Different Polling Cycles
Figure 2: Multi-Jobs in Different Polling Cycle
Most embedded systems can execute multi-jobs in different polling cycles. For example, job A needs to be executed every 20 ms, job B is set at 8 ms, and job C is read every 2 ms. Assume that the latency time on each job can be ignored and the minimum delay is set to 1 ms. A simple implementation using the delay function is as follows:
initialize timer to 0
loop:
if timer mod 20 equal to 0, then execute Job_A
if timer mod 8 equal to 0, then execute Job_B
if timer mod 2 equal to 0, then execute Job_C
delay for 1 ms
increase timer
if timer equal LowestCommonMultiple, then reset timer to 0
repeat
If the system requires a more accurate time interval, the SysTic can be used in the code:
initialize timer to 0
loop:
get the SysTick value to time1
if timer mod 20 equal to 0, then execute Job_A
if timer mod 8 equal to 0, then execute Job_B
if timer mod 2 equal to 0, then execute Job_C
loop until (time1 - SysTick) greater than or equal to 1 ms
increase timer
if timer equal to LowestCommonMultiple, then reset timer to 0
repeat
Same Polling Cycle, Different Delays
Same Polling Cycle, Different Delays
Sometimes, we need to repeat some related jobs at different intervals, while the system executes other jobs. In other words, the delay time between different jobs will not affect other jobs (the execution time of each job is ignored here).
For example, the polling time for the system to check all the jobs is 10 ms. Job A will trigger the sub-Job A1, delay for 1200 ms, then execute sub-Job A2. Job B and Job C also will trigger the related sub-jobs with a different delay time. All delay times must be in integer factor upon the polling interval. Otherwise, you have to change either the delay time or the polling interval.
A simple implementation using one delay function and timer variables is as follows:
initialize timerA, timerB and timerC to -1
loop:
if Job_A is activated, then
execute Job_A1
set timerA to 120
if timerA equal to 0
execute Job_A2
set timerA to -1
if Job_B is activated, then
execute Job_B1
set timerB to 20
if timerB equal to 0
execute Job_B2
set timerB to -1
if Job_C is activated, then
execute Job_C1
set timerC to 9
if timerC equal to 0
execute Job_C2
set timeC to -1
delay for 10 ms
if timerA > 0 then decrease timerA by 1
if timerB > 0 then decrease timerB by 1
if timerC > 0 then decrease timerC by 1
repeat
If the system requires a more accurate time interval, the SysTic can be used in the code:
initialize timerA, timerB and timerC to -1
loop:
get the SysTick value to time1
if Job_A is activated, then
execute Job_A1
set timerA to 120
if timerA equal to 0
execute Job_A2
set timerA to -1
if Job_B is activated, then
execute Job_B1
set timerB to 20
if timerB equal to 0
execute Job_B2
set timerB to -1
if Job_C is activated, then
execute Job_C1
set timerC to 9
if timerC equal to 0
execute Job_C2
set timeC to -1
loop until (time1 - SysTick) greater than or equal to 10 ms
if timerA > 0 then decrease timerA by 1
if timerB > 0 then decrease timerB by 1
if timerC > 0 then decrease timerC by 1
repeat