在ZYNQ编程初期 (未上操作系统),据大多数时候都在裸跑。这时候绝大多数时候程序是阻塞的,也就是说必须得等一行代码执行完才能进行下一步。此时效率极低。一个常见的应用场景就是控制低俗通信口的时候。即使可以使用中断部分提高效率,大部分情况下还是需要设一个flag变量来在主函数中检查某消息是否发送完毕。此时,无外乎还是一个while(1)然后检查标志变量。为此,很多时候我们需要一个非阻塞的运行机制,从而尽可能的模仿操作系统的调度机制。
首先声明,我的这套非阻塞裸跑机制是通过深挖了一家加拿大的培训公司的代码后总结、简化出来的。该公司的github账户链接是:https://github.com/Engenuics。该公司曾被我本科学校请来做了一学期的初级嵌入式系统培训,该机制其实并未深度涉及。
这套机制的核心是利用定时器中断控制while(1)主循环的循环时间。普通的单片机裸跑while(1) 完成一次需要的时间其实是根据任务数量决定的。如下图所示,一个方块代表一次主循环。可见,其长度是可变的,所以对于任何一个子任务,其实不能过多使用sleep()函数来进行延时,因为此时会使得所有任务被拖延,更不必说检查flag变量了。
这个问题的解法是在每个task后插入一个IDlE状态,在IDLE中,只检查定时器中断。待定时器中断出发后,才结束当前循环。如下图所示。