驅動 實現三個燈的亮滅

1、編寫LED燈的驅動,可以控制三個燈,應用程序中編寫控制燈的邏輯,要使用自動創建設備節點機制

head.h

#ifndef __HEAD_H__
#define __HEAD_H__#define PHY_LED1_MODER 0x50006000
#define PHY_LED1_ODR 0x50006014
#define PHY_LED1_RCC 0x50000A28#define PHY_LED2_MODER 0x50007000
#define PHY_LED2_ODR 0x50007014
#define PHY_LED2_RCC 0x50000A28#define PHY_LED3_MODER 0x50006000
#define PHY_LED3_ODR 0x50006014
#define PHY_LED3_RCC 0x50000A28#endif

mycdev.c

#include <linux/init.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/uaccess.h>
#include <linux/io.h>
#include <linux/device.h>
#include "head.h"
int major;
char kbuf[128] = {0};
// 定義指針接收映射成功的虛擬內存首地址
unsigned int *vir_led1_moder;
unsigned int *vir_led1_odr;
unsigned int *vir_led1_rcc;
unsigned int *vir_led2_moder;
unsigned int *vir_led2_odr;
unsigned int *vir_led2_rcc;
unsigned int *vir_led3_moder;
unsigned int *vir_led3_odr;
unsigned int *vir_led3_rcc;
struct class *cls;
struct device *dev;
// 封裝操作方法
int mycdev_open(struct inode *inode, struct file *file)
{printk("%s:%s:%d\n", __FILE__, __func__, __LINE__);return 0;
}
ssize_t mycdev_read(struct file *file, char *ubuf, size_t size, loff_t *lof)
{printk("%s:%s:%d\n", __FILE__, __func__, __LINE__);int ret;ret = copy_to_user(ubuf, kbuf, size);if (ret){printk("copy_to_user filad\n");return ret;}return 0;
}
ssize_t mycdev_write(struct file *file, const char *ubuf, size_t size, loff_t *lof)
{int ret;ret = copy_from_user(kbuf, ubuf, size);if (ret){printk("copy_from_user filed\n");return ret;}if (kbuf[0] == '1' && kbuf[1]== '1') // 開燈{// 開燈邏輯printk("開燈\n");(*vir_led1_odr) |= (0X1 << 10);}if (kbuf[0] == '1' && kbuf[1]== '0') // 關燈{// 關燈邏輯printk("關燈\n");(*vir_led1_odr) &= (~(0X1 << 10));}if (kbuf[0] == '2' && kbuf[1]== '1') // 開燈{// 開燈邏輯printk("開燈\n");(*vir_led2_odr) |= (0X1 << 10);}if (kbuf[0] == '2' && kbuf[1]== '0') // 關燈{// 關燈邏輯printk("關燈\n");(*vir_led2_odr) &= (~(0X1 << 10));}if (kbuf[0] == '3' && kbuf[1]== '1') // 開燈{// 開燈邏輯printk("開燈\n");(*vir_led3_odr) |= (0X1 << 8);}if (kbuf[0] == '3' && kbuf[1]== '0') // 關燈{// 關燈邏輯printk("關燈\n");(*vir_led3_odr) &= (~(0X1 << 8));}return 0;
}
int mycdev_close(struct inode *inode, struct file *file)
{printk("%s:%s:%d\n", __FILE__, __func__, __LINE__);return 0;
}
// 定義操作方法結構體遍歷并且初始化
struct file_operations fops = {.open = mycdev_open,.read = mycdev_read,.write = mycdev_write,.release = mycdev_close,
};static int __init mycdev_init(void)
{int i;// 注冊字符設備驅動major = register_chrdev(0, "mycdev", &fops);if (major < 0){printk("字符設備驅動注冊失敗\n");return major;}printk("字符設備驅動注冊成功major=%d\n", major);// 向上提交目錄信息cls = class_create(THIS_MODULE, "mycdev");if (IS_ERR(cls)){printk("向上提交目錄信息失敗\n");return -PTR_ERR(cls);}printk("向上提交目錄信息成功\n");// 向上提交設備信息for (i = 0; i < 3; i++){dev = device_create(cls, NULL, MKDEV(major, i), NULL, "mycdev%d", i);if (IS_ERR(dev)){printk("向上提交設備節點失敗\n");return -PTR_ERR(cls);}}printk("向上提交設備節點信息成功\n");// 完成硬件寄存器物理內存的映射vir_led1_moder = ioremap(PHY_LED1_MODER, 4);if (vir_led1_moder == NULL){printk("物理內存映射失敗%d\n", __LINE__);return -EFAULT;}vir_led1_odr = ioremap(PHY_LED1_ODR, 4);if (vir_led1_odr == NULL){printk("物理內存映射失敗%d\n", __LINE__);return -EFAULT;}vir_led1_rcc = ioremap(PHY_LED1_RCC, 4);if (vir_led1_rcc == NULL){printk("物理內存映射失敗%d\n", __LINE__);return -EFAULT;}vir_led2_moder = ioremap(PHY_LED2_MODER, 4);if (vir_led2_moder == NULL){printk("物理內存映射失敗%d\n", __LINE__);return -EFAULT;}vir_led2_odr = ioremap(PHY_LED2_ODR, 4);if (vir_led2_odr == NULL){printk("物理內存映射失敗%d\n", __LINE__);return -EFAULT;}vir_led2_rcc = ioremap(PHY_LED2_RCC, 4);if (vir_led2_rcc == NULL){printk("物理內存映射失敗%d\n", __LINE__);return -EFAULT;}vir_led3_moder = ioremap(PHY_LED3_MODER, 4);if (vir_led3_moder == NULL){printk("物理內存映射失敗%d\n", __LINE__);return -EFAULT;}vir_led3_odr = ioremap(PHY_LED3_ODR, 4);if (vir_led3_odr == NULL){printk("物理內存映射失敗%d\n", __LINE__);return -EFAULT;}vir_led3_rcc = ioremap(PHY_LED3_RCC, 4);if (vir_led3_rcc == NULL){printk("物理內存映射失敗%d\n", __LINE__);return -EFAULT;}printk("物理內存映射成功\n");// 硬件寄存器的初始化(*vir_led1_moder) &= (~(0X3 << 20)); // 設置為輸出(*vir_led1_moder) |= (0X1 << 20);(*vir_led2_moder) &= (~(0X3 << 20)); // 設置為輸出(*vir_led2_moder) |= (0X1 << 20);(*vir_led3_moder) &= (~(0X3 << 16)); // 設置為輸出(*vir_led3_moder) |= (0X1 << 16);// rcc使能(*vir_led1_rcc) |= (0X1 << 4);(*vir_led2_rcc) |= (0X1 << 5);(*vir_led3_rcc) |= (0X1 << 4);// 默認關燈(*vir_led1_odr) &= (~(0X1 << 10));(*vir_led2_odr) &= (~(0X1 << 10));(*vir_led3_odr) &= (~(0X1 << 8)); return 0;
}
static void __exit mycdev_exit(void)
{// 取消物理內存的映射iounmap(vir_led1_moder);iounmap(vir_led1_odr);iounmap(vir_led1_rcc);iounmap(vir_led2_moder);iounmap(vir_led2_odr);iounmap(vir_led2_rcc);iounmap(vir_led3_moder);iounmap(vir_led3_odr);iounmap(vir_led3_rcc);//銷毀設備信息int i;for(i=0;i<3;i++){device_destroy(cls,MKDEV(major,i));}//銷毀目錄信息class_destroy(cls);// 字符設備驅動的注銷unregister_chrdev(major, "mychrdev");
}
module_init(mycdev_init);
module_exit(mycdev_exit);
MODULE_LICENSE("GPL");

