单片机系统中的多任务多线程机制的实现
如不能同时测量不项目,不过随意在不同通道中测试不同版本,即使有空余通道也不能在上一样本测试过程中启动下一样本的测试;而且还牺牲效率,浪费时间,因为要等每个阶段最慢的一个处理完才能进入下一阶段。这其实是单任务的多次简单重复,设计也容易。国内很多类似产品采用了这种方案,但我们放弃
了。
我们选择了安全并行的设计,即要求所有通道可以完全独立工作;任意启动和停止;彼此没有约速;时间上可以任意重叠;是几个独立的任务,如图2。
这里我们把每一个启动通道进行测试的程序叫做一个任务,把各自任务下的每一个单独的、分开处理的程序段叫做一个线程,每个线程依靠自己的标识来识别。一个通道的测试任务可分为启动、设置、加样品、预温计时、加试剂与搅拌、通道轮流采样、数据处理和作图打印等多个线程。另外,有一个温度的实时监控独立线程,它的优先级要次于通道的测试采样。
图3前台控制流程1----voidXlnt0()interrupt0
这些线程可分属于前台和后台两类:前台主要是一些中断的处理,例如两路温度的实时监控、每100ms内的各通道循环检测一遍、采用中断方式的键盘干预等;后台主要是扫描方式下响应操作员的按键请求、数据处理、图形显示、打印报告等内容。
整个实现机制可以简单地概括如下:前台通过合理安排中断的响应和服务方式来对多个任务的实时线程进行处理;后台操作主要以循环方式扫描各个任务的线程标识,满足条件的线程被激活予以处理。
限于篇幅,不可能详细介绍整个设计方案,在此只能给出各测试通道工作任务的前台和后台线程划分及流程,供参考。然后,给出一个中断退出后返回到任意地址的函数,它比C51自己的setjmp和longjmp全程跳转函数的使用要方便很多。实时任务中,中断服务结束后不是返回到断点地址执行原有程序,而是强制返回到某一地址执行新程序的情况非常普遍。我们采用设置环境变量的方法,使中断退出后可以任意返回到多个设置入口中的某一个去执行,有效地解决了前台和后台任务线程的灵活切换这一关键问题。我们使用的CPU是97C52,编程语言为KeilC516.0版。
图3是主定时器中断服务,12C887提供中断请求信号至int0。12C887的三个中断触发服务中,温度扫描是独立线程,四次500ms“周期中断”(即每2s)后执行一遍;需要屏幕显示预温侄计时的时候使用“更新中断”,每秒一次,各测试任务,其倒计时线程依靠各自的标识启动和停止;“报警中断”需要时设置为每分钟1次,用于主菜单界面显示当前时间和长定时的返回。
图4是CPU内部定时器0的中断服务,用于A/D转换。每个测试任务的A/D分为两个线程:检测试剂加入和测试剂样品的反应曲线,虽然都是通过对光学传感器和输出进行检测的,但处理方法完全不同,数据量也很不一样。定时器0设定为每100ms中断1次,因为要用高精度∑-Δ转换器件,CPU必须直接控制器件的整个转换过程,所以,要注意所有通道轮扫一遍A/D的时间不能超过100ms。
图5为后台流程。后台程序依靠通道按键启动一个测试任务,然后进行该任务预处理,类似初始化的一些功能。如果这期间又启动别的任务,则未初始化完的先前任务中止。
图4前台控制流程2----voidtime0()interrupt1
初始化完成后进入多任务所属线程的循环处理阶段,其间可以随时由通道按键引起的中断来加入新的任务,每个线程的调度标识可以由相关的前台线程给出,也可来自相关的后台线程。配合Getadd()和Putadd()从中断强制返回某地此后,使用跳转语句到真正的目标地址。
最后给出强制返回程序代码(供参考):
/*保存当前地址信息到环境变量JMPEnv[env1][]中,每个变量由三项组成,env1是二维下标参数*/
voidgetadd(unsignedcharenv1)
{unsignedchartemp;
temp=SP;
JMPEnv[env1][0]=(*((unsignedcharidata*)SP));
temp--;
JMPEnv[env1][1]=(*((unsignedcharidata*)temp));
JMPEnv[env1][2]=SP-2;
}
/*置中断 《单片机系统中的多任务多线程机制的实现(第2页)》
本文链接地址:http://www.oyaya.net/fanwen/view/173113.html
了。
我们选择了安全并行的设计,即要求所有通道可以完全独立工作;任意启动和停止;彼此没有约速;时间上可以任意重叠;是几个独立的任务,如图2。
这里我们把每一个启动通道进行测试的程序叫做一个任务,把各自任务下的每一个单独的、分开处理的程序段叫做一个线程,每个线程依靠自己的标识来识别。一个通道的测试任务可分为启动、设置、加样品、预温计时、加试剂与搅拌、通道轮流采样、数据处理和作图打印等多个线程。另外,有一个温度的实时监控独立线程,它的优先级要次于通道的测试采样。
图3前台控制流程1----voidXlnt0()interrupt0
这些线程可分属于前台和后台两类:前台主要是一些中断的处理,例如两路温度的实时监控、每100ms内的各通道循环检测一遍、采用中断方式的键盘干预等;后台主要是扫描方式下响应操作员的按键请求、数据处理、图形显示、打印报告等内容。
整个实现机制可以简单地概括如下:前台通过合理安排中断的响应和服务方式来对多个任务的实时线程进行处理;后台操作主要以循环方式扫描各个任务的线程标识,满足条件的线程被激活予以处理。
限于篇幅,不可能详细介绍整个设计方案,在此只能给出各测试通道工作任务的前台和后台线程划分及流程,供参考。然后,给出一个中断退出后返回到任意地址的函数,它比C51自己的setjmp和longjmp全程跳转函数的使用要方便很多。实时任务中,中断服务结束后不是返回到断点地址执行原有程序,而是强制返回到某一地址执行新程序的情况非常普遍。我们采用设置环境变量的方法,使中断退出后可以任意返回到多个设置入口中的某一个去执行,有效地解决了前台和后台任务线程的灵活切换这一关键问题。我们使用的CPU是97C52,编程语言为KeilC516.0版。
图3是主定时器中断服务,12C887提供中断请求信号至int0。12C887的三个中断触发服务中,温度扫描是独立线程,四次500ms“周期中断”(即每2s)后执行一遍;需要屏幕显示预温侄计时的时候使用“更新中断”,每秒一次,各测试任务,其倒计时线程依靠各自的标识启动和停止;“报警中断”需要时设置为每分钟1次,用于主菜单界面显示当前时间和长定时的返回。
图4是CPU内部定时器0的中断服务,用于A/D转换。每个测试任务的A/D分为两个线程:检测试剂加入和测试剂样品的反应曲线,虽然都是通过对光学传感器和输出进行检测的,但处理方法完全不同,数据量也很不一样。定时器0设定为每100ms中断1次,因为要用高精度∑-Δ转换器件,CPU必须直接控制器件的整个转换过程,所以,要注意所有通道轮扫一遍A/D的时间不能超过100ms。
图5为后台流程。后台程序依靠通道按键启动一个测试任务,然后进行该任务预处理,类似初始化的一些功能。如果这期间又启动别的任务,则未初始化完的先前任务中止。
图4前台控制流程2----voidtime0()interrupt1
初始化完成后进入多任务所属线程的循环处理阶段,其间可以随时由通道按键引起的中断来加入新的任务,每个线程的调度标识可以由相关的前台线程给出,也可来自相关的后台线程。配合Getadd()和Putadd()从中断强制返回某地此后,使用跳转语句到真正的目标地址。
最后给出强制返回程序代码(供参考):
/*保存当前地址信息到环境变量JMPEnv[env1][]中,每个变量由三项组成,env1是二维下标参数*/
voidgetadd(unsignedcharenv1)
{unsignedchartemp;
temp=SP;
JMPEnv[env1][0]=(*((unsignedcharidata*)SP));
temp--;
JMPEnv[env1][1]=(*((unsignedcharidata*)temp));
JMPEnv[env1][2]=SP-2;
}
/*置中断 《单片机系统中的多任务多线程机制的实现(第2页)》