4 Linux下的驱动程序设计
系统采用ARM+嵌入式Linux的构架,Linux版本为2.4.18,采集系统必须和高效灵活的接口驱动程序相结合才能在操作系统下正常工作。
4.1 驱动程序的基本概念
设备驱动程序是操作系统内核和硬件之间的接口,它属于内核一部分,主要功能如下:
(1)对设备初始化或释放;
(2)把数据从内核传送至硬件。从硬件读取数据:
(3)读取应用程序传送给设备的数据,回送应用程序请求的数据:
(4)监测和处理设备出现的异常。
设备驱动程序为应用程序屏蔽了硬件的细节,在应用程序中,硬件设备只是一个设备文件,可以像操作普通文件一样对硬件设备进行操作。
4.2 修改代码
嵌入式Linux在arch/arm/mach-s3c2410目录下的DMA.c文件中定义了一些与DMA操作相关的通用函数,主要有:申请DMA通道函数s3c2410_re,quest_dma()、申请DMA中断函数request_irq()、加入DMA队列函数s3c2410_dma_queue_buffer()、进行DMA操作函数process_dma()以及中断处理程序dma_irq_handler()等。在进行特定接口操作时,必须对其进行适当的修改。根据接口设置修改如下内容:
增加外部DMA操作的寄存器设置:
#define XDREQ0_CTL(DEMAND_MODE | SYNC_HCLK | INT_MODE | TSZ_UNIT | SINGLE_SERVICE | HWSRC(CH0_nXDREQ0) | DMA_SRC_HW | CLR_ATRELOAD | DSZ(DSZ_BYTE)| TX_CNT(0));
//设置DMA为单服务命令模式,8位数据总线、允许中断且通过DREQ0硬件触发DMA操
#define XDREQ0_RD_SRC 0x22000000
#define XDREQ0_RD_SRC_CTL BUF_ON_MEM_FIX
//设置DMA操作的源地址为系统总线上的0x22000000且地址固定
#define XDREQO_RD_DST_CTL BUF_ON_MEM
//设置DMA操作的目的地址在系统总线且地址逐次加1
通过DMA读取FPGA数据时必须由操作系统在内存中开辟一个空间做为DMA操作的目的地址。操作系统开辟的内存位于虚拟空间.而DMA操作的目的地址必须为物理地址,所以必须进行虚拟地址到物理地址的转换。因此在process_dma()中增加如下代码设置DMA的目的地址寄存器:
regs->DIDST=virt_to_bus(buf->dma_start)
virt_to_bus()是操作系统提供的虚拟地址到物理地址的转换函数,buf->dma_start是系统开辟的虚拟地址空间的首地址。
另外由接口原理图可知,S3C2410须向FPGA发送START信号启动FIFO的读写和DMA操作。所以系统定义GPB3作为START信号,定义如下:
#define START(GPIO_MODE_OUT | GPIO_PULLUP_DIS | GPIO_B3);
同时在process_dma()函数中增加如下代码启动DMA操作:
write_gpio_bit(START,1);
START引脚置为高电平后立即启动FIFO的写操作,同时也就启动了DMA操作进行数据传输,当DMA计数器减为0后发生DMA中断,并且在中断处理程序中将START位置0停止FIFO的写操作。
4.3 接口驱动的关键代码
利用系统提供的DMA操作函数,接口驱动的设计就显得比较容易。接口驱动属于字符设备驱动.重点在初始化和read函数部分。
初始化函数中完成DMA引脚定义、BANK4总线设置、申请DMA通道以及注册字符设备等。read函数是接口驱动的核心。应用程序正是通过调用read函数来读取数据。其核心代码如下:
1.部分资源来自网络,经ET电子归类整理,旨在服务电子爱好者并无商业目的,不保证正确性与完整性.
2.如果您觉得本站资源对您有用,请告知您的好友,用搜索引擎搜"ET电子"即可.

