GEC6818蜂鳴器驅動開發

相關知識:Linux設備驅動開發

insmod 編譯好的.ko文件后再運行beep_app.c編譯完成的可執行文件即可使板子蜂鳴。

beep_drv.c:

#include <linux/module.h> //包含了加載模塊時需要使用的大量符號和函數聲明
#include <linux/kernel.h> //包含了printk內核打印函數等函數聲明
#include <linux/init.h>  //包含了模塊加載函數和模塊釋放函數的宏定義
#include <linux/errno.h>
#include <linux/cdev.h>
#include<linux/fs.h>
#include <linux/device.h>
#include <linux/ioport.h>
#include <linux/io.h>
#include <linux/uaccess.h>int devno_major=0;//beep的主設備號
int devno_minor=0;//beep的次設備號
struct class *beep_class;
struct device *beep_device;
struct resource *beep_resource;
void __iomem *gpioc_base_va;
void __iomem *gpiocout_va;    
void __iomem *gpiocoutenb_va; 
void __iomem *gpiocaltfn0_va; 
void __iomem *gpiocaltfn1_va; 
void __iomem *gpiocpad_va;    module_param(devno_major,int,0660);
module_param(devno_minor,int,0660);enum beep_state{BEEP_OFF,BEEP_ON};int beep_state=BEEP_OFF;/*1、定義一個字符設備 ---> struct cdev*/
struct cdev beep_cdev;/*2、定義并初始化字符設備的文件操作集 ---> struct file_operations*/
int gec6818_beep_open(struct inode *inode, struct file *filp)
{printk("beep have been opened!\n");return 0;
}
ssize_t gec6818_beep_read (struct file *filp, char __user *user_buf,size_t size, loff_t *off)
{int r = copy_to_user(user_buf, (void*)&beep_state, size);if(r != 0)return EINVAL;return size;
}
ssize_t gec6818_beep_write (struct file *filp, const char __user *user_buf, size_t size, loff_t *off)
{int r = copy_from_user((void*)&beep_state, user_buf, size);if(r != 0)return EINVAL;if(beep_state == BEEP_ON)writel(readl(gpiocout_va)|(0x01<<14),gpiocout_va);elsewritel(readl(gpiocout_va)&(~(0x01<<14)),gpiocout_va);return size;
}
int gec6818_beep_release (struct inode *inode, struct file *filp)
{printk("beep have been closed!\n");return 0;
}static const struct file_operations gec6818_beep_fops = {.owner = THIS_MODULE,.open = gec6818_beep_open,.read = gec6818_beep_read,.write = gec6818_beep_write,.release = gec6818_beep_release
};//入口函數 -->安裝驅動
static int  __init gec6818_beep_init(void)
{dev_t devno;//beep的設備號int ret=0;/*3、給字符設備申請一個設備號 ---> 設備號=主設備號<<20 + 次設備號*/if(devno_major != 0){devno = MKDEV(devno_major,devno_minor);if(register_chrdev_region(devno, 1, "gec6818_beep")){printk("register_chrdev_region error!\n");if(alloc_chrdev_region(&devno, devno_minor, 1, "gec6818_beep")){printk("alloc_chrdev_region error!\n");ret = EINVAL;goto alloc_chrdev_region_err;}}}else{if(alloc_chrdev_region(&devno, devno_minor, 1, "gec6818_beep")){printk("alloc_chrdev_region error!\n");ret = EINVAL;goto alloc_chrdev_region_err;}}devno_major = MAJOR(devno);devno_minor = MINOR(devno);/*4、初始化字符設備*/cdev_init(&beep_cdev, &gec6818_beep_fops);/*5、將字符設備加入內核*/if(cdev_add(&beep_cdev, devno, 1)<0){ret = EINVAL;goto cdev_add_err;	}/*6、創建class*/beep_class = class_create(THIS_MODULE, "gec6818_beep");if(beep_class == NULL){ret = EBUSY;goto class_create_err;}/*7、創建device*/beep_device = device_create(beep_class, NULL,devno, NULL, "gec6818_beep");if(beep_device == NULL){ret = EBUSY;goto device_create_err;}/*8、申請物理內存區*/beep_resource = request_mem_region(0xC001C000, 0x1000, "GPIOC_MEM");if(beep_resource == NULL){ret = EBUSY;goto request_mem_region_err;}/*9、IO內存動態映射,得到虛擬地址*/gpioc_base_va = ioremap(0xC001C000, 0x1000);if(gpioc_base_va == NULL){ret = EBUSY;goto ioremap_err;}/*10、使用虛擬地址,把beep進行初始化*/gpiocout_va    = gpioc_base_va + 0x00;gpiocoutenb_va = gpioc_base_va + 0x04;gpiocaltfn0_va = gpioc_base_va + 0x20;gpiocaltfn1_va = gpioc_base_va + 0x24;gpiocpad_va    = gpioc_base_va + 0x18;//GPIOCALTFN0 &= ~(0x03<<28);//把GPIOC14設置為GPIO功能writel(readl(gpiocaltfn0_va)&(~(0x03<<28)),gpiocaltfn0_va);//GPIOCALTFN0 |= (0x01<<28);writel(readl(gpiocaltfn0_va)|((0x01<<28)),gpiocaltfn0_va);//GPIOCOUTENB |= 1<<14;//把GPIOC14設置為輸出模式writel(readl(gpiocoutenb_va)|((0x01<<14)),gpiocoutenb_va);//GPIOCOUT &= ~(1<<14);//把GPIOC14輸出低電平,默認beep不響writel(readl(gpiocout_va)&(~(0x01<<14)),gpiocout_va);printk("gec6818 beep init success!\n");return 0;
ioremap_err:release_mem_region(0xC001C000, 0x1000);
request_mem_region_err:device_destroy(beep_class, devno);
device_create_err:class_destroy(beep_class);
class_create_err:
cdev_add_err:unregister_chrdev_region(devno, 1);//注銷設備號
alloc_chrdev_region_err:return ret;
}//出口函數 -->卸載驅動
static void __exit gec6818_beep_exit(void)
{iounmap(gpioc_base_va);release_mem_region(0xC001C000, 0x1000);device_destroy(beep_class, MKDEV(devno_major,devno_minor));class_destroy(beep_class);unregister_chrdev_region(MKDEV(devno_major,devno_minor), 1);//注銷設備號printk("6818gec beep exit\n ");
}//驅動程序的入口: #insmod hello.ko ==> module_init() ==> gec6868_hello_init();
module_init(gec6818_beep_init);
//驅動程序的出口: #rmmod hello.ko ==> module_exit() ==> gec6818_hello_exit();
module_exit(gec6818_beep_exit);
//module的描述: #modinfo  hello.ko
MODULE_AUTHOR("GEC_Liudehua@163.com");
MODULE_DESCRIPTION("beep driver for GEC6818");
MODULE_LICENSE("GPL");
MODULE_VERSION("V1.0");

?beep_app.c:

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
int beep_state;
int readbuf;int main()
{int fd = open("/dev/gec6818_beep",O_RDWR);if(fd == -1){printf("open failed!\n");return -1;}while(1){beep_state=1;int r = write(fd,&beep_state,4);if(r !=4 ){printf("write error!\n");}read(fd,&readbuf,4);printf("read buf is %d\n",readbuf);sleep(2);beep_state=0;write(fd,&beep_state,4);read(fd,&readbuf,4);printf("read buf is %d\n",readbuf);sleep(2);}
}

makefile:


#KERNELRELEASE這個變量,在內核源碼的根目錄下面的Makefile會初初始化的ifeq ($(KERNELRELEASE),)KERN_DIR := /home/china/6818GEC/kernel#在Makefile中可以調用shell的命令,調用方法如下:
# $(shell  shell命令) -> 整個這個表達式,表示調用該shell命令的輸出結果
PWD := $(shell pwd)CROSS_COMPILE := /home/china/6818GEC/prebuilts/gcc/linux-x86/arm/arm-eabi-4.8/bin/arm-eabi-modules:make -C $(KERN_DIR)  M=$(PWD) ARCH=arm CROSS_COMPILE=$(CROSS_COMPILE)  modules
clean:rm -rf *.orm -rf  modules.order  .tmp_versions *.ko  Module.symversrm -f  *.cmd .*.cmd  *.mod.celseobj-m += beep_drv.oendif

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

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

相關文章

電腦定時管家!Wise Auto Shutdown 深度測評:多任務執行 + 靈活定時

各位電腦小達人,今天給大家介紹一款超厲害的Windows系統定時任務管理工具——Wise Auto Shutdown!這玩意兒就像電腦的貼心小管家,能自動執行關機、重啟這些操作,時間設定靈活得很,還有提醒機制呢。下面我給大家好好嘮嘮…

vscode 配置qt

工具:vscode、qttools、qtconfigure Search Mode改成基于cmake的。 # 在項目中指定Qt的路徑 set(Qt5_DIR "/home/jp/qt-everywhere-src-5.12.9/arm-qt/lib/cmake/Qt5") # 用于指定 Qt5 的安裝路徑 find_package(Qt5 REQUIRED COMPONENTS Widgets)這樣就…

基于Boost庫、Jsoncpp、cppjieba、cpp-httplib等構建Boost搜索引擎

??個人主頁:小羊 ??所屬專欄:項目 很榮幸您能閱讀我的文章,誠請評論指點,歡迎歡迎 ~ 目錄 項目背景技術棧和項目環境正排索引和倒排索引數據去標簽與清洗下載數據源去標簽 建立索引構建正排索引構建倒排索引 建立搜索引擎h…

QMK機械鍵盤固件開發指南:從源碼到實踐

QMK機械鍵盤固件開發指南:從源碼到實踐 前言 QMK(Quantum Mechanical Keyboard)是一款開源的鍵盤固件,支持眾多自定義鍵盤的功能配置。通過QMK,您可以完全掌控鍵盤的每一個按鍵,實現復雜的宏指令、多層按…

WPF 導航

WPF 導航相關控件/機制 控件 / 類說明常用屬性/方法Frame用來承載不同的頁面 (Page) 并在它們之間切換的容器。Source(導航到的 URI) Navigate()(導航方法) CanGoBack / GoBack() CanGoForward / GoForward()Page表示一個單獨的可…

時序建模演進之路:從 MLP、RNN 到 LSTM 與 GRU

時序建模演進之路:從 MLP、RNN 到 LSTM 與 GRU 您是否好奇機器如何能像人類一樣理解、生成流暢的文本,甚至是從海量代碼中自動生成文檔?這些自然語言處理 (NLP) 領域的迷人挑戰,其核心在于模型處理和記憶 序列數據 的能力。 然而…

【Redis——數據類型和內部編碼和Redis使用單線程模型的分析】

文章目錄 Redis的數據類型和內部編碼單線程模型的工作過程Redis在處理命令時雖然是一個單線程模型,為啥效率那么高,速度快呢? 總而言之,Redis提供的哈希表容器并不一定真的是真的哈希表,而是在特點的場景下&#xff0c…

鴻蒙NEXT開發動畫(風格的旋轉加載動畫組件)

1.創建空白項目 2.Page文件夾下面新建Spin.ets文件,代碼如下: /*** SpinKit 風格的旋轉加載動畫組件。** component* param spinSize - 動畫容器大小(必須為正數)* param spinColor - 動畫顏色(支持資源引用&#xf…

后端接口請求http改為https

1、使用 OpenSSL 生成自簽名證書 在Linxu服務器上執行如下命令: openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -days 365 -nodes 運行此命令后,會提示輸入一些信息(如國家、省份、城市、組織名稱等)&…

工作記錄 2017-12-12 + 在IIS下發布wordpress

工作記錄 2017-12-12 序號 工作 相關人員 1 修改郵件上的問題。 更新RD服務器。 在IIS下發布wordpress。 郝 服務器更新 RD服務器更新了,更新的文件放在190的D:\Temp\CHTeam\fnehr_update_20171212\下了。 數據庫更新: 數據庫沒有更新 更新的文件&#xf…

【PostgreSQL數據分析實戰:從數據清洗到可視化全流程】1.2 安裝與配置PostgreSQL(Windows/Linux/macOS)

?? 點擊關注不迷路 ?? 點擊關注不迷路 ?? 點擊關注不迷路 文章大綱 1.2 安裝與配置 PostgreSQL(Windows/Linux/macOS)1.2.1 操作系統兼容性與硬件要求1.2.2 Windows 安裝與配置1.2.2.1 安裝步驟1.2.2.2 服務管理1.2.2.3 配置文件路徑1.2.3 Linux 安裝與配置(以 Ubuntu…

epub格式轉txt格式工具,txt批量轉PDF

epub格式轉txt格式工具,功能如圖: txt格式批量轉PDF 參考原文:epub格式轉txt格式工具,txt批量轉PDF 輕輕一點就關注, 好運連連擋不住,點個關注吧。

56.[前端開發-前端工程化]Day03-webpack構建工具

邂逅Webpack和打包過程 1 認識webpack工具 前端開發的流程 內置模塊path path常見的API 在webpack中的使用 認識webpack 腳手架依賴webpack Webpack到底是什么呢 Webpack官方的圖片 Vue項目加載的文件有哪些呢? Webpack的使用前提 Webpack的安裝 2 webpack基本打包…

Rockchip Android平臺打開GKI無法開機問題

Rockchip Android平臺打開GKI無法開機問題 問題描述 Rockchip Android平臺由于編譯環境對pahole版本有要求,如果版本不對會導致ko無法加載從而導致系統無法開機。pahole的版本具體要求如下: Android版本pahole版本Android12/13版本pahole v1.21Androi…

SQL命令二:SQL 高級查詢與特殊算法

引言 在掌握了 SQL 的基礎操作和建表約束后,我們可以進一步探索 SQL 的高級查詢功能和一些特殊算法。這些高級技巧能夠幫助我們更高效地處理和分析數據,滿足復雜的業務需求。 一、查詢進階 (一)簡單查詢 簡單查詢通過 select 語…

HTML04:圖像標簽

圖像標簽 常見的圖像標簽 JPGGIFPNGBMP <img src"路徑" alt"名稱" title"懸停名稱" width"高" height"寬"/><!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8&quo…

Docker —— 技術架構的演進

Docker —— 技術架構的演進 技術架構演進總結單機架構優點缺點總結 應用數據分離架構優點缺點總結 應用服務集群架構1. Nginx2. HAProxy3. LVS&#xff08;Linux Virtual Server&#xff09;4. F5 BIG-IP對比總結選型建議 讀寫分離/主從分離架構1. MyCat簡介 2. TDDL&#xff…

[machine learning] Transformer - Attention (一)

Attention是Transformer的核心&#xff0c;本系列先通過介紹Attention來學習Transformer。本文先介紹簡單版的Attention。 在Attention出現之前&#xff0c;通常使用recurrent neural networds (RNNs)來處理長序列數據。模型架構上&#xff0c;又通常使用encoder-decoder的結構…

Android 輸入控件事件使用示例

一 前端 <EditTextandroid:id="@+id/editTextText2"android:layout_width="match_parent"android:layout_height="wrap_content"android:ems="10"android:inputType="text"android:text="Name" />二 后臺代…

【向量數據庫】用披薩點餐解釋向量數據庫:一個美味的技術類比

文章目錄 前言場景設定&#xff1a;披薩特征向量化顧客到來&#xff1a;生成查詢向量相似度計算實戰1. 歐氏距離計算&#xff08;值越小越相似&#xff09;2. 余弦相似度計算&#xff08;值越大越相似&#xff09; 關鍵發現&#xff1a;度量選擇影響結果現實啟示結語 前言 想象…