嵌入式学习——硬件(Linux内核驱动编程LED、蜂鸣器、按键)——day59

1. 编写LED驱动(初始化所有子设备号)

#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <asm/uaccess.h>
#include <asm/io.h>#define GPBCON  (0x56000010)
#define GPBDAT  (0x56000014)
static unsigned int *regGPBCON;
static unsigned int *regGPBDAT;int led_driver_open(struct inode *p_node, struct file *fp)
{printk("open\n");return 0;
}ssize_t led_driver_read(struct file *fp, char __user *user_buffer, size_t n, loff_t * offset)
{printk("read\n");return 0;
}void ledOn(unsigned int n)
{*regGPBDAT |= (0x0F << 5);if(n < 1 || n > 4){return;}*regGPBDAT &= ~(1 << (n + 4));
}ssize_t led_driver_write(struct file *fp, const char __user *user_buffer, size_t n, loff_t *offset)
{char s[10];copy_from_user(s, user_buffer, n);ledOn(s[0]);printk("write\n");return n;
}int led_driver_close(struct inode *p_node, struct file *fp)
{printk("close\n");return 0;
}struct file_operations fops =
{	.owner = THIS_MODULE,.release = led_driver_close,.open = led_driver_open,.read = led_driver_read,.write = led_driver_write,
};static int __init led_driver_init(void)
{	int ret;printk("init\n");ret = register_chrdev(200, "first driver", &fops);if(ret != 0){return ret;}regGPBCON = ioremap(GPBCON, 4);regGPBDAT = ioremap(GPBDAT, 4);*regGPBCON &= ~((3 << 10) | (3 << 12) | (3 << 14) | (3 << 16));*regGPBCON |= (1 << 10) | (1 << 12) | (1 << 14) | (1 << 16);*regGPBDAT |= (0x0F << 5);return 0;
}static void __exit led_driver_exit(void)
{iounmap(regGPBDAT);iounmap(regGPBCON);unregister_chrdev(200, "first driver");printk("exit\n");
}module_init(led_driver_init);
module_exit(led_driver_exit);MODULE_LICENSE("GPL");
MODULE_AUTHOR("PuTe");

2. 编写LED驱动(初始化一个子设备号)

#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/cdev.h>
#include <asm/uaccess.h>
#include <asm/io.h>#define GPBCON  (0x56000010)
#define GPBDAT  (0x56000014)
static unsigned int *regGPBCON;
static unsigned int *regGPBDAT;
static dev_t dev_num;
struct cdev led_dev;int led_driver_open(struct inode *p_node, struct file *fp)
{printk("open\n");return 0;
}ssize_t led_driver_read(struct file *fp, char __user *user_buffer, size_t n, loff_t * offset)
{printk("read\n");return 0;
}void ledOn(unsigned int n)
{*regGPBDAT |= (0x0F << 5);if(n < 1 || n > 4){return;}*regGPBDAT &= ~(1 << (n + 4));
}ssize_t led_driver_write(struct file *fp, const char __user *user_buffer, size_t n, loff_t *offset)
{char s[10];copy_from_user(s, user_buffer, n);ledOn(s[0]);printk("write\n");return n;
}int led_driver_close(struct inode *p_node, struct file *fp)
{printk("close\n");return 0;
}struct file_operations fops =
{	.owner = THIS_MODULE,.release = led_driver_close,.open = led_driver_open,.read = led_driver_read,.write = led_driver_write,
};static int __init led_driver_init(void)
{	int ret;ret = alloc_chrdev_region(&dev_num, 0, 1, "first device");if(ret){printk("alloc_chrdev_region is error\n");return ret;}printk("major = %u, minior = %u\n", MAJOR(dev_num), MINOR(dev_num));cdev_init(&led_dev, &fops);ret = cdev_add(&led_dev, dev_num, 1);if(ret){unregister_chrdev_region(dev_num, 1);printk("cdev_add is error\n");return ret;}regGPBCON = ioremap(GPBCON, 4);regGPBDAT = ioremap(GPBDAT, 4);*regGPBCON &= ~((3 << 10) | (3 << 12) | (3 << 14) | (3 << 16));*regGPBCON |= (1 << 10) | (1 << 12) | (1 << 14) | (1 << 16);*regGPBDAT |= (0x0F << 5);return 0;
}static void __exit led_driver_exit(void)
{iounmap(regGPBDAT);iounmap(regGPBCON);cdev_del(&led_dev);unregister_chrdev_region(dev_num, 1);printk("exot\n");
}module_init(led_driver_init);
module_exit(led_driver_exit);MODULE_LICENSE("GPL");
MODULE_AUTHOR("PuTe");

3. LED标准字符设备驱动(省去在linux终端mknod的过程,直接insmod的即可运行程序)

