⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sc2410_led_test1.c

📁 一个入门的linux的IO驱动,非常详细的注释,一看就会
💻 C
字号:
#include<linux/config.h>
#include<linux/module.h>
#include<linux/kernel.h>
#include<linux/init.h>

#include<linux/miscdevice.h>
#include<linux/sched.h>
#include<linux/delay.h>
#include<linux/poll.h>
#include<linux/spinlock.h>
#include<linux/irq.h>

#include<asm/hardware.h>

#define DEVICE_NAME "leds"  //定义led设备名
#define LED_MAJOR   333     //定义led设备的主设备号

static unsigned long led_table[]= //IO方式led对应的硬件资源
{
  GPIO_B5,    //定义4个IO口
  GPIO_B6,
  GPIO_B7,
  GPIO_B8
};

//  通过系统调用ioctl和输入的参数控制led
//  ioctl(fd,on,led_no);
//下方这个程序中 指针file是设备文件句柄
//其中,第一个inode指针是驱动程序自动给定的
static int sc2410_led_ioctl(struct inode * inode,struct file *file,unsigned int cmd, unsigned long arg) //led控制函数
{
  switch(cmd)   //输入的命令
  {
    case 0:
    case 1:
      if(arg>4)
      {
        return -EINVAL;
      }
      write_gpio_bit(led_table[arg],!cmd);
     default:
     return -EINVAL;
  }
}

static struct file_operations sc2410_led_fops=
{
  owner:  THIS_MODULE,        //fops所属的设备模块
  ioctl:  sc_2410_led_ioctl,  //指向“拥有”该结构的模块的指针,内核使用该指针维护模块的使用计数
};

static devfs_handle_t devfs_handle;

static int __init sc2410_led_init(void) //模块方式驱动程序加载
{
  int ret;
  int i;
  
  ret=register_chrdev(LED_MAJOR,DEVICE_NAME,&sc2410_led_fops);    //注册设备
  if(ret<0)
  {
    printk(DEVICE_NAME"can't register major number\n");
    return ret;
  }
  devfs_handle=devfs_register(NULL,DEVICE_NAME,DEVFS_FL_DEFAULT,LED_MAJOR,0,S_IFCHR|S_IRUSR|S_IWUSR,&sc2410_led_fops,NULL); //向VFS注册统一的设备操作函数
  for(i=0;i<8;i++)
  {
    set_gpio_ctrl(led_table[i]|GPIO_PULLUP_EN|GPIO_MODE_OUT);     //规定为上拉,输出端口
    write_gpio_bit(led_table[i],i);                               //向led_table[i]写数据
  }
  printk(DEVICE_NAME " initialized\n");
  return 0;
}

static void __exit sc2410_led_exit(void)  //模块方式驱动程序卸载
{
  devfs_unrgister(devfs_handle);              //反注册设备
  unregister_chrdev(LED_MAJOR,DEVICE_NAME);   //卸载设备
}

module_init(sc2410_led_init); //加载驱动程序模块入口
module_exit(sc2410_led_exit); //卸载驱动程序模块入口



/********************调用方式***********************/


#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<sys/ioctl.h>

int main(int argc,char **argv)
{
  int on;
  int led_no;
  int fd;
  
  //检查led控制的两个参数,如果没有传入就退出
  if(argc!=3||sscanf(argv[1],"%d",&led_no)!=1||sscanf(argv[2],"%d",&on)!=1)||on<0||on>1||led_no<0||led_no>3)
  {
    fprintf(stderr,"Usage:leds led_no 0|1\n");  //提示错误
    exit(1);
  }
  //打开/dev/leds设备文件
  fd=open("/dev/leds",0);
  if(fd<0)
  {
    perror("open device leds err");
    exit(1);  
  }
  //通过系统调用ioctl和输入的参数控制led
  ioctl(fd,on,led_no);
  //关闭设备句柄
  close(fd);
  return 0;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -