Ehome:智能家居之led控制系统

来源:互联网 发布:网站关键词优化方案 编辑:程序博客网 时间:2024/04/28 04:16

3. LED的控制
3.1 LED驱动程序
     实质就是一个linux字符设备驱动
     
     $:' cd project
     $:' mkdir drivers
     $:' cd drivers
     $:' mkdir leds
     $:' cd leds
        // ---> madir drivers/leds -p
     $:' vi led_drv.c
     $:' vi Makefile
     $:' make
     $:' mkdir ../../rootfs/home/drivers
     $:' cp leds_drv.ko  ../../rootfs/home/drivers/
     $:' vi test.c
        // 验证程序。使用arm-...-gcc编译。
     
     编译test.c,测试驱动程序是否好用
     
3.2 编写LED的控制应用程序
      有两种方式
      3.2.1 简单的方式 - 槽函数方式1
           当点击亮灯按钮时,完成该信号的槽函数
           在槽函数中
           fd = open("/dev/leds", ...)
           ioctl(fd, CMD_LED_ON, &i); // i 是第几盏灯
           close (fd);
           修改图片
           
           再次点击时灭灯
           fd = open("/dev/leds", ...)
           ioctl(fd, CMD_LED_OFF, &i);
           close (fd);
           修改图片 
           GUI界面程序一定部署到开发板才能有效果
           
      3.2.2 复杂方式 - 槽函数方式2
           希望GUI界面程序不管是运行在PC
           或者运行在开发板,都能控制开发板的LED状态
           
           'Client (GUI 开发板/PC)'       'Server (UDP 运行在开发板)'
            点击按钮发送命令LED_ON         接收命令,根据命令open设备 ioctl亮灯
            sendto (sd, cmd);

        公共头文件:project/include/ehome.h
        
         1)界面客户端程序 client
           $:' mkdir gui_client
           $:' cd gui_client
           $:' qtcreator
              建立工程 完成界面编程
              先将mainwindow窗口的大小调整为 1024*600
              添加按钮 - 转到槽
                  槽函数中给UDP服务器发送命令
              ---> 3.2.1
        2)服务器程序  server
           $:' cd project
           $:' mkdir server
           $:' cd server
           $:' vi server.c
              // udp 创建socket,接收客户端发送的命令,解析命令调用不同的硬件操作
              recvfrom(cmd) 
              if(cmd == LED_ON)
                 open("/dev/leds",...)
                 ioctl(fd, LED_ON, 0)  
          $:' vi leds.c
            // 进一步解析命令:操作哪盏灯,如何操作,调用对应灯的对应操作函数
          $:' vi leds_hw.c
            // hw 代表硬件 hardware,操作硬件
                      open
                      ioctl
                      close
          $:' arm-cor.....gcc server.c -o server
          $:' cp server rootfs/home/bin/
    #:' insmod /home/drivers/leds_drv.ko
    #:' source /home/etc/profile
    #:' /home/bin/server &
    #:' /home/bin/client

              启动server
              启动client
              点击按钮实验是否亮灯
    
   注意编程过程中的调试技巧
#define DEBUG
#ifdef DEBUG
    /*##表示如果可变参数被忽略或为空,将使预处理器( preprocessor )去除掉它前面的那个逗号。*/
    #define pr_debug(fmt, ...) printf(fmt, ##__VA_ARGS__)
#else
    #define pr_debug(fmt, ...) 
#endif



   BUG的调试,顺着数据流分析该调用的函数是否调用到。




/* leds_drv.c 驱动源代码 */#include <linux/init.h>#include <linux/module.h>#include <linux/miscdevice.h>#include <linux/gpio.h>#include <linux/fs.h>#include <mach/platform.h>#include <linux/uaccess.h>MODULE_LICENSE("GPL");#define LED_ON  0x100001#define LED_OFF 0x100002struct led_desc {    char *name;    int gpio;};struct led_desc leds[]={    {"led_bedroom", PAD_GPIO_C+12},    {"led_saloon", PAD_GPIO_C+7},    {"led_kitchen", PAD_GPIO_C+11},    {"led_restroom", PAD_GPIO_B+26},};long leds_ioctl(struct file *file,unsigned int cmd,unsigned long arg){    //1.定义内核缓冲区    int kindex = 0;    int ret = 0;    int status = 0;    //2.拷贝用户缓冲区到内核    ret = copy_from_user(&kindex, (int *)arg, 4);    //3.解析命令,操作硬件    switch(cmd) {        case LED_ON:            status = 0;            break;        case LED_OFF:            status = 1;            break;        default:            return -EINVAL;    }    if(kindex>= 0 && kindex <4)    {        gpio_direction_output(leds[kindex].gpio, status);    }    return 0;}struct file_operations leds_fops ={    .owner = THIS_MODULE,    .unlocked_ioctl = leds_ioctl,};struct miscdevice leds_misc ={    .minor = MISC_DYNAMIC_MINOR,//自动分配次设备号    .name  = "leds", //设备文件名称    .fops = &leds_fops,};int __init leds_drv_init(void){    int i = 0;    for(; i<ARRAY_SIZE(leds); i++)    {        gpio_request(leds[i].gpio, leds[i].name);    }    misc_register(&leds_misc);    return 0;}void __exit leds_drv_exit(void){    int i = 0;    misc_deregister(&leds_misc);    for(; i<ARRAY_SIZE(leds); i++)    {        gpio_free(leds[i].gpio);    }}module_init(leds_drv_init);module_exit(leds_drv_exit);


0 0
原创粉丝点击