#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/cdev.h>
#include <linux/device.h>
#include <asm/uaccess.h>
#include <asm/io.h>#define GPBCON  (0x56000010)
#define GPBDAT  (0x56000014)
static unsigned int *regGPBCON;
static unsigned int *regGPBDAT;
static dev_t dev_num;
struct cdev led_dev;
static struct class *p_class;
static struct device *p_device;int led_driver_open(struct inode *p_node, struct file *fp)
{printk("open\n");return 0;
}ssize_t led_driver_read(struct file *fp, char __user *user_buffer, size_t n, loff_t * offset)
{printk("read\n");return 0;
}void ledOn(unsigned int n)
{*regGPBDAT |= (0x0F << 5);if(n < 1 || n > 4){return;}*regGPBDAT &= ~(1 << (n + 4));
}ssize_t led_driver_write(struct file *fp, const char __user *user_buffer, size_t n, loff_t *offset)
{char s[10];copy_from_user(s, user_buffer, n);ledOn(s[0]);printk("write\n");return n;
}int led_driver_close(struct inode *p_node, struct file *fp)
{printk("close\n");return 0;
}struct file_operations fops =
{	.owner = THIS_MODULE,.release = led_driver_close,.open = led_driver_open,.read = led_driver_read,.write = led_driver_write,
};static int __init led_driver_init(void)
{	int ret;ret = alloc_chrdev_region(&dev_num, 0, 1, "first device");if(ret){printk("alloc_chrdev_region is error\n");goto alloc_chrdev_region_err;}printk("major = %u, minior = %u\n", MAJOR(dev_num), MINOR(dev_num));cdev_init(&led_dev, &fops);ret = cdev_add(&led_dev, dev_num, 1);if(ret){printk("cdev_add is error\n");goto cdev_add_err;}p_class = class_create(THIS_MODULE, "Led class");if(IS_ERR(p_class)){printk("class_create is error!");goto class_create_err;}p_device = device_create(p_class, NULL, dev_num, NULL, "led");if(p_device == NULL){printk("device_create is error\n");goto device_create_err;}regGPBCON = ioremap(GPBCON, 4);regGPBDAT = ioremap(GPBDAT, 4);*regGPBCON &= ~((3 << 10) | (3 << 12) | (3 << 14) | (3 << 16));*regGPBCON |= (1 << 10) | (1 << 12) | (1 << 14) | (1 << 16);*regGPBDAT |= (0x0F << 5);return 0;device_create_err:class_destroy(p_class);
class_create_err:cdev_del(&led_dev);
cdev_add_err:unregister_chrdev_region(dev_num, 1);
alloc_chrdev_region_err:return ret;
}static void __exit led_driver_exit(void)
{iounmap(regGPBDAT);iounmap(regGPBCON);device_destroy(p_class, dev_num);class_destroy(p_class);cdev_del(&led_dev);unregister_chrdev_region(dev_num, 1);printk("exit\n");
}module_init(led_driver_init);
module_exit(led_driver_exit);MODULE_LICENSE("GPL");
MODULE_AUTHOR("PuTe");

4. 蜂鸣器——混杂设备驱动

#include <linux/init.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/miscdevice.h>
#include <asm/uaccess.h>
#include <asm/io.h>#define GPBCON (0x56000010)
#define GPBDAT (0x56000014)
static unsigned int *regGPBCON;
static unsigned int *regGPBDAT;int beep_open(struct inode *p_node, struct file *fp)
{return 0;
}int beep_release(struct inode *p_node, struct file *fp)
{return 0;
}ssize_t beep_write(struct file *fp, const char __user *user_buffer, size_t n, loff_t * offset)
{int ret;copy_from_user(&ret, user_buffer, 4);printk("kernel : %d",ret);if(ret){*regGPBDAT |= (1 << 0);}else{*regGPBDAT &= ~(1 << 0);}return 4;
}static struct file_operations fops =
{.owner = THIS_MODULE,.open = beep_open,.release = beep_release,.write = beep_write
};static struct miscdevice beep_device =
{.minor = MISC_DYNAMIC_MINOR,.name = "beep",.fops = &fops,
};static int __init beep_init(void)
{int ret;ret = misc_register(&beep_device);if(ret){printk("misc_register is error");return ret;}regGPBCON = ioremap(GPBCON, 4);regGPBDAT = ioremap(GPBDAT, 4);*regGPBCON &= ~(3 << 0);*regGPBCON |= (1 << 0);return 0;
}static void __exit beep_exit(void)
{iounmap(regGPBCON);iounmap(regGPBDAT);misc_deregister(&beep_device);
}module_init(beep_init);
module_exit(beep_exit);MODULE_LICENSE("GPL");

5. 按键(轮询查看按键)——混杂设备驱动

