chinese直男口爆体育生外卖, 99久久er热在这里只有精品99, 又色又爽又黄18禁美女裸身无遮挡, gogogo高清免费观看日本电视,私密按摩师高清版在线,人妻视频毛茸茸,91论坛 兴趣闲谈,欧美 亚洲 精品 8区,国产精品久久久久精品免费

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

Openwrt開發(fā)指南 第16章 驅動開發(fā)之字符設備驅動程序框架

嵌入式大雜燴 ? 來源:嵌入式大雜燴 ? 作者:嵌入式大雜燴 ? 2023-06-30 09:01 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

1 字符設備驅動程序框架簡介

我們在學習 C 語言的時候,知道每個應用程序的入口函數,即第一個被執(zhí)行的函數是 main函數,那么,我們自己的驅動程序,哪個函數是入口函數呢?

在寫驅動程序的時候,如果函數的名字可以任意取,常常為 xxxx_init(),當實現好這個 xxxx_init()函數以后,內核其實并不知道這個就是我們驅動的入口函數,因此我們要想辦法告訴內核,我們的入口函數是哪個?我們通過 module_init()函數來告訴內核,具體如下。

module_init(RT5350_drv_init);

通過上面的修飾以后, RT5350_drv_init()這個函數就變成了我們的驅動程序的入口函數了。當然,有入口函數,自然還需要一個出口函數,我們通過 module_exit()函數來告訴內核,具體如下。

module_exit(RT5350_drv_exit);

從上一章中,我們知道,應用程序是通過 open、read、write ...函數來和我們的驅動程序進行交互的,那么我們的驅動程序是怎么給應用程序提供這些接口的呢?我們在寫驅動程序的時候,我們首先需要定義出一個 file_operations 結構體,該結構體便是驅動和應用程序交互的接口。具體定義如下。

struct file_operations {
struct module *owner;
loff_t (*llseek) (struct file *, loff_t, int);
ssize_t (*read) (struct file *, char __user *, size_t, loff_t *);
ssize_t (*write) (struct file *, const char __user *, size_t, loff_t *);
ssize_t (*aio_read) (struct kiocb *, const struct iovec *, unsigned long,loff_t);
ssize_t (*aio_write) (struct kiocb *, const struct iovec *, unsigned long,loff_t);
int (*readdir) (struct file *, void *, filldir_t);
unsigned int (*poll) (struct file *, struct poll_table_struct *);
long (*unlocked_ioctl) (struct file *, unsigned int, unsigned long);
long (*compat_ioctl) (struct file *, unsigned int, unsigned long);
int (*mmap) (struct file *, struct vm_area_struct *);
int (*open) (struct inode *, struct file *);
int (*flush) (struct file *, fl_owner_t id);
int (*release) (struct inode *, struct file *);
int (*fsync) (struct file *, loff_t, loff_t, int datasync);
int (*aio_fsync) (struct kiocb *, int datasync);
int (*fasync) (int, struct file *, int);
int (*lock) (struct file *, int, struct file_lock *);
ssize_t (*sendpage) (struct file *, struct page *, int, size_t, loff_t *, int);
unsigned long (*get_unmapped_area)(struct file *, unsigned long, unsigned long,
unsigned long, unsigned long);
int (*check_flags)(int);
int (*flock) (struct file *, int, struct file_lock *);
ssize_t (*splice_write)(struct pipe_inode_info *, struct file *, loff_t *,
size_t, unsigned int);
ssize_t (*splice_read)(struct file *, loff_t *, struct pipe_inode_info *, size_t,
unsigned int);
int (*setlease)(struct file *, long, struct file_lock **);
long (*fallocate)(struct file *file, int mode, loff_t offset,
loff_t len);
};

我們的驅動程序要給應用程序提供哪些接口,就只需要填充相應的成員即可。比如我們想提供 open、read、write 這三個接口,就應該如下定義。

static struct file_operations RT5350_drv_fops = {
.owner = THIS_MODULE, /*這是一個宏,推向編譯模塊時自動創(chuàng)建的__this_module 變量 */
.open = RT5350_drv_open,
.read = RT5350_drv_read,
.write = RT5350_drv_write,
};

當 file_operations 結構體定義、設置好以后,我們只需要通過 register_chrdev()函數將該機構圖注冊進內核即可。

2 字符設備驅動程序框架實現

