DDl_back.jpg

Tsinghua

DSP开发技术 (BM: chaosboy wbs)

banner.gif


[回到开始][上一层][下一篇]


1.1 任务调度模块(HWI/SWI/TSK)
标 题: DSP/BIOS中的I/O设备驱动编程技术
发信站: BBS 水木清华站 (Mon Jun 17 10:55:38 2002)

作者:南京邮电学院信息工程系(210003)李灿伟 刘胜美 来源:《电子技术应应用》

DSP/BIOS中的I/O设备驱动编程技术



摘要:介绍了DSP/BIOS中I/O设备驱动程序的编写,并给出了一个在TMS3220C5402 DSK上开发语音处理程序的实例。
关键词:数字信号处理器(DSP) 实时操作系统 I/O设备驱动 应用程序浇 口(API)

近年来,随着信息技术的飞速发展,DSP在航空、航天、雷达、通信、消费类电子设备等方妹 都得到了广泛应用;同时,DSP的运算能力也越大越强大,TI公司新推出的TMS320C6400系列的运算能力可以达到8800MIPS。这些都要求开发DSP的应用程序要缩
短开发时间,增加软件的可编护性和可
重用性。语音压缩、语音识别、图像处理等方面的应用要求DSP的开发尽可能简单,还要求创 码的执行效率高。
DSP/BIOS是TI公司推出的一个实时操作系统。DSP/BIOS与TI的CCS(Code Compposer
Studio)集成在一起。目前最新的版本是CCS 1.2中的DSP/BIOS
II。应用DSP/BIOS可以大大简化DSP应用程序的开发和调试。与外部设备的I/OO接口是DSP应用开发中不可缺少的重要部分。基于DSP/BIOS的I/O设备驱动将软件与硬件分离,提高了软件的可重用性,在软件或硬件改动时可使相互的影响降为
最小。
1 DSP/BISO操作系统简介

DSP/BIOS实际上是一组可重复调用的系统模块API的集合。只占用DSP很少的资源,可以满足足DSP实时运行时的调试性能分析,编写高效的程序。例如,在TMS320C6211上运行printf()函数需花费4000个周期,而运行LOG_printf()只花费36个周期,可pri
GetBuf

在DSP/BIOS中,任务的调度是通过HWI、SWI和TSK三个模块实现的。HWI(硬件中断管理模块块)管理硬件中断,主要负责DSP与外设的交互,从外设中读写数据。由于硬件中断直接与硬件打交道,对应的中断服务程序ISR应尽可能短小精焊。HWI不引起任
调度,它在处理完数据的输入输出后
调用SWI_post()来调度相应的软件中断SWI完成数据处理工作。

DSP/BIOS提供两类优先线程:SWI(软件中断管理模块)和TSK(任务管理模块)。SWI是DSPP/BIOS任务调度的核心,SWI任务是抢断式的,即高优先级的任务可以抢断低优先级的任务。但是SWI任务是不可阻塞的,所有SWI任务共享一个堆栈,SWI任务只
在程序编制时预先定义好。DSP/BIOS
中对任务的动态产生和对阻塞状态的支持是通过TSK模块来实现的。TSK也是可以抢断的,但但每个TSK任务使用独立的 颜弧
1.2 通讯模块(PIP/SIO)
PIP(带缓冲管道管理模块)和SIO(流输入输出管理模块)是DSP/BIOS提供的的两个接口对象,用于支持DSP与外设之间
数据交换。PIP对象带有一个缓冲队列,可以执行带缓冲的读任务和写任务。SSIO没有缓冲队列,SIO的操作get()和put()在应用程序和驱动程序之间交换缓冲的指针,而不是数据的拷贝,因此执行效率比PIP高。
PIP和SIO对象支持基于帧的信号处理系统的实现。在多速率系统中需要使用优优先级线程来统一端口通信,在其它需要处理不同尺寸、不同速率的帧的系统中,优先级线程也是必须的。PIP对象可被SWI或TSK线程使用,而SIO对象只能被TSK
用。
2 低级设备驱动(LIO)
LIO(Low Level
I/O)是一组基于DSP/BIOS设计的API函数。它由控制函数、I/O缓冲区管理函适 、信令函数组成,如表1所示。应用程序可以通过LIO函数控制一个或多个外设通道。