#include <linux/init.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/miscdevice.h>
#include <asm/uaccess.h>
#include <asm/io.h>#define GPGCON (0x56000060)
#define GPGDAT (0x56000064)
#define GPGUP (0x56000068)static unsigned int *regGPGCON;
static unsigned int *regGPGDAT;
static unsigned int *regGPGUP;int key_open(struct inode *p_node, struct file *fp)
{return 0;
}int key_release(struct inode *p_node, struct file *fp)
{return 0;
}ssize_t key_write(struct file *fp, const char __user *user_buffer, size_t n, loff_t * offset)
{return 0;
}ssize_t key_read(struct file *fp, char __user *user_buffer, size_t n, loff_t *offset)
{int ret = -1;if (0 == (*regGPGDAT & (1 << 0))){ret = 1;}else if (0 == (*regGPGDAT & (1 << 3))){ret = 2;}else if (0 == (*regGPGDAT & (1 << 5))){ret = 3;}else if (0 == (*regGPGDAT & (1 << 6))){ret = 4;}else if (0 == (*regGPGDAT & (1 << 7))){ret = 5;}else if (0 == (*regGPGDAT & (1 << 11))){ret = 6;}if (ret != (-1)){copy_to_user(user_buffer, &ret, 4);}return 0;
}static struct file_operations fops =
{.owner = THIS_MODULE,.open = key_open,.release = key_release,.write = key_write,.read = key_read,
};static struct miscdevice key_device =
{.minor = MISC_DYNAMIC_MINOR,.name = "key",.fops = &fops,
};static int __init key_init(void)
{int ret;ret = misc_register(&key_device);if(ret){printk("misc_register is error");return ret;}regGPGCON = ioremap(GPGCON, 4);regGPGDAT = ioremap(GPGDAT, 4);regGPGUP = ioremap(GPGUP, 4);*regGPGCON &= ~((3 << 0) | (3 << 6) | (3 << 10) | (3 << 12) | (3 << 14) | (3 << 22));	*regGPGDAT |= ((1 << 0) | (1 << 3) | (1 << 5) | (1 << 6) | (1 << 7) | (1 << 11));*regGPGUP |= ((1 << 0) | (1 << 11));*regGPGUP &= ~((1 << 3) | (1 << 5) | (1 << 6) | (1 << 7));return 0;
}static void __exit key_exit(void)
{iounmap(regGPGCON);iounmap(regGPGDAT);iounmap(regGPGUP);misc_deregister(&key_device);
}module_init(key_init);
module_exit(key_exit);MODULE_LICENSE("GPL");

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

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

相关文章

2024年7月5日 (周五) 叶子游戏新闻

老板键工具来唤去: 它可以为常用程序自定义快捷键&#xff0c;实现一键唤起、一键隐藏的 Windows 工具&#xff0c;并且支持窗口动态绑定快捷键&#xff08;无需设置自动实现&#xff09;。 卸载工具 HiBitUninstaller: Windows上的软件卸载工具 《乐高地平线大冒险》为何不登陆…

江汉大学刘春萌同学整理的wifi模块 上传mqtt实验步骤

一.固件烧录 1.打开安信可官网 2.点击wifi模组系列的ESP8266 3.点击各类固件后选择固件号1471下载 4.打开烧录工具将下载的二进制文件导入并将后面的起始地址写为0x00000,下面勾选40mhz QIO 8Mbit点击start下载即可 二.本地部署mqtt服务器(windows) 1.下载mosquitto后有一个m…

Java并发编程知识整理笔记

目录 ​1. 什么是线程和进程&#xff1f; 线程与进程有什么区别&#xff1f; 那什么是上下文切换&#xff1f; 进程间怎么通信&#xff1f; 什么是用户线程和守护线程&#xff1f; 2. 并行和并发的区别&#xff1f; 3. 创建线程的几种方式&#xff1f; Runnable接口和C…

微博视频下载

video_urls 获取xpath://video/src|//video/autoplay # !/usr/bin/python3 # -*- coding:utf-8 -*- """ author: JHC000abcgmail.com file: demo1.py time: 2024/6/3 18:00 desc:""" import os import re import requests from urllib.parse im…

Qt实现流动的管道效果代码示例

在现代图形用户界面&#xff08;GUI&#xff09;应用程序中&#xff0c;动态效果可以显著增强用户体验。本文将介绍如何使用Qt框架实现一个流动的管道效果。我们将通过自定义QWidget来绘制管道&#xff0c;并使用定时器来实现流动效果。 1. 准备工作 首先&#xff0c;确保你已…

LeetCode.68文本左右对齐

问题描述 给定一个单词数组 words 和一个长度 maxWidth &#xff0c;重新排版单词&#xff0c;使其成为每行恰好有 maxWidth 个字符&#xff0c;且左右两端对齐的文本。 你应该使用 “贪心算法” 来放置给定的单词&#xff1b;也就是说&#xff0c;尽可能多地往每行中放置单词…

