ret = copy_to_user(userbuf, &key_val, 1);
ev_press = 0;//按鍵已經(jīng)處理可以繼續(xù)睡眠
if(ret)
{
printk('copy errorn');
return -1;
}
return 1;
}
static unsigned int sixth_drv_poll(struct file *file, poll_table *wait)
{
unsigned int ret = 0;
poll_wait(file, &button_waitq, wait);//將當(dāng)前進(jìn)程放到button_waitq列表
if(ev_press)
ret |=POLLIN;//說明有數(shù)據(jù)被取到了
return ret;
}
static int sixth_drv_fasync(int fd, struct file * file, int on)
{
int err;
printk('fansync_helpern');
err = fasync_helper(fd, file, on, &sixth_fasync);//初始化sixth_fasync
if (err < 0)
return err;
return 0;
}
static struct file_operations sixth_drv_ops =
{
.owner = THIS_MODULE,
.open = sixth_drv_open,
.read = sixth_drv_read,
.release = sixth_drv_close,
.poll = sixth_drv_poll,
.fasync = sixth_drv_fasync,
};
static int sixth_drv_init(void)
{
sixthmajor = register_chrdev(0, 'buttons', &sixth_drv_ops);//注冊(cè)驅(qū)動(dòng)程序
if(sixthmajor < 0)
printk('failes 1 buttons_drv registern');
sixth_drv_class = class_create(THIS_MODULE, 'buttons');//創(chuàng)建類
if(sixth_drv_class < 0)
printk('failes 2 buttons_drv registern');
sixth_drv_class_dev = class_device_create(sixth_drv_class, NULL, MKDEV(sixthmajor,0), NULL,'buttons');//創(chuàng)建設(shè)備節(jié)點(diǎn)
if(sixth_drv_class_dev < 0)
printk('failes 3 buttons_drv registern');
gpfcon = ioremap(0x56000050, 16);//重映射
gpfdat = gpfcon + 1;
gpgcon = ioremap(0x56000060, 16);//重映射
gpgdat = gpgcon + 1;
printk('register buttons_drvn');
return 0;
}
static void sixth_drv_exit(void)
{
unregister_chrdev(sixthmajor,'buttons');
class_device_unregister(sixth_drv_class_dev);
class_destroy(sixth_drv_class);
iounmap(gpfcon);
iounmap(gpgcon);
printk('unregister buttons_drvn');
}
module_init(sixth_drv_init);
module_exit(sixth_drv_exit);
MODULE_LICENSE('GPL');
接著改寫測(cè)試程序,測(cè)試加入阻塞方式打開文件,在fd = open(filename, O_RDWR|O_NONBLOCK)函數(shù)中加入O_NONBLOCK即可以按阻塞方式打開。
#include #include #include #include #include #include static int fd; //static void fifth_testsignal(int signum) //{ // unsigned char key_val; // // printf('signal = %dn',signum); // read(fd, &key_val, 1); // printf('signumkey_val: 0x%xnn',key_val); //} /* *usage ./buttonstest */ int main(int argc, char **argv) { char* filename='dev/buttons'; int oflags,ret; unsigned char key_val; fd = open(filename, O_RDWR|O_NONBLOCK);//打開dev/firstdrv設(shè)備文件,非阻塞方式打開 if (fd < 0)//小于0說明沒有成功 { printf('error, can't open %sn', filename); return 0; } if(argc !=1) { printf('Usage : %s ',argv[0]); return 0; } // signal(SIGIO, fifth_testsignal);//注冊(cè)一個(gè)信號(hào),函數(shù)為fifth_testsignal // // fcntl(fd, F_SETOWN, getpid()); // 告訴內(nèi)核,發(fā)給誰 // // oflags = fcntl(fd, F_GETFL); //取得當(dāng)前的狀態(tài) // // fcntl(fd, F_SETFL, oflags | FASYNC); // 改變fasync標(biāo)記,最終會(huì)調(diào)用到驅(qū)動(dòng)的faync > fasync_helper:初始化/釋放fasync_struct while(1) { ret = read(fd, &key_val, 1); printf('ret = %d,key_val: 0x%xn',ret,key_val); sleep(5); } return 0; } 將驅(qū)動(dòng)程序與測(cè)試程序編譯后運(yùn)行。發(fā)現(xiàn)以阻塞方式運(yùn)行的測(cè)試程序如果再次運(yùn)行會(huì)處于睡眠狀態(tài);如果以非阻塞方式再次運(yùn)行程序,會(huì)導(dǎo)致第二個(gè)程序退出。 以上只是記錄了怎么調(diào)用內(nèi)核函數(shù)來實(shí)現(xiàn)互斥、阻塞機(jī)制,具體原理還未分析,后面再分析。
上一篇:Linux驅(qū)動(dòng)之定時(shí)器在按鍵去抖中的應(yīng)用
下一篇:Linux驅(qū)動(dòng)之異步OR同步,阻塞OR非阻塞概念介紹
推薦閱讀最新更新時(shí)間:2025-05-09 18:30








