华清远见嵌入式学习——驱动开发——day9

2024-02-24 14:28

本文主要是介绍华清远见嵌入式学习——驱动开发——day9,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

目录

作业要求:

作业答案:

代码效果:

​编辑

Platform总线驱动代码:

应用程序代码:

设备树配置:


作业要求:

通过platform总线驱动框架编写LED灯的驱动,编写应用程序测试,发布到CSDN

作业答案:

代码效果:

Platform总线驱动代码:

#include <linux/init.h>
#include <linux/module.h>
#include <linux/of_gpio.h>
#include <linux/gpio.h>
#include <linux/platform_device.h>
#include <linux/mod_devicetable.h>//主设备号
int major;//用于上传目录和设备节点信息
struct class *cls;
struct device *device;// led设备号
struct gpio_desc *gpiono1;
struct gpio_desc *gpiono2;
struct gpio_desc *gpiono3;// 创建功能码
#define LED_ON _IOW('l', 1, int)
#define LED_OFF _IOW('l', 0, int)// ioctl函数,用于控制led设备
long mycdev_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{switch (cmd){case LED_ON:switch (arg){case 1:gpiod_set_value(gpiono1, 1);break;case 2:gpiod_set_value(gpiono2, 1);break;case 3:gpiod_set_value(gpiono3, 1);break;}break;case LED_OFF:switch (arg){case 1:gpiod_set_value(gpiono1, 0);break;case 2:gpiod_set_value(gpiono2, 0);break;case 3:gpiod_set_value(gpiono3, 0);break;}break;}return 0;
}// 定义操作方法结构体变量并赋值
struct file_operations fops = {.unlocked_ioctl = mycdev_ioctl,
};// 封装probe函数,当设备和驱动匹配成功之后执行
int pdrv_probe(struct platform_device *dev)
{printk("%s:%s:%d\n", __FILE__, __func__, __LINE__);// 字符设备驱动注册major = register_chrdev(0, "mychrdev", &fops);if (major < 0){printk("字符设备驱动注册失败\n");return major;}printk("字符设备驱动注册成功:major=%d\n", major);// 向上提交目录cls = class_create(THIS_MODULE, "mychrdev");if (IS_ERR(cls)){printk("向上提交目录失败\n");return -PTR_ERR(cls);}printk("向上提交目录成功\n");// 向上提交设备节点信息int i; // 向上提交三次设备节点信息for (i = 0; i < 3; i++){device = device_create(cls, NULL, MKDEV(major, i), NULL, "myled%d", i);if (IS_ERR(dev)){printk("向上提交设备节点失败\n");return -PTR_ERR(dev);}}printk("向上提交设备节点成功\n");// 解析LED1的gpio编号gpiono1 = gpiod_get_from_of_node(dev->dev.of_node, "led1-gpio", 0, GPIOD_OUT_LOW, NULL);if (gpiono1 == NULL){printk("解析led1对应gpio编号失败\n");return -ENXIO;}printk("解析led1对应gpio编号成功\n");// 解析LED1的gpio编号gpiono2 = gpiod_get_from_of_node(dev->dev.of_node, "led2-gpio", 0, GPIOD_OUT_LOW, NULL);if (gpiono2 == NULL){printk("解析led2对应gpio编号失败\n");return -ENXIO;}printk("解析led2对应gpio编号成功\n");// 解析LED1的gpio编号gpiono3 = gpiod_get_from_of_node(dev->dev.of_node, "led3-gpio", 0, GPIOD_OUT_LOW, NULL);if (gpiono3 == NULL){printk("解析led3对应gpio编号失败\n");return -ENXIO;}printk("解析led3对应gpio编号成功\n");return 0;
}
// 封装remove函数,用于驱动和设备卸载时执行
int pdrv_remove(struct platform_device *dev)
{// 销毁设备节点信息device_destroy(cls, MKDEV(major, 0));// 销毁设备节点信息int i;for (i = 0; i < 3; i++){device_destroy(cls, MKDEV(major, i));}// 释放gpio编号gpiod_put(gpiono1);gpiod_put(gpiono2);gpiod_put(gpiono3);// 销毁目录class_destroy(cls);// 注销字符设备驱动unregister_chrdev(major, "mychrdev");printk("%s:%s:%d\n", __FILE__, __func__, __LINE__);return 0;
}
// 构建用于匹配的设备树表
struct of_device_id oftable[] = {{.compatible = "hqyj,myplatform",},{/* end node */}, // 防止数组越界
};
// 分配驱动对象并初始化
struct platform_driver pdrv = {.probe = pdrv_probe,.remove = pdrv_remove,.driver = {.name = "bbbbb",.of_match_table = oftable, // 设置设备树匹配},};
// 一键注册宏
module_platform_driver(pdrv);
MODULE_LICENSE("GPL");

应用程序代码:

#include<stdlib.h>
#include<stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include<unistd.h>
#include<string.h>
#include<sys/ioctl.h>//创建功能码
#define LED_ON _IOW('l',1,int)  
#define LED_OFF _IOW('l',0,int)int main(int argc, char const *argv[])
{int a,b;int fd=open("/dev/myled0",O_RDWR);if(fd<0){printf("打开设备文件失败\n");exit(-1);}while(1){//从终端读取printf("请输入要实现的功能\n");printf("0(关灯) 1(开灯)\n");printf("请输入>");scanf("%d",&a);printf("请输入要控制的灯\n");printf("1(LED1) 2(LED2) 3(LED3)\n");printf("请输入>");scanf("%d",&b);switch(a){case 1:ioctl(fd,LED_ON,b);break;case 0:ioctl(fd,LED_OFF,b);break;}}close(fd);return 0;
}

设备树配置:

/dts-v1/;
#include "stm32mp157.dtsi"
#include "stm32mp15xa.dtsi"
#include "stm32mp15-pinctrl.dtsi"
#include "stm32mp15xxac-pinctrl.dtsi"
#include "stm32mp15xx-fsmp1x.dtsi" 
/ {model = "HQYJ STM32MP157 FSMP1A Discovery Board";compatible = "st,stm32mp157a-dk1", "st,stm32mp157";aliases {serial0 = &uart4;serial5 = &usart3;};chosen {stdout-path = "serial0:115200n8";};reserved-memory {gpu_reserved: gpu@d4000000 {reg = <0xd4000000 0x4000000>;no-map;};optee_memory: optee@0xde000000 {reg = <0xde000000 0x02000000>;no-map;};};mynode@0x12345678{compatible = "hqyj,mynode";astring="hello 23091";uint  =<0xaabbccdd 0x11223344>;binarry=[00 0c 29 7b f9 be];mixed ="hello",[11 22],<0x12345678>;};myled{led1-gpio=<&gpioe 10 0>; led2-gpio=<&gpiof 10 0>;led3-gpio=<&gpioe 8 0>;           };myirq{compatible = "hqyj,myirq";interrupt-parent = <&gpiof>;interrupts=<9 0>,<7 0>,<8 0>;};myplatform{compatible = "hqyj,myplatform";led1-gpio=<&gpioe 10 0>;led2-gpio=<&gpiof 10 0>;led3-gpio=<&gpioe 8 0>;           interrupt-parent = <&gpiof>;interrupts=<9 0>;reg=<0X12345678 0X400>;}; 
};

这篇关于华清远见嵌入式学习——驱动开发——day9的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/742399

相关文章

基于Python开发电脑定时关机工具

《基于Python开发电脑定时关机工具》这篇文章主要为大家详细介绍了如何基于Python开发一个电脑定时关机工具,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录1. 简介2. 运行效果3. 相关源码1. 简介这个程序就像一个“忠实的管家”,帮你按时关掉电脑,而且全程不需要你多做

Java中的Opencv简介与开发环境部署方法

《Java中的Opencv简介与开发环境部署方法》OpenCV是一个开源的计算机视觉和图像处理库,提供了丰富的图像处理算法和工具,它支持多种图像处理和计算机视觉算法,可以用于物体识别与跟踪、图像分割与... 目录1.Opencv简介Opencv的应用2.Java使用OpenCV进行图像操作opencv安装j

基于Qt开发一个简单的OFD阅读器

《基于Qt开发一个简单的OFD阅读器》这篇文章主要为大家详细介绍了如何使用Qt框架开发一个功能强大且性能优异的OFD阅读器,文中的示例代码讲解详细,有需要的小伙伴可以参考一下... 目录摘要引言一、OFD文件格式解析二、文档结构解析三、页面渲染四、用户交互五、性能优化六、示例代码七、未来发展方向八、结论摘要

在 VSCode 中配置 C++ 开发环境的详细教程

《在VSCode中配置C++开发环境的详细教程》本文详细介绍了如何在VisualStudioCode(VSCode)中配置C++开发环境,包括安装必要的工具、配置编译器、设置调试环境等步骤,通... 目录如何在 VSCode 中配置 C++ 开发环境:详细教程1. 什么是 VSCode?2. 安装 VSCo

C#图表开发之Chart详解

《C#图表开发之Chart详解》C#中的Chart控件用于开发图表功能,具有Series和ChartArea两个重要属性,Series属性是SeriesCollection类型,包含多个Series对... 目录OverviChina编程ewSeries类总结OverviewC#中,开发图表功能的控件是Char

鸿蒙开发搭建flutter适配的开发环境

《鸿蒙开发搭建flutter适配的开发环境》文章详细介绍了在Windows系统上如何创建和运行鸿蒙Flutter项目,包括使用flutterdoctor检测环境、创建项目、编译HAP包以及在真机上运... 目录环境搭建创建运行项目打包项目总结环境搭建1.安装 DevEco Studio NEXT IDE

Python开发围棋游戏的实例代码(实现全部功能)

《Python开发围棋游戏的实例代码(实现全部功能)》围棋是一种古老而复杂的策略棋类游戏,起源于中国,已有超过2500年的历史,本文介绍了如何用Python开发一个简单的围棋游戏,实例代码涵盖了游戏的... 目录1. 围棋游戏概述1.1 游戏规则1.2 游戏设计思路2. 环境准备3. 创建棋盘3.1 棋盘类

HarmonyOS学习(七)——UI(五)常用布局总结

自适应布局 1.1、线性布局(LinearLayout) 通过线性容器Row和Column实现线性布局。Column容器内的子组件按照垂直方向排列,Row组件中的子组件按照水平方向排列。 属性说明space通过space参数设置主轴上子组件的间距,达到各子组件在排列上的等间距效果alignItems设置子组件在交叉轴上的对齐方式,且在各类尺寸屏幕上表现一致,其中交叉轴为垂直时,取值为Vert

Ilya-AI分享的他在OpenAI学习到的15个提示工程技巧

Ilya(不是本人,claude AI)在社交媒体上分享了他在OpenAI学习到的15个Prompt撰写技巧。 以下是详细的内容: 提示精确化:在编写提示时,力求表达清晰准确。清楚地阐述任务需求和概念定义至关重要。例:不用"分析文本",而用"判断这段话的情感倾向:积极、消极还是中性"。 快速迭代:善于快速连续调整提示。熟练的提示工程师能够灵活地进行多轮优化。例:从"总结文章"到"用

这15个Vue指令,让你的项目开发爽到爆

1. V-Hotkey 仓库地址: github.com/Dafrok/v-ho… Demo: 戳这里 https://dafrok.github.io/v-hotkey 安装: npm install --save v-hotkey 这个指令可以给组件绑定一个或多个快捷键。你想要通过按下 Escape 键后隐藏某个组件,按住 Control 和回车键再显示它吗?小菜一碟: <template