单片机实验
编写Small RTOS51 的驱动程序
函数的可重入
我们在编写一个驱动程序之前要判断该函数是否为可重入函数。如果一个函数可能被多
个任务和/或中断同时调用,那么该函数就必须是可重入的,而驱动程序一般要求可被多个
任务/或中断同时调用,这就需要可重入了。一个函数具有可重入性的条件是:
1) 不使用任何共享资源(全局变量、共享外设、内部设备等);
2) 如果必须使用一些共享资源,可在使用共享资源前关中断,使用完共享资源后开中
断;
3) 如果必须使用一些共享资源,而且使用时又不能关中断,则任何使用这个共享资源
的任务在使用共享资源前申请相应信号量,得到允许后再使用共享资源,使用完共
享资源后释放信号量。
在ANSI C 的标准实现中,以上条件比较好实现,但在Keil C51 中就比较麻烦,最主
要是判断函数是否有局部变量分配在内存中。如何判断一个函数是否有局部变量分配在内存
中?方法也不难。我们假设文件file1.c 中有一个函数Fuction, 首先,让编译器将文件
file1.c 编译成汇编文件file.src(在Uv2 中,在相应的文件上点鼠标右键,选择Options For
File ‘file1.c’在Properties 页选上Assemble SRC File。注意是实勾非虚勾。然后编译工
程即可)。打开file.src,查找?DT? Fuction? FILE1、?PD? Fuction? FILE1 和?XD?
Fuction? FILE1(如果Fuction 有参数则查找?DT?_Fuction? FILE1、?PD? _Fuction?
FILE1 和?XD? _Fuction? FILE1),看这些数据段下是否定义有变量,如果没有,恭喜您,
Fuction 的所有局部变量都分配到寄存器中,可以按照一般的方法让函数具备重入性。如果
其中任意一个数据段定义有变量,很不幸,您只有另想办法了。特别的,如果参数在这些数
据段中定义,即使不将该函数与任何函数进行覆盖分析,在函数中使用2)、3)的方法都不
能使函数具有重入性。这是因为在函数执行第一条语句前已经把参数复制到这些变量中,
2)、3)的方法的前提已经不存在了。
驱动程序的编写方法
1. 使用任务编写驱动程序
有一些设备需要CPU 周期地为其服务,典型的是扫描显示和扫描键盘。可以给它们分配
相应的任务,与用户任务一起调度。这样,就可以使用任何任务间通信的方法实现驱动程序。
2. 使用消息队列编写驱动程序
有一些设备具有自己的中断,典型的是串口输出。可以利用消息队列将用户任务需要的
服务通过消息队列排队、缓冲起来,利用中断功能依次服务。这样,一般不需要考虑重入这
个头疼的问题。
3. 使用信号量编写驱动程序
有一些设备既不需要CPU 的周期服务,又不具有自己的中断,典型的是全局变量、模
拟I2C 总线等。假如该设备速度又比较慢,就需要用信号量来独占该设备了。这时,就不能
将驱动程序编写成一个函数。这是因为函数调用OSSemPend 后,编译器认为所有寄存器
已经发生变化,它不会用这些寄存器保存有用的数据。而参数肯定是有用数据,必将分配到
内存中。这就不可能使其具有重入性。替代的方法是按照一般的方法编写一个函数,这个函
数只是对这个设备进行操作。然后定义一个宏,在宏中申请信号量,调用这个函数并释放信
号量。这样,只要保证那个函数的局部变量全部分配到寄存器中就可以了。
4. 复合方法
有一些驱动程序比较复杂(例如TCP/IP 通讯协议),可以结合两种或两种以上的方法
实现。下面我们就举一些例子来说明,驱动程序的编写。
全部0条评论
快来发表一下你的评论吧 !