编写灯、风扇、蜂鸣器的驱动
阿里云国内75折 回扣 微信号:monov8 |
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6 |
.h头文件
#ifndef __LED_H__
#define __LED_H__
typedef struct led
{
volatile unsigned int model;
volatile unsigned int OTYPER;
volatile unsigned int OSPEEDR;
volatile unsigned int PUPDR;
volatile unsigned int IDR;
volatile unsigned int ODR;
}gpio_t;
#define RCC_ADDR 0x50000A28
#define GPIOE 0x50006000
#define GPIOF 0x50007000
#define GPIOZ 0x54004000
#define GPIOB 0x50003000 //b6 蜂鸣器
//f6 马达
#define RCC_MP_AHB5LPENSETR 0x50000290
enum LED_ID
{
LED1 = 1,
LED2,
LED3,
LED4,
LED5,
LED6,
BEEP1,
FAN1,
};
enum PLACE
{
MASTER,
SOLVE,
};
enum DRVICE
{
LED,
BEEP,
FAN,
};
#define LED_ON _IOW('a',1,int)
#define LED_OFF _IOW('a',0,int)
#endif
驱动函数
#include <linux/init.h>
#include <linux/module.h>
#include <linux/device.h>
#include <linux/fs.h>
#include <linux/err.h>
#include <linux/wait.h>
#include <linux/sched.h>
#include <linux/smp.h>
#include<linux/io.h>
#include<linux/delay.h>
#include<linux/string.h>
#include"led.h"
gpio_t *vir_gpioe;
gpio_t *vir_gpiof;
gpio_t *vir_gpioz;
gpio_t *vir_gpiob;
unsigned int *vir_rcc;
unsigned int *vir_RCC_MP_AHB5LPENSETR;
int major;
struct class *cls;
int chrdev_open(struct inode *inode,struct file *file)
{
return 0;
}
ssize_t chrdev_write (struct file *fd, const char __user *user, size_t count, loff_t *off)
{
return 0;
}
int chrdev_release (struct inode *node, struct file *fd)
{
return 0;
}
void func(int cmd,int arg)
{
if(cmd == LED_ON)
switch(arg)
{
case LED1:
vir_gpioe->ODR |= 1<<10;
break;
case LED2:
vir_gpiof->ODR |= 1<<10;
break;
case LED3:
vir_gpioe->ODR |= 1<<8;
break;
case LED4:
vir_gpioz->ODR |= 1<<5;
break;
case LED5:
vir_gpioz->ODR |= 1<<6;
break;
case LED6:
vir_gpioz->ODR |= 1<<7;
break;
case BEEP1:
vir_gpiob->ODR |= 1<<6;
break;
case FAN1:
vir_gpiof->ODR |= 1<<6;
}
else
switch(arg)
{
case LED1:
vir_gpioe->ODR &= ~(1<<10);
break;
case LED2:
vir_gpiof->ODR &= ~(1<<10);
break;
case LED3:
vir_gpioe->ODR &= ~(1<<8);
break;
case LED4:
vir_gpioz->ODR &= ~(1<<5);
break;
case LED5:
vir_gpioz->ODR &= ~(1<<6);
break;
case LED6:
vir_gpioz->ODR &= ~(1<<7);
break;
case BEEP1:
vir_gpiob->ODR &= ~(1<<6);
break;
case FAN1:
vir_gpiof->ODR &= ~(1<<6);
break;
}
printk("cmd = %d choice = %d\r\n",cmd,arg);
}
long chrdev_ioctl (struct file *file, unsigned int cmd, unsigned long arg)
{
int whitch,ret;
switch(cmd)
{
case LED_ON:
ret = copy_from_user(&whitch,(void *)arg,sizeof(int));
printk("whitch = %d\r\n",whitch);
if (ret)
{
printk("copy_from_user failed!\r\n");
return -1;
}
func(cmd,whitch);
break;
case LED_OFF:
ret = copy_from_user(&whitch,(void *)arg,sizeof(int));
printk("whitch = %d\r\n",whitch);
if (ret)
{
printk("copy_from_user failed!\r\n");
return -1;
}
func(cmd,whitch);
break;
}
return 0;
}
struct file_operations ledchrdev_fops =
{
.open = chrdev_open,
.release = chrdev_release,
.write = chrdev_write,
.unlocked_ioctl = chrdev_ioctl,
};
static void led_init(void)
{
//扩展板led灯初始化
//led1初始化
vir_gpioz = ioremap(GPIOZ,sizeof(gpio_t));
vir_RCC_MP_AHB5LPENSETR = ioremap(RCC_MP_AHB5LPENSETR,4);
vir_gpioz->model &= ~(3<<10);
vir_gpioz->model |= 1<<10;
vir_gpioz->ODR |= 1<<5;
vir_gpioz->model &= ~(3<<12);
vir_gpioz->model |= 1<<12;
vir_gpioz->ODR |= 1<<6;
vir_gpioz->model &= ~(3<<14);
vir_gpioz->model |= 1<<14;
vir_gpioz->ODR |= 1<<7;
printk("扩展板LED初始化\r\n");
vir_gpioe = ioremap(0x50006000,4);
vir_rcc = ioremap(0x50000A28,4);
*vir_rcc |= (3<<4);
*vir_rcc |= 1<<1;
vir_gpioe->model &= (~(3<<20));
vir_gpioe->model |= (1<<20);
vir_gpioe->ODR |= (1<<10);
printk("led1_init success!\r\n");
//led2初始化
vir_gpiof = ioremap(0x50007000,4);
vir_gpiof->model &= (~(3<<20));
vir_gpiof->model |= (1<<20);
vir_gpiof->ODR |= (1<<10);
printk("led2_init success!\r\n");
//led3初始化
vir_gpioe->model &= (~(3<<16));
vir_gpioe->model |= (1<<16);
vir_gpioe->ODR |= (1<<8);
printk("led3_init success!\r\n");
vir_gpiob = ioremap(GPIOB,4);
vir_gpiob->model &= ~(0x3<<12);
vir_gpiob->model |= (1<<12);
vir_gpiof->model &= ~(0x3<<12);
vir_gpiof->model |= (0x1<<12);
}
int __init ioctldev_init(void)
{
int i = 0;
major = register_chrdev(0,"ioctldev",&ledchrdev_fops);
if(major < 0)
{
printk("register_chrdev failed!\r\n");
return major;
}
led_init();
cls = class_create(THIS_MODULE,"LED");
if(IS_ERR(cls))
{
printk("创建结点目录失败\r\n");
return IS_ERR_VALUE(cls);
}
printk("创建结点目录成功\r\n");
for(i=0;i<3;i++)
{
//向上提交设备节点
device_create(cls,NULL,MKDEV(major,i),NULL,"myled%d",i);
printk("创建节点myled%d成功\r\n",i);
}
printk("major = %d\r\n",major);
printk("ledchrdev init\r\n");
return 0;
}
void __exit ioctldev_exit(void)
{
int i = 0;
iounmap(vir_gpioe);
iounmap(vir_gpiof);
iounmap(vir_rcc);
iounmap(vir_gpioz);
iounmap(vir_RCC_MP_AHB5LPENSETR);
for(i = 0;i<3;i++)
{
device_destroy(cls,MKDEV(major,i));
printk("销毁节点myled%d成功\r\n",i);
}
class_destroy(cls);
printk("销毁节点目录成功\r\n");
unregister_chrdev(major,"ioctldev");
printk("ledchrdev exit\r\n");
}
module_init(ioctldev_init);
module_exit(ioctldev_exit);
MODULE_LICENSE("GPL");
测试代码
#include<stdio.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<unistd.h>
#include<string.h>
#include<stdlib.h>
#include<sys/ioctl.h>
#include"led.h"
int main()
{
int device;
int place;
int choice;
int pin;
int fd = open("/dev/myled0",O_RDWR);
if(fd < 0)
{
printf("open failed!]n");
return -1;
}
while(1)
{
printf("请输入您想操作的设备1LED1 2 LED2 3 LED3 4 LED4 5 LED5 5 LED6 7马达 8蜂鸣器>>>");
scanf("%d",&device);
switch (device)
{
case LED1:
printf("请输入状态 1 0\n");
scanf("%d",&choice);
if(choice)
ioctl(fd,LED_ON,&device);
else
ioctl(fd,LED_OFF,&device);
break;
case LED2:
printf("请输入状态 1 0\n");
scanf("%d",&choice);
if(choice)
ioctl(fd,LED_ON,&device);
else
ioctl(fd,LED_OFF,&device);
break;
case LED3:
printf("请输入状态 1 0\n");
scanf("%d",&choice);
if(choice)
ioctl(fd,LED_ON,&device);
else
ioctl(fd,LED_OFF,&device);
break;
case LED4:
printf("请输入状态 1 0\n");
scanf("%d",&choice);
if(choice)
ioctl(fd,LED_ON,&device);
else
ioctl(fd,LED_OFF,&device);
break;
case LED5:
printf("请输入状态 1 0\n");
scanf("%d",&choice);
if(choice)
ioctl(fd,LED_ON,&device);
else
ioctl(fd,LED_OFF,&device);
break;
case LED6:
printf("请输入状态 1 0\n");
scanf("%d",&choice);
if(choice)
ioctl(fd,LED_ON,&device);
else
ioctl(fd,LED_OFF,&device);
break;
case BEEP1:
printf("请输入状态 1 0\n");
scanf("%d",&choice);
if(choice)
ioctl(fd,LED_ON,&device);
else
ioctl(fd,LED_OFF,&device);
break;
case FAN1:
printf("请输入状态 1 0\n");
scanf("%d",&choice);
if(choice)
ioctl(fd,LED_ON,&device);
else
ioctl(fd,LED_OFF,&device);
break;
default:
printf("输入错误请重新输入0 1 2\n");
break;
}
}
}