赛灵思 ZYNQ UltraScale+ MPSoC Petalinux驱动开发:EMIO-GPIO输入驱动

news2024/12/29 10:15:56

在这里插入图片描述

目录

    • Zynq UltraScale+ MPSoC Linux下EMIO-GPIO驱动
      • 1、MPSOC GPIO简介
      • 2、vivado中EMIO配置
      • 3、EMIO设备树修改

Zynq UltraScale+ MPSoC Linux下EMIO-GPIO驱动

声明:本文是学习赛灵思 Zynq UltraScale+ MPSoC 5EV过程中写的笔记,便于以后复习,参考《 ug1144-petalinux-tools-reference-guide》、《ug1085》、黑金Zynq UltraScale+ MPSoC 5EV开发板资料。

1、MPSOC GPIO简介

MPSOCGPIO 是有 6 个BANK;如下图;BANK0 有 26 个信号,控制 MIO[0:25]BANK1 有 26 个信号,控制 MIO[26:51]BANK2有 26 个信号,控制 MIO[52:77]MIO 总共有 78 个引脚,也就是诸如 SPI,I2C,USB,SD 等 PS端外设接口;

BANK3~BANK5 总共能控制 96 个 PL 端引脚,注意每一组都有三个信号,输入EMIOGPIOI,输出 EMIOGPIOO,输出使能 EMIOGPIOTN,类似于三态门,共 288 个信号。

可以连接到 PL 端引脚,通过 PS 端控制。

在这里插入图片描述

2、vivado中EMIO配置

使用PL端的emio需要在vivado中进行约束;如需要将BANK4中的AA13引脚设置为EMIO1

在这里插入图片描述

则需要在vivadoXDC文件中做如下约束

set_property PACKAGE_PIN AA13 [get_ports {emio_tri_io[1]}]

作用:将AA13约束为EMIO1;在zynqmpsoc中emio的编号是从78开始的,所以emio1对应的就是78+1 = 79。

3、EMIO设备树修改

#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/pinctrl/pinctrl-zynqmp.h>


/{
	/* ps端 MIO*/
	ledps{
		compatatible = "led-ps";
		pinctrl-names = "default";
		pinctrl-0 = <&pinctrl_led_default>;
		led-gpios = <&gpio 78 GPIO_ACTIVE_HIGH>;
	};
	
	keypl{
		compatible = "keypl";
		/* 79-emio引脚 GPIO_PULL_UP-GPIO属性 上拉输入 */
		key-gpios = <&gpio 79 GPIO_PULL_UP>;
	};
};


/* SD */
&sdhci1 {
	disable-wp;
	no-1-8-v;
};

/* USB */
&dwc3_0 {
	status = "okay";
	dr_mode = "host";
};

&gpio {
	status = "okey";
};

&pionctrl0 {
	status = "okey";
	pinctrl_led_default:led-default{
		mux {
			groups = "gpio0_78_grp";
			function = "gpio0";
		};
        
        conf {
			pins = "EMIO78";
			bias-disable;
			slew-rate = <SLEW_RATE_SLOW>;
			io-standard = <IO_STANDARD_LVCMOS18>;
		};
	};
};

在设备树中 emio 不需要配置pinctrl,直接使用gpio子系统即可。

驱动程序编写 key.c

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/init.h>
#include <linux/ide.h>
#include <linux/types.h>
#include <linux/cdev.h>
#include <linux/device.h>
#include <linux/of.h>
#include <linux/gpio/consumer.h>
#include <linux/delay.h>

#define CHAR_DEV_NAME "pl_key_dev"

/* 定义key设备结构体 */
struct key_dev{
	dev_t					devid;
    struct cdev				cdev;
    struct class			*class;
    struct device			*device;
    struct device_node 		*nd;
    struct gpio_desc		*gpio_d;
    struct semaphore		lock;
};

static struct key_dev key_char = {
    .cdev = {
  		.owner = THIS_MODULE,      
    },
};

/* 打开设备 */
static int key_open(struct inode *inode_p,struct file *file_p)
{
	int ret = 0;
    ret = down_interruptible(&key_char.lock);
    if(ret)
    {
        printk("%s wait resource break\n", CHAR_DEV_NAME);
        ret = -1;
    }
    else
    {
        printk("char dev open\n");
    }
    return ret;
}