經過前面部分的講解,相信大家一定對如何寫一個自己的驅動程序,有所感悟了。接下來,給大家一個簡單的驅動程序的例子,可以用于作為框架模板,以后的驅動都可以基于該驅動進行修改。

#include < linux/mm.h >
#include < linux/miscdevice.h >
#include < linux/slab.h >
#include < linux/vmalloc.h >
#include < linux/mman.h >
#include < linux/random.h >
#include < linux/init.h >
#include < linux/raw.h >
#include < linux/tty.h >
#include < linux/capability.h >
#include < linux/ptrace.h >
#include < linux/device.h >
#include < linux/highmem.h >
#include < linux/crash_dump.h >
#include < linux/backing-dev.h >
#include < linux/bootmem.h >
#include < linux/splice.h >
#include < linux/pfn.h >
#include < linux/export.h >
#include < linux/io.h >
#include < linux/aio.h >
#include < linux/kernel.h >
#include < linux/module.h >

#include < asm/uaccess.h >

#define DEVICE_NAME     "RT5350"  /* 加載模式后,執(zhí)行”cat /proc/devices”命令看到的設備名稱 */
#define RT5350_MAJOR       0       /* 主設備號 */

static struct class *RT5350_drv_class;

static int RT5350_drv_open(struct inode *inode, struct file *file)
{
	printk("%s:Hello RT5350
", __FUNCTION__);	// printk用于驅動中添加打印,用法和應用程序中的printf一樣

	return 0;
}

static ssize_t RT5350_drv_read(struct file *file, char __user *buf, size_t size, loff_t *ppos)
{
	printk("%s:Hello RT5350
", __FUNCTION__);	// printk用于驅動中添加打印,用法和應用程序中的printf一樣

	return 0;
}

static ssize_t RT5350_drv_write(struct file *file, const char __user *buf, size_t size, loff_t *ppos)
{
	printk("%s:Hello RT5350
", __FUNCTION__);	// printk用于驅動中添加打印,用法和應用程序中的printf一樣

	return 0;
}

/* 這個結構是字符設備驅動程序的核心
** 當應用程序操作設備文件時所調用的open、read、write等函數,
** 最終會調用這個結構中指定的對應函數
**/
static struct file_operations RT5350_drv_fops = {
	.owner  	= THIS_MODULE,    /* 這是一個宏,推向編譯模塊時自動創(chuàng)建的__this_module變量 */
	.open   	= RT5350_drv_open,     
	.read	= RT5350_drv_read,	   
	.write	= RT5350_drv_write,	   
};

int major;
/*
** 執(zhí)行insmod命令時就會調用這個函數 
*/
static int __init RT5350_drv_init(void)
{
	/* 注冊字符設備
	** 這步是寫字符設備驅動程序所必須的
	** 參數為主設備號、設備名字、file_operations結構;
	** 這樣,主設備號就和具體的file_operations結構聯系起來了,
	** 操作主設備為RT5350_MAJOR的設備文件時,就會調用RT5350_drv_fops中的相關成員函數
	** RT5350_MAJOR可以設為0,表示由內核自動分配主設備號
	*/
	major = register_chrdev(RT5350_MAJOR, DEVICE_NAME, &RT5350_drv_fops);
	if (major < 0)
	{
		printk(DEVICE_NAME " can't register major number
");
		return major;
	}

	/*
	** 以下兩行代碼用于創(chuàng)建設備節(jié)點,是必須的。
	** 當然,如果不寫這兩行,那么就必須在linux系統(tǒng)命令行中通過mknod這個命令來創(chuàng)建設備節(jié)點
	*/
	/* 創(chuàng)建類 */
	RT5350_drv_class = class_create(THIS_MODULE, "RT5350");
	/* 類下面創(chuàng)建設備節(jié)點 */
	device_create(RT5350_drv_class, NULL, MKDEV(major, 0), NULL, "RT5350");		// /dev/RT5350

	/*
	** 打印一個調試信息
	*/
	printk("%s:Hello RT5350
", __FUNCTION__);	// printk用于驅動中添加打印,用法和應用程序中的printf一樣

	return 0;
}

/*
 * 執(zhí)行rmmod命令時就會調用這個函數 
 */
static void __exit RT5350_drv_exit(void)
{
	unregister_chrdev(major, "RT5350");		// 與入口函數的register_chrdev函數配對使用
	device_destroy(RT5350_drv_class, MKDEV(major, 0));	// 與入口函數的device_create函數配對使用
	class_destroy(RT5350_drv_class);	// 與入口函數的class_create函數配對使用

	printk("%s:Hello RT5350
", __FUNCTION__);	// printk用于驅動中添加打印,用法和應用程序中的printf一樣
}

/* 這兩行指定驅動程序的初始化函數和卸載函數 */
module_init(RT5350_drv_init);
module_exit(RT5350_drv_exit);

/* 描述驅動程序的一些信息,不是必須的 */
MODULE_AUTHOR("BruceOu");
MODULE_VERSION("0.1.0");
MODULE_DESCRIPTION("RT5350 FIRST Driver");
MODULE_LICENSE("GPL");
聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規(guī)問題,請聯系本站處理。 舉報投訴
  • C語言
    +關注

    關注

    183

    文章

    7646

    瀏覽量

    146187
  • 驅動程序
    +關注

    關注

    19

    文章

    872

    瀏覽量

    50763
  • 函數
    +關注

    關注

    3

    文章

    4422

    瀏覽量

    67859
  • 驅動開發(fā)

    關注

    0

    文章

    142

    瀏覽量

    12725
  • OpenWrt
    +關注

    關注

    10

    文章

    136

    瀏覽量

    41428
收藏 人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評論

    相關推薦
    熱點推薦

    芯科科技低功耗Wi-Fi開發(fā)指南

    Silicon Labs(芯科科技)整理并制作了低功耗Wi-Fi開發(fā)指南的網站資源,以幫助開發(fā)人員使用低功耗 Wi-Fi 6協(xié)議進行下一代物聯網產品開發(fā)
    的頭像 發(fā)表于 04-21 10:09 ?210次閱讀

    C#上位機實戰(zhàn)開發(fā)指南

    電子發(fā)燒友網站提供《C#上位機實戰(zhàn)開發(fā)指南.pdf》資料免費下載
    發(fā)表于 01-11 17:15 ?6次下載

    【「Linux 設備驅動開發(fā) 2 版)」閱讀體驗】+讀內核處理的核心輔助函數

    ,Linux內核平臺抽象和設備驅動程序;3篇,充分發(fā)揮硬件的潛力;4篇,嵌入式領域內的多種內核子系統(tǒng)。總共17節(jié),內容豐富,圍繞Lin
    發(fā)表于 01-10 22:08

    Linux驅動開發(fā)的必備知識

    驅動框架進行開發(fā)。 6、調試技能: 掌握內核調試工具,如 KDB、KGDB、printk 等。 能夠分析內核日志,定位驅動程序中的問題。
    發(fā)表于 12-04 07:58

    【免費送書】成為硬核Linux開發(fā)者:《Linux 設備驅動開發(fā) 2 版)》

    Linux系統(tǒng)的設備驅動開發(fā),一直給人門檻較高的印象,主要因內核機制抽象、需深度理解硬件原理、開發(fā)調試難度大所致。2021年,一本講解驅動
    的頭像 發(fā)表于 11-18 08:06 ?1852次閱讀
    【免費送書】成為硬核Linux<b class='flag-5'>開發(fā)</b>者:《Linux <b class='flag-5'>設備</b><b class='flag-5'>驅動</b><b class='flag-5'>開發(fā)</b>(<b class='flag-5'>第</b> 2 版)》

    【書籍評測活動NO.67】成為硬核Linux開發(fā)者:《Linux 設備驅動開發(fā) 2 版)》

    ,助力讀者學習后能獨立完成驅動程序開發(fā)。結語在當前人工智能與物聯網緊密結合的AIoT時代,各類傳感器、可穿戴設備要在低功耗狀態(tài)下承載智能計算,高效的驅動程序是關鍵環(huán)節(jié)?!禠inux
    發(fā)表于 11-17 17:52

    【迅為工業(yè)RK3568穩(wěn)定可靠】itop-3568開發(fā)驅動開發(fā)4驅動模塊傳參實驗

    【迅為工業(yè)RK3568穩(wěn)定可靠】itop-3568開發(fā)驅動開發(fā)4驅動模塊傳參實驗
    的頭像 發(fā)表于 11-06 14:25 ?538次閱讀
    【迅為工業(yè)RK3568穩(wěn)定可靠】itop-3568<b class='flag-5'>開發(fā)</b>板<b class='flag-5'>驅動</b><b class='flag-5'>開發(fā)</b><b class='flag-5'>第</b>4<b class='flag-5'>章</b><b class='flag-5'>驅動</b>模塊傳參實驗

    避坑指南!RK3568開發(fā)板選型,這5點沒看清千萬別下手!(附迅為驅動開發(fā)指南資源)

    避坑指南!RK3568開發(fā)板選型,這5點沒看清千萬別下手!(附迅為驅動開發(fā)指南資源)
    的頭像 發(fā)表于 10-30 15:49 ?1096次閱讀
    避坑<b class='flag-5'>指南</b>!RK3568<b class='flag-5'>開發(fā)</b>板選型,這5點沒看清千萬別下手!(附迅為<b class='flag-5'>驅動</b><b class='flag-5'>開發(fā)指南</b>資源)

    【北京迅為】itop-3568開發(fā)驅動開發(fā)指南(重制版)

    iTOP-RK3568開發(fā)驅動開發(fā)指南目錄:前言學習方法Linux驅動基礎 1 你好!內
    發(fā)表于 10-30 15:48 ?43次下載

    為FreeRTOS增加新的設備驅動程序

    如果你正在使用FreeRTOS構建嵌入式系統(tǒng),并且考慮添加新的設備驅動程序,那么這篇文章很適合你。高效的設備集成不僅僅是讓設備功能正常運行——更關乎模塊化、可靠性和安全性。
    的頭像 發(fā)表于 08-06 15:44 ?1124次閱讀
    為FreeRTOS增加新的<b class='flag-5'>設備</b><b class='flag-5'>驅動程序</b>

    zephyr設備驅動程序模型

    ? ? 1:Zephyr 內核支持多種設備驅動程序。驅動程序是否可用取決于board 和驅動程序。 Zephyr 設備模型為配置作為系統(tǒng)一部
    的頭像 發(fā)表于 07-29 10:34 ?856次閱讀
    zephyr<b class='flag-5'>設備</b><b class='flag-5'>驅動程序</b>模型

    驅動到應用:RT-Thread環(huán)境下的SDIO開發(fā)指南

    目錄硬件介紹搭建開發(fā)環(huán)境配置SDIO驅動掛載文件系統(tǒng)文件讀寫測試演示視頻源碼工程總結本文主要講述RT-Thread環(huán)境下的SDIO開發(fā)指南,基于MCXN947開發(fā)板。1硬件介紹本次測評
    的頭像 發(fā)表于 06-28 09:02 ?3074次閱讀
    從<b class='flag-5'>驅動</b>到應用:RT-Thread環(huán)境下的SDIO<b class='flag-5'>開發(fā)指南</b>

    RK3568驅動指南|第十二篇 GPIO子系統(tǒng)-130 GPIO的調試方法

    RK3568驅動指南|第十二篇 GPIO子系統(tǒng)-130 GPIO的調試方法
    的頭像 發(fā)表于 06-03 11:32 ?1464次閱讀
    RK3568<b class='flag-5'>驅動</b><b class='flag-5'>指南</b>|第十二篇 GPIO子系統(tǒng)-<b class='flag-5'>第</b>130<b class='flag-5'>章</b> GPIO的調試方法

    RK3568驅動指南|第十二篇 GPIO子系統(tǒng)-135 GPIO子系統(tǒng)與pinctrl子系統(tǒng)相結合實驗

    RK3568驅動指南|第十二篇 GPIO子系統(tǒng)-135 GPIO子系統(tǒng)與pinctrl子系統(tǒng)相結合實驗
    的頭像 發(fā)表于 05-23 13:47 ?1213次閱讀
    RK3568<b class='flag-5'>驅動</b><b class='flag-5'>指南</b>|第十二篇 GPIO子系統(tǒng)-<b class='flag-5'>第</b>135<b class='flag-5'>章</b> GPIO子系統(tǒng)與pinctrl子系統(tǒng)相結合實驗

    itop-3568開發(fā)驅動開發(fā)指南-實驗程序的編寫

    本實驗對應的網盤路徑為:iTOP-RK3568 開發(fā)板【底板 V1.7 版本】\\\\03_【iTOP-RK3568開發(fā)板】指南教程\\\\02_Linux 驅動配套資料\\\\04_
    發(fā)表于 05-19 10:26