这两天写了个LED驱动程序,网上也看了好多的帖子。

开始思路很清晰了,就是先看电路图,发现LED灯是接在GPM端口上的,

然后看S3C6410数据手册,先向GPMCON口写命令字,让GPM0-5设置为输出,再向GPMDAT口写数据字,在GPM0-5引脚拉低或拉高电平,

从而控制LED的亮灭。

1、电路图

很显然LED灯是接在GPM口引脚下面的

2、数据手册

3、LED驱动程序

[cpp] view plaincopy
  1. #include <linux/module.h>
  2. #include <linux/kernel.h>
  3. #include <linux/fs.h>
  4. #include <linux/uaccess.h>    /*copy_to_user,copy_from_user*/
  5. #include <linux/io.h>         /*inl(),outl()*/
  6. #include <linux/miscdevice.h>
  7. #include <linux/pci.h>
  8. static long S3C64XX_GPMCON=0xF4500820;   /*这里是虚拟地址,物理地址可以再S3C6410数据手册上找到。也可以根据物理地址,ioremap()获得虚拟地址。*/
  9. static long S3C64XX_GPMDAT=0xF4500824;
  10. #define LED_MAJOR 240                    /*主设备号*/
  11. int led_open(struct inode *inode,struct file *file)
  12. {
  13. unsigned tmp;
  14. tmp=inl(S3C64XX_GPMCON);
  15. printk("the pre GPMCON is %x",tmp);
  16. tmp=inl(S3C64XX_GPMDAT);
  17. printk("the pre GPMDAT is %x",tmp);
  18. outl(0x00111111,S3C64XX_GPMCON);         /*向GPMCON命令端口写命令字,设置GPM0-5为output口*/
  19. printk("#############open#############");
  20. return 0;
  21. }
  22. static ssize_t led_read(struct file *file,char __user *buf,size_t count,loff_t * f_pos)
  23. {
  24. unsigned tmp=inl(S3C64XX_GPMDAT);
  25. int num=copy_to_user(buf,&tmp,count);
  26. if(num==0)
  27. printk("copy successfully");
  28. else printk("sorry  copy failly");
  29. printk("the GPMDAT is %x.",tmp);
  30. return count;
  31. }
  32. static ssize_t led_write(struct file * file,const char __user * buf,size_t count,loff_t * f_pos)/*我是通过write()来控制LED灯的,也可以通过ioctl()来控制*/
  33. {
  34. char kbuf[10];
  35. printk("###########write###########");
  36. int num=copy_from_user(kbuf,buf,count);
  37. if(num==0)
  38. printk("copy successfully");
  39. else printk("sorry  copy failly");
  40. printk("##the kbuf is %c",kbuf[0]);
  41. switch(kbuf[0])
  42. {
  43. case 0://off
  44. outl(0xff,S3C64XX_GPMDAT);  /*拉高GPMDAT[0:5]的引脚,使LED灯灭,因为LED是低电平有电流通过*/
  45. break;
  46. case 1://on
  47. outl(0x00,S3C64XX_GPMDAT);  /*拉低GPMDAT[0:5]的引脚,使LED灯亮*/
  48. break;
  49. default:
  50. break;
  51. }
  52. return count;
  53. }
  54. int led_release(struct inode *inode,struct file *file)
  55. {
  56. printk("#######release##########");
  57. return 0;
  58. }
  59. struct file_operations led_fops={
  60. .owner = THIS_MODULE,
  61. .open = led_open,
  62. .read = led_read,
  63. .write = led_write,
  64. .release = led_release,
  65. };
  66. int __init led_init(void)
  67. {
  68. int rc;
  69. printk("Test led dev\n");
  70. rc=register_chrdev(LED_MAJOR,"led",&led_fops);
  71. if(rc<0)
  72. {
  73. printk("register %s char dev error\n","led");
  74. return -1;
  75. }
  76. printk("OK!\n");
  77. return 0;
  78. }
  79. void __exit led_exit(void)
  80. {
  81. unregister_chrdev(LED_MAJOR,"led");
  82. printk("module exit\n");
  83. }
  84. module_init(led_init);
  85. module_exit(led_exit);

