版主: 51FPGA |
xilinx论坛
最后登陆时间:2015-03-19 10:58:07 |
Xilinx 深圳办事处 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需要的基地址,时钟、中段号等硬件信息。 |
共1条 1/1 1 |