/*****************************************************************

mini2440 LED设备驱动开发源代码:

*****************************************************************/

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/errno.h>
#include <linux/types.h>

//使用宋宝华推荐的普通字符设备框架
#include <linux/fcntl.h>
#include <linux/cdev.h>
#include <linux/version.h>
#include <linux/vmalloc.h>
#include <linux/ctype.h>
#include <linux/pagemap.h>

#include <linux/device.h>

#include <asm/io.h> 
//#include <asm/arch/regs-gpio.h>  //2.6.12
#include <mach/regs-gpio.h>    // 2.6.32

//LED1
#define LED1_OUT     __raw_writel(( __raw_readl(S3C2410_GPBCON) & (~(3<<10)))|(1<<10),S3C2410_GPBCON) //
#define LED1_H  __raw_writel(__raw_readl(S3C2410_GPBDAT)|(1<<5),S3C2410_GPBDAT)
#define LED1_L  __raw_writel(__raw_readl(S3C2410_GPBDAT)&(~(1<<5)),S3C2410_GPBDAT)

//LED2
#define LED2_OUT     __raw_writel(( __raw_readl(S3C2410_GPBCON) & (~(3<<12)))|(1<<12),S3C2410_GPBCON) //
#define LED2_H  __raw_writel(__raw_readl(S3C2410_GPBDAT)|(1<<6),S3C2410_GPBDAT)
#define LED2_L  __raw_writel(__raw_readl(S3C2410_GPBDAT)&(~(1<<6)),S3C2410_GPBDAT)

//LED3
#define  LED3_OUT     __raw_writel(( __raw_readl(S3C2410_GPBCON) & (~(3<<14)))|(1<<14),S3C2410_GPBCON) //
#define LED3_H  __raw_writel(__raw_readl(S3C2410_GPBDAT)|(1<<7),S3C2410_GPBDAT)
#define LED3_L  __raw_writel(__raw_readl(S3C2410_GPBDAT)&(~(1<<7)),S3C2410_GPBDAT)

//LED4
#define LED4_OUT     __raw_writel(( __raw_readl(S3C2410_GPBCON) & (~(3<<16)))|(1<<16),S3C2410_GPBCON) //
#define LED4_H  __raw_writel(__raw_readl(S3C2410_GPBDAT)|(1<<8),S3C2410_GPBDAT)
#define LED4_L  __raw_writel(__raw_readl(S3C2410_GPBDAT)&(~(1<<8)),S3C2410_GPBDAT)

#define  LEDOFF 0
#define  LEDON 1
//#define DEMO_MAJOR 235  //静态分配
#define DEMO_MAJOR 0 //动态分配
#define DEMO_MINOR 0

int devmajor =   DEMO_MAJOR;
int devminor =   DEMO_MINOR;
dev_t dev = 0;
//设备结构
//设备结构
struct DEMO_dev
{
 struct cdev cdev;   /* Char device structure*/
 
};

struct DEMO_dev *DEMO_devices;
struct class *led_class;