/* 从设备读取数据 */
static int key_read(struct file *file_p, char __user *buf, size_t len, loff_t *loff_t_p)
{
	int ret = 0;
    unsigned char state = 0;
    
    if(0 == gpiod_get_value(key_char.gpio_d))
    {
        medlay(50);
        while(0 == gpiod_get_value(key_char.gpio_d));
        state = 1;
        ret = copy_to_user(buf,&state,sizeof(state));
    }
    else
    {
        ret = copy_to_user(buf, &state,sizeof(state));
    }
    
    return ret;
}

/* 关闭/释放设备 */
static int key_release(struct inode *inode_p, struct file *file_p)
{
    up(&key_char.lock);
    printk("char dev release\n");
    return 0;
}

/* 设备操作函数 */
static struct file_operations key_fops = {
  	.owner	=	THIS_MODULE,
    .open	=	key_open,
    .read	=	key_read,
    //.write	=	key_write,
    .release =	key_release,
};

/* 驱动初始化函数 */
static int __init key_drv_init(void)
{
	int ret = 0;
    ret = alloc_chrdev_region(&key_char.devid,0,1,CHAR_DEV_NAME);
    if(ret < 0)
    {
        goto err;
    }
    
    cdev_init(&key_char.cdev.&key_fops);
    
    ret = cdev_add(&key_char.cdev,key_char.devid,1);
    if(ret < 0)
    {
        goto err;
    }
    
    key_char.class = class_create(THIS_MODULE,CHAR_DEV_NAME);
    if(IS_ERR(key_char.class))
    {
        ret = PTR_ERR(key_char.class);
        goto err;
    }
    
    key_char.device = device_create(key_char.class,NULL,key_char.devid,NULL,CHAR_DEV_NAME);
    if(IS_ERR(key_char.device))
    {
        ret = PTR_ERR(key_char.device);
        goto err;
    }
    
    key_char.device->of_node = of_find_node_path("/keypl");
    key_char.gpio_d = gpio_get_index(key_char.device,"key",0,GPIO_IN);
    gpiod_direection_input(key_char.gpio_d);
    
    sema_init(&key_char.lock,1);
    
err:
    return ret;
    
}

static void __exit key_drv_exit(void)
{
    gpio_put(key_char.gpio_d);
    
    cdev_del(&key_char.cdev);
    
    device_destroy(key_char.class,key_char.devid);
    
    class_destroy(key_char.class);
    
    unregister_chrdev_region(key_char.devid,1);
}

module_init(key_drv_init);
module_exit(key_drv_exit);

MODULE_AUTHOR("kevin");
MODULE_ALIAS("emio_key");
MODULE_DESCRIPTION("EMIO KEY driver");
MODULE_VERSION("v1.0");
MODULE_LICENSE("GPL");

应用程序:Emio_Key_Test.c

#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>

int mian(int argc, char *argv[])
{
    int fd_led,fd_key;
    int ret;
    unsigned int key_value = 0;
    
    fd_key = opne("/dev/pl_key_dev", O_RDWR);
    if(fd_key < 0)
    {
        printf("file /dev/pl_key_dev open failed\r\n");
    	return -1;
    }
    
    fd_led = open("/dev/led_dev", O_RDWR);
    if(fd_led < 0)
    {
        printf("file /dev/led_dev open failed\r\n");
        return -1;
    }
    
    while(1)
    {
        ret = read(fd_key,&key_value, sizeof(key_value));
        if(ret < 0)
        {
            printf("read failed\r\n");
            break;
        }
        
        if(1 == key_value)
        {
            printf("key pushed\n");
            led_value = !led_value;
            ret = write(fd_led,&led_value,sizeof(led_value));
            if(ret < 0)
            {
                printf("write failed\r\n");
                break;
            }
        }
        
    }
    
    close(fd_key);
    close(fd_led);
    
    return 0;
   
}

测试

修改设备树后重新编译petalinux,并打包生成BOOT.bin文件,烧录到SD卡中

petalinux-build

petalinux-package --boot --u-boot --fsbl --force

进入板载Linux系统中,加载ledkey两个驱动文件

insmod pl-key.ko
insmod ps-led.ko

运行./Emio_Key_Test

printf("请关注微信公众号:Kevin的学习站,关于AUTSAR和自动驾驶嵌入式相关的文章!")

赛灵思-Zynq UltraScale+ MPSoC学习笔记汇总

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/594846.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

基于Faster R-CNN实现目标检测

目录 1. 作者介绍2. Faster RCNN基本框架3.模型训练及测试3.1 数据集3.2 环境配置3.3 训练参数3.4 训练参数3.5 代码展示3.6 问题及分析 参考&#xff08;可供参考的链接和引用文献&#xff09; 1. 作者介绍 杨金鹏&#xff0c;男&#xff0c;西安工程大学电子信息学院&#x…

Mybatis-puls——入门案例和概述和CURD功能实现

前言 虽然但是&#xff0c;现在MyBatis_puls并不支持springboot3.x版本。 MyBatis_puls就像SpringBoot是为了快速开发Spring程序一样&#xff0c;这个是为了快速开发MyBatis程序。基于SpringBoot使用MP的开发流程 按照下面这个模板造就对了。 SpingBoot——SB整合MB的web项…

Profinet通信协议基础知识

目录 1、Profinet是PI退出的开放式以太网标准: 2、Profinet的参考模式 3、Profinet的应用领域

若依框架快速搭建(一)

若依框架开发 若依框架介绍前期准备相关工具IDEAwebstromNavcatMavenRedis 前后端项目搭建 后端搭建前端搭建源码下载 若依框架介绍 若以管理系统的网址&#xff1a;http://ruoyi.vip/ 代码为开源代码 主要分为四部分&#xff0c;第一个是整体项目&#xff0c;第二个是前后端…

UFS 3 - UFS RPMB

UFS 1-UFS RPMB 1 RPMB介绍2 RPMB Well Known Logical Unit Description3 Requirements3.1 RPMB Resources3.2 Algorithm and Key for MAC Calculation3.3 RPMB Message Components3.4 Request Message Types3.5 Response Message Types3.6 RPMB Operation Result 4 Implementa…

Springboot +spring security,前后端分离时的security处理方案(二)

一.简介 在前后端分离这样的开发模式下&#xff0c;前后端的交互都是通过 JSON 来进行数据传递的&#xff0c;无论登录成功还是失败&#xff0c;都不会有服务端跳转或者客户端跳转之类的操作。 也就是说无论登录成功还是失败&#xff0c;服务端都会返回一段登录成功或失败的 …

Go 1.19 排序算法

插入排序&#xff08;InsertionSort&#xff09; 插入排序是一种简单直观的排序算法&#xff0c;它的基本思想是将待排序的元素插入到已经排好序的序列中&#xff0c;从而得到一个新的有序序列。插入排序的具体过程如下&#xff1a; 从第一个元素开始&#xff0c;认为它已经是…

RK3568 i2s TDM数据抓取

1. I2S接口 I2S协议只定义三根信号线:时钟信号SCK、串行数据信号SD、左右声道选择信号WS。 SCK 时钟信号,Serial Clock,也可能称BCLK/Bit Clock或SCL/Serial Clock。 WS 左右声道选择信号,Word Select,也称帧时钟,也可能称LRCLK/Left Right Clock。 SD 串行数据信号,Ser…

计算机网络第一章——计算机网络系统结构(下)

提示&#xff1a;总角之宴&#xff0c;言笑晏晏。信誓旦旦&#xff0c;不思其反。反是不思&#xff0c;亦已焉哉。 文章目录 1.2.1 分层结构&#xff0c;协议&#xff0c;接口和服务为什么要有分层&#xff1f;怎么分层正式认识分层结构概念总结 1.2.2 OSI 参考模型ISO参考模型…

Markdown 格式文章的图床

chatGPT 奖励模型示意图&#xff1a; chatGPT RLHF(基于人类反馈的强化学习) 模型示意图&#xff1a; 强化学习过程示意图&#xff1a;

《HashMap的数据结构》

