娇小w搡bbbb搡bbb,《第一次の人妻》,中国成熟妇女毛茸茸,边啃奶头边躁狠狠躁视频免费观看

歷史上的今天

今天是:2025年03月23日(星期日)

正在發生

2021年03月23日 | S3C6410開發板按鍵驅動代碼分析及測試代碼分析

發布者:吉州古玩齋 來源: eefocus關鍵字:S3C6410  開發板  按鍵驅動 手機看文章 掃描二維碼
隨時隨地手機看文章

在本文中,我們對S3C6410開發板按鍵驅動代碼的實現過程進行分析,然后通過一個實例對按鍵功能進行測試。在本文的資源中包含了設備驅動的源碼和測試的源碼。


一、設備驅動源碼分析

按鍵的設備驅動主要實現了模塊的初始化、模塊的卸載、設備打開、設備關閉、設備讀取、設備阻塞功能。


1、模塊初始化

模塊的初始化的源碼如下所示。


static int __init dev_init(void)

{

int ret;

 

ret = misc_register(&misc);

 

printk (DEVICE_NAME"tinitializedn");

 

return ret;

}


這段代碼只實現了一個功能,就是使用misc_register()函數向內核注冊按鍵的混雜設備。


2、模塊卸載

模塊卸載的代碼比較簡單,如下所示。


static void __exit dev_exit(void)

{

misc_deregister(&misc);

}


模塊卸載代碼實現的功能是將按鍵的混雜設備從內核中取消注冊。


3、設備打開

設備打開代碼主要實現了按鍵對應的GPIO接口的初始化。


static int s3c64xx_buttons_open(struct inode *inode, struct file *file)

{

    int i;

    int err = 0;

    

    for (i = 0; i < sizeof(button_irqs)/sizeof(button_irqs[0]); i++) {

if (button_irqs[i].irq < 0) {

continue;

}

        err = request_irq(button_irqs[i].irq, buttons_interrupt, IRQ_TYPE_EDGE_BOTH, 

                          button_irqs[i].name, (void *)&button_irqs[i]);

        if (err)

            break;

    }

 

    if (err) {

        i--;

        for (; i >= 0; i--) {

    if (button_irqs[i].irq < 0) {

continue;

    }

    disable_irq(button_irqs[i].irq);

            free_irq(button_irqs[i].irq, (void *)&button_irqs[i]);

        }

        return -EBUSY;

    }

 

    ev_press = 1;

    

    return 0;

}


在這段代碼中,使用request_irq()函數用來初始化GPIO接口,主要是開啟了GPIO接口的輸入中斷功能,將中斷號與中斷處理函數、中斷描述結構體綁定在一起。其中,button_irqs[i].irq是中斷號,buttons_interrupt是中斷處理函數,(void *)&button_irqs[i]是指向中斷描述結構體的指針,函數還將中斷的模式設置為雙邊沿觸發。當按下或松開按鍵時,會產生下降沿或上升沿,就會觸發中斷,中斷會把相應的中斷描述結構體保持下來,并轉到buttons_interrupt函數去處理中斷。


buttons_interrupt()函數的源碼如下所示。


static irqreturn_t buttons_interrupt(int irq, void *dev_id)

