亚洲av成人无遮挡网站在线观看,少妇性bbb搡bbb爽爽爽,亚洲av日韩精品久久久久久,兔费看少妇性l交大片免费,无码少妇一区二区三区

  免費(fèi)注冊 查看新帖 |

Chinaunix

  平臺(tái) 論壇 博客 文庫
最近訪問板塊 發(fā)新帖
查看: 1830 | 回復(fù): 0
打印 上一主題 下一主題

[原]三星s3c2410ARM平臺(tái)下的按鍵驅(qū)動(dòng)注釋 [復(fù)制鏈接]

論壇徽章:
0
跳轉(zhuǎn)到指定樓層
1 [收藏(0)] [報(bào)告]
發(fā)表于 2009-06-16 10:12 |只看該作者 |倒序?yàn)g覽
源碼來自如下鏈接
http://hi.baidu.com/cduytl/blog/item/ef2a6f54ae998f5dd1090683.html
針對代碼,我加了一些注釋,也對程序一處代碼有些疑問,望大家不吝指教。
帥得不敢出門           C++哈哈堂         31843264  ------轉(zhuǎn)載請保留此信息

本程序是基于三星s3c2410ARM平臺(tái)下的按鍵驅(qū)動(dòng)例程,程序中兩個(gè)按鍵分別占用了ARM芯片上的外部中斷16和17,程序中設(shè)定外部中斷為下降沿響應(yīng)中斷.本程序是在2.6.16內(nèi)核版本下編譯測試通過,交叉編譯器采用3.4.1版本的arm-linux-gcc. 1.驅(qū)動(dòng)程序文件名為button.c,其源碼如下示:
/**********************start*******************************/
/*************************end***************************/   
#include linux/config.h>
#include linux/module.h>
#include linux/version.h>
#include linux/kernel.h>
#include linux/init.h>
#include linux/fs.h>
#include asm/hardware.h>
#include asm/delay.h>
#include asm/uaccess.h>
#include asm-arm/arch-s3c2410/regs-gpio.h>
#include asm/io.h>
#include asm-arm/arch-s3c2410/irqs.h>
#include asm-arm/irq.h>
#include linux/interrupt.h>
#include linux/wait.h>
#define BUTTON_IRQ1 IRQ_EINT16
#define BUTTON_IRQ2 IRQ_EINT17
#define DEVICE_NAME "button"
static int buttonMajor=0;//用來存放主設(shè)備號(hào)
#define BUTTONMINOR 0//次設(shè)備號(hào)
#define MAX_BUTTON_BUF 16
   
