学fpga(hls之驱动代码)

Posted 费晓行

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了学fpga(hls之驱动代码)相关的知识,希望对你有一定的参考价值。

【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing @163.com】

        利用hls编写好了ip之后,那么驱动代码如何编写?好在hls sdk已经提前考虑到了这一点,在export rtl的时候,除了正常输出verilog和vhdl代码之外,也会提前帮助我们写好驱动代码。驱动代码有两种格式,一种是逻辑系统的驱动,类似于rtos里面用到的驱动;还有一种是linux驱动,但是也是在用户层对设备进行访问,不是真正的kernel module文件。

1、hls代码,主要是一个按键和s_axilite控制的led闪烁功能

#include <ap_cint.h>


extern "C" void led_twinkle(uint1 key, uint32 num, uint2* led)

#pragma HLS INTERFACE s_axilite port=num
#pragma HLS INTERFACE ap_none port=key
#pragma HLS INTERFACE ap_none port=led
#pragma HLS INTERFACE ap_ctrl_none port=return
	int i;

	if(key)
	
		for(i = 0; i < num; i++)
		
			if(i < num/2)
			
				*led = 1;
			
			else
			
				*led = 2;
			
		
	
	else
	
		*led = 0;
	

2、导出的驱动代码位置

3、驱动代码的内容

4、驱动的组成

如果是裸机系统,需要的文件是

xled_twinkle_sinit.c、xled_twinkle.c

如果是linux系统,需要的文件时

xled_twinkle_linux.c、xled_twinkle.c

5、裸机系统的初始化函数,见xled_twinkle_sinit.c

int XLed_twinkle_Initialize(XLed_twinkle *InstancePtr, u16 DeviceId) 
	XLed_twinkle_Config *ConfigPtr;

	Xil_AssertNonvoid(InstancePtr != NULL);

	ConfigPtr = XLed_twinkle_LookupConfig(DeviceId);
	if (ConfigPtr == NULL) 
		InstancePtr->IsReady = 0;
		return (XST_DEVICE_NOT_FOUND);
	

	return XLed_twinkle_CfgInitialize(InstancePtr, ConfigPtr);

6、linux驱动并不内核代码,而是通过user layer访问kernel layer,见xled_twinkle_linux.c

int XLed_twinkle_Initialize(XLed_twinkle *InstancePtr, const char* InstanceName) 
	XLed_twinkle_uio_info *InfoPtr = &uio_info;
	struct dirent **namelist;
    int i, n;
    char* s;
    char file[ MAX_UIO_PATH_SIZE ];
    char name[ MAX_UIO_NAME_SIZE ];
    int flag = 0;

    assert(InstancePtr != NULL);

    n = scandir("/sys/class/uio", &namelist, 0, alphasort);
    if (n < 0)  return XST_DEVICE_NOT_FOUND;
    for (i = 0;  i < n; i++) 
    	strcpy(file, "/sys/class/uio/");
    	strcat(file, namelist[i]->d_name);
    	strcat(file, "/name");
        if ((line_from_file(file, name) == 0) && (strcmp(name, InstanceName) == 0)) 
            flag = 1;
            s = namelist[i]->d_name;
            s += 3; // "uio"
            InfoPtr->uio_num = atoi(s);
            break;
        
    
    if (flag == 0)  return XST_DEVICE_NOT_FOUND;

    uio_info_read_name(InfoPtr);
    uio_info_read_version(InfoPtr);
    for (n = 0; n < MAX_UIO_MAPS; ++n) 
        uio_info_read_map_addr(InfoPtr, n);
        uio_info_read_map_size(InfoPtr, n);
    

    sprintf(file, "/dev/uio%d", InfoPtr->uio_num);
    if ((InfoPtr->uio_fd = open(file, O_RDWR)) < 0) 
        return XST_OPEN_DEVICE_FAILED;
    

    // NOTE: slave interface 'Axilites' should be mapped to uioX/map0
    InstancePtr->Axilites_BaseAddress = (u32)mmap(NULL, InfoPtr->maps[0].size, PROT_READ|PROT_WRITE, MAP_SHARED, InfoPtr->uio_fd, 0 * getpagesize());
    assert(InstancePtr->Axilites_BaseAddress);

    InstancePtr->IsReady = XIL_COMPONENT_IS_READY;

    return XST_SUCCESS;


int XLed_twinkle_Release(XLed_twinkle *InstancePtr) 
	XLed_twinkle_uio_info *InfoPtr = &uio_info;

    assert(InstancePtr != NULL);
    assert(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);

    munmap((void*)InstancePtr->Axilites_BaseAddress, InfoPtr->maps[0].size);

    close(InfoPtr->uio_fd);

    return XST_SUCCESS;

7、寄存器设置代码,见xled_twinkle.c代码

void XLed_twinkle_Set_num(XLed_twinkle *InstancePtr, u32 Data) 
    Xil_AssertVoid(InstancePtr != NULL);
    Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);

    XLed_twinkle_WriteReg(InstancePtr->Axilites_BaseAddress, XLED_TWINKLE_AXILITES_ADDR_NUM_DATA, Data);


u32 XLed_twinkle_Get_num(XLed_twinkle *InstancePtr) 
    u32 Data;

    Xil_AssertNonvoid(InstancePtr != NULL);
    Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);

    Data = XLed_twinkle_ReadReg(InstancePtr->Axilites_BaseAddress, XLED_TWINKLE_AXILITES_ADDR_NUM_DATA);
    return Data;

8、测试与验证

        在一开始设计ip的时候,可以通过简单的逻辑系统+驱动代码的方式进行验证。等到后期成熟了,再转成linux驱动、或者是linux kernel驱动,都是可以的。

以上是关于学fpga(hls之驱动代码)的主要内容,如果未能解决你的问题,请参考以下文章

学fpga(hls之花式led配置)

学fpga(hls之系统开发)

学fpga(hls之图像处理)

学fpga(hls之unroll的使用)

学fpga(hls之平均值算法编写)

学fpga(hls之vivadozynq和petalinux)