{

struct button_irq_desc *button_irqs = (struct button_irq_desc *)dev_id;

int down;

int number;

unsigned tmp;

 

udelay(0);

number = button_irqs->number;

switch(number) {

case 0: case 1: case 2: case 3: case 4: case 5:

tmp = readl(S3C64XX_GPNDAT);

down = !(tmp & (1< break;

case 6: case 7:

tmp = readl(S3C64XX_GPLDAT);

down = !(tmp & (1 << (number + 5)));

break;

default:

down = 0;

}

 

if (down != (key_values[number] & 1)) {

key_values[number] = '0' + down;

 

        ev_press = 1;

        wake_up_interruptible(&button_waitq);

    }

 

    return IRQ_RETVAL(IRQ_HANDLED);

}


中斷處理函數的重要輸入是中斷描述結構體dev_id,結構體內部包含了,中斷號、按鍵編號、以及按鍵名。程序根據按鍵編號對GPIO數據寄存器的值進行讀取,從而判斷外部輸入電平的狀態,并將按鍵狀態保存到key_values[ ]數組中,‘1’代表按鍵按下,‘0’代表按鍵沒有按下。當按鍵狀態有變化時,程序調用wake_up_interruptible(&button_waitq);將阻塞的內核排隊隊列喚醒。


4、設備關閉

設備關閉代碼如下所示


static int s3c64xx_buttons_close(struct inode *inode, struct file *file)

{

    int i;

    

    for (i = 0; i < sizeof(button_irqs)/sizeof(button_irqs[0]); i++) {

if (button_irqs[i].irq < 0) {

    continue;

}

free_irq(button_irqs[i].irq, (void *)&button_irqs[i]);

    }

 

    return 0;

}


功能比較簡單,主要是將按鍵的中斷功能禁止。


5、設備讀取

設備的讀取代碼主要是讀取8個按鍵的狀態,代碼如下。


static int s3c64xx_buttons_read(struct file *filp, char __user *buff, size_t count, loff_t *offp)

{

    unsigned long err;

 

    if (!ev_press) {

if (filp->f_flags & O_NONBLOCK)

    return -EAGAIN;

else

    wait_event_interruptible(button_waitq, ev_press);

    }

    

    ev_press = 0;

 

    err = copy_to_user((void *)buff, (const void *)(&key_values), min(sizeof(key_values), count));

 

    return err ? -EFAULT : min(sizeof(key_values), count);

}

代碼實現的功能是將設備狀態數組key_values[ ]回傳到用戶程序的buf中。


6、設備阻塞

設備阻塞函數是用來相應用戶空間的select()系統調用函數的,代碼如下


static unsigned int s3c64xx_buttons_poll( struct file *file, struct poll_table_struct *wait)

{

    unsigned int mask = 0;

    poll_wait(file, &button_waitq, wait);

    if (ev_press)

        mask |= POLLIN | POLLRDNORM;

    return mask;

}


阻塞函數功能比較簡單,是在沒有按鍵按下或松開時將程序阻塞,當有按鍵按下或松開時退出阻塞狀態。


二、測試代碼分析

編寫了一個簡單的測試代碼對按鍵的驅動進行測試,代碼如下。


int main()

{

int fd_led,fd_key;

fd_set read_set;

int max_fd;

struct timeval timeout;

int ret;

 

char buf[8];

 

fd_led = open("/dev/leds",0);

fd_key = open("/dev/buttons",O_RDONLY);

 

if(fd_led<0||fd_key<0)

{

fprintf(stderr,"can't open leds or buttons!n");

return 1;

}

 

while(1)

{

//清零描述符集合

FD_ZERO(&read_set);

FD_SET(fd_key,&read_set);

max_fd = fd_key;

//設置超時時間

timeout.tv_sec=3;

timeout.tv_usec=0;

ret = select(max_fd+1, &read_set, 0, 0, &timeout);

 

if(ret>0)

{

read(fd_key,buf,8);

if(buf[0]=='1')

{

ioctl(fd_led,1,0);

}

else

{

ioctl(fd_led,0,0);

}

 

if(buf[1]=='1')

{

ioctl(fd_led,1,1);

}

else

{

ioctl(fd_led,0,1);

}

 

if(buf[2]=='1')

{

ioctl(fd_led,1,2);

}

else

{

ioctl(fd_led,0,2);

}

 

if(buf[3]=='1')

{

ioctl(fd_led,1,3);

}

else

{

ioctl(fd_led,0,3);

}

}

}

 

close(fd_key);

close(fd_led);

 

return 0;

}


在這個代碼中,通過select()函數將程序阻塞,等待按鍵的狀態變化。當按鍵狀態有變化時,讀取按鍵狀態,并根據按鍵狀態對LED燈進行控制。當按鍵按下時,將相應的LED燈點亮;松開按鍵時,將相應的LED燈熄滅。


關鍵字:S3C6410  開發板  按鍵驅動 引用地址:S3C6410開發板按鍵驅動代碼分析及測試代碼分析

上一篇:S3C6410開發板adc驅動代碼分析及測試代碼分析
下一篇:基于RS-485總線的智能家居網絡系統

推薦閱讀

  這是一場投入巨大、關乎生死的豪賭。已入局的,朝兢夕惕、馬不停蹄,絕非高枕無憂;未入局的,心急如焚、忐忑不安,只能竭盡所能。  這是一場萬箭齊發、勝敗難判的亂戰。來自行業內外的參與者,聞風而動、各顯神通,誰也不愿輸;而競技的規則,不同以往、變數不斷,牽一發而動全身。  這即是當下的新能源汽車產業,風平浪靜已不再。  3月兩會期...
今年的政府工作報告中,首次提及“智能+”這一概念,指出要打造工業互聯網平臺,拓展“智能+”,為制造業轉型升級賦能。人工智能再次成為備受關注的科技熱點。自從2017年被寫入《政府工作報告》、十九大報告以來,人工智能作為國家戰略受到政府和業界的格外重視。作為引領新一輪科技革命和產業變革的戰略性技術,人工智能與實體經濟和制造、醫療、金融科技...
LCD有如下控制線:CS:Chip Select 片選,低電平有效RS:Register Select 寄存器選擇WR:Write 寫信號,低電平有效RD:Read 讀信號,低電平有效RESET:重啟信號,低電平有效DB0-DB15:數據線假如這些線,全部用普通IO口控制。根據LCD控制芯片手冊(大部分控制芯片時序差不多):如果情況如下:DB0-DB15的IO全部為1(表示數據0xff),也可以為其他任...
基礎元件初始化步驟一、GPIO(1)、確定GPIO的方向:DDRx(2)、訪問GPIO口:PORTx、PTx注意:輸入輸出時引腳的初始狀態二、中斷(1)、確定中斷的有效信號特性:上升/下降(2)、使能中斷(3)、開總中斷:EnableInterrups;三、串口通信SCI(別的單片機為UART)SCI串行通信的基本編程方法:①初始化:設置波特率寄存器、設置控制寄存器1和設置控制寄存器2...

史海拾趣

問答坊 | AI 解惑

基于DSP的智能電機保護器設計

前言        由于生產自動化及各種自動控制、順序控制設備的出現,要求電機經常運行在頻繁的起動、制動、正反傳、間歇以及變負荷等各種方式。電機的運行要求越來越高。同時,由于電機與配套機械連在一起,當電機發生 ...…

查看全部問答∨

SMT表面裝貼技術資料

表面粘著技術 (Surface Mount Technology) 已漸漸地取代傳統『人工插件』的波焊作業方式,儼然成為現代電子組裝產業的主流,因它可以組裝制造出相當輕、薄、短、小且品質良好的電子產品。據統計資料顯示大約百分之九十的個人計算機,皆制造于表面粘 ...…

查看全部問答∨

來談談:神奇的過采樣技術

此前參加嵌入式系統聯誼會,被天津大學精密儀器與光電子工程學院 李剛老師的講解,震動著, 這里拿出來與大家分享,同時也期待著大家談談對過采樣技術的理解。 …

查看全部問答∨

開關電源小知識

 開關電源是一種電壓轉換電路,主要的工作內容是升壓和降壓,廣泛應用于現代電子產品。因為開關三極管總是工作在 “開” 和“關” 的狀態,所以叫開關電源。開關電源實質就是一個振蕩電路,這種轉換電能的方式,不僅應用在電源電路,在其它的電路 ...…

查看全部問答∨

驅動發送消息給應用程序,加載異常!

我的驅動里面用到了RegisterWindowMessage來注冊一個消息,目的是用PostMessage把他發送給應用程序,我用了we-hjb的調試助手調試,一切都是正常的,但當我把DLL加到NK是,啟動時就出現異常, 如果我把RegisterWindowMessage部分的代碼屏蔽掉,驅 ...…

查看全部問答∨

關于usb,dma驅動的一些疑惑

大家好:     最近在學習usb的驅動的編寫,所以看了不少關于usb的知識。正如大家所知:USB傳輸可以用URB 而用urb的時候可以選擇用DMA來傳輸,當然這需要程序員自己申請空間(usb_alloc_dma()函數等),這樣就會返回一個DMA認識的地址 ...…

查看全部問答∨

SYMBOL MC1000 英文wince4.2上會提示錯誤,中文不會

偶新手一個,遇到問題請教一下:同一個程序,在中文wince4.2上可以運行,但在英文wince4.2上會提示錯誤如下: A managed OperationFailureException occured at application: Run + 0xf Scan_GetreaderParams Application: Run + 0xf main: ...…

查看全部問答∨

VB.NET串口接收數據不完整

我在用VB.NET開發winsCE,在用串口通信的時候,我用代碼 n = Me.SerialPort1.BytesToRead                                  &nb ...…

查看全部問答∨

復位后系統中MCLK和SMCLK的相位是否保持一致?

我用的是msp430f435,SMCLK時鐘源為4M的外部晶振,MCLK由ACLK倍頻后停止調整獲得1M。在程序復位后兩者的相位是否一致,即是否同時出現上升沿? 復位后系統中MCLK和SMCLK的相位是否保持一致?…

查看全部問答∨

IGBT實用的驅動電路,以及一些設計細節,適合工程師、采購、維修人員

(秦皇島國安電力電子技術有限公司) 第1講 IGBT的基本驅動電路   概要:筆者從事電力電子研發領域,經常使用IGBT,積累了一些設計經驗,在此與大家分享。大部分內容不追求理論深度,而主要是幫助大家提高感性認識,為使用IGBT提供一些參考 ...…

查看全部問答∨
小廣播
設計資源 培訓 開發板 精華推薦

最新單片機文章
何立民專欄 單片機及嵌入式寶典

北京航空航天大學教授,20余年來致力于單片機與嵌入式系統推廣工作。

 
EEWorld訂閱號

 
EEWorld服務號

 
汽車開發圈

 
機器人開發圈

電子工程世界版權所有 京ICP證060456號 京ICP備10001474號-1 電信業務審批[2006]字第258號函 京公網安備 11010802033920號 Copyright ? 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
主站蜘蛛池模板: 治多县| 砚山县| 夏邑县| 中卫市| 金塔县| 新郑市| 潞西市| 博爱县| 普兰店市| 城市| 靖西县| 六盘水市| 宜川县| 稻城县| 昌黎县| 和田县| 鹰潭市| 扎鲁特旗| 台安县| 祥云县| 滕州市| 吴忠市| 乌审旗| 隆林| 龙南县| 四川省| 军事| 高密市| 宁明县| 彭山县| 铜川市| 兴安县| 宁夏| 南投县| 黎城县| 西乡县| 淳化县| 英山县| 噶尔县| 宣城市| 察哈|