linux dev uio,Zynq-7000学习笔记(十)——Linux下通过UIO配置FAST corner寄存器

9287a9032d2a807db58e9bae1ace90c1.png

PC平台:WINDOWS 10 64位 + 虚拟机Ubuntu 14.04

Xilinx设计开发套件:Xilinx_vivado_sdk_2015.4

开发板:Zed Board

USB摄像头:罗技 C270(720P)

在zynq平台上做开发,肯定避免不了在linux下对有AXI Lite接口的IP进行寄存器的配置,UIO是一个很方便的方法,不管你有多少个IP,都可以搞定;原理很简单,就是物理地址的映射,把IP的AXI Lite寄存器基地址映射出来,就可以对所有的寄存器进行操作了;通过HLS综合出来的IP,如果使用了AXI Lite接口,会自动生成相应的驱动代码,包括standalone和linux的驱动,直接拿来用就好了,这里说的驱动并不是指linux底层的设备驱动,而是UIO用户端的驱动;前面我已经在standalone模式下验证了FAST corner,当时只是一张预先准备好的图片,因为环境有限,在PL端还没接摄像头,无法实时地采集到图像,而现在经过一段时间的准备,可以先在linux下就把USB摄像头采集的图像进行验证了。

一、配置linux,支持UIO11867.html

二、修改Env.txt,启动参数增加:uio_pdrv_genirq.of_id="generic-uio"

三、修改设备书,把FAST corner加上去,

hls_fast_corner {

compatible = "generic-uio";

reg = < 0x43c00000 0x10000>;

};

四、FAST corner的linux驱动代码如下,在HLS的项目目录下可以找到

// ==============================================================

// File generated by Vivado(TM) HLS - High-Level Synthesis from C, C++ and SystemC

// Version: 2015.4

// Copyright (C) 2015 Xilinx Inc. All rights reserved.

//

// ==============================================================

#ifdef __linux__

/***************************** Include Files *********************************/

#include "xhls_fast_corner.h"

/***************** Macros (Inline Functions) Definitions *********************/

#define MAX_UIO_PATH_SIZE 256

#define MAX_UIO_NAME_SIZE 64

#define MAX_UIO_MAPS 5

#define UIO_INVALID_ADDR 0

/**************************** Type Definitions ******************************/

typedef struct {

u32 addr;

u32 size;

} XHls_fast_corner_uio_map;

typedef struct {

int uio_fd;

int uio_num;

char name[ MAX_UIO_NAME_SIZE ];

char version[ MAX_UIO_NAME_SIZE ];

XHls_fast_corner_uio_map maps[ MAX_UIO_MAPS ];

} XHls_fast_corner_uio_info;

/***************** Variable Definitions **************************************/

static XHls_fast_corner_uio_info uio_info;

/************************** Function Implementation *************************/

static int line_from_file(char* filename, char* linebuf) {

char* s;

int i;

FILE* fp = fopen(filename, "r");

if (!fp) return -1;

s = fgets(linebuf, MAX_UIO_NAME_SIZE, fp);

fclose(fp);

if (!s) return -2;

for (i=0; (*s)&&(i

if (*s == '\n') *s = 0;

s++;

}

printf("linebuf:%s\n", linebuf);

return 0;

}

static int uio_info_read_name(XHls_fast_corner_uio_info* info) {

char file[ MAX_UIO_PATH_SIZE ];

sprintf(file, "/sys/class/uio/uio%d/name", info->uio_num);

return line_from_file(file, info->name);

}

static int uio_info_read_version(XHls_fast_corner_uio_info* info) {

char file[ MAX_UIO_PATH_SIZE ];

sprintf(file, "/sys/class/uio/uio%d/version", info->uio_num);

return line_from_file(file, info->version);

}

static int uio_info_read_map_addr(XHls_fast_corner_uio_info* info, int n) {

int ret;

char file[ MAX_UIO_PATH_SIZE ];

info->maps[n].addr = UIO_INVALID_ADDR;

sprintf(file, "/sys/class/uio/uio%d/maps/map%d/addr", info->uio_num, n);

FILE* fp = fopen(file, "r");

if (!fp) return -1;

ret = fscanf(fp, "0x%x", &info->maps[n].addr);

fclose(fp);

if (ret < 0) return -2;

return 0;

}

static int uio_info_read_map_size(XHls_fast_corner_uio_info* info, int n) {

int ret;

char file[ MAX_UIO_PATH_SIZE ];

sprintf(file, "/sys/class/uio/uio%d/maps/map%d/size", info->uio_num, n);

FILE* fp = fopen(file, "r");

if (!fp) return -1;

ret = fscanf(fp, "0x%x", &info->maps[n].size);

fclose(fp);

if (ret < 0) return -2;

return 0;

}

int XHls_fast_corner_Initialize(XHls_fast_corner *InstancePtr, const char* InstanceName) {

XHls_fast_corner_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 'Control_bus' should be mapped to uioX/map0

InstancePtr->Control_bus_BaseAddress = (u32)mmap(NULL, InfoPtr->maps[0].size, PROT_READ|PROT_WRITE, MAP_SHARED, InfoPtr->uio_fd, 0 * getpagesize());

assert(InstancePtr->Control_bus_BaseAddress);

InstancePtr->IsReady = XIL_COMPONENT_IS_READY;

return XST_SUCCESS;

}

int XHls_fast_corner_Release(XHls_fast_corner *InstancePtr) {

XHls_fast_corner_uio_info *InfoPtr = &uio_info;

assert(InstancePtr != NULL);

assert(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);

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

close(InfoPtr->uio_fd);

return XST_SUCCESS;

}

#endif

五、写一个main.c调用上面的初始化函数,然后进行相应寄存器的配置

// init hls_fast_corner

if(XST_SUCCESS != XHls_sobel_Initialize(&sobel, "hls_sobel"))

{

printf("XHls_sobel_Initialize failed\n");

return 0;

}

XHls_sobel_SetRows(&sobel, IMAGE_HEIGHT);

XHls_sobel_SetCols(&sobel, IMAGE_WIDTH);

XHls_sobel_DisableAutoRestart(&sobel);

XHls_sobel_InterruptGlobalDisable(&sobel);

我现在还没用到中断,所有先禁用掉了

来源:luotong86的专栏

*本文已由作者授权转发,如需转载请联系作者本人获得授权

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值