OK6410A学习笔记四:嵌入式Linux驱动之LED驱动进阶

发布者:blazings最新更新时间:2016-04-12 来源: eefocus关键字:OK6410A  Linux驱动  LED驱动进阶 手机看文章 扫描二维码
随时随地手机看文章
作为上一篇介绍的LED驱动的续篇,主要的改动之处在于实现了利用Linux系统支持的mdev机制在驱动加载的过程中自动创建设备节点的功能,另外,对write函数有了比较大的改进。
 
//s3c6410_led.c – driver file
#include
#include
#include
#include
#include
#include
#include
#include
 
#define DEV_MAJOR 176
#define DEV_NAME "s3c6410_leds"
 
 
 
#define GPMCON 0x7F008820
#define GPMDAT 0x7F008824
#define GPMPUD 0x7F008828
 
 
volatile unsigned long *gpmcon = NULL;
volatile unsigned long *gpmdat = NULL;
volatile unsigned long *gpmpud = NULL;
 
static struct class *s3c6410_led_class;
static struct class_device *s3c6410_led_class_dev;
 
 
static int s3c6410_led_open(struct inode *inode, struct file *filp)
{
         //int ret;
        
         printk(KERN_ALERT "This is open function of s3c6410 led driver.\n");
 
         *gpmpud &= 0xffffffaa; //set GPM0~3 as pull up enabled
         *gpmcon &= 0xffff1111; //set GPM0~3 as output
         *gpmdat &= 0xfffffff0; //set GPM0~3 to low level, which turn on leds
 
         return 0;
 
}
 
static ssize_t s3c6410_led_write(struct file *filp, const char __user *buf,
 size_t count, loff_t *ppos)
{
         char val;
 
         copy_from_user(&val,buf,count);
 
         //printk("val is %c\n",val);
 
         printk(KERN_ALERT "This is write function of s3c6410 led driver.\n");
 
         *gpmpud &= 0xffffffaa;
         *gpmcon &= 0xffff1111;
 
         if((int)val){
                   //turn on leds
                   printk(KERN_ALERT "Turn on the leds.\n");
                   *gpmdat &= 0xfffffff0; //set GPM0~3 to low level, which turn on leds
                  
         }else{
                   printk(KERN_ALERT "Turn off the leds.\n");
                   *gpmdat |= 0x0000000f; //set GPM0~3 to low level, which turn off leds
         }
 
         return count;
}
 
 
struct file_operations s3c6410_led_flops = {
         .owner = THIS_MODULE,
         .open = s3c6410_led_open,
         .write = s3c6410_led_write,
};
 
static int __init s3c6410_led_init(void)
{
         int ret;
 
         //register led device driver into kernel
         ret = register_chrdev(DEV_MAJOR,DEV_NAME,&s3c6410_led_flops);
 
         //retriver the vritual address by ioremap
         gpmcon = (volatile unsigned long *)ioremap(GPMCON,4); //32-bit reg
         gpmdat = gpmcon + 1;
         gpmpud = gpmcon + 2;
 
         //create led device node
         s3c6410_led_class = class_create(THIS_MODULE,"s3c6410_led");
         s3c6410_led_class_dev = device_create(s3c6410_led_class,NULL,MKDEV(DEV_MAJOR,0),
NULL,DEV_NAME);
 
         return 0;
}
 
static void __exit s3c6410_led_exit(void)
{
         //unregister led device dirver from kernel
         unregister_chrdev(DEV_MAJOR,DEV_NAME);
 
         //iounmap
         iounmap(gpmcon);
 
         //delete led driver node
         device_unregister(s3c6410_led_class_dev);
         class_destroy(s3c6410_led_class);
}
 
module_init(s3c6410_led_init);
module_exit(s3c6410_led_exit);
 
MODULE_DESCRIPTION("This is led driver sample for OK6410A board.");
MODULE_VERSION("1.0");
MODULE_AUTHOR("");
MODULE_LICENSE("Dual BSD/GPL");
 
//s3c6410_led_test.c – test file
#include
#include
#include
#include
 
int main(int argc,char* argv[])
{
         int fd;
         int val;
 
         if(argc != 2){
                   printf("Usage: \n");
                   printf("%s \n",argv[0]);
                   return 0;
                   }
         else{
                   if(strcmp(argv[1],"on") == 0) val = 1;
                   else if(strcmp(argv[1],"off") == 0) val = 0;
                   else{
                            printf("Usage: \n");
                            printf("%s ",argv[0]);
                            return 0;
                            }
                   }
 
         fd = open("/dev/s3c6410_leds",O_RDWR);
 
         write(fd,&val,1);
        
         return 0;
}
 
操作过程:



关键字:OK6410A  Linux驱动  LED驱动进阶 引用地址:OK6410A学习笔记四:嵌入式Linux驱动之LED驱动进阶

上一篇:ARM体系结构详解之ARM寄存器
下一篇:OK6410A学习笔记三:嵌入式Linux驱动之LED驱动

推荐阅读最新更新时间:2024-03-16 14:50