int DEMO_open(struct inode *inode, struct file *filp)
{
 struct DEMO_dev *demo_dev;
 unsigned int temp;

filp->private_data=DEMO_devices;
 //5
 //LED1_OUT; 
 temp=__raw_readl(S3C2410_GPBCON);  //__raw_readl函数在#include <asm/io.h>  定义
 temp &= (~(3<<10))|(1<<10);
 __raw_writel(temp,S3C2410_GPBCON);
 //printk("S3C2410_GPBCON=%x,S3C2410_GPBDAT=%x\n",S3C2410_GPBCON,S3C2410_GPBDAT);
     //S3C2410_GPBCON=fb000010,S3C2410_GPBDAT=fb000014

//6
 //LED2_OUT;
 temp=__raw_readl(S3C2410_GPBCON);
 temp &= (~(3<<12))|(1<<12);
 __raw_writel(temp,S3C2410_GPBCON);

//7
 // LED3_OUT;
 temp=__raw_readl(S3C2410_GPBCON);
 temp &= (~(3<<14))|(1<<14);
 __raw_writel(temp,S3C2410_GPBCON);

//8
 //LED4_OUT;
 temp=__raw_readl(S3C2410_GPBCON);
 temp &= (~(3<<16))|(1<<16);
 __raw_writel(temp,S3C2410_GPBCON);

return 0;
}
int DEMO_release(struct inode *inode, struct file *filp)
{
 
 return 0;
}
int DEMO_ioctl(struct inode *inode, struct file *filp,unsigned int cmd, unsigned long arg)
{
 unsigned int  temp;
 //printk("**********arg=%d**************\n",arg);
 switch(cmd)
 {
  case LEDOFF:
  {
   if(arg == 1)
   {
    //printk("ioctl LED1_OFF successfully\n");
    //LED1_H;
    temp=__raw_readl(S3C2410_GPBDAT);
    temp|=(1<<5);
    __raw_writel(temp,S3C2410_GPBDAT);
   }
   if(arg == 2)
   {
    //printk("ioctl LED2__OFF successfully\n");
    LED2_H;
   }
   if(arg == 3)
   {
    //printk("ioctl LED3_OFF successfully\n");
    LED3_H;
   }
   if(arg == 4)
   {
    //printk("ioctl LED4_OFF successfully\n");
    LED4_H;
   }
   return 0;
  }
  case LEDON:
  {
   
   if(arg == 1)
   {
    //printk("ioctl LED1_ON successfully\n");
    //LED1_L;
    temp=__raw_readl(S3C2410_GPBDAT);
    temp&=~(1<<5);
    __raw_writel(temp,S3C2410_GPBDAT);
   }
   if(arg == 2)
   {
    //printk("ioctl LED2_ON successfully\n");
    LED2_L;
   }
   if(arg == 3)
   {
    //printk("ioctl LED3_ON successfully\n");
    LED3_L;
   }
   if(arg == 4)
   {
    //printk("ioctl LED4_ON successfully\n");
    LED4_L;
   }
   return 0;
  }
  default:
    printk("ioctl error successfully\n");
  return -EFAULT;
 }
}

//也可以使用DEMO_write来替代DEMO_ioctl
ssize_t DEMO_write(struct file *filp, const char __user *buf, size_t count, loff_t *f_pos)
{

int cmd;
 int temp;
 if(copy_from_user(&cmd,buf,4))
 {
  printk("copy_from_user erro\n");
  return -EFAULT;
 }
   printk("cmd=%d\n",cmd);
 switch(cmd)
 {
  case LEDOFF:
  {
   //printk("ioctl LEDOFF successfully\n");
   //LED1_H;
   temp=__raw_readl(S3C2410_GPBDAT);
   temp|=(1<<5);
   __raw_writel(temp,S3C2410_GPBDAT);
   return 0;
  }
  case LEDON:
  {
   //printk("ioctl LEDON successfully\n");
   LED1_L;
   return 0;
  }
  default:
   // printk("ioctl error successfully\n");
  return -EFAULT;
  
 }
}

ssize_t DEMO_read(struct file *filp,char __user *buff,size_t size,loff_t *offp)
{
 int count;
 count = sizeof(int);
 int temp;
 int status;
 temp=__raw_readl(S3C2410_GPBDAT);
 if(temp&(1<<5)==0) 
    status=0;
 else
    status=1;  
 if (copy_to_user(buff, &status, count))
 {
  return -EFAULT;
 }
 return 0;
}

struct file_operations DEMO_fops = {
 .owner = THIS_MODULE,
 .ioctl = DEMO_ioctl,
 .open = DEMO_open,
 .write = DEMO_write,
 .read =  DEMO_read,
 .release=DEMO_release,
};

/*******************************************************
                MODULE ROUTINE
*******************************************************/

