在S3C6410开发板上的LED驱动程序
这两天写了个LED驱动程序,网上也看了好多的帖子。
开始思路很清晰了,就是先看电路图,发现LED灯是接在GPM端口上的,
然后看S3C6410数据手册,先向GPMCON口写命令字,让GPM0-5设置为输出,再向GPMDAT口写数据字,在GPM0-5引脚拉低或拉高电平,
从而控制LED的亮灭。
1、电路图
很显然LED灯是接在GPM口引脚下面的
2、数据手册
3、LED驱动程序
- #include <linux/module.h>
- #include <linux/kernel.h>
- #include <linux/fs.h>
- #include <linux/uaccess.h> /*copy_to_user,copy_from_user*/
- #include <linux/io.h> /*inl(),outl()*/
- #include <linux/miscdevice.h>
- #include <linux/pci.h>
- static long S3C64XX_GPMCON=0xF4500820; /*这里是虚拟地址,物理地址可以再S3C6410数据手册上找到。也可以根据物理地址,ioremap()获得虚拟地址。*/
- static long S3C64XX_GPMDAT=0xF4500824;
- #define LED_MAJOR 240 /*主设备号*/
- int led_open(struct inode *inode,struct file *file)
- {
- unsigned tmp;
- tmp=inl(S3C64XX_GPMCON);
- printk("the pre GPMCON is %x",tmp);
- tmp=inl(S3C64XX_GPMDAT);
- printk("the pre GPMDAT is %x",tmp);
- outl(0x00111111,S3C64XX_GPMCON); /*向GPMCON命令端口写命令字,设置GPM0-5为output口*/
- printk("#############open#############");
- return 0;
- }
- static ssize_t led_read(struct file *file,char __user *buf,size_t count,loff_t * f_pos)
- {
- unsigned tmp=inl(S3C64XX_GPMDAT);
- int num=copy_to_user(buf,&tmp,count);
- if(num==0)
- printk("copy successfully");
- else printk("sorry copy failly");
- printk("the GPMDAT is %x.",tmp);
- return count;
- }
- static ssize_t led_write(struct file * file,const char __user * buf,size_t count,loff_t * f_pos)/*我是通过write()来控制LED灯的,也可以通过ioctl()来控制*/
- {
- char kbuf[10];
- printk("###########write###########");
- int num=copy_from_user(kbuf,buf,count);
- if(num==0)
- printk("copy successfully");
- else printk("sorry copy failly");
- printk("##the kbuf is %c",kbuf[0]);
- switch(kbuf[0])
- {
- case 0://off
- outl(0xff,S3C64XX_GPMDAT); /*拉高GPMDAT[0:5]的引脚,使LED灯灭,因为LED是低电平有电流通过*/
- break;
- case 1://on
- outl(0x00,S3C64XX_GPMDAT); /*拉低GPMDAT[0:5]的引脚,使LED灯亮*/
- break;
- default:
- break;
- }
- return count;
- }
- int led_release(struct inode *inode,struct file *file)
- {
- printk("#######release##########");
- return 0;
- }
- struct file_operations led_fops={
- .owner = THIS_MODULE,
- .open = led_open,
- .read = led_read,
- .write = led_write,
- .release = led_release,
- };
- int __init led_init(void)
- {
- int rc;
- printk("Test led dev\n");
- rc=register_chrdev(LED_MAJOR,"led",&led_fops);
- if(rc<0)
- {
- printk("register %s char dev error\n","led");
- return -1;
- }
- printk("OK!\n");
- return 0;
- }
- void __exit led_exit(void)
- {
- unregister_chrdev(LED_MAJOR,"led");
- printk("module exit\n");
- }
- module_init(led_init);
- module_exit(led_exit);
写好源码后,写Makefile
- obj-m:=led_driver.o
- KDIR:=/home/tmp/linux2.6.28
- all:
- 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、测试驱动程序
- #include <stdio.h>
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <fcntl.h>
- /*#include <unistd.h>*/
- int main()
- {
- printf("hello led device .");
- char buf[10]={0,1,0,1};
- int fd=open("/dev/led",2,0777);
- if(fd<0){
- printf("can't open led device");
- return -1;
- }
- printf("open the led device successfully.");
- while(1)
- {
- int num=write(fd,&buf[0],1);
- if(num<0)
- printf("we set the led failly.");
- else printf("we set the led off");
- sleep(1);
- write(fd,&buf[1],1);
- printf("we set the led on");
- sleep(1);
- }
- close(fd);
- printf("bye led device .");
- return 0;
- }
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驱动程序相关推荐
- 设置vmware vsphere web client_Arduino+前端高级应用-通过WEB网页控制Arduino开发板上的LED灯...
在本教程中,让我们继续学习如何控制GPIO 引脚,不过这次进入高级阶段,我们将从一个可以访问的WEB网页中开关led灯.超详细代码解读,前端工程师也可以轻松玩起嵌入式.听起来是不很酷,Let's go ...
- linux开发板led怎么亮,TQ2440开发板上实现按键点亮LED(转载)
//声明:该文章是在网上搜到的,对作者表示感谢. 文章记录了作者在TQ2440开发板上实现按键点亮LED驱动开发的详细过程,还记录了一些容易出现的错误,以及怎么解决这些错误. 一.驱动开发流程 二.驱 ...
- S3C6410开发板LED驱动代码分析及测试代码分析
在本文中,我们对S3C6410开发板LED驱动代码的实现过程进行分析,然后通过一个实例对LED进行控制.在本文的资源中包含了设备驱动的源码和测试的源码. 一.设备驱动源码分析 设备驱动主要实现了模块的 ...
- firefly-rk3288开发板Linux驱动——LED驱动
本文主要介绍三个部分的内容:一.准备SDK源码 二.如何操作GPIO 三.LED设备驱动的实现.由于firefly官方一直在对源码进行更新,所以本文只以我正在用的版本介绍.此外,官方提供的下载工具版本 ...
- 开发板——在X210开发板上进行裸机开发的流程
流程总结 本文以"LED流水灯"为例,说明在X210开发板上进行裸机开发的流程. 步骤一:搭建嵌入式Linux开发环境 在虚拟机中安装与配置Linux系统,并安装交叉编译工具链: ...
- 在ARM开发板上实现LCD+USB键盘
一.LCD驱动 这个地方先留着 二.USB键盘驱动 在linux内核里边提供了usbkbd.c可以直接借助这个模块,编译生成驱动模块加载进内核,其实对于驱动程序,这里还不是重点,最后想要实现的是直接在 ...
- 使用QT程序控制Linux开发板上的继电器(一)
`使用QT程序控制Linux开发板上的继电器(一)` 测试平台介绍 测试系统接线 编写PlatformIO驱动程序 修改设备树 烧录设备树 Platform字符设备驱动设备框架 完善驱动框架 编写测试 ...
- arm11 s3c6410 开发板比较 哪个公司的arm11开发板好? arm11开发板推荐
代理arm11开发板已经几个月了,说下我自己的看法. 我首先用语言描述一下国内主流的arm开发板情况,个人对各个公司开发板的看法,仅代表个人意见,没有针对某个公司的意思,由于6410 的开发难度以及工 ...
- arm11 s3c6410 开发板 学习板 工业开发板 比较 国内主流的arm开发板比较
代理arm11开发板已经几个月了,说下我自己的看法. 我首先用语言描述一下国内主流的arm开发板情况,个人对各个公司开发板的看法,仅代表个人意见,没有针对某个公司的意思,由于6410 的开发难度以及工 ...
最新文章
- mongo里的type_MongoDB $type 操作符
- buu [BJDCTF 2nd]老文盲了
- java构造器_Java构造器就是这么简单!
- TensorFlow实验(2)
- idea每次都要build_Lombok有啥牛皮的?SpringBoot和IDEA官方都要支持它!
- django jsonresponse_0基础掌握Django框架(29)HttpResponse对象
- Python爬取唐人街探案3豆瓣短评并生成词云
- setTimeout 带参数调用问题
- 使用windows远程桌面连接ubuntu
- vue2.0一起在懵逼的海洋里越陷越深(二)
- php嗅探链接,教你如何利用php来嗅探劫持服务器数据
- Android下载文件,如何获取实际的文件名
- Xilinx下载安装与在win10闪退问题解决方法
- openbsd停止mysql_英特尔处理器超线程功能被OpenBSD 停用,并爆bug
- 【愚公系列】2022年05月 vue3系列 axios请求的封装(TS版)
- Linux 永久修改主机名(转载)
- 使用Python来模拟鼠标的点击; 模拟键盘
- mysql分组语句的子句_MySQL 中的排序与分组 语句
- 达梦数据库和mysql索引引擎_达梦数据库如何建索引和使用
- 使用hive制作一张日历表