表1 LIO API函数
函 数函数类型描 述
Open
Close
Cntl
GetBuf
PutBuf
IsEmpty
IsFull
SetCallback控制
控制
控制
控制
控制
缓冲区队列
缓冲区队列
缓冲区队列
缓冲区队列
信令分配资源,初始化设备
释放资源,复位设备
设备特殊操作
缓冲区传送使能
缓冲区传送使不能
从设备输出队列重新得到缓冲区
将缓冲区放入设备输入队列
若设备输出队列为空返回真
若设备输入队列为满返回真
当传送毕,设置函数为调用
或多个存储单元用业存储指针为以后


LIO函数不考虑数据的转送方向,也就是说仅执行输出设备、仅执行输入设备和能执行输入  输出的设备执行的是同样的函数。输入与输出之间的主要不同点是传送到缓冲区队列函数的参数意义不同。既然所有其它的操作都是同样的,大多数控制代码
在单个驱动程序中被所有通道共享。
2.1 总体设计、设想和命名规范
所有的驱动程序函数都不能设置成全局中断。驱动程序应不影响全局中断使能能标记的状态,仅影响由它控制的外设所能触发的中断所对应使能标记的状态。这样可以阻止一个驱动程序与其它驱动程序或应用程序争夺CPU资源

为了避免由不同驱动程序使用同一函数名引起的命名空间冲突,也为了改变驱动程序而不需需再编译应用程序代码,可以通过函数表访问驱动程序函数。用这种方式,仅需要为每个驱动程序定义一个外部符号。这种符号有其命名规范。此命名规范通过
线板、在片外设、LIO接口等来区分。
如包含应用程序注释的源代码为TI
TMS320VC5402
DSK的AD50音频编解码器执行基于DMA的驱动程序,驱动程序函数表名是DSK54002_DMA_AD50_TI_ILIO。

设备驱动程序支持的各通道半双工(输入或输出)通道。每个函数对应一个通道变量。一个个能执行输入和输出的物理设备,如连接到音频编解码器的DSP串口,可通过两个半双工通道(一个输入,一个输出)来访问。一个驱动程序支持多少个物理设备
屯 道依具体实现而实。一般一个驱动
程序应能控制一个物理设备,此设备可能有多个通道。通道号与物理设备通道的映射执行时时确定。通道号应约定从0开始。对I/O设备,一般约定偶数号为输入,奇数号为输出
2.2 三类函数
LIO接口中有三类函数:控制函数、缓冲区和队列管理函数、信令函数。
2.2.1 控制函数
控制函数用来实现设备的启动、关闭和控制。其初始函数为驱动程序保存资源源(物理外设和内存)。它使用结构指针作为可选变量,此结构是一种设备的特殊变量结构
2.2.2 队列管理

device”队列增加另一个缓冲区。驱动程序将此缓冲区指针存进一个队列,此此时状态为“FFE”,“to
或多个存储单元用业存储指针为以后
传送用,此队列为“to
device”队列。能包含缓冲区指针的第三个存储单元是“from
device”队列,在驱动程序中为一变量。当设备准备传送缓冲区时,缓冲区从从输入队列传送到外设寄存器。这些缓冲区然后移到输出队列以完成传送,作为对CPU中断的响应