目录 HashMap概述&#xff1a; 数据结构的组成&#xff1a; 一个键值对是如何存入该结构中&#xff1a; HashMap中链表和红黑树的用途和转换方式 &#xff1a; HashMap概述&#xff1a; HashMap是基于哈希表的Map接口实现的&#xff0c;它存储的内容是键值对<key,value&g…

Web安全:文件包含漏洞测试(防止 黑客利用此漏洞.)

Web安全&#xff1a;文件包含漏洞测试. 文件包含的漏洞是 程序员在开发网站的时候&#xff0c;为了方便自己开发构架&#xff0c;使用了一些包含的函数&#xff08;比如&#xff1a;php开发语言&#xff0c;include() , include_once() , require_once() 等等 &#xff09;&a…

书单 | 数据治理的30本书

随着数字经济时代的到来&#xff0c;数据的价值不断被发掘。党的十九届四中全会首次将“数据”列为生产要素&#xff0c;充分凸显了数字经济时代数据对于经济活动和社会生活的巨大价值。开展数据治理的理论探索和实践创新&#xff0c;有利于全面释放数据价值助力数字经济发展&a…

校园高校共享单车管理系统nodejs+vue+express

设计的管理员的详细功能见下图&#xff0c;管理员登录进入本人后台之后&#xff0c;管理单车和区域&#xff0c;审核租赁订单和还车订单&#xff0c;收取租赁费用&#xff0c;查看单车租赁统计信息。 vue的文件结构其实就是一个index.html 中间的内容&#xff0c;用的是vue&am…

代码随想录算法训练营第二十二天|235. 二叉搜索树的最近公共祖先、701.二叉搜索树中的插入操作 、450.删除二叉搜索树中的节点

二叉搜索树的最近公共祖先 题目链接&#xff1a;力扣 其实可以用之前普通二叉树最近公共祖先的算法。但是这样没有很好的利用二叉搜索树是有序的性质。 TreeNode* lowestCommonAncestor1(TreeNode* root, TreeNode* p, TreeNode* q) {if(!root || root p ||rootq) return roo…

嵌入式系统中重要的编程思想:分层与时间片

1. 分层思想 分层的思想&#xff0c;并不是什么神秘的东西&#xff0c;事实上很多做项目的工程师本身自己也会在用。分层结构确是很有用的东西&#xff0c;参透后会有一种恍然大悟的感觉。 如果说我不懂LCD怎么驱动&#xff0c;那好办&#xff0c;看一下datasheet&#xff0c…

Java技术规范概览

Java技术规范 目录概述需求&#xff1a; 设计思路实现思路分析1.Java JSR的部分2.JSR-000373.JSR-0000394.JSR-000337 参考资料和推荐阅读 Survive by day and develop by night. talk for import biz , show your perfect code,full busy&#xff0c;skip hardness,make a bet…

三步快速激活chatGPT4

0、背景 Depay停止注册背景下&#xff0c;新用户如何开通chatGPT4&#x1f914;? 注意事项; 1.选在8:00-22:00之间阅读本教程&#x1f600;&#x1f601;&#x1f604; 2.本教程尝试过欧易和nodepay&#xff0c;但都不好用&#xff0c;故采用FOMEpay&#x1f60d;&#x1f60…

#Microsoft Edge功能测评!# 关于Edge浏览器以及插件推荐

关于Edge浏览器以及插件推荐 1.关于Microsoft Edge......1.1 什么是Microsoft Edge1.2Microsoft Edge的优势 2.Microsoft Edge的分屏功能2.1 如何分屏&#xff1f;2.2分屏的优势 3.Microsoft Edge插件推荐3.1 AIX智能下载器(图片/视频/音乐/文档)3.2 AdGuard 广告拦截器3.3 破解…

python基础知识(五):while循环、for循环、continue语句和break语句

目录 1. while循环2. for循环3. 循环语句和if语句结合3. continue语句4. break语句5. 双重循环6. 双重循环和continue语句以及break语句 1. while循环 while循环简单来说就是满足循环条件就执行循环语句&#xff0c;直到不满足为止&#xff0c;否则陷入死循环。 while语法 wh…