嵌入式學習——硬件(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.pswp.cn/web/40300.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/40300.shtml
英文地址,請注明出處:http://en.pswp.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;、昆蟲生態大圖鑒等書籍資料。