zynq-7000学习笔记(十)——Linux下通过UIO配置FAST corner寄存器
2016-09-09 11:33
603 查看
PC平台:WINDOWS 10 64位 + 虚拟机Ubuntu 14.04
Xilinx设计开发套件:Xilinx_vivado_sdk_2015.4
开发板:Zed Board
USB摄像头:罗技 C270(720P)
Linux源码:2016_R1
Linaro文件系统:linaro-vivid-developer-20150618-705.tar.gz
在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,支持UIO
二、修改Env.txt,启动参数增加:uio_pdrv_genirq.of_id="generic-uio"
三、修改设备书,把FAST corner加上去,
五、写一个main.c调用上面的初始化函数,然后进行相应寄存器的配置
Xilinx设计开发套件:Xilinx_vivado_sdk_2015.4
开发板:Zed Board
USB摄像头:罗技 C270(720P)
Linux源码:2016_R1
Linaro文件系统:linaro-vivid-developer-20150618-705.tar.gz
在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,支持UIO
二、修改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<MAX_UIO_NAME_SIZE); 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 .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 .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 .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); <span style="white-space:pre"> </span>XHls_sobel_SetCols(&sobel, IMAGE_WIDTH); <span style="white-space:pre"> </span>XHls_sobel_DisableAutoRestart(&sobel); <span style="white-space:pre"> </span>XHls_sobel_InterruptGlobalDisable(&sobel);我现在还没用到中断,所有先禁用掉了
相关文章推荐
- zynq-7000学习笔记(十二)——Linux下USB摄像头+VDMA+FAST corner+frame buffer测试
- Zynq-Linux移植学习笔记之11-qspi驱动配置与测试接口
- Zynq-Linux移植学习笔记之十-u-boot网络配置
- zynq-7000学习笔记(三)——编译linux
- Zynq-Linux移植学习笔记之五-rootfs配置
- Zynq-Linux移植学习笔记之12-gpio驱动配置
- zynq-7000学习笔记(十一)——Linux下VDMA的使用
- Zynq-Linux移植学习笔记之十-u-boot网络配置
- Zynq-Linux移植学习笔记之11-qspi驱动配置
- Zynq-Linux移植学习笔记之23-QSPI速度配置
- Zynq-Linux移植学习笔记之13-i2c驱动配置
- Zynq-Linux移植学习笔记之十-u-boot网络配置
- 菜鸟学习linux笔记与练习-----第二天。一些基本命令以及初级网络配置
- Linux 学习笔记一常规网络配置
- Linux学习笔记---RHEL-5配置CentOS-5的yum源
- linux学习笔记之apache的简单配置
- Linux+Apache+PHP+MYSQL环境配置学习笔记
- Linux学习笔记之Centos 6.3下NFS的安装配置
- linux学习笔记3--tomcat服务器的配置
- Linux学习笔记1—Linux文件权限及目录配置