s3c2440上的LED灯的驱动程序

硬件平台: OK2440-III

系统平台:linux-2.6.12

软件环境:vim


/*************************************************************************
    > File Name: led.c
    > Author: dongzhihong
    > Mail: hnaydzh@gmail.com 
    > Created Time: 2012年12月01日 星期六 10时32分53秒
 ************************************************************************/


#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/interrupt.h>
#include <linux/devfs_fs_kernel.h>
#include <linux/delay.h>
#include <linux/mm.h>
#include <linux/ioport.h>
#include <linux/cdev.h>
#include <linux/ioport.h>
#include <linux/fs.h>


#include <asm/io.h>
#include <asm/irq.h>
#include <asm/uaccess.h>
#include <asm/arch-s3c2410/regs-gpio.h>
#include <asm/arch-s3c2410/hardware.h>






#define LED_MAJOR 115
#define DEVICE_NAME  "led_dev"
#define SUCCESS   0
#define LED_ON     _IO('g', 33)//6721
#define LED_OFF    _IO('g', 34)//6722


static int Device_Open = 0;
unsigned long gpf_con,gpf_dat;


int led_init(void);
void led_cleanup(void);
static int device_open(struct inode *,struct file *);
static int device_release(struct inode *,struct file *);
static int device_ioctl(struct inode * fnode, struct file* filp, unsigned int cmd,unsigned long param);
static int Major;


struct file_operations  led_ops =
{
        owner :     THIS_MODULE,
        open:       device_open,
        ioctl:      device_ioctl,
        release:    device_release,
};


struct cdev led_cdev;


int led_init(void)
{
int err;
    dev_t devnum = MKDEV(LED_MAJOR,0);
    gpf_con  =    (unsigned long)ioremap(0x56000050,4); 
    gpf_dat =    (unsigned long)ioremap(0x56000054,4);


    *(unsigned long *)gpf_con  &= ~(0xff<<6);   
    *(unsigned long *)gpf_con  |= 0x1540;   
// 注册设备号
#if 0
    Major = register_chrdev_region(devnum,1,DEVICE_NAME);

#endif 
Major = register_chrdev(LED_MAJOR,DEVICE_NAME,&led_ops);
    if(Major <0) 
    {
        printk("key init_module:failed with %d\n",Major);    //涓昏澶囧彿灏忎簬0锛屽垯娉ㄥ唽澶辫触
        return Major;
    }
    Major = LED_MAJOR;
#if 0 
//注册完设备号,该向内核添加设备了
    cdev_init (&led_cdev , &led_ops);//初始化设备
    led_cdev.owner = THIS_MODULE;  //表示谁拥有这个驱动程序
    led_cdev.ops = &led_ops;
    err = cdev_add(&led_cdev , devnum, 1);//对于已经知道类设备号,就用cdev_add()来添加设备
      /**
  * 由此可见,使用register_chrdev_region()比使用register_chrdev()多了一步,
  * 就是向内核注册添加设备的步骤
  * */ 
    if (err) printk("Key init Error %d\n", err);
#endif
    printk("LED_MAJOR registred: Major = %d\n",Major);
    devfs_mk_cdev(MKDEV(LED_MAJOR, 0), S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP, DEVICE_NAME);


    return 0;
}




static int device_ioctl(struct inode * fnode, struct file* filp, unsigned int cmd,unsigned long param)
{
    switch (cmd)
    {
        case LED_ON:
            *(unsigned long *)gpf_dat &= ~(0xf<<3);         
            break;      
        case LED_OFF:
            *(unsigned long *)gpf_dat |= 0xf<<3;          
            break;  
        default:
            return -EINVAL; 
        }   
    return SUCCESS;
}




static int device_open(struct inode * inode,struct file *file)
{
        if(Device_Open)
        {
            return -EBUSY;
        }
        Device_Open++;


    return SUCCESS;
}


static int device_release(struct inode * inode,struct file *file)
{
    Device_Open --;
    return 0;
}


void led_cleanup(void)
{


    unregister_chrdev_region(MKDEV(LED_MAJOR,0),1);
    devfs_remove(DEVICE_NAME);
    printk(DEVICE_NAME" delete cdev\n");
}


module_init(led_init);
module_exit(led_cleanup);
MODULE_AUTHOR("dzh");
MODULE_LICENSE("GPL");


一下附上测试程序


/*************************************************************************
    > File Name: ledtest.c
    > Author: dongzhihong
    > Mail: hnaydzh@gmail.com 
    > Created Time: 2012年12月01日 星期六 13时56分23秒
 ************************************************************************/


#include<stdio.h>
#include<sys/types.h>
#include<sys/ioctl.h>
#include<stdlib.h>
#include<termios.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<sys/time.h>
#define LED_ON  0x6721
#define LED_OFF 0x6722
int main(void)
{
char str;
int fd = open("/dev/led_dev",O_RDWR);
if(fd < 0)
{
printf("can't open device");
return 0;
}
printf("*********************************************************************\n");
printf("**                  LED TEST  BEGIN                                **\n");  
printf("**     Please input N (to open led)or F(to getoff led)             **\n");
printf("**                  Input E to exit LED Test                       **\n");
printf("*********************************************************************\n");
while(1){
printf("Enter:");
scanf("%c",&str);
if(str == 'N'){
ioctl(fd,LED_ON);
}
else if(str == 'F')
{
ioctl(fd,LED_OFF);
}
else if(str == 'E')
{
break;
}
}
return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值