久久婷婷香蕉热狠狠综合,精品无码国产自产拍在线观看蜜,寡妇房东在做爰3,中文字幕日本人妻久久久免费,国产成人精品三上悠亚久久


嵌入式linux下LED驅動教程

分享到:
           

  ;  在(zai)嵌(qian)入式系統的(de)設計中,LED一(yi)般(ban)(ban)直(zhi)接由(you)(you)CPU的(de)GPIO(通(tong)用可(ke)(ke)編程I/O口)控(kong)(kong)制。GPIO一(yi)般(ban)(ban)由(you)(you)兩組(zu)寄(ji)存器控(kong)(kong)制,即一(yi)組(zu)控(kong)(kong)制寄(ji)存器和一(yi)組(zu)數(shu)據(ju)寄(ji)存器。控(kong)(kong)制寄(ji)存器可(ke)(ke)設置GPIO口的(de)工作方式為輸(shu)入或是輸(shu)出。當引(yin)(yin)腳被設置為輸(shu)出時(shi),向數(shu)據(ju)寄(ji)存器的(de)對(dui)應位(wei)寫入1和0會分別在(zai)引(yin)(yin)腳上產生(sheng)高電(dian)平和低電(dian)平;當引(yin)(yin)腳設置為輸(shu)入時(shi),讀取數(shu)據(ju)寄(ji)存器的(de)對(dui)應位(wei)可(ke)(ke)獲得引(yin)(yin)腳上的(de)電(dian)平為高或低。

    LED設備(bei)介于字符設備(bei)和塊設備(bei)之(zhi)間(jian)我們稱之(zhi)為misc(雜設備(bei)),其實按(an)linux下(xia)的(de)驅動位置來(lai)講還是一(yi)種字符設備(bei)。代碼清單1.1給(gei)出了Linux下(xia)LED的(de)驅動。

代碼清單1.1 Linux操作系統(tong)下LED的驅動(dong)

    1 #include .../*包含內核中的多個頭文件*/

    2 /*設備結構體*/
    3 struct light_dev {
    4     struct cdev cdev; /*字符設備cdev結構體*/
    5     unsigned char vaule; /*LED亮時為1,熄滅時為0,用戶可讀寫此值*/
    6 };

    7 struct light_dev *light_devp;
    8 int light_major = LIGHT_MAJOR;

    9 MODULE_AUTHOR("Barry Song <21cnbao@gmail.com>");
    10 MODULE_LICENSE("Dual BSD/GPL");
    11 /*打開和關閉函數*/
    12 int light_open(struct inode *inode, struct file *filp)
    13 {
    14     struct light_dev *dev;
    15     /* 獲得設備結構體指針 */
    16     dev = container_of(inode->i_cdev, struct light_dev, cdev);
    17     /* 讓設備結構體作為設備的私有信息 */
    18     filp->private_data = dev;
    19     return 0;
    20 }

    21 int light_release(struct inode *inode, struct file *filp)
    22 {
    23     return 0;
    24 }

    25 /*讀寫設備:可以不需要 */
    26 ssize_t light_read(struct file *filp, char __user *buf, size_t count,
    27     loff_t *f_pos)
    28 {
    29     struct light_dev *dev = filp->private_data; /*獲得設備結構體 */
    30     if (copy_to_user(buf, &(dev->value), 1))
    31         return -EFAULT;

    32     return 1;
    33 }

    34 ssize_t light_write(struct file *filp, const char __user *buf, size_t count,
    35 loff_t *f_pos)
    36 {
    37     struct light_dev *dev = filp->private_data;

    38     if (copy_from_user(&(dev->value), buf, 1))
    39         return -EFAULT;

    40     /*根據寫入的值點亮和熄滅LED*/
    41     if (dev->value == 1)
    42         light_on();
    43     else
    44         light_off();

    45     return 1;
    46 }

    47 /* ioctl函數 */
    48 int light_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
    49     unsigned long arg)
    50 {
    51     struct light_dev *dev = filp->private_data;

    52     switch (cmd) {
    53     case LIGHT_ON:
    54         dev->value = 1;
    55         light_on();
    56         break;
    57     case LIGHT_OFF:
    58         dev->value = 0;
    59         light_off();
    60         break;
    61     default:
    62         /* 不能支持的命令 */
    63         return -ENOTTY;
    64     }

    65     return 0;
    66 }

    67 struct file_operations light_fops = {
    68     .owner = THIS_MODULE,
    69     .read = light_read,
    70     .write = light_write,
    71     .ioctl = light_ioctl,
    72     .open = light_open,
    73     .release = light_release,
    74 };

    75 /*設置字符設備cdev結構體*/
    76 static void light_setup_cdev(struct light_dev *dev, int index)
    77 {
    78     int err, devno = MKDEV(light_major, index);
    79     cdev_init(&dev->cdev, &light_fops);
    80     dev->cdev.owner = THIS_MODULE;
    81     dev->cdev.ops = &light_fops;
    82     err = cdev_add(&dev->cdev, devno, 1);
    83     if (err)
    84         printk(KERN_NOTICE "Error %d adding LED%d", err, index);
    85 }

    86 /*模塊加載函數*/
    87 int light_init(void)
    88 {
    89     int result;
    90     dev_t dev = MKDEV(light_major, 0);
    91     /* 申請字符設備號*/
    92     if (light_major)
    93         result = register_chrdev_region(dev, 1, "LED");
    94     else {
    95         result = alloc_chrdev_region(&dev, 0, 1, "LED");
    96         light_major = MAJOR(dev);
    97     }
    98     if (result < 0)
    99         return result;

    100     /* 分配設備結構體的內存 */
    101     light_devp = kmalloc(sizeof(struct light_dev), GFP_KERNEL);
    102     if (!light_devp) {
    103         result = -ENOMEM;
    104         goto fail_malloc;
    105     }
    106     memset(light_devp, 0, sizeof(struct light_dev));
    107     light_setup_cdev(light_devp, 0);
    108     light_gpio_init();
    109     return 0;

    110 fail_malloc:
    111     unregister_chrdev_region(dev, light_devp);
    112     return result;
    113 }

    114 /*模塊卸載函數*/
    115 void light_cleanup(void)
    116 {
    117     cdev_del(&light_devp->cdev); /*刪除字符設備結構體*/
    118     kfree(light_devp); /*釋放在light_init中分配的內存*/
    119     unregister_chrdev_region(MKDEV(light_major, 0), 1); /*刪除字符設備*/
    120 }

    121 module_init(light_init);
    122 module_exit(light_cleanup);

   熱點(dian)鏈(lian)接:

   1、嵌入式linux驅動要學哪些
   2、典型嵌入式Linux系統設置

更多新聞>>