写好源码后,写Makefile

[cpp] view plaincopy
  1. obj-m:=led_driver.o
  2. KDIR:=/home/tmp/linux2.6.28
  3. all:
  4. make -C $(KDIR) M=$(shell pwd) modules CROSS_COMPILE=/usr/local/arm/4.4.1/bin/arm-linux-

/*之前make,出现一些问题,比如说缺少什么头文件啦之类,原来是没有建立内核树,到内核源码目录里面make一下就好了*/

写好驱动源代码和Makefile文件后就在本目录下make

之后生成了led_driver.ko文件,下载到开发板上

4、测试驱动程序

[cpp] view plaincopy
  1. #include <stdio.h>
  2. #include <sys/types.h>
  3. #include <sys/stat.h>
  4. #include <fcntl.h>
  5. /*#include <unistd.h>*/
  6. int main()
  7. {
  8. printf("hello led device .");
  9. char buf[10]={0,1,0,1};
  10. int fd=open("/dev/led",2,0777);
  11. if(fd<0){
  12. printf("can't open led device");
  13. return -1;
  14. }
  15. printf("open the led device successfully.");
  16. while(1)
  17. {
  18. int num=write(fd,&buf[0],1);
  19. if(num<0)
  20. printf("we set the led failly.");
  21. else printf("we set the led off");
  22. sleep(1);
  23. write(fd,&buf[1],1);
  24. printf("we set the led on");
  25. sleep(1);
  26. }
  27. close(fd);
  28. printf("bye led device .");
  29. return 0;
  30. }

arm-linux-gcc -o led_test.o led_test.c

编译好后,把led_test.o文件下载到开发板上

5、具体操作步骤

本人的OK6410开发板之前已装好linux-2.6.18内核的Linux系统,然后输shell命令

insmod led_driver.ko                                                  //加载led_driver.ko驱动到内核

mknod /dev/led c 240 0                                              //把led设备文件挂载到/dev/led上,c 代表字符设备 ,240 是主设备号 , 0 是次设备号

./led_test.o                                                                   //启动测试程序,点亮LED灯

注意:

在PC机上写ARM开发板的驱动程序,需要在PC(俗称上位机)上配置交叉编译工具链  arm-linux-

开始想不通过驱动程序,通过iopl(3);提升权限,直接操作硬件的,发现在ARM开发板上不能这么做。

原来以为只能写驱动程序的方式控制寄存器的,后来发现,mmap()那个“/dev/mem”文件系统也可以的。

开始在开发板上调试,cat /var/log/messages 查看printk的输出,发现什么也没有,原来需要输入shell命令 klogd 来开启日志功能。

祝大家在开发板上玩的愉快。

转载地址:http://blog.csdn.net/wq897387/article/details/7387615

在S3C6410开发板上的LED驱动程序相关推荐

  1. 设置vmware vsphere web client_Arduino+前端高级应用-通过WEB网页控制Arduino开发板上的LED灯...

    在本教程中,让我们继续学习如何控制GPIO 引脚,不过这次进入高级阶段,我们将从一个可以访问的WEB网页中开关led灯.超详细代码解读,前端工程师也可以轻松玩起嵌入式.听起来是不很酷,Let's go ...

  2. linux开发板led怎么亮,TQ2440开发板上实现按键点亮LED(转载)

    //声明:该文章是在网上搜到的,对作者表示感谢. 文章记录了作者在TQ2440开发板上实现按键点亮LED驱动开发的详细过程,还记录了一些容易出现的错误,以及怎么解决这些错误. 一.驱动开发流程 二.驱 ...

  3. S3C6410开发板LED驱动代码分析及测试代码分析

    在本文中,我们对S3C6410开发板LED驱动代码的实现过程进行分析,然后通过一个实例对LED进行控制.在本文的资源中包含了设备驱动的源码和测试的源码. 一.设备驱动源码分析 设备驱动主要实现了模块的 ...

  4. firefly-rk3288开发板Linux驱动——LED驱动

    本文主要介绍三个部分的内容:一.准备SDK源码 二.如何操作GPIO 三.LED设备驱动的实现.由于firefly官方一直在对源码进行更新,所以本文只以我正在用的版本介绍.此外,官方提供的下载工具版本 ...

  5. 开发板——在X210开发板上进行裸机开发的流程

    流程总结 本文以"LED流水灯"为例,说明在X210开发板上进行裸机开发的流程. 步骤一:搭建嵌入式Linux开发环境 在虚拟机中安装与配置Linux系统,并安装交叉编译工具链: ...

  6. 在ARM开发板上实现LCD+USB键盘

    一.LCD驱动 这个地方先留着 二.USB键盘驱动 在linux内核里边提供了usbkbd.c可以直接借助这个模块,编译生成驱动模块加载进内核,其实对于驱动程序,这里还不是重点,最后想要实现的是直接在 ...

  7. 使用QT程序控制Linux开发板上的继电器(一)

    `使用QT程序控制Linux开发板上的继电器(一)` 测试平台介绍 测试系统接线 编写PlatformIO驱动程序 修改设备树 烧录设备树 Platform字符设备驱动设备框架 完善驱动框架 编写测试 ...

  8. arm11 s3c6410 开发板比较 哪个公司的arm11开发板好? arm11开发板推荐

    代理arm11开发板已经几个月了,说下我自己的看法. 我首先用语言描述一下国内主流的arm开发板情况,个人对各个公司开发板的看法,仅代表个人意见,没有针对某个公司的意思,由于6410 的开发难度以及工 ...

  9. arm11 s3c6410 开发板 学习板 工业开发板 比较 国内主流的arm开发板比较

    代理arm11开发板已经几个月了,说下我自己的看法. 我首先用语言描述一下国内主流的arm开发板情况,个人对各个公司开发板的看法,仅代表个人意见,没有针对某个公司的意思,由于6410 的开发难度以及工 ...

最新文章

  1. mongo里的type_MongoDB $type 操作符
  2. buu [BJDCTF 2nd]老文盲了
  3. java构造器_Java构造器就是这么简单!
  4. TensorFlow实验(2)
  5. idea每次都要build_Lombok有啥牛皮的?SpringBoot和IDEA官方都要支持它!
  6. django jsonresponse_0基础掌握Django框架(29)HttpResponse对象
  7. Python爬取唐人街探案3豆瓣短评并生成词云
  8. setTimeout 带参数调用问题
  9. 使用windows远程桌面连接ubuntu
  10. vue2.0一起在懵逼的海洋里越陷越深(二)
  11. php嗅探链接,教你如何利用php来嗅探劫持服务器数据
  12. Android下载文件,如何获取实际的文件名
  13. Xilinx下载安装与在win10闪退问题解决方法
  14. openbsd停止mysql_英特尔处理器超线程功能被OpenBSD 停用,并爆bug
  15. 【愚公系列】2022年05月 vue3系列 axios请求的封装(TS版)
  16. Linux 永久修改主机名(转载)
  17. 使用Python来模拟鼠标的点击; 模拟键盘
  18. mysql分组语句的子句_MySQL 中的排序与分组 语句
  19. 达梦数据库和mysql索引引擎_达梦数据库如何建索引和使用
  20. 使用hive制作一张日历表

热门文章

  1. C语言 打印杨辉三角
  2. IE8中文件下载不兼容问题
  3. python IDEL 快捷键
  4. echarts 雷达图
  5. hexo solar主题 + github搭建个人博客(二)----基本信息、头像图标、联系方式、导航栏
  6. 微星主板黑苹果_技嘉X79-UD7主板设置一键启动u盘方法【详解】
  7. 如果金融男和IT男同时追你,你选谁?
  8. JavaEE学习08(解决项目导入eclipse后项目中的红错号)
  9. 20221128-20221202周总结
  10. java爬虫抓取极客时间专栏页面