一、简介 (1)金山151-RTOSV1.1(以下简称金山151)是笔者专门为AI8051U单片机8BIT模式写的RTOS。Ai8051U单片机的8BIT模式使用8051指令集,在片上就有32KB的XDATA存储器,特别适合运行RTOS。 (2)金山151是为RTOS初学者准备的定制版:它具有5个实时任务,每个任务具有3KB的位于XDATA区域的任务堆栈空间。 (3)由于AI8051U只有2KB的EDATA空间,如果在32BIT模式下实现RTOS,全部任务堆栈空间加起来也不能超过2KB的EDATA空间,因此对于AI8051U单片机,只适合使用8BIT模式实现RTOS。 (4)金山151是一个完整的功能强大的RTOS操作系统,除了有5个实时任务 外,还有4个前台定时任务,有2个系统定时器中断钩子和一套完整的系统时间部分。 并且为了实现信息的实时显示和RTOS的动态调试(代替静态仿真),金山151内部集成了一个完整的8位数码管显示驱动程序。 (5)金山151-RTOS使用STCIDE作为编写程序和项目管理的IDE软件,使用金水151作为C语言编译器,使用AIAPP-ISP为辅助编程和烧录软件。附录中给出了STCIDE集成开发环境,解压后可以参照其中的说明使用。 二、最小空任务框架
(6)本文关于金山151-RTOS编程方法的第一篇,介绍它在AI8051U实验箱上实现的最小空任务框架。该框架只有显示当前的系统时间和一个心跳灯的功能,其运行效果的视频如下:
(7)金山151-RTOS采用将整个系统封装为OBJ模块的方式提供。 单片机RTOS的运行需要一整套完整的系统来支持,比如系统中断,核心代码、任务程序架构以及系统初始化等等,考虑到AI8051U是一类新的单片机,其上面的的RTOS不能全盘照抄8051单片机上的各种RTOS,同时考虑到初学者需要通过逐渐地学习才能深入地掌握RTOS的理论知识和编程方法,因此金山151-RTOS将各种建立和初始化RTOS的运行环境的程序和单片机启动的“main”函数一起封装,只留下建立用户自己的运行系统的框架供用户填写自己的程序和新增自己的程序。
(8)金山151-RTOS最小系统包括以下文件: 其中“main.c”是用户的主程序,“RTOS_FTask.c”是用户的前台定时任务程序,“RTOS_RTask.c”是用户的实时多任务程序,“JS151_Mini_8Bit_V11_18K6T.OBJ”是金山151-RTOS最小系统的二进制模块文件,“JS151_DRV_DIG8_AI8U_V12.c”是专门为AI8051U实验箱的8位数码管写得动态刷新函数。
(9)金山151-RTOS程序文件的开头声明部分如下: 上面图中第17行是一个固定格式的单片机类型模式声明,用来指导编译器按给的的单片机类型模式将C语言编译成为对应的机器指令。 定义中“MCU_DEFINE”是一个固定的关键字,表示这一行宏定义程序是一个单片机类型模式定义。17行中的“STC8U_8BIT”指定编译目标是AI8051U单片机的8BIT模式代码。17行中的“32000”是指定编译器可使用的XDATA空间上限,这个上限之上的XDATA空间编译器不得使用,留给用户自己做特殊用途。 (10)金水151编译器是一个面向模块的编译器,意思是每一个源程序文件对应一个模块,对于不同的模块,可以指定的目标单片机类型模式。因此使用金水151编译器时,每一个源程序的开头都要有上面17行那样的单片机类型模式定义语句。 比如你想让某个数码管驱动程序模块同时支持AI8051U单片机和STC8H单片机,那么单片机类型模式就应该指定为“INTEL_8051”模式,这样金水151编译出的代码就不会出现MDU32和TFPU32加速器的指令,在两种类型的单片机上都可以使用。 (11)金山151-RTOS系统主函数“JS151_main()”是系统提供的用于进行用户设置的钩子函数,类似于“Arduino”编程中的“setup()”函数。系统从单片机主函数“main()”开始执行,进行了RTOS系统的建立与设置后,调用这个“JS151_main()”函数后,就启动多任务调度系统,RTOS正式开始运行。
本范例的“JS151_main()”函数程序如下图: 其中第34行到第43行是LOGO和测试程序,取消第36行和43行的注释可以测试软件延迟函数“JS151_Delay_MS”的延时精确性。 第46行到第50行是让5个实时任务都处于就绪状态,等等进行任务调度。 加电是第56行程序将系统时间设置为第0天的“23:59:55”,这样就很容易观察到系统时间的每天进位。
(12)金山151-RTOS系统提供给用户两个硬件中断钩子函数,用户可以在其中编程完成自己的各种任务。下图是这两个钩子函数的接口程序: 上面图中的“/*{ A351”和“}*/”语句对是表明其中的程序是A351汇编语言程序,免得其他编译器产生错误的理解。必须注意的是每个这种嵌入式汇编语句都需要像C语言一样,用分号做结尾。 (13)金山151-RTOS系统使用定时器0的不可屏蔽中断模式3作为系统中断,系统中断采用8KHz的中断频率,用来进行不可中断的系统任务处理。由于该中断是不可屏蔽的且频率较高,因此用户要避免在第64行开始的钩子函数中放处理时间长的程序。 (14)金山151-RTOS系统使用外中断INT3作为1KHz的系统节拍中断,在每个节拍中进行前台定时任务处理和实时任务调度。前面第66行和第77行程序是测试程序,通过连接P00和P01的LED灯可以测量到这两个中断是否工作正常。
(15)4个前台定时任务的钩子函数在文件“RTOS_FTask.c”中定义: 其中1KHz的钩子函数可以作为1毫秒的计数器使用,500Hz的钩子函数可以作为8位数码管的动态刷新用,40Hz的钩子函数可以作为检测键盘的外设状态用,而4Hz的钩子函数可以作为各个任务的秒信号同步用。
(16)金山151-RTOS预先定义了5个实时任务,这5个实时任务已经预定义在源程序文件“RTOS_RTask.c”,本范例的具体程序见下图: 图中任务0到任务3都是空任务,其中“JS151_OS_Task_Suspend(JS151_PRIO_SELF);”语句的意思是将任务自己挂起。用户将来可以用自己的程序来代替它,实现自己的功能。 (17)RTOS的空闲任务函数很特殊,其程序如果写不好容易造成系统崩溃,因此笔者决定在金山151中空闲任务函数不向用户开放。这样优先级最低的实时任务4就成为用户留守任务,当其他所有任务都都未就绪时执行该任务。 最简单的留守任务就是本范例给出对一个1毫秒的计数变量进行计数,并且利用这个计数变量按1秒钟的周期闪烁生命灯。 附件1:STCIDE-金水151_V22 单片机集成开发环境 附件2:实验箱AI8051U-SCH-20240820电路图
附件3:本文范例金山151_空任务_AI8051U_BOX_V12_STCIDE
|