test.c

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
int main(int argc, const char *argv[])
{char buf[128] = {};int fd = open("/dev/mycdev0",O_RDWR);if(fd < 0){printf("打開設備文件失敗\n");exit(-1);}printf("成功打開設備文件\n");while(1){printf("輸入要實現的邏輯:>\n");fgets(buf,sizeof(buf),stdin);//從終端讀取一個字符存放到bufbuf[strlen(buf)-1]='\0';write(fd,buf,sizeof(buf));}close(fd);return 0;
}

實驗現象

?

?

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/39643.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/39643.shtml
英文地址,請注明出處:http://en.pswp.cn/news/39643.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

設計模式之責任鏈模式【Java實現】

責任鏈&#xff08;Chain of Resposibility&#xff09; 模式 概念 責任鏈&#xff08;chain of Resposibility&#xff09; 模式&#xff1a;為了避免請求發送者與多個請求處理者耦合在一起&#xff0c;于是將所有請求的處理者 通過前一對象記住其下一個對象的引用而連成一條…

什么是ServiceMesh(Istio一)

現在最火的后端架構無疑是微服務了&#xff0c;微服務將之前的單體應用拆分成了許多獨立的服務應用&#xff0c;每個微服務都是獨立的&#xff0c;好處自然很多&#xff0c;但是隨著應用的越來越大&#xff0c;微服務暴露出來的問題也就隨之而來了&#xff0c;微服務越來越多&a…

【Python】使用python解析普通格式的報文為someip格式報文

文章目錄 1.安裝scapy庫2.示例 1.安裝scapy庫 使用 pip 安裝 scapy 第三方庫&#xff0c;打開 cmd&#xff0c;輸入以下命令&#xff1a; pip install scapy出現如圖所示&#xff0c;表示安裝成功&#xff1a; 2.示例 要解析someip格式報文&#xff0c;需要導入someip模塊&a…

【Spring 】了解Spring AOP

目錄 一、什么是Spring AOP 二、AOP的使用場景 三、AOP組成 四、Spring AOP的實現 1、添加Spring AOP依賴 2、定義切面和切點 3、定義相關通知 五、 AOP的實現原理 1、什么是動態代理 2、 JDK代理和CGLIB代理的區別 一、什么是Spring AOP AOP&#xff08;Aspect Ori…

PLY模型格式詳解【3D】

本文介紹PLY 多邊形文件格式&#xff0c;這是一種用于存儲被描述為多邊形集合的圖形對象。 PLY文件格式的目標是提供一種簡單且易于實現但通用的格式足以適用于各種模型。 PLY有兩種子格式&#xff1a;易于入門的 ASCII 表示形式和用于緊湊存儲和快速保存和加載的二進制格式。 …

【FastColoredTextBox】C# 開源文本編輯控件

主界面截圖 使用Demos演示 FastColoredTextBox 是一個用于在 C# 程序中實現高亮語法著色、代碼編輯和文本顯示的自定義控件。它提供了許多功能&#xff0c;包括&#xff1a; 語法高亮&#xff1a;FastColoredTextBox 支持多種語言的語法高亮&#xff0c;可以根據語法規則將不同…

write javaBean error, fastjson version 1.2.76

fastjson JSON.toJSONString 報錯&#xff1a; > [0] JavaBeanSerializer.java->541: com.alibaba.fastjson.serializer.JavaBeanSerializer->write()> [1] JavaBeanSerializer.java->154: com.alibaba.fastjson.serializer.JavaBeanSerializer->write()>…

vite4+vue3+electron23.3+ts桌面應用bs端開發 打包windows、linux、max三個系統的安裝包

vite4vue3electron23.3ts桌面應用bs端開發 打包windows、linux、max三個系統的安裝包 主要包依賴 "electron-store": "^8.1.0", //全局數據狀態管理&#xff0c;可選擇性安裝"electron": "23.3.8","electron-builder": &q…

Android 使用SQLite的案例詳解

1、說明 sqlite是個輕量級的數據庫,可用于嵌入式。有時候做本地的web開發的時候,我會把sqlite作為內置數據庫,這樣便于部署,直接啟動應用即可。 這里主要是將android中的使用過程記錄一下。主要包含,數據如何初始化,在不同的activity中如何使用,以及增刪改查的實現。 …

網頁顯示攝像頭數據的方法---基于web video server

1. 背景&#xff1a; 在ros系統中有發布攝像頭的相關驅動rgb數據&#xff0c;需求端需要將rgb數據可以直接在網頁上去顯示。 問題解決&#xff1a; web_video_server功能包&#xff0c;相關鏈接&#xff1a; web_video_server - ROS Wiki 2. 下載&#xff0c;安裝和編譯&a…

Ubuntu20 ctrl+alt+T無法打開終端

事情是這樣的&#xff0c;某天改了下python版本&#xff0c;發現linux默認打開終端的快捷鍵ctrlaltT寄了&#xff0c;網上給出的都是修改快捷鍵不出意外肯定沒用 但是幸好我們是會分析的&#xff0c;我看到&#xff0c;很多回答說新增一個快捷鍵運行的命令是gnome-terminal&…

21、stm32使用LTDC驅動LCD

注&#xff1a;本文基于stm32使用FMC驅動SDRAM(IS42S32800G-6BLI)工程繼續開發 本例使用安富萊的H743XIH板子驅動LTDC點亮7寸LCD 硬件接線&#xff1a;RGB888 一、cubemx配置 1、LTDC配置 注意此引腳應于上面的硬件接線圖一致 2、配置DMA2D 3、背光引腳和觸摸引腳 4、時鐘…

在 IntelliJ IDEA 中使用 Docker 開發指南

目錄 一、IDEA安裝Docker插件 二、IDEA連接Docker 1、Docker for Windows 連接 2、SSH 連接 3、Connection successful 連接成功 三、查看Docker面板 四、使用插件生成鏡像 一、IDEA安裝Docker插件 打開 IntelliJ IDEA&#xff0c;點擊菜單欄中的 "File" -&g…

LeetCode 778. Swim in Rising Water【最小瓶頸路;二分+BFS或DFS;計數排序+并查集;最小生成樹】2096

本文屬于「征服LeetCode」系列文章之一&#xff0c;這一系列正式開始于2021/08/12。由于LeetCode上部分題目有鎖&#xff0c;本系列將至少持續到刷完所有無鎖題之日為止&#xff1b;由于LeetCode還在不斷地創建新題&#xff0c;本系列的終止日期可能是永遠。在這一系列刷題文章…

cs231n assignment 3 Q2 Image Captioning with Vanilla RNNs

文章目錄 嫌啰嗦直接看代碼Q2 Image Captioning with Vanilla RNNs一個給的工具代碼里的bug問題展示問題解決思路解決辦法 rnn_step_forward題面解析代碼輸出 rnn_step_backward題面解析代碼輸出 rnn_forward題面解析代碼輸出 rnn_backward題面解析代碼輸出 word_embedding_for…

使用 BERT 進行文本分類 (02/3)

? 一、說明 在使用BERT&#xff08;1&#xff09;進行文本分類中&#xff0c;我向您展示了一個BERT如何標記文本的示例。在下面的文章中&#xff0c;讓我們更深入地研究是否可以使用 BERT 來預測文本是使用 PyTorch 傳達積極還是消極的情緒。首先&#xff0c;我們需要準備數據…

3.1 Qt樣式選擇器

本期內容 3.1 樣式選擇器 3.1.1 Universal Selector (通用選擇器) 3.1.2 Type Selector (類型選擇器) 3.1.3 Property Selector (屬性選擇器) 3.1.4 Class Selector (類選擇器) 3.1.5 ID Selector (ID選擇器) 3.1.6 Descendant Selector (后裔選擇器) 3.1.7 Chil…

前端跨域的原因以及解決方案(vue),一文讓你真正理解跨域

跨域這個問題,可以說是前端的必需了解的,但是多少人是知其然不知所以然呢&#xff1f; 下面我們來梳理一下vue解決跨域的思路。 什么情況會跨域&#xff1f; ? 跨域的本質就是瀏覽器基于同源策略的一種安全手段。所謂同源就是必須有以下三個相同點&#xff1a;協議相同、域名…

WinCC V7.5 中的C腳本對話框不可見,將編輯窗口移動到可見區域的具體方法

WinCC V7.5 中的C腳本對話框不可見&#xff0c;將編輯窗口移動到可見區域的具體方法 由于 Windows 系統更新或使用不同的顯示器&#xff0c;在配置C動作時&#xff0c;有可能會出現C腳本編輯窗口被移動到不可見區域的現象。 由于該窗口無法被關閉&#xff0c;故無法進行進一步…

KafkaStream:Springboot中集成

1、在kafka-demo中創建配置類 配置kafka參數 package com.heima.kafkademo.config;import lombok.Data; import org.apache.kafka.common.serialization.Serdes; import org.apache.kafka.streams.StreamsConfig; import org.springframework.boot.context.properties.Configu…