設(shè)計(jì)資源 培訓(xùn) 開發(fā)板 精華推薦
- LGVL配合FreeType為可變字體設(shè)置字重-ESP32篇
- 使用樹莓派進(jìn)行 ESP32 Jtag 調(diào)試
- ESP32怎么在SPIFFS里面存儲(chǔ)html,css,js文件,以及網(wǎng)頁(yè)和arduino的通訊
- ESP32 freeRTOS使用測(cè)試
- API調(diào)用小記(Touchdesigner和ESP32)
- 關(guān)于ESP32/8266使用async-mqtt-client庫(kù)的一些基本介紹
- arduino環(huán)境下利用ESP32控制舵狗(初始位置的調(diào)試)
- 使用ESP32驅(qū)動(dòng)TI的TMP117溫度傳感器
- (3)ESP32 Python 制作一個(gè)辦公室溫度計(jì)
- 雙閃燈的設(shè)計(jì)
- 具有 12V VDD 輸入的 LTC2945CMS 3.3V 輸入電源監(jiān)視器的典型應(yīng)用
- 使用 NXP Semiconductors 的 ISP1504 的參考設(shè)計(jì)
- 【廣西師大校賽】波形發(fā)生
- m1_mh743_ada_v4
- AD8548ARZ-RL 4 mA至20 mA電流環(huán)路變送器的典型應(yīng)用電路
- MIC2090-1YM5 EV,數(shù)碼攝像機(jī)USB開關(guān)評(píng)估板
- 【已驗(yàn)證】 CW1244-3S鋰電保護(hù)板
- LTC6990HS6#TRMPBF 過壓檢測(cè)器/警報(bào)的典型應(yīng)用。壓電報(bào)警器直接驅(qū)動(dòng)
- LDK120C33R 3.3V低壓降穩(wěn)壓器典型應(yīng)用(D版)電路
- 肖特激光玻璃助力實(shí)現(xiàn)核聚變領(lǐng)域又一個(gè)歷史性里程碑
- 英飛凌SEMPER? NOR閃存系列獲得ASIL-D功能安全認(rèn)證
- 如何在開關(guān)模式電源中運(yùn)用氮化鎵技術(shù)
- LGVL配合FreeType為可變字體設(shè)置字重-ESP32篇
- 使用樹莓派進(jìn)行 ESP32 Jtag 調(diào)試
- ESP32怎么在SPIFFS里面存儲(chǔ)html,css,js文件,以及網(wǎng)頁(yè)和arduino的通訊
- ESP32 freeRTOS使用測(cè)試
- API調(diào)用小記(Touchdesigner和ESP32)
- 芯科科技Tech Talks技術(shù)培訓(xùn)重磅回歸: 賦能物聯(lián)網(wǎng)創(chuàng)新,共筑智能互聯(lián)未來
- 關(guān)于ESP32/8266使用async-mqtt-client庫(kù)的一些基本介紹
- 沒有靈魂,這是小米最大的缺點(diǎn)?
- 聯(lián)發(fā)科連續(xù)3季度領(lǐng)跑手機(jī)芯片市場(chǎng) 或拉開與高通差距
- 聯(lián)想會(huì)重回巔峰,你信嗎?
- 潔美科技:國(guó)產(chǎn)離型膜產(chǎn)線處滿產(chǎn)狀態(tài) 韓國(guó)產(chǎn)線批量供應(yīng)
- 5G手機(jī)還沒上,5G電腦就要面世了?
- Stacy J. Smith將成為東芝存儲(chǔ)器新任執(zhí)行總裁
- 人工智能芯片的DNA
- 超低光及Nyxel?近紅外成像技術(shù),OmniVision推出新款圖像傳感
- 推動(dòng)中國(guó)本土模擬芯片設(shè)計(jì),思瑞浦與NI強(qiáng)強(qiáng)聯(lián)手
- MIT“重塑”計(jì)算與人工智能學(xué)院 迎來成立70年最大架構(gòu)變化
- 論壇的審核效率太低了吧?
- 具體用什么接收cc2530的信號(hào),求指導(dǎo),可有償
- 電源+12v轉(zhuǎn)+-12v
- 基于RFID的電子關(guān)鎖系統(tǒng)設(shè)計(jì)與實(shí)現(xiàn)
- MSP430F5529做USB通信實(shí)驗(yàn)時(shí)候安裝驅(qū)動(dòng)失敗
- ARM架構(gòu)上網(wǎng)本電源解決方案
- wince的啟動(dòng)速度的問題
- 一個(gè)課程設(shè)計(jì):基于單片機(jī)的波形發(fā)生器的設(shè)計(jì)
- 威世的產(chǎn)品不錯(cuò)的!支持
- Linux/UNIX人才培訓(xùn)