PutBuf()将缓冲区从应用程序传送到驱动程序的输入队列。GetBuf()从输出队列得到缓冲区区。IsEmpty()和IsFull()返回输入队列、输出队列的状态。如果输入队列满,因为无空间装新缓冲区,调用putBuf()会返回错误代码。若IsFull()返回false,
下来可调用putBuf()。如果IsFull()返
回true,但若在IsFull()返回true和调用putBuf()之间完成传送,则调用putBuf()也可能会会成功
2.2.3 信令
如图1所示,当传送结束一般会触发CPU中断。此中断会使应用程序将传送的缓缓冲区转移到输出队列,然后调用calback()传到驱动程序。Callback()应向应用程序发信号告知传送完毕
3 LIO驱动程序例子
音频处理如语音压缩、呼叫过程音调检测等,是DSP的一般应用。本例是使用TTMS320C5402
DSK上的DMA将音频编解码数据从McBSP移到缓冲区中。
当驱动程序响应应用程序调用和设备中断时,采用数据结构跟踪驱动程序的状状态。有效状态是设备驱动程序缓冲区队列的状态,如图1所示
图2给出了此模式中最简单的传送状态集。圆圈中单词表示设备驱动程序缓冲乔 队列的状态。第一个单词是“to
device”队列,第二个表示外设占用缓冲区指针,第三个是“from
device”队列,第二个表示外设占用缓冲区指针,第三个是“from device”抖恿小表示空,F表示满,EEE是起始状态。
每个队列可以是空(E),满(F),非空非满(N)。应用程序调用PutBuf()浇 缓冲区放到“to
device”队列中。驱动程序立即将缓冲区放进外设,转移到状态“EFE”。当创屯瓯 ,外设向驱动程序发中断信号, 后驱动中断处理程序将缓冲区从外设寄存器转移到“from
device”队列,转移到状态“EEF”,接着调用应用程序的回调函数。回调函适 调用GetBuf()从驱动程序的“from
device”队列重新得到缓冲区,驱动程序返回起始状态。
如果驱动程序支持硬件排队,则当一个缓冲区正由外设传送时,“to
device”队列增加另一个缓冲区。驱动程序将此缓冲区指针存进一个队列,此此时状态为“FFE”,“to
device”队列为满,外设正在传送一个缓冲区,“from device”队列为空。适褂肅数据结构实现这种状态机器的状态向量。
使用DMA全局重新加载寄存器来控制“to device”队列,状态结构如下所示。
Typedef struct drv_state{
Bool enabled;
Ptr currentBuffer;
Uns currentSize;
Ptr fullBuffer;
Uns fullSize;
LIO_TcallBack callback;
Arg calbackArg;
} LIO_Obj;
第一个字段“enabled”是一个布尔值,表示程序的开始或结束。下面两个字抖巍癱urrentBuffer”“currentSize”控制当前传送缓冲区的起始地址和尺寸。当传送完毕,它们转移到“from
device”队列。“fullBuffer”“fullSize”字段实现长度为1的“from
device”队列。Callback()的地址和参数通过setCallback()存储在状态结构怪小
驱程序对每个缓冲区只接收一个中断,而不是每个采样一个断。发生中断时,,驱动程序已经知道缓冲区传送完毕,重新加载,DMA不需再重新编程。中断处理程序首先将currentBuffer内容移到fullBuffer中。如果缓冲区已在“to
device”队列中,即已使用重新加载的DMA,则新缓冲区指针和长度记录进currrentBuffer字段中,然后调用callback()。一旦定义了基本的状态机器,相似硬件的新驱动程序就很容易写出。








21IC电子技术书店 找本您需要的书


Copyright (C) 2000 21IC.com,All Rights Reserved

本文文章著作权归作者和相关媒体所有21IC经授权准许制作发布
任何单位和个人未经许可,严禁链接,镜像,复制,拷贝或转载
北京欣星网科技有限公司 网页版权所有
*webmaster@21ic.com

--

※ 来源:·BBS 水木清华站 smth.edu.cn·[FROM: 210.32.156.200]


[回到开始][上一层][下一篇]

欢迎访问Cterm主页