单片机实现多线程(转载)
发布时间:2009-08-13 08:49:50 |
技术类别:单片机 |
关键词:多线程;单片机控制系统;扩展型多线程模拟
1. 引言
随着计算机的不断发展,越来越多的,优秀的编程思想被提出来,并付诸实践。在某些方面已出现了根本性的变革。另一方面,单片机自从80年代诞生以来,便以飞快的速度发展起来,但由于其物理条件的限制,单片机控制系统的编程仍然局限于经验的模式,很少应用那些新提出的高级语言的编程思想。如果将不断发展的编程思想与广泛应用的单片机控制系统结合起来,一定会大大促进单片机控制系统的进一步发展。使其更广泛的应用于各个方面。
在下面这个具体项目中,实际情况对系统有一些比较苛刻的要求。按照一般的单线程的控制方法已经无法满足实际需求。具体情况如表1(表1所示为生化分析仪的设计中对单片机系统的要求的一部分)
表1
表1所示只占了整个系统要求的1/6。下面对表1中的几项内容加以说明。
对象M1开始动作17操作,即首先步进电机M1(正向)转动查找光电开关信号PS1;查到后执行两次‘过程1‘。过程1:向电机打出30拍。由表1可知该动作从C 段执行到 K段停止;
对象M2即步进电机M2等对象M1执行完动作17后执行动作23等。对象M3和对象M4 则在开始时同时启动,分别执行各自的动作。各个对象之间有的独立,有的相互关联。
整个项目需要控制16台步进电机,21个电磁阀,3个泵,1个直流电机,系统要求全部执行时间为6秒钟,系统要求步进电机以其最快的速度-----40us—60us打拍。如果以单线程的方式编程让一台电机转到位之后,再转其他电机。这样16台电机打一拍就需要640us---960us已经无法满足系统要求。这就需要使单片机并行控制多台电机运转。这种以并行的方式驱动各个电机同时启动可以在最短的时间将各个电机同时到位。在转动电机的同时还需要检测一些开关量已确定电机的位置。为了实现这个目的。下面提供第一种解决方案(此方案是常用的方案之一,但作者并不推荐这个方案。因为这个方案成本太高。)。
方案一: 硬件实现。
我们可以用多个CPU,将各个电机的控制分到不同的CPU中执行,并可将不互相冲突的电机控制过程放到一个CPU中,其结构如图1
图1多cpu实现方案结构图
如图所示系统中设定一个主CPU,其功能为与计算机通讯,并将计算机下达的指令分发给相应的从CPU,更主要的是主CPU将监控整个并行控制的运作。因为各个控制过程之间有的彼此关联,所以主CPU不仅要控制各个线程的执行,还要兼顾线程之间的通讯。以表1为例,具体作法如下:
1.开始后,主CPU发给从CPU1一个信号,从CPU启动对象M1进行动作17,并由从CPU向主CPU返回一个信号。主CPU收到信号后,置起标志1。当对象M1进行完动作17后,从CPU向主CPU发出信号,CPU将标志1清掉。
2.开始后,主CPU发给从M2一个信号,从CPU启动对象M2。从CPU向主CPU不断查询标志1。当标志1被清掉后,从//控制对象2执行动作23。
3.开始后,主CPU发给从CPU一个信号,从CPU启动对象M3和对象M4。执行动作25,然后开电磁阀6,然后延时1秒,关电磁阀6,执行动作24,然后执行动作26,等////1的动作17完成后,启动步进电机20,执行动作25,等等。
如上所说, 主CPU设置了多个标志位用以跟踪各个线程的运行情况。并用这些标志位承担了各个相关线程之间的通讯。凡是线程运行到与其他线程相关的地方都会在主CPU内设置一个标志位以供其它相关线程查询。而那些不相关的线程可以完全独立运行。相关线程除了需检测标志的部分,其他部分也可独立运行。
这种多CPU控制的作法实现了单片机的并行运作方式。但多CPU的控制方案成本几乎是成倍提高,而且在硬件的基础上实现的多CPU之间的通讯花费时间稍长。并且容易有干扰。
方案二(作者推荐): 另一种实现的方法是在软件的层面上模拟多cpu的运作。从而实现单片机的伪并行处理.这种实现方法借鉴了计算机实现多线程的编程方法。
多线程编程编程思想,即:同时给CPU分配了几个任务或线程。当然计算机 CPU实际上不可能同一时间做几件事,而是把时间分到不同的线程,使每个线程都有点进展。如果一个线程无法进行,比如线程要求的键盘输入尚未取得,则转入另一个线程的工作。通常,CPU在线程间的切换非常迅速,使人们感觉好象所有的线程是同时进行的。
多线程编程中有一个很重要的环节:各个线程之间的通讯与控制问题
在多线程编程中,每个线程都用编码提供线程的行为,用数据供给编码操作。多个线程同时处理同一编码和数据,不同线程可能各有不同的编码和数据。事实上,编码和数据部分是相当独立的,需要时即可向线程提供。因此经常是几个线程使用同一段编码和数据这就会出现下面的情况
当一个线程在调用数据时,另一个线程可能正在修改这些数据。则前一个线程所调用的数据出现了不确定性。这会影响整个运行结果。为了避免这个问题,多线程编程中,各个线程之间通讯和控制尤为重要。在将多线程的思想向单片机控制系统移植时,这点要非常注意。 因为系统多线程运作的实现从其最基本的层面看仍然是单线程的操作;他的实现归根结底是利用了计算机的高速度。它将系统运行的基准时间分成了许多时间片,将各个时间片分给不同的线程,如此一来在一个基准时间内各个线程全都向前行进了一步,然后运行下一个基准时间,周而复始。这样在用户层的角度看来,各个线程是同步进行的。只要速度够块,时间片的划分不会影响用户层面上的应用,这样就可以实现多线程的操作。近年来单片机速度的大幅度提升,这就使多线程思想向单片机控制系统的移植成为可能。
在整个项目中全部的输入信号共39个;同时并行查询的对象最多时有61个系统要求以步进电机最快的速度打拍。时间约40us---60us,为了保证步进电机打拍的稳定性和灵活性。我选用了DSP内部的一个定时器,定时时间为打拍时间的1/3—1/5。设定为10us中断。这个时间为整个系统运行的基准时间。在这段时间内,系统要查询一遍所有对象并向相应的步进电机打拍。在一些线程中还需要采样多次。换句话说,在这个系统时间内。所有线程都要向前行进一步。
就像计算机一样,将这个基准时间分为多个时间片。将各个时间片分给不同的线程,在这种情况下,各个线程的执行是间断的。这与用硬件模拟多线程有本质的不同。像这样既要应用各线程执行的间断性,又要保证各线程运行的连续性。这对软件的设计有了很高的要求,这同时也是单片机控制系统用软件模拟多线程方法中的难点之一,为了解决这个问题,可在个线程自带线程进度指示器用来标志线程的运行进度,即用一个变量记载线程的每一步;如图2
图2
系统设定线程进度指示器用来指引线程的连续运行,同时在一个中断中轮询所有对象。其编程结构大致如下:
时钟中断:
线程1:
线程进度标志:
1: ;
2: ;
3 ;
线程2:
线程进度标志:
1: ;
2: ;
。。。。。。。。
用软件模拟多线程还有很多要注意的地方。
如果选用20兆的DSP来实现控制功能,步进电机最快的打拍速度为40us---60us,则有下面的计算结果,,取1/4,即10us产生一中断,在中断里查询61个对象。20兆DSP单条指令的执行时间大约为50ns在一次中断内可执行的语句数=10us/50ns=200条,如果在分给61个对象,每个对象所分得的指令数仅为3条,已经不够用了,即使选择60兆的DSP,说分指令也只是9条,若以牺牲打拍的灵活性为代价,以60us为已中断。则每个对象所分得的指令数仅为36条勉强够用,如果所控制的对象再多的话,软件编程的灵活性将进一步被压缩,
下面提出了一种扩展的多线程模拟方法,如图3
图3
s1,s2为系统运行的基准时间,M1.1 为第一对象组中第一对象。M1.2 为第一对象组中第二对象。
这种扩展的多线程模拟方法 仍将系统时间化成多个时间片,与上面不同的是有几个线程(对象)组成一个线程组,共享同一个时间片,例如:当系统运行到第一次基准时间的第一个时间片时,由共享时间片的第一个线程占用,当系统运行到第2次基准时间的第1个时间片时,由共享时间片的第2个线程占用,如此类推,这种扩展模式可以灵活的掌控线程与所用时间的比例,但是这是以牺牲运行时间为代价的。
结论:本文对单片机控制系统的编程思想作出了扩展,将本属于计算机高级语言编程思想的多线程编程移植到单片机控制系统中。这种方法使单片机控制系统可工作于对系统运行速度要求很高的系统中,并且对其他的高级语言编程思想,如对事件句柄的处理等向单片机控制系统移植起了示范作用。
参考文献
[1]柳永新主编。Windows c 程序设计入门与提高。清华大学出版社,1999,6。
[2]李朝青主编。单片机原理及接口技术,1994。