4168|2

1234

帖子

4

TA的资源

纯净的硅(高级)

楼主
 

[记录]ARM,linux开发控制硬件之还是那个LED [复制链接]

本帖最后由 ywlzh 于 2016-7-23 23:54 编辑

  搭载好了一个空的字符设备驱动程序,接下来就是填充对硬件的控制程序,查看自己板子的LED驱动程序例子,用的misc,混杂设备,现在不用那么深入(慢慢积累),提出其中对硬件控制的程序  
  #define LED_GPIO        MXS_PIN_TO_GPIO(PINID_LCD_D23)  //硬件引脚

  gpio_request   //这个函数是对GPIO口做初始化的函数,就像单片机引脚初始化一样


  gpio_direction_output //这个函数是对GPIO输出高低电平做改变的函数


然后是添加进自己的字符设备驱动程序里,只做了write操作
  1. #include <linux/module.h>
  2. #include <linux/kernel.h>
  3. #include <linux/types.h>
  4. #include <linux/sched.h>
  5. #include <linux/init.h>
  6. #include <linux/fs.h>
  7. #include <linux/ioctl.h>
  8. #include <linux/delay.h>
  9. #include <linux/bcd.h>
  10. #include <linux/capability.h>
  11. #include <linux/rtc.h>
  12. #include <linux/cdev.h>
  13. #include <linux/miscdevice.h>
  14. #include <linux/gpio.h>

  15. #include <../arch/arm/mach-mx28/mx28_pins.h>

  16. #define DEVICE_NAME     "led"   /* 加载模式后,执行”cat /proc/devices”命令看到的设备名称 */

  17. #define LED_GPIO        MXS_PIN_TO_GPIO(PINID_LCD_D23)  //硬件引脚

  18. static struct class *led_class;
  19. static struct class_device        *led_class_devs;

  20. static int led_open(struct inode *inode, struct file *file)
  21. {
  22.   printk("led open ok\n");
  23.   gpio_request(LED_GPIO, "led");
  24.   return 0;
  25. }

  26. static int  led_release(struct inode *inode, struct file *filp)
  27. {
  28.         gpio_free(LED_GPIO);
  29.         return 0;
  30. }

  31. ssize_t led_write(struct file *filp, const char __user *buf, size_t count,
  32.                 loff_t *f_pos)
  33. {
  34.         char data[2];

  35.         copy_from_user(data, buf, count);
  36.         gpio_direction_output(LED_GPIO, data[0]);

  37.         printk("write data:%d \n",data[0]);
  38.         return count;
  39.   
  40. }



  41. static struct file_operations led_fops = {
  42.     .owner   =   THIS_MODULE,    /* 这是一个宏,推向编译模块时自动创建的__this_module变量 */
  43.     .open    =   led_open,     
  44.         .write         =         led_write,
  45.         .release =          led_release,
  46. };

  47. int major;
  48. static int __init led_init(void)
  49. {
  50.         
  51.     major = register_chrdev(0, DEVICE_NAME, &led_fops); //主设备号为0 就自动分配
  52.         
  53.     if (major < 0) {
  54.       printk(" can't register major number\n");
  55.       return major;
  56.     }
  57.         printk("register sucess /dev/led OK!\n");
  58.         led_class = class_create(THIS_MODULE, DEVICE_NAME);
  59.         if (IS_ERR(led_class))
  60.                 return PTR_ERR(led_class);
  61.         
  62.         led_class_devs = device_create(led_class, NULL, MKDEV(major, 0), NULL, "led");
  63.         if (unlikely(IS_ERR(led_class_devs)))
  64.                         return PTR_ERR(led_class_devs);
  65.                
  66.     printk(DEVICE_NAME " initialized\n");
  67.         return 0;
  68. }

  69. static void __exit led_exit(void)
  70. {
  71.    unregister_chrdev(major, DEVICE_NAME);
  72.    
  73.    device_unregister(led_class_devs);
  74.    
  75.    class_destroy(led_class);
  76.    
  77.    printk(" led rmmod OK!\n");
  78. }

  79. module_init(led_init);
  80. module_exit(led_exit);

  81. MODULE_LICENSE("GPL");
复制代码
内核写好了,是不是该写测试文件了,看着LCD屏还是触摸的,不来点交互怎么能行呢?
那就用QT来测试吧:
对内核写进 1 就是点亮灯
  对内核写进 0 就是熄灭灯
我选择用QCommandLinkButton,个人感觉这个控件比QPushbutton要好看一些,就选择它了,按下一个点亮灯,按下另一个熄灭灯
具体程序如下:
  
  1. #include "mainwindow.h"

  2. MainWindow::MainWindow(QWidget *parent)
  3.     : QMainWindow(parent)
  4. {
  5.     fd  = open("/dev/led", O_RDWR);
  6.     ON  = new QCommandLinkButton("open LED","",this);
  7.     OFF = new QCommandLinkButton("close LED","",this);

  8.     ON->setGeometry(10,10,100,30);
  9.     OFF->setGeometry(10,40,100,30);
  10.     connect(ON,SIGNAL(clicked()),this,SLOT(open_led()));
  11.     connect(OFF,SIGNAL(clicked()),this,SLOT(close_led()));
  12. }

  13. MainWindow::~MainWindow()
  14. {

  15. }

  16. void MainWindow::open_led()
  17. {
  18.     val = 0;
  19.     write(fd, &val, 1);
  20. }

  21. void MainWindow::close_led()
  22. {
  23.     val = 1;
  24.     write(fd, &val, 1);
  25. }
复制代码
然后是.h文件要包含对应的头文件
  1. #ifndef MAINWINDOW_H
  2. #define MAINWINDOW_H

  3. #include <QtGui/QMainWindow>

  4. #include <stdio.h>
  5. #include <stdlib.h>
  6. #include <unistd.h>
  7. #include <sys/types.h>
  8. #include <sys/stat.h>
  9. #include <fcntl.h>
  10. #include <termios.h>
  11. #include <errno.h>
  12. #include <limits.h>
  13. #include <asm/ioctls.h>
  14. #include <time.h>
  15. #include <pthread.h>

  16. #include <QCommandLinkButton>
  17. class MainWindow : public QMainWindow
  18. {
  19.     Q_OBJECT

  20. public:
  21.     MainWindow(QWidget *parent = 0);
  22.     ~MainWindow();
  23.     QCommandLinkButton *ON;
  24.     QCommandLinkButton *OFF;
  25. private:
  26.     int fd;
  27.     char val;
  28. private slots:
  29.     void open_led();
  30.     void close_led();
  31. };

  32. #endif // MAINWINDOW_H
复制代码
经过编译 进入nfs目录    加载内核驱动文件,运行QT
   
  
点击"open LED",会发现左边的灯变亮

点击“close LED” 会发现左边的灯会熄灭


同时,终端也会打印出数据

此帖出自ARM技术论坛

最新回复

不错啊,我的ZLG 283也在吃灰,不知从何学起  详情 回复 发表于 2016-7-24 17:34
点赞 关注(1)
个人签名天地庄周马;江湖范蠡船。
个性签名还是放QQ号吧,2060347305,添加说明EEworld好友
 

回复
举报

975

帖子

2

TA的资源

纯净的硅(初级)

沙发
 
床底下的周公板还在吃灰……
此帖出自ARM技术论坛
 
 
 

回复

155

帖子

1

TA的资源

一粒金砂(中级)

板凳
 
不错啊,我的ZLG 283也在吃灰,不知从何学起
此帖出自ARM技术论坛
 
 
 

回复
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/10 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表