Consider a interrupt-driven input routine which reads in data from an IO port of an input device, processes it, and writes it into a FIFO queue. There is a interrupt-driven output routine which tries to fetch the data from the FIFO queue, and write this processed data to a IO port of an output device. It will be triggered when output device's status changes from busy to ready.
Therefore, it creates two problems:
- When the input ISR write the first data into the FIFO queue, the output device's status is already ready. Therefore, the output ISR will not be triggered.
- If somehow the output device's status changes from busy to ready, so CPU executes the the output ISR. However, the processed data is not ready (queue is empty), so the output device's status remain on ready. Therefore, the output ISR will not be triggered anymore.
To solve these problems, we can use kick starting technique. To do it, we write an output routine (not ISR) to write data to the IO port of the output device, and use a device busy flag to determine whether we should kick start the output routine.
- The output routine first verifies whether the data is enqueued, if yes, it outputs data, and set busy flag to true; if not, it does nothing and returns.
- The input ISR test the busy flag, if it is false, then call the output routine (kick start); if it is true, then don't call the output routine (kick start). After that, it returns.
- The output ISR first clears the busy flag, and calls the routine. Therefore, if queue is empty, output routine does nothing, then busy flag remains false, so input ISR will kick start when it enqueue data. After that, it returns.