zoukankan      html  css  js  c++  java
  • 05day01ioctl_led

      1 /*
      2     long (*unlocked_ioctl) (struct file *, unsigned int, unsigned long);
      3 
      4 misc 混杂字符设备
      5 
      6 应用层通过ioctl 函数来
      7  int ioctl(int d, unsigned long request, ...);
      8 
      9 底层下 实现file_operations 中的unlocked_ioctl 接口
     10 */
     11 #include <linux/module.h>
     12 #include <linux/init.h>
     13 #include <linux/kernel.h> //printk
     14 
     15 #include <linux/miscdevice.h> //misc_register....
     16 #include <linux/fs.h> //file_operations
     17 #include <mach/regs-gpio.h> //S5P_VA_GPIO2
     18 #include <linux/ioport.h> //request_mem_region
     19 
     20 #include "led_ctl.h"
     21 //ioctl 命令的定义
     22 
     23 #define DEVNAME "ldm"
     24 
     25 #define LED_REG_BASE  0x110002e0
     26 
     27 #define GPM4CON       (*(volatile u32 *)(S5P_VA_GPIO2 + 0x02e0))
     28 #define GPM4DAT       (*(volatile u8 *)(S5P_VA_GPIO2 + 0x02e4))
     29 
     30 struct   ldm_info 
     31 {
     32     struct miscdevice dev;
     33     struct file_operations  ops;
     34 };
     35 
     36 struct ldm_info ldm;
     37 
     38 static void led_on(u8  stat)
     39 {
     40     GPM4DAT = (GPM4DAT & ~0xf) | (stat & 0xf);
     41 }
     42 
     43 
     44 //int ioctl(int d, unsigned long request, ...);
     45 long ldm_ioctl(struct file *  file, unsigned int  cmd, unsigned long arg)
     46 {
     47     int ret = 0;
     48     printk("led_stat = %ld
    ", arg);
     49 //cmd 
     50 //关于cmd 命令的定义,有四个宏辅助定义_IO,
     51 //_IOR, _IOW, _IOWR
     52 //底层用于生成的命令,应用层需要知道
     53 //通常的做法,把cmd的生成放到.h文件,该头文件也提供给应用层
     54 
     55     switch(cmd) {
     56         case LED_STATUS:
     57             //GPM4DAT = (GPM4DAT & ~0xf) | (arg & 0xf);
     58             led_on(arg);
     59             break;
     60         case LED1_ON:
     61             led_on(0b1110);
     62             break;
     63         case LED1_OFF:
     64             led_on(0b1111);
     65             break;
     66         case GET_STATUS:
     67             ret = (GPM4DAT & 0xf);
     68             break;
     69         default:
     70             break;
     71     }
     72 
     73     return ret;
     74 
     75 }
     76 
     77 static int ldm_init(void)
     78 {
     79     int ret = 0;
     80     printk("%s:%s, %d
    ", __FILE__, __FUNCTION__, __LINE__);
     81 
     82     //向内核中注册使用的地址
     83     if(! request_mem_region(LED_REG_BASE, 8 , DEVNAME)) {
     84         printk("request_mem_region  failed
    ");
     85         ret = -EBUSY; 
     86         goto err_request_mem_region;
     87     }
     88 
     89     //初始化GPIO  把对应的端口设置为输出模式
     90     GPM4CON =  (GPM4CON & ~0xffff) | 0x1111;
     91 
     92     //misc
     93     ldm.dev.minor =  MISC_DYNAMIC_MINOR;
     94     ldm.dev.name  = DEVNAME;
     95     ldm.dev.fops = &ldm.ops;
     96     ldm.ops.unlocked_ioctl = ldm_ioctl;
     97 
     98 
     99     ret = misc_register(&ldm.dev);
    100     if(ret < 0) {
    101         printk("misc_register  failed
    ");
    102         goto err_misc_register;
    103     }
    104 
    105 
    106     return 0;
    107 err_misc_register:
    108     release_mem_region(LED_REG_BASE, 8);
    109 err_request_mem_region:
    110     return ret;
    111 }
    112 
    113 static void ldm_exit(void)
    114 {
    115     printk("%s:%s, %d
    ", __FILE__, __FUNCTION__, __LINE__);
    116     misc_deregister(&ldm.dev);
    117     release_mem_region(LED_REG_BASE, 8);
    118 }
    119 
    120 
    121 module_init(ldm_init);
    122 module_exit(ldm_exit);
    123 MODULE_LICENSE("GPL");

     .h

     1 #pragma once
     2 
     3 #include <linux/ioctl.h>
     4 //参考下内核文档 linux/linux-3.5/Documentation/ioctl
     5 //ioctl-decoding.txt  和 ioctl-number.txt
     6 //例如 实现  控制LED灯
     7 /*
     8 _IO (魔数, 基数);
     9 • _IOR (魔数, 基数, 变量型)
    10 • _IOW (魔数, 基数, 变量型)
    11 • _IOWR (魔数, 基数,变量型 )
    12 */
    13 
    14 //
    15 #define  LED_STATUS   _IOW('l', 1, unsigned char)
    16 //底层的驱动生成的一系列 命令  这个头文件同样也需要提供给应用层
    17 
    18 #define LED1_ON   _IO('l',   2)
    19 #define LED1_OFF    _IO('l',  3)
    20 
    21 //
    22 #define GET_STATUS _IOR('l', 4, unsigned char)
    23 

    app

     1 //应用层
     2 #include <stdio.h>
     3 #include <sys/stat.h>
     4 #include <fcntl.h>
     5 #include <unistd.h>
     6 #include <sys/ioctl.h>
     7 
     8 #include "led_ctl.h"
     9 
    10 
    11 int main(int argc, char const *argv[])
    12 {
    13     if(argc != 3) {
    14         printf("usage: cmd <device file>  <led status>
    ");
    15         return -1;
    16     }
    17 
    18     int fd = open(argv[1], O_RDWR);
    19     if(fd < 0) {
    20            perror("open");
    21            goto err_open;
    22     }
    23 
    24     unsigned char led_status = atoi(argv[2]);
    25 
    26     //ioctl(fd, LED_STATUS, led_status);
    27     ioctl(fd, LED1_ON);
    28 
    29     close(fd);
    30 
    31     return 0;
    32 
    33 err_open:
    34     return -1;
    35 }
  • 相关阅读:
    用AB对Webservice做压力测试
    web压力测试工具(小而精)
    让IIS支持10万并发
    数据库之间数据转换最快方法
    C#中执行Dos命令
    .NET 4.0中使用内存映射文件实现进程通讯
    HTML解析利器HtmlAgilityPack
    C#快速找出磁盘内的所有文件
    ORM for Net主流框架汇总与效率测试
    新浪微博基于MySQL的分布式数据库实践
  • 原文地址:https://www.cnblogs.com/baoshulin/p/6477008.html
Copyright © 2011-2022 走看看