//卸载
void DEMO_cleanup_module(void)
{
 //dev_t devno = MKDEV(DEMO_MAJOR, DEMO_MINOR);

if (DEMO_devices)
 {
  cdev_del(&DEMO_devices->cdev);//5 从系统中移除一个字符设备
  kfree(DEMO_devices);
 }
 device_destroy(led_class, MKDEV(devmajor, 0));         //delete device node under /dev
 class_destroy(led_class);                               //delete class created by us
 unregister_chrdev_region(dev,1);// 6 释放设备编号
}
//挂载
int DEMO_init_module(void)
{
 int result;

if(devmajor)
 {
  dev = MKDEV(devmajor, devminor); // 1 获得设备号
  result = register_chrdev_region(dev, 1, "led"); // 2 分配设备编号
 }
 else
 {
  result = alloc_chrdev_region(&dev, devminor, 1, "led_driver");
 // //2  动态分配设备编号
  devmajor = MAJOR(dev);
 }
 if (result < 0)
 {
  printk(KERN_WARNING "scull: can't get major %d\n", devmajor);
  return result;
 }
 
 printk(KERN_WARNING "led get major: %d\n", devmajor);
 DEMO_devices = kmalloc(sizeof(struct DEMO_dev), GFP_KERNEL);//分配内存给本设备结构体

if (!DEMO_devices)
 {
  result = -ENOMEM;
  goto fail;
 }
 
 memset(DEMO_devices, 0, sizeof(struct DEMO_dev));

cdev_init(&DEMO_devices->cdev, &DEMO_fops);//(1)  // 字符设备的注册,即将结构嵌入到自己的设备中
 DEMO_devices->cdev.owner = THIS_MODULE;
 DEMO_devices->cdev.ops = &DEMO_fops; //(2)
 result = cdev_add (&DEMO_devices->cdev, dev, 1);// 4 把本设备放内核中
 if(result)
 {
  printk(KERN_NOTICE "Error %d adding DEMO\n", result);
  goto fail;
 }
  //创建节点方法2  使用函数自动创建  方法1是手动创建#mknod /dev/test c 235 0
// 下面方法2.6.32支持。2.6.18 2.6.12不支持

/* create your own class under /sysfs   2.6.32*/
   led_class = class_create(THIS_MODULE, "led_class");
   if(IS_ERR(led_class))
   {
     printk("Err: failed in creating class.\n");
     return -1;
    }
 
   /* register your own device in sysfs, and this will cause udev to create corresponding device node */
    device_create( led_class, NULL, MKDEV(devmajor, 0),  NULL, "led_driver");
 
 return 0;

fail:
 DEMO_cleanup_module(); //注销
 return result;
}

module_init(DEMO_init_module); //注册
module_exit(DEMO_cleanup_module); //注销
MODULE_AUTHOR("hui");
MODULE_LICENSE("GPL");

/*****************************************************************

mini2440 应用程序测试源代码:

*****************************************************************/

//#bash-2.05b# insmod led.ko
//Using led.ko
//#bash-2.05b# ./user
//#bash-2.05b# mknod /dev/led_su c 235 0

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#define MYLED "/dev/led_driver"

void Delay_MS( unsigned int time)  //50 ns
{
 unsigned int i,j;
 
 for ( i=0; i<time; i++)
 {
    for(j=0;j<30000;j++)
    {
   
    } 
   } 
}

int main(void)
{
 int fd,i=0;
 int cmd;
 int status;
 
       fd = open(MYLED,O_RDWR,0666);
 if (fd < 0)
 {
  perror("open device led_driver error\n");
  exit(1);
 }
 printf("open device led_driver success!\n");
 
 while(i<9)
 {
  
  ioctl(fd, 1, 1);
  ioctl(fd, 1, 2);
  ioctl(fd, 1, 3);
  ioctl(fd, 1, 4);
  //sleep(1);
  Delay_MS(200);
  ioctl(fd, 0, 1);
  ioctl(fd, 0, 2);
  ioctl(fd, 0, 3);
  ioctl(fd, 0, 4);
  i++;
  
 }
 
 close(fd);
 return 0;
}

mini2440 LED设备驱动开发源代码(宋宝华框架)相关推荐

  1. Linux下LED设备驱动开发(LED灯实现闪烁)

    文章目录 一.配置连接说明 二.更新设备树 (1)将led灯引脚添加到pinctrl子系统 (2)设备树中添加LDE灯的设备树节点 (3)编译更新设备树 三.驱动开发与测试 (1)编写设备驱动代码 ( ...

  2. linux内核led驱动开发,从Linux内核LED驱动来理解字符设备驱动开发流程

    目录 博客说明 开发环境 1. Linux字符设备驱动的组成 1.1 字符设备驱动模块加载与卸载函数 1.2 字符设备驱动的file_operations 结构体中的成员函数 2. 字符设备驱动--设 ...

  3. platform设备驱动全透析(转自宋宝华老师)

    platform设备驱动全透析(转自宋宝华老师) 2013-04-12 09:58 384人阅读 评论(0) 收藏 举报 分类: linux kernel(22) 1.1 platform总线.设备与 ...

  4. 宋宝华:Linux设备与驱动的手动解绑与手动绑定

    众所周知,Linux靠设备与驱动之间的match,来完成设备与驱动的bind,从而触发驱动的probe()成员函数被执行.每个bus都有相应的match方法,完成match的总的入口函数是: stat ...

  5. 《Linux设备驱动开发详解(第2版)》隆重出版

    Linux设备驱动开发详解(第2版)(前一版狂销3万册,畅销书最新升级) [新品] 点击看大图     基本信息 * 作者: 宋宝华       * 出版社:人民邮电出版社     * ISBN:97 ...

  6. 《Linux 设备驱动开发详解(第2版)》——1.4 Linux设备驱动

    本节书摘来自异步社区<Linux 设备驱动开发详解(第2版)>一书中的第1章,第1.1节,作者:宋宝华著,更多章节内容可以访问云栖社区"异步社区"公众号查看 1.4 L ...

  7. 《Linux设备驱动开发详解(第3版)》(即《Linux设备驱动开发详解:基于最新的Linux 4.0内核》)网购链接

    <Linux设备驱动开发详解:基于最新的Linux 4.0内核> china-pub   天猫     dangdang   京东 China-pub 8月新书销售榜 推荐序一 技术日新月 ...

  8. 《Linux设备驱动开发详解 A》一一2.3 接口与总线

    本节书摘来华章计算机出版社<Linux设备驱动开发详解 A>一书中的第2章,第2.3节,作者:宋宝华 更多章节内容可以访问云栖社区"华章计算机"公众号查看.1 2.3 ...

  9. Linux设备驱动开发概述

    作者:宋宝华 email:author@linuxdriver.cn 在过去这些年,Linux已经成功应用于服务器和桌面系统,而近年来,随着嵌入式系统应用的持续升温,Linux也开始广泛应用于嵌入式领 ...

  10. 宋宝华_2010年11-12月Linux驱动和内核讲座PPT下载

        12月29日,宋宝华老师在线讲座(按键和LCD驱动) cloudquan 2010-12-20 2/146 heyan0208 3 天前 00:37     宋宝华_2010年12月11日_& ...

最新文章

  1. linux 环境 安装jdk tomcat mysql git
  2. 51php绑定多个域名,设置Wordpress站点绑定多域名访问 - Mr.bin的博客
  3. python笔记:正则表达式
  4. C语言关于signal()函数
  5. 生物信息学搞计算机,生物信息学前景展望,谈谈感想(已经停止)
  6. 博客园看到的很好的Linux网络编程技巧(此处一字不动的转载过来)
  7. java全世界各国城市地址解析
  8. 2021年啤酒酿造行业发展研究报告
  9. SPSS时序全局主成分分析方法
  10. Android NDK 建立cocos2dx项目
  11. 沙普利算法java实现_Java实现婚姻稳定匹配Gale- Shapley算法
  12. <C语言程序实例>C语言实现菱形输出
  13. springboot+老年康复中心信息管理系统 毕业设计-附源码250859
  14. 多数据中心架构,异地多活架构
  15. iOS中打一个包上传后,iTunes中找不到上传的包的解决方法
  16. 明解C语言(入门篇)第二章
  17. Foobar 2000 EIKO 增强版 取消“最小化到托盘”设置
  18. html导航栏悬停过渡,JS 实现导航栏悬停效果
  19. NetXMS中文版用户手册部分翻译
  20. 开闭原则的例子_开闭原则

热门文章

  1. 硬件工程师实用工具网站
  2. mybatis基础入门
  3. 程序员教你不背单词学英语!流利英语一周成!!!
  4. QOS-CBWFQ\QOS-LLQ\QOS-PQ\QOS-CQ\QOS-WFQ
  5. pepe:从Pastebin收集邮件地址的信息
  6. LaTeX 文档类型
  7. 永远的Beyond, 永远的家驹
  8. mysql高速写数据_高永志---全国书画人才资料数据库
  9. 一个投标经理的标书检查笔记,拿来就用!
  10. 手机html保存工具,用手机保存任何网页视频:Pro Recorder 使用介绍