频谱仪多种内核间通信机制的方案设计
来源:21IC 作者:—— 时间:2011-11-15 11:00
写Linux设备驱动的第一步,是完善头文件中的宏定义,除了各种参数的定义外,主要是实现硬件寄存器的物理地址到虚拟地址的映射。对于硬件寄存器的操作,其实就是对其物理地址进行读写操作。而Linux系统提供了一种内存管理机制,在这种机制下,程序可以使用比真实物理地址大得多的地址空间,称为虚拟地址。Linux系统中程序的操作部是使用虚拟地址,所以要完成物理地址到虚拟地址的映射。
本课题采用ioremap函数的方法,如下: #define AT91C_SMC_CSR2*(volatile unsigned long*)ioremap(0xFFFFFF78.4)
对于ioremap函数,就是将物理地址0xFFFFFF78开始的4字节的地址映射到虚拟地址空间中,返回值即4字节虚拟地址的首地址,赋给宏定义的变量名AT91C_SMC_CSR2。对宏定义的操作即对物理地址的操作。
4.1.2 HPI驱动的初始化
首先是对HPI硬件的初始化以及中断初始化。对于HPI,主要是重置DSP,已完成时序的同步。设置SMC(静态存储控制器),因为ARM跟DSP的HPI通信是使用PIO线复用。最后向DSP发送握手信号,表示初始化完成。
对于中断的初始化,使用: request_irq(AT91C_ID_IRQ0,handler,SA_INTERRUPT,”irqO”,NULL);此函数向内核注册中断,包括中断号和中断处理函数handler。对于HPI设备的注册,为HPI设备分配系统未使用的254作为主设备号,0为次设备号。通过register_chrdev_region函数向内核注册。函数cdev_init是初始化设备,其实就是建立设备与file_operations结构的对应关系。最后将设备加入内核。代码如下:
上述的代码都是在驱动模块的hpi_init函数中实现。在HPI驱动被加载到内核时就完成了一系列初始化。
4.1.3 file_operations结构中函数的实现
设计驱动的大部分工作就是实现file_operations结构中的函数。代码如下:
其中,“.owner=THIS_MODULE”表示结构属于本模块,然后是open、read等各函数的对应关系。由于初始化在hpi_init函数中实现,所以open函数并没有特别的操作,主要是在终端输出信息。函数release主要是申请中断资源的释放,使用free_irq函数。下面主要讲解read函数,write函数与之类似,不再详述。
ssize_t hpi_read(struct file*file,char*buf,size_t count,loff_t*offp)
其中,参数file是打开文件的标识符;参数buf和count就是要向buf指向的地址存放count字节的数据;参数offp是文件读取的位置,默认为文件头,不用设置。
在read函数的最开始有如下代码:
wait_event interruptible(hpi_wait,ev_start);
down(&sem);
……
up(&sem);
其中wait_event_interruptible函数会阻塞进程,使其进入等待队列。直到DSP的数据准备好后,发来中断。HPI设备注册的中断处理函数handler会将变量ev_start置1,同时唤醒hpi_wait等待队列。read函数继续执行之后的代码,即开始从DSP的HPID寄存器读取数据到参数buf指向的地址。读取完成后向DSP指定地址写入0xffffffff,表示读取完成。函数down与up是操作二进制信号量,使渎取数据的过程为“原子”操作,避免执行过程中被打断,从而影响读取结果。read函数的流程如图5所示。
4.1.4 资源的释放
与hpi_init函数相对应的是hpi_exit函数,实现的是资源的释放。代码如下:
以上代码包括中断资源释放、映射关系释放、内存释放、没备释放。与hpi_init函数比较可看出,释放的顺序与申请注册的顺序正好相反。
4.1.5 模块的编译、加载
在驱动文件的最后加上如下代码,设置模块加载与释放对应的函数:
module_init(hpi_init);
module_exit(hpi_exit);
完成了驱动程序的编写,将源程序文件在Linux开发环境下编译成.ko的模块文件,使用insmod和rmmod指令来加载和卸载模块。
4.2 SPI设备驱动程序实现
在SPI的驱动设计中,大体的框架跟HPI是相同的。包括头文件宏定义的完善、SPI设备的初始化、file_operations结构中函数的实现、资源释放,最后编译、加载。需要说明的是AT91RM9200自带了SPI接口,所以初始化时要根据芯片手册对SPI接口的I/O线、时钟、工作模式
等进行配置,才能保证硬件的正常工作。
在SPI驱动的write函数中,使用了如下代码: copy_from_user(Ytos,buf,count);
在Linux的驱动设计中,经常涉及到用户空间和内核空间的通信问题,即数据的交换。copy_from_user与copy_to_user函数就是为了实现这一功能。上述代码实现的功能就是将用户空间buf的count字节的内容复制到内核中定义的数组Ytos中,从而完成用户空间和内核的数据交换。驱动的其余实现类似HPI,不再详述。
4.3 驱动的调试
对于程序语法的调试,在编译的过程中解决。根据Linux平台下的交叉编译器arm-linux-gcc的提示信息,修改出现的语法类错误。在保证了驱动文件的成功编译后,对于程序功能的调试,采用打印函数printk跟踪调试。在程序适当的位置加入printk打印信息,如根据设备注册函数的返回值来打印成功或者失败的信息,可以很直观的了解程序的运行情况,是很有效的调试方法。在调试过程中,利用示波器来检测某些通信端口的电平信息,可以了解到是否有数据通信。通过几种手段的结合,最后完成驱动程序的调试。
5 结语
本课题采用ARM、DSP、FPGA的三核构建的系统平台,将它们各自的优点有机的结合起来。在完成各自的数据处理后,分别通过HPI、SPI接口进行数据交换,在ARM的整体控制下,实现了系统稳定运作。而基于ARM的嵌入式Linux操作系统,还能提供友好的人机交互界面。该平台在智能仪表、信号测试分析等领域都能发挥很好的作用。
上一篇:多功能USB组合设备的结构设计
- •免费直播预告 | 从理论到实操,全面解析ADC/DAC芯片测试前沿方案!2025-06-17
- •摩尔斯微电子携手Gateworks,利用Wi-Fi HaLow革新工业连接2025-06-04
- •重磅!中国或禁止政府采购这类芯片和品牌2024-03-25
- •最新PMIC芯片市场竞争格局、供应商及发展趋势2024-03-19
- •出货量翻50多倍!这类芯片涨价20%!村田/ST/微芯/华邦电等最新现货行情 | 周行情137期2024-03-18
- •对标ST!这家国产厂商的该类芯片加速上车2024-03-15
- •马来西亚芯片的崛起2024-03-14
- •这些芯片,将大幅涨价2024-03-11
- •CITE2024开展倒计时 等你来看大模型、芯片、机器人、智能驾驶……2024-03-04
- •裁员潮!这些品类芯片售罄!ST/微芯/华邦等最新现货行情 | 周行情135期2024-03-04