#define BUTTONSTATUS_1 16
#define BUTTONSTATUS_2 17
static unsigned char buttonRead(void);
static int flag=0;
typedef struct {
    unsigned int buttonStatus; //按鍵狀態(tài)
    unsigned char buf[MAX_BUTTON_BUF]; //按鍵緩沖區(qū)
    unsigned int head,tail; //按鍵緩沖區(qū)頭和尾
    wait_queue_head_t wq; //等待隊(duì)列
} BUTTON_DEV;
static BUTTON_DEV buttondev;
#define BUF_HEAD (buttondev.buf[buttondev.head])
#define BUF_TAIL (buttondev.buf[buttondev.tail])
#define INCBUF(x,mod) ((++(x)) & ((mod)-1)) //移動(dòng)緩沖區(qū)指針,可限定x的值在0~(mod-1)范圍
static void (*buttonEvent)(void);
static void buttonEvent_dummy(void) {}
static void buttonEvent_1(void)
{
    if(buttondev.buttonStatus==BUTTONSTATUS_2) {
    BUF_HEAD=BUTTONSTATUS_2;//按鍵狀態(tài)存儲(chǔ)到緩沖區(qū)中
     }
    else {
    BUF_HEAD=BUTTONSTATUS_1;
     }
    buttondev.head=INCBUF(buttondev.head,MAX_BUTTON_BUF);//移動(dòng)緩沖區(qū)指針
    flag=1;
    wake_up_interruptible(&(buttondev.wq));//喚醒等待隊(duì)列中的讀進(jìn)程
    printk("buttonEvent_1\n");
}
static irqreturn_t isr_button(int irq,void *dev_id,struct pt_regs *regs)//中斷處理函數(shù)
{
   
    printk("Occured key board Inetrrupt,irq=%d\n",irq-44);
    switch (irq) {
    case BUTTON_IRQ1:buttondev.buttonStatus=BUTTONSTATUS_1;
                break;
    case BUTTON_IRQ2:buttondev.buttonStatus=BUTTONSTATUS_2;
                break;
    default:break;
     }
   
    buttonEvent();
    return 0;
}
static int button_open(struct inode *inode,struct file *filp)
{
    int ret;
    buttondev.head=buttondev.tail=0;
    buttonEvent=buttonEvent_1;
    ret=request_irq(BUTTON_IRQ1,isr_button,SA_INTERRUPT,DEVICE_NAME,NULL);//中斷線注冊,SA_INTERRUPT表示一個(gè)"快
//速"中斷處理 快速中斷(那些使用 SA_INTERRUPT 被請求的)執(zhí)行時(shí)禁止所有在當(dāng)前處理器上的其他中斷
  if(ret) {
    printk("BUTTON_IRQ1: could not register interrupt\n");
    return ret;
     }
    ret=request_irq(BUTTON_IRQ2,isr_button,SA_INTERRUPT,DEVICE_NAME,NULL);
    if(ret) {
    printk("BUTTON_IRQ2: could not register interrupt\n");
    return ret;
     }
   return 0;
}
static int button_release(struct inode *inode,struct file *filp)
{
    buttonEvent=buttonEvent_dummy;
    free_irq(BUTTON_IRQ1,NULL);//注銷中斷處理
    free_irq(BUTTON_IRQ2,NULL);
    return 0;
}
static ssize_t button_read(struct file *filp,char *buffer,size_t count,loff_t *ppos)
{
    static unsigned char button_ret;
retry:
    printk("retry start\n");
    if(buttondev.head!=buttondev.tail) {
    button_ret=buttonRead();//得到緩沖區(qū)中一個(gè)unsigned char值
    copy_to_user(buffer,(char *)&button_ret,sizeof(unsigned char));//把button_ret值復(fù)制到用戶空間
    printk("the button_ret is 0x%x\n",button_ret);
    return sizeof(unsigned char);
     }
    else {//若無數(shù)據(jù)
    if(filp->f_flags & O_NONBLOCK)//非阻塞
        return -EAGAIN;
    printk("sleep\n");
    //interruptible_sleep_on(&(buttondev.wq));//為安全起見,最好不要調(diào)用該睡眠函數(shù)
    wait_event_interruptible(buttondev.wq,flag);//等待被喚醒
    flag=0;
    printk("sleep_after\n");
    if(signal_pending(current))//若是被信號(hào)喚醒則返回-ERESTARTSYS錯(cuò)誤碼
         {
        printk("rturn -ERESTARTSYS\n");
        return -ERESTARTSYS;
          }
    goto retry;//若是阻塞的,則阻塞
     }
    return sizeof(unsigned char);
}
static struct file_operations button_fops= {//這個(gè)結(jié)構(gòu)用來連接設(shè)備操作到設(shè)備編號(hào)上
    .owner = THIS_MODULE,
    .open = button_open,
    .read = button_read,
    .release = button_release,
};
static int __init s3c2410_button_init(void) //模塊初始化
{
    int ret;
    set_irq_type(BUTTON_IRQ1,IRQT_FALLING);
    set_irq_type(BUTTON_IRQ2,IRQT_FALLING);
    buttonEvent=buttonEvent_dummy;//此處不解 為何在初始化中,把它架空了??
   
    ret=register_chrdev(0,DEVICE_NAME,&button_fops);//注冊字符設(shè)備(第一個(gè)參數(shù)為0表示動(dòng)態(tài)分配一個(gè)主設(shè)備號(hào))
    if(ret0) {
    printk("button: can't get major number\n");
    return ret;
     }
    buttonMajor=ret;//存放主設(shè)備號(hào)
#ifdef CONFIG_DEVFS_FS
devfs_mk_cdev(MKDEV(buttonMajor,BUTTONMINOR),S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP,DEVICE_NAME);//創(chuàng)建設(shè)備文件
//主次編號(hào), 需要將其轉(zhuǎn)換為一個(gè) dev_t, 使用MKDEV(int major, int minor);
#endif
    //buttondev.head=buttondev.tail=0;
    buttondev.buttonStatus=BUTTONSTATUS_1;
    init_waitqueue_head(&(buttondev.wq));//初始化等待隊(duì)列
//將自旋鎖初始化為未鎖,等待隊(duì)列初始化為空的雙向循環(huán)鏈表。
    printk(DEVICE_NAME"initialized\n");
    return 0;
}
static unsigned char buttonRead(void)//得到緩沖區(qū)一個(gè)unsigned char類型的字符 并把tail指向下一個(gè)(循環(huán))緩沖區(qū)單元
{
    unsigned char button_ret;
    button_ret=BUF_TAIL;
    buttondev.tail=INCBUF(buttondev.tail,MAX_BUTTON_BUF);
    return button_ret;
}
   
static void __exit s3c2410_button_eixt(void)
{
#ifdef CONFIG_DEVFS_FS
    devfs_remove(DEVICE_NAME);//移除設(shè)備文件
   
#endif
    unregister_chrdev(buttonMajor,DEVICE_NAME);//卸載設(shè)備
}
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Kision");
MODULE_DESCRIPTION ("the first char device driver");
module_init(s3c2410_button_init);
module_exit(s3c2410_button_eixt);


本文來自ChinaUnix博客,如果查看原文請點(diǎn):http://blog.chinaunix.net/u2/64540/showart_1965614.html
您需要登錄后才可以回帖 登錄 | 注冊

本版積分規(guī)則 發(fā)表回復(fù)

  

北京盛拓優(yōu)訊信息技術(shù)有限公司. 版權(quán)所有 京ICP備16024965號(hào)-6 北京市公安局海淀分局網(wǎng)監(jiān)中心備案編號(hào):11010802020122 niuxiaotong@pcpop.com 17352615567
未成年舉報(bào)專區(qū)
中國互聯(lián)網(wǎng)協(xié)會(huì)會(huì)員  聯(lián)系我們:huangweiwei@itpub.net
感謝所有關(guān)心和支持過ChinaUnix的朋友們 轉(zhuǎn)載本站內(nèi)容請注明原作者名及出處

清除 Cookies - ChinaUnix - Archiver - WAP - TOP