Petalinux对zcu106编译自定义驱动模块

平台

ubuntu16.04
petalinux2018.3
vscode编辑器

前言

之前写过imx28的驱动,这次因为毕设要用zcu106的vcu,涉及到驱动的部分,所以再来回顾下开发流程,petalinux工具提供了极大的便利,对于开发来说,但也有自己的坏处,每次编译贼慢,想直接载kenrel中编译写makefile又出问题,算了就这样吧。

过程

1、创建linux,见上一篇文章,这里硬件平台挂载一个PL的自定义gpio输出,硬件框图如下所示:
在这里插入图片描述
这里的gpio全部挂载到pl的led上,然后4个一组,挂载两组,查看他们的地址线,如下
在这里插入图片描述
2、修改设备树,这里加一个led,根目录加上如下:

/include/ "system-conf.dtsi"
/ {
    zynqmp-ledctl {
        #address-cells = <0x1>;
	    #size-cells = <0x1>;
	    compatible = "xlnx,zynqmp-ledctl";
        status = "okay";
        reg = < 0x80000000 0x04     /* data 0*/
                0x80001000 0x04 >;  /* oen  0*/
    };
};

3、创建自己的module,这里起一个zynqmp-ledctl

petalinux-create -t modules --name zynqmp-ledctl --enable

4、核心驱动部分如下,open、read自己写吧,下面主要是创建设备、类、驱动啥的

static int setup_ledctl_cdev(void)
{
	alloc_chrdev_region(&zynqmp_ledctl_dev.dev_id, 0, DEVLED_CNT, DRIVER_NAME);
	zynqmp_ledctl_dev.major = MAJOR(zynqmp_ledctl_dev.dev_id);

	cdev_init(&zynqmp_ledctl_dev.cdev, &zynmp_ledctl_fops);
	cdev_add(&zynqmp_ledctl_dev.cdev, zynqmp_ledctl_dev.dev_id, DEVLED_CNT);

	zynqmp_ledctl_dev.class = class_create(THIS_MODULE, DRIVER_NAME);
	if (IS_ERR(zynqmp_ledctl_dev.class)) {
		return PTR_ERR(zynqmp_ledctl_dev.class);
	}

	zynqmp_ledctl_dev.device = device_create(zynqmp_ledctl_dev.class, NULL,\
								 zynqmp_ledctl_dev.dev_id, NULL, DRIVER_NAME);
	if (IS_ERR(zynqmp_ledctl_dev.device)) {
		return PTR_ERR(zynqmp_ledctl_dev.device);
	}

	return 0;
}

static int zynqmp_ledctl_probe(struct platform_device *dev)
{
	u32 val = 0;
	int ret;
	u32 regdata[6];
	const char *str;
	struct property *proper;
	 /* 获取设备树中的属性数据 */
	 /* 1、获取设备节点 */
	zynqmp_ledctl_dev.nd = of_find_node_by_path("/zynqmp-ledctl");
	if(zynqmp_ledctl_dev.nd == NULL) {
		printk("zynqmp-ledctl node nost find!\r\n");
		return -EINVAL;
	} else {
		printk("zynqmp-ledctl node find!\r\n");
	}
	/* 2、获取 compatible 属性内容 */
	proper = of_find_property(zynqmp_ledctl_dev.nd, "compatible", NULL);
	if(proper == NULL) {
		printk("compatible property find failed\r\n");
	} else {
		printk("compatible = %s\r\n", (char*)proper->value);
	}
	 /* 3、获取 status 属性内容 */
	ret = of_property_read_string(zynqmp_ledctl_dev.nd, "status", &str);
	if(ret < 0){
		printk("status read failed!\r\n");
	} else {
		printk("status = %s\r\n",str);
	}
	ret = of_property_read_u32_array(zynqmp_ledctl_dev.nd, "reg", regdata, 4);
	if(ret < 0) {
		printk("reg property read failed!\r\n");
	} else {
		u8 i = 0;
		printk("reg data:\r\n");
		for(i = 0; i < 4; i++)
			printk("%#X ", regdata[i]);
		printk("\r\n");
	}		

	data_r = ioremap(regdata[0], regdata[1]);
	printk("%#X ", data_r);
	data1_r = ioremap(regdata[2], regdata[3]);
	printk("%#X ", data1_r );
	
	setup_ledctl_cdev();
	
	if(data_r)
		zynqmp_ledctl_set_dir(1, 1);
		
	return 0;
}

5、编译

petalinux-build -c zynqmp-ledctl#only for moudule
petalinux-build -c device-tree#only for device-tree
petalinux-build #for all
petalinux-package --boot --format BIN --fsbl images/linux/zynqmp_fsbl.elf --u-boot images/linux/u-boot.elf --pmufw images/linux/pmufw.elf --fpga images/linux/*.bit --force
#combine to image

5、开机加载驱动,zynqmp-ledctl就是我们编写的驱动
在这里插入图片描述
加载驱动之后可以在/dev下查看到我们的设备zynqmp-ledctl
6、测试app编写,因为主机超级终端啥的都是在win10,所以app在win10上交叉编译了,之前有过教程怎么配环境,编写app

int main(char argc, char *argv[])
{

    printf("Joydon Jiang@doncejiang@163.com\n");

    if(argc < 3){
        printf("app : %s ,error input!\r\n", argv[0]);
        return -1;
    }

    char* file_name = argv[1];
    printf("app : %s\r\n", file_name);
    int fd = open(file_name, O_RDWR);

    if(fd < 0){
        printf("app : %s , file %s open failed!\r\n", argv[1]);
        return -1;
    }

    unsigned char val = atoi(argv[2]);
    int ret = write(fd, &val, sizeof(val));

    if(ret < 0){
        printf("app : %s , file %s write failed!\r\n", argv[1]);
        close(fd);
        return -1;
    }

    ret = close(fd);
    
    return 0;
}

很简单一看就懂,下面进行代码测试,然后再win10下make
在这里插入图片描述
通过lrz工具通过串口传输到开发板
在这里插入图片描述

测试

运行app如下:
在这里插入图片描述
开发板亮灯,踩坑完成,告辞

编译进内核

正常传统配置Linux默认内核加载项是在Makefile记忆Kconfig中修改,参考链接

https://blog.csdn.net/cediy2088long/article/details/7409236

现在是加一条命令:

donce@donce:~/project/linux_img/nohdmi$ petalinux-build -x mrproper
donce@donce:~/project/linux_img/nohdmi$ petalinux-build -c zynqmp-ledctl -x do_install

这里就是点灯的驱动安装在内核中,然后进行编译测试,失败,哈哈,以后再搞吧,先记录下。

Logo

更多推荐