OK6410A 开发板 (八) 79 linux-5.11 OK6410A schedule总览
__schedule 功能描述 __schedule 1.完成一些必要的检查, 并设置进程状态, 处理进程所在的就绪队列 2.调度全局的pick_next_task选择抢占的进程 2.1 如果当前cpu上所有的进程都是cfs调度的普通非实时进程, 则直接用cfs调度找到进程 如果无程序可调度则找到 idle进程 2.2 否则从优先级最高的调度器类sched_class_highest(目前是stop_sched_class)开始依次遍历所有调度器类的pick_next_task函数, 选择最优的那个进程 //本例有 dl - rt - fair - idle //支持
[单片机]
嵌入式Linux应用程序访问物理地址的实例
前言   按照Linux分层驱动思想,外设驱动与主机控制器的驱动不相关,主机控制器的驱动不关心外设,而外设驱动也不关心主机,外设访问核心层的通用应用程序接口进行数据传输,主机和外设之间可以进行任意的组合。这样思想要求应用程序不应当直接访问物理地址,而是应当通过驱动程序的调用来实现,以便保持应用程序的可移植性,操作访问的统一性,应用程序利用系统的统一调用接口访问外设,如使用write(),read()等函数进行实际的外设读写控制。应用程序通过调用接口进入内核函数后,内核利用copy_from_user()获得应用层数据,内核驱动程序也通过分层最终执行物理访问,之后把获得的数据用copy_to_user()回传给应用程序的调用者。由于
[嵌入式]
基于Linux的液晶显示屏驱动设计
引 言 Linux设备驱动程序属于Linux内核的一部分,并在Linux内核中扮演着十分重要的角色。它们像一个个“黑盒子”,使某个特定的硬件响应一个定义良好的内部编程接口,同时完全隐蔽了设备的工作细节。用户通过一组和具体设备驱动无关的标准化的调用来完成相关操作,驱动程序的任务就是把这些调用映射到具体设备对于实际硬件的特定操作上。   硬件设备只是一个设备文件,应用程序可以像操作普通文件一样对硬件设备进行操作。设备驱动程序是内核的一部分,它实现以下功能:   ①对设备初始化和释放。   ②把数据从内核传送到硬件和从硬件读取数据。   ③读取应用程序传送给设备文件的数据和回送应用程序请求的数据。   ④检测和处理设备
[家用电子]
基于<font color='red'>Linux</font>的液晶显示屏<font color='red'>驱动</font>设计
OK6410A 开发板 (八) 40 linux-5.11 OK6410A buddy 的 alloc 和 free
第三阶段建立的是 buddy buddy 的使用期限 mm_init- mem_init返回 - 无结束点 buddy 管理的内存大小 buddy 管理的内存 是 memblock 决定的 属于 memblock.memory 中 但不包括 memblock.reserved 的部分 memblock 可以通过 memblock_alloc或memblock_reserve 来 预留内存 buddy 的使用方法 alloc alloc_pages/alloc_page // 返回的是 struct page get_zeroed_page // 返回的是虚拟地址 __get_free_pages/__get_f
[单片机]
Linux系统下USB摄像头驱动开发
摘要:介绍了在Iinux系统下开发符合Video for Linux标准的USB摄像头驱动的方法,并对该标准提出“不间断采集”的改进思路,配合双URB、双帧缓冲等方法,提高采集速度。 关键词:Linux设备驱动 USB摄像头 Video for Linux 不间断采集 USB摄像头以其良好的性能和低廉的价格得到广泛应用。同时因其灵活、方便的特性,易于集成到嵌入式系统中。但是如果使用现有的符合Video for Linux标准的驱动程序配合通用应用程序,难以充分利用USB带宽,帧速不高,不易满足实时监控等要求。本文首先介绍在Linux系统下USB摄像头驱动编制的一般方法,然后说明在此基础上如何提高帧速。 1 Linux系统中
[应用]
嵌入式Linux操作系统的驱动程序开发要点
在Linux操作系统下有3类主要的设备文件类型:块设备、字符设备和网络设备。这种分类方法可以将控制输入/输出设备的驱动程序与其他操作系统软件分离开来。 字符设备与块设备的主要区别是:在对字符设备发出读/写请求时,实际的硬件I/O一般紧接着发生。块设备则不然,它利用一块系统内存作为缓冲区,若用户进程对设备的请求能满足用户的要求,就返回请求的数据;否则,就调用请求函数来进行实际的I/O操作。块设备主要是针对磁盘等慢速设备设计的,以免耗费过多的CPU时间用来等待。网络设备可以通过BSD套接口访问数据。 每个设备文件都有其文件属性(c/b),表示是字符设备还是块设备。另外每个文件都有2个设备号,第一个是主设备号,标识驱动程序;第二个是
[嵌入式]
S3C2440,Linux,LCD驱动
到了神秘的LCD驱动了,信息还真有点胆怯,但是还是不得不走下去。对刚刚学习的linux驱动坐一下总结,毕竟是Linux内核当中的东东,而且是那么的繁琐。做一总结,等用笔记把学过东西几下来,这样就不会忘了。哈哈! 那就开始!!! 在编写裸机LCD程序的时候,首先就是硬件初始化操作。有一个寄存器当中存放了帧缓冲的起始地址。这个参数是非常重要的。当配置好硬件后,帧缓冲中的数据能够脱离CPU不停地将真缓冲当中的数据写入到LCD屏。如果我们要现实一个图片的话只需要将图片数据放到帧缓冲当中,这样就非常的方便了。 在linux当中,把整个LCD驱动分为两层:LCD帧缓冲区层和LCD硬件驱动层。LCD帧缓冲区层其实就是将内核中的一部分空间当作一个
[单片机]
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved