Xilinx设备的驱动程序

FPGA/ASIC技术

190人已加入

描述

Xilinx为所有设备都提供了standalone模式的驱动程序。Xilinx SDK会根据硬件系统的配置情况,将使用的设备的驱动加入到创建的BSP工程中。

Xilinx设备的驱动程序的存放路径是安装目录下的sw目录下。以Vivado 2013.4, 驱动程序的相对路径是\SDK\2013.4\sw\XilinxProcessorIPLib\drivers\。其中src目录存放驱动程序,examples目录存放了使用实例代码。

对于一个设备,驱动必须的硬件信息有设备的基地址,时钟、中段号等。Xilinx的驱动程序还为每个设备分配了一个设备号。这些信息都是在Xparameters_ps.h中定义的,一般使用如下的命名,MOD_DEVICE_ID, MOD _BASEADDR, MOD _CLOCK_HZ, MOD _INTR, MOD _INT_ID。Xparameters_ps.h是由SDK自动根据硬件工程生成的。

Xilinx的驱动程序主要有下列文件:mod.c, mod_g.c, mod_hw.c, mod_options.c, mod_selftest.c, mod_sinit.c, mod.h, mod_hw.h;有些驱动还有mod_intr.c。其中的mod代表具体的设备名称。

驱动程序中主要用到了两个数据结构,都定义在文件中mod.h。mod_Config主要用于向驱动程序传递他需要的硬件信息。Zynq的SPI设备的硬件信息数据结构。

typedef struct {
u16 DeviceId; /**< Unique ID of device */
u32 BaseAddress; /**< Base address of the device */
u32 InputClockHz; /**< Input clock frequency */
} XSpiPs_Config;

另外一个数据结构是以模块名命名,含有驱动程序运行过程中需要的信息,比如是否就绪、是否忙等状态信息吗,甚至收发数据的缓冲区地址也可能有。Zynq的SPI设备的驱动程序数据结构。

typedef struct {
XSpiPs_Config Config; /**< Configuration structure */
u32 IsReady; /**< Device is initialized and ready */

u8 *SendBufferPtr; /**< Buffer to send (state) */
u8 *RecvBufferPtr; /**< Buffer to receive (state) */
unsigned RequestedBytes; /**< Number of bytes to transfer (state) */
unsigned RemainingBytes; /**< Number of bytes left to transfer(state) */
u32 IsBusy; /**< A transfer is in progress (state) */
u32 SlaveSelect; /**< The slave select value when
XSPIPS_FORCE_SSELECT_OPTION is set */

XSpiPs_StatusHandler StatusHandler;
void *StatusRef; /**< Callback reference for status handler */

} XSpiPs;

mod_g.c主要定义一个全局变量,向驱动程序提供设备的硬件信息。比如Zynq的SPI设备的Xspips_g.c文件主要是下列变量定义。其中的宏,都是在Xparameters_ps.h定义的。这个文件是由SDK自动根据硬件工程生成的。

XSpiPs_Config XSpiPs_ConfigTable[XPAR_XSPIPS_NUM_INSTANCES] = {
{
XPAR_XSPIPS_0_DEVICE_ID, /* Device ID for instance */
XPAR_XSPIPS_0_BASEADDR, /* Device base address */
XPAR_XSPIPS_0_CLOCK_HZ
},
{
XPAR_XSPIPS_1_DEVICE_ID, /* Device ID for instance */
XPAR_XSPIPS_1_BASEADDR, /* Device base address */
XPAR_XSPIPS_1_CLOCK_HZ
}
};

mod_sinit.c完成设备硬件信息的初始化工作。它其中有一个XSpiPs_LookupConfig()函数,根据设备号,查找对应的硬件信息。这样驱动程序的大部分代码可以支持多个设备。Zynq的SPI设备的设备硬件初始化函数:

XSpiPs_Config *XSpiPs_LookupConfig(u16 DeviceId)
{
XSpiPs_Config *CfgPtr = NULL;
int Index;

for (Index = 0; Index < XPAR_XSPIPS_NUM_INSTANCES; Index++) {
if (XSpiPs_ConfigTable[Index].DeviceId == DeviceId) {
CfgPtr = &XSpiPs_ConfigTable[Index];
break;
}
}
return CfgPtr;
}

mod_hw.h主要用来定义硬件寄存器信息,如偏移地址、寄存器的各位的功能。另外它还附带有主要寄存器操作的宏的实现。

mod_hw.c主要用来实现设备的复位函数。另外一些底层的函数,如果与中断等无关,也可能放在这里,比如串口设备的收发函数,就在这个文件中。这个文件一般很小,函数很少。

mod_selftest.c用来实现自测函数。

mod_intr.c用来实现与中断相关的函数。可以参考Xuartps_intr.c。

驱动程序的对外接口都在mod.c中实现。其它没有专门文件存放的函数,一般也放在这个文件中。初始化用的mod_CfgInitialize( )也是在这个函数中实现。其它常见的收发函数等一般也放在这个文件中。mod.h中实现其它模块可能使用的宏,并声明mod.c中实现的函数。

所有设备的驱动程序使用方法类似。第一步是用设备ID调用mod_LookupConfig( ), 查询设备信息。第二步是使用设备信息调用mod_CfgInitialize( ),初始化设备,一般会设置默认工作状态。这一步后,设备硬件就应该进入就绪状态。第三步是调用mod_SelfTest(), 对设备做一下自检。这三步一般都需要完成。接下来可以最设备做一些设备相关的设置,比如设置串口的波特率等。然后设备就进入工作状态,可以进行正常服务。

有些客户用到了Linux。standalone模式是没有操作系统的场景。但是如果把设备的地址空间映射到用户空间,standalone模式的驱动程序也可以直接作为Linux 用户空间的驱动程序。具体代码,可以参考UG873操作CDMA设备的代码。这时没有SDK自动生成的Xparameters_ps.h文件。用户需要自己创建一个头文件,提供mod_g.c需要的基地址,时钟、中段号等硬件信息。

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分