HMI 的 UI 风格创造奇迹

HMI 的 UI 风格创造奇迹

Table-driven Declarative Rewrite Rule (DRR)

Table-driven Declarative Rewrite Rule (DRR 好处规则定义原模式基于位置的匹配操作的匹配有向无环图&#xff08;DAG&#xff09;(AOp (BOp), $attr): 绑定操作的结果 好处 模式创建者只需要声明性地指定重写模式&#xff0c;而不必担心调用具体的C方法。 消除样板代码&…

Laravel5+mycat 报错 “Packets out of order”

背景 近期对负责项目&#xff0c;配置了一套 主从复制的 MySQL 集群 使用了中间件 mycat 但测试发现&#xff0c;替换了原来的数据连接后&#xff0c;会出现 Packets out of order 的报错 同时注意到&#xff0c;有的框架代码中竟然也会失效&#xff0c;比如 controller 类中&…

Linux:进程间通信(一.初识进程间通信、匿名管道与命名管道、共享内存)

上次结束了基础IO&#xff1a;Linux&#xff1a;基础IO&#xff08;三.软硬链接、动态库和静态库、动精态库的制作和加载&#xff09; 文章目录 1.认识进程间通信2.管道2.1匿名管道2.2pipe()函数 —创建匿名管道2.3匿名管道的四种情况2.4管道的特征 3.基于管道的进程池设计4.命…

基于java将dicom转化为jpg的几种方式

参考1 JAVA代码实现DICOM文件转换JPG package com.example;import java.awt.image.BufferedImage; import java.io.File;import javax.imageio.ImageIO;import ij.plugin.DICOM;/*** dicom文件java解析&#xff0c;生成图片* 不过这里不能解析压缩的dicom文件*/ public class …

Vue3学习笔记(n.0)

vue指令之v-for 首先创建自定义组件&#xff08;practice5.vue&#xff09;&#xff1a; <!--* Author: RealRoad1083425287qq.com* Date: 2024-07-05 21:28:45* LastEditors: Mei* LastEditTime: 2024-07-05 21:35:40* FilePath: \Fighting\new_project_0705\my-vue-app\…

重载一元运算符

自增运算符 #include<iostream> using namespace std; class CGirl { public:string name;int ranking;CGirl() { name "zhongge"; ranking 5; }void show() const{ cout << "name : "<<name << " , ranking : " <…

cmake编译源码教程(一)

1、介绍 本次博客介绍使用cmake编译平面点云分割的源代码,其对室内点云以及TLS点云中平面结构进行分割,分割效果如下: 2、编译过程 2.1 源代码下载 首先,下载源代码,如下所示,在该文件夹下新建一个build文件夹,用于后续生成sln工程。 同时,由于该库依赖open…

自动化设备上位机设计 二

目录 一 设计原型 二 后台代码 一 设计原型 二 后台代码 namespace 自动化上位机设计 {public partial class Form1 : Form{public Form1(){InitializeComponent();timer1.Enabled true;timer1.Tick Timer1_Tick;}private void Timer1_Tick(object? sender, EventArgs e)…

您的私人办公室!-----ONLYOFFICE8.1版本的桌面编辑器测评

随时随地创建并编辑文档&#xff0c;还可就其进行协作 ONLYOFFICE 文档是一款强大的在线编辑器&#xff0c;为您使用的平台提供文本文档、电子表格、演示文稿、表单和 PDF 编辑工具。 网页地址链接&#xff1a; https://www.onlyoffice.com/zh/office-suite.aspxhttps://www…

AJAX-day1:

注&#xff1a;文件布局&#xff1a; 一、AJAX的概念&#xff1a; AJAX是浏览器与服务器进行数据通信的技术 >把数据变活 二、AJAX的使用&#xff1a; 使用axios库&#xff0c;与服务器进行数据通信 基于XMLHttpRequest封装&#xff0c;代码简单 Vue,React项目使用 学习…

自定义控件绘图篇(一)基本几何图形绘制

在Android开发中&#xff0c;自定义控件是一种强大的技术&#xff0c;它允许开发者创建具有独特外观和行为的UI组件。通过自定义控件&#xff0c;你可以实现标准组件库中没有的功能和设计。自定义控件通常涉及两个主要方面&#xff1a;布局和绘图。本回答将重点介绍如何在自定义…

哪个品牌的加密软件稳定方便使用?

一、什么是企业加密软件&#xff1f; 企业加密软件是一种用于保护企业内部数据安全的工具。在数字化时代&#xff0c;随着数据量的爆炸式增长&#xff0c;信息安全和隐私保护变得愈发重要。企业加密软件作为保障数据安全的关键工具&#xff0c;受到越来越多用户的青睐。 企业…

昆虫学(书籍学习资料)

包括昆虫分类&#xff08;上下册&#xff09;、昆虫生态大图鉴等书籍资料。