1.h
#ifndef __HEAD_H__
#define __HEAD_H__
//PE10
#define PHY_LED1_MODER 0x50006000
#define PHY_LED1_ODR 0x50006014
#define PHY_LED1_RCC 0x50000A28
//pf10
#define PHY_LED2_MODER 0x50007000
#define PHY_LED2_ODR 0x50007014
#define PHY_LED2_RCC 0x50000A28
//PE8
#define PHY_LED3_MODER 0x50006000
#define PHY_LED3_ODR 0x50006014
#define PHY_LED3_RCC 0x50000A28
//蜂鸣器PB6---TIM4_CH1
#define RCC_MP_AHB4ENSETR 0x50000A28
#define PHY_BEEP_MODER 0x50003000
#define PHY_BEEP_ODR 0x50003014
//风扇PE9--->TIM1_CH1
#define RCC_MP_AHB4ENSETR 0x50000A28
#define PHY_FAN_MODER 0x50006000
#define PHY_FAN_ODR 0x50006014
//马达PF6--->TIM6_CH1
#define RCC_MP_AHB4ENSETR 0x50000A28
#define PHY_MOTOR_MODER 0x50007000
#define PHY_MOTOR_ODR 0x50007014
//功能码
//LED灯
#define LED_ON _IOW('l',1,int)
#define LED_OFF _IOW('l',0,int)
//蜂鸣器
#define BEEP_ON _IO('f',1)
#define BEEP_OFF _IO('f',0)
//风扇
#define FAN_ON _IO('s',1)
#define FAN_OFF _IO('s',0)
//马达
#define MOTOR_ON _IO('m',1)
#define MOTOR_OFF _IO('m',0)
#endif
test.c
#include
#include
#include
#include
#include
#include
#include
#include
#include "1.h"
int main(int argc, char const *argv[])
{
int a, b, c;
char buf[128] = {0};
int fd = open("/dev/myled0", O_RDWR);
if (fd < 0)
{
printf("打开设备文件LED失败\n");
exit(-1);
}
int fd1 = open("/dev/mybeep", O_RDWR);
if (fd1 < 0)
{
printf("打开设备文件beep失败\n");
exit(-1);
}
int fd2 = open("/dev/myfan", O_RDWR);
if (fd2 < 0)
{
printf("打开设备文件fan失败\n");
exit(-1);
}
int fd3 = open("/dev/mymotor", O_RDWR);
if (fd3 < 0)
{
printf("打开设备文件motor失败\n");
exit(-1);
}
while (1)
{
// 从终端读取
printf("请输入要控制的/灯1/蜂鸣器2/风扇3/马达4/ >>>");
scanf("%d", &c);
printf("!!!提示1(启动)0(关闭)\n");
printf("please input 1 or 0 >>");
scanf("%d", &a);
switch (c)
{
case 1:
switch (a)
{
case 1:
printf("请输入开哪个灯1(LED1) 2(LED2) 3(LED3)>>");
scanf("%d", &b);
ioctl(fd, LED_ON, b); // 开灯
break;
case 0:
ioctl(fd, LED_OFF, b); // 关灯
break;
}
break;
case 2:
switch (a)
{
case 1:
ioctl(fd1, BEEP_ON); // 开蜂鸣器
break;
case 0:
ioctl(fd1, BEEP_OFF); // 关蜂鸣器
break;
}
break;
case 3:
switch (a)
{
case 1:
ioctl(fd2, FAN_ON); // 开风扇
break;
case 0:
ioctl(fd2, FAN_OFF); // 关风扇
break;
}
break;
case 4:
switch (a)
{
case 1:
ioctl(fd3, MOTOR_ON); // 开马达
break;
case 0:
ioctl(fd3, MOTOR_OFF); // 关马达
break;
}
break;
}
close(fd);
close(fd1);
close(fd2);
close(fd3);
return 0;
}
}
mychrdev.c ---led
#include
#include
#include
#include
#include
#include "1.h"
char kbuf[128] = {0};
unsigned int major; // 定义一个变量保存主设备号
unsigned int *vir_moder;
unsigned int *vir_odr;
unsigned int *vir_rcc;
unsigned int *vir2_moder;
unsigned int *vir2_odr;
unsigned int *vir2_rcc;
unsigned int *vir3_moder;
unsigned int *vir3_odr;
unsigned int *vir3_rcc;
struct class *cls;
struct device *dev;
int mycdev_open(struct inode *inode, struct file *file)
{
printk("%s : %s : %d\n", __FILE__, __func__, __LINE__);
return 0;
}
long mydev_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
switch (cmd)
{
case LED_ON:
switch (arg)
{
case 1:
*vir_odr |= (0x1 << 10); // led1开灯
break;
case 2:
*vir2_odr |= (0x1 << 10); // led2开灯
break;
case 3:
*vir3_odr |= (0x1 << 8); // led3开灯
break;
}
break;
case LED_OFF:
switch (arg)
{
case 1:
*vir_odr &= (~(0x1 << 10));
break;
case 2:
*vir2_odr &= (~(0x1 << 10));
break;
case 3:
*vir3_odr &= (~(0x1 << 8));
break;
}
break;
}
return 0;
}
int mycdev_close(struct inode *inode, struct file *file)
{
printk("%s : %s : %d\n", __FILE__, __func__, __LINE__);
return 0;
}
struct file_operations fops =
{
.open = mycdev_open,
.release = mycdev_close,
.unlocked_ioctl = mydev_ioctl,
};
static int __init mydev_init(void)
{
major = register_chrdev(0, "mychrdev", &fops);
if (major < 0)
{
printk("注册字符设备驱动失败\n");
return major;
}
printk("注册字符设备驱动文件成功major = %d\n", major);
// 向上提交目录
int i;
cls = class_create(THIS_MODULE, "myled");
if (IS_ERR(cls))
{
printk("向上提交目录失败\n");
return -PTR_ERR(cls);
}
printk("向上提交目录成功\n");
// 向上提交设备节点信息
for (i = 0; i < 3; i++)
{
dev = device_create(cls, NULL, MKDEV(major, i), NULL, "myled%d", i);
if (IS_ERR(dev))
{
printk("向上提交节点信息失败\n");
return -PTR_ERR(dev);
}
}
printk("向上提交设备节点成功\n");
// 进行LED1寄存器地址的映射
vir_moder = ioremap(PHY_LED1_MODER, 4);
if (vir_moder == NULL)
{
printk("映射物理内存失败%d\n", __LINE__);
return -EFAULT;
}
vir_odr = ioremap(PHY_LED1_ODR, 4);
if (vir_odr == NULL)
{
printk("映射物理内存失败%d\n", __LINE__);
return -EFAULT;
}
vir_rcc = ioremap(PHY_LED1_RCC, 4);
if (vir_rcc == NULL)
{
printk("映射物理内存失败%d\n", __LINE__);
return -EFAULT;
}
printk("映射物理内存成功\n");
// 硬件LED1寄存器初始化
(*vir_rcc) |= (0x1 << 4);
(*vir_moder) &= (~(0x3 << 20));
(*vir_moder) |= (0x1 << 20);
(*vir_odr) &= (~(0x1 << 10));
printk("硬件初始化成功\n");
// 进行LED2寄存器地址的映射
vir2_moder = ioremap(PHY_LED2_MODER, 4);
if (vir2_moder == NULL)
{
printk("映射物理内存失败%d\n", __LINE__);
return -EFAULT;
}
vir2_odr = ioremap(PHY_LED2_ODR, 4);
if (vir2_odr == NULL)
{
printk("映射物理内存失败%d\n", __LINE__);
return -EFAULT;
}
vir2_rcc = ioremap(PHY_LED2_RCC, 4);
if (vir2_rcc == NULL)
{
printk("映射物理内存失败%d\n", __LINE__);
return -EFAULT;
}
printk("映射物理内存成功\n");
// 硬件LED2寄存器初始化
(*vir2_rcc) |= (0x1 << 5);
(*vir2_moder) &= (~(0x3 << 20));
(*vir2_moder) |= (0x1 << 20);
(*vir2_odr) &= (~(0x1 << 10));
printk("硬件初始化成功\n");
// 进行LED3寄存器地址的映射
vir3_moder = ioremap(PHY_LED3_MODER, 4);
if (vir3_moder == NULL)
{
printk("映射物理内存失败%d\n", __LINE__);
return -EFAULT;
}
vir3_odr = ioremap(PHY_LED3_ODR, 4);
if (vir3_odr == NULL)
{
printk("映射物理内存失败%d\n", __LINE__);
return -EFAULT;
}
vir3_rcc = ioremap(PHY_LED3_RCC, 4);
if (vir3_rcc == NULL)
{
printk("映射物理内存失败%d\n", __LINE__);
return -EFAULT;
}
printk("映射物理内存成功\n");
// 硬件LED3寄存器初始化
(*vir3_rcc) |= (0x1 << 4);
(*vir3_moder) &= (~(0x3 << 16));
(*vir3_moder) |= (0x1 << 16);
(*vir3_odr) &= (~(0x1 << 8));
printk("硬件初始化成功\n");
return 0;
}
static void __exit mycdev_exit(void)
{
// 取消地址映射
iounmap(vir_moder);
iounmap(vir_odr);
iounmap(vir_rcc);
iounmap(vir2_moder);
iounmap(vir2_odr);
iounmap(vir2_rcc);
iounmap(vir3_moder);
iounmap(vir3_odr);
iounmap(vir3_rcc);
// 销毁节点信息
int i;
for (i = 0; i < 3; i++)
{
device_destroy(cls, MKDEV(major, i));
}
// 销毁目录信息
class_destroy(cls);
// 注销字符设备驱动
unregister_chrdev(major, "mychrdev");
}
module_init(mydev_init);
module_exit(mycdev_exit);
MODULE_LICENSE("GPL");
mychrdev1.c---beep
#include
#include
#include
#include
#include
#include "1.h"
char kbuf[128] = {0};
unsigned int major; // 定义一个变量保存主设备号
unsigned int *vir_moder;
unsigned int *vir_odr;
unsigned int *vir_rcc;
struct class *cls;
struct device *dev;
int mycdev_open(struct inode *inode, struct file *file)
{
printk("%s : %s : %d\n", __FILE__, __func__, __LINE__);
return 0;
}
long mydev_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
switch (cmd)
{
case BEEP_ON:
*vir_odr |= (0x1 << 6); // 开蜂鸣器
break;
case BEEP_OFF:
*vir_odr &= (~(0x1 << 6)); // 关蜂鸣器
break;
}
return 0;
}
int mycdev_close(struct inode *inode, struct file *file)
{
printk("%s : %s : %d\n", __FILE__, __func__, __LINE__);
return 0;
}
struct file_operations fops =
{
.open = mycdev_open,
.release = mycdev_close,
.unlocked_ioctl = mydev_ioctl,
};
static int __init mydev_init(void)
{
major = register_chrdev(0, "mychrdev1", &fops);
if (major < 0)
{
printk("注册字符设备驱动失败\n");
return major;
}
printk("注册字符设备驱动文件成功major = %d\n", major);
// 向上提交目录
cls = class_create(THIS_MODULE, "mybeep");
if (IS_ERR(cls))
{
printk("向上提交目录失败\n");
return -PTR_ERR(cls);
}
printk("向上提交目录成功\n");
// 向上提交设备节点信息
dev = device_create(cls, NULL, MKDEV(major, 0), NULL, "mybeep");
if (IS_ERR(dev))
{
printk("向上提交节点信息失败\n");
return -PTR_ERR(dev);
}
printk("向上提交设备节点成功\n");
// 进行蜂鸣器寄存器地址的映射
vir_moder = ioremap(PHY_BEEP_MODER, 4);
if (vir_moder == NULL)
{
printk("映射物理内存失败%d\n", __LINE__);
return -EFAULT;
}
vir_odr = ioremap(PHY_BEEP_ODR, 4);
if (vir_odr == NULL)
{
printk("映射物理内存失败%d\n", __LINE__);
return -EFAULT;
}
vir_rcc = ioremap(RCC_MP_AHB4ENSETR, 4);
if (vir_rcc == NULL)
{
printk("映射物理内存失败%d\n", __LINE__);
return -EFAULT;
}
printk("映射物理内存成功\n");
// 硬件蜂鸣器寄存器初始化
(*vir_rcc) |= (0x1 << 1);
(*vir_moder) &= (~(0x3 << 12));
(*vir_moder) |= (0x1 << 12);
(*vir_odr) &= (~(0x1 << 6));
printk("硬件初始化成功\n");
return 0;
}
static void __exit mycdev_exit(void)
{
// 取消地址映射
iounmap(vir_moder);
iounmap(vir_odr);
iounmap(vir_rcc);
// 销毁节点信息
device_destroy(cls, MKDEV(major, 0));
// 销毁目录信息
class_destroy(cls);
// 注销字符设备驱动
unregister_chrdev(major, "mychrdev1");
}
module_init(mydev_init);
module_exit(mycdev_exit);
MODULE_LICENSE("GPL");
mychrdevfan.c ---fan
#include
#include
#include
#include
#include
#include "1.h"
char kbuf[128] = {0};
unsigned int major; // 定义一个变量保存主设备号
unsigned int *vir_moder;
unsigned int *vir_odr;
unsigned int *vir_rcc;
struct class *cls;
struct device *dev;
int mycdev_open(struct inode *inode, struct file *file)
{
printk("%s : %s : %d\n", __FILE__, __func__, __LINE__);
return 0;
}
long mydev_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
switch (cmd)
{
case FAN_ON:
*vir_odr |= (0x1 << 9); // 开风扇
break;
case FAN_OFF:
*vir_odr &= (~(0x1 << 9)); // 关风扇
break;
}
return 0;
}
int mycdev_close(struct inode *inode, struct file *file)
{
printk("%s : %s : %d\n", __FILE__, __func__, __LINE__);
return 0;
}
struct file_operations fops =
{
.open = mycdev_open,
.release = mycdev_close,
.unlocked_ioctl = mydev_ioctl,
};
static int __init mydev_init(void)
{
major = register_chrdev(0, "mychrdevfan", &fops);
if (major < 0)
{
printk("注册字符设备驱动失败\n");
return major;
}
printk("注册字符设备驱动文件成功major = %d\n", major);
// 向上提交目录
cls = class_create(THIS_MODULE, "myfan");
if (IS_ERR(cls))
{
printk("向上提交目录失败\n");
return -PTR_ERR(cls);
}
printk("向上提交目录成功\n");
// 向上提交设备节点信息
dev = device_create(cls, NULL, MKDEV(major, 0), NULL, "myfan");
if (IS_ERR(dev))
{
printk("向上提交节点信息失败\n");
return -PTR_ERR(dev);
}
printk("向上提交设备节点成功\n");
// 进行蜂鸣器寄存器地址的映射
vir_moder = ioremap(PHY_FAN_MODER, 4);
if (vir_moder == NULL)
{
printk("映射物理内存失败%d\n", __LINE__);
return -EFAULT;
}
vir_odr = ioremap(PHY_FAN_ODR, 4);
if (vir_odr == NULL)
{
printk("映射物理内存失败%d\n", __LINE__);
return -EFAULT;
}
vir_rcc = ioremap(RCC_MP_AHB4ENSETR, 4);
if (vir_rcc == NULL)
{
printk("映射物理内存失败%d\n", __LINE__);
return -EFAULT;
}
printk("映射物理内存成功\n");
// 硬件风扇寄存器初始化
(*vir_rcc) |= (0x1 << 4);
(*vir_moder) &= (~(0x3 << 18));
(*vir_moder) |= (0x1 << 18);
(*vir_odr) &= (~(0x1 << 9));
printk("硬件初始化成功\n");
return 0;
}
static void __exit mycdev_exit(void)
{
// 取消地址映射
iounmap(vir_moder);
iounmap(vir_odr);
iounmap(vir_rcc);
// 销毁节点信息
device_destroy(cls, MKDEV(major, 0));
// 销毁目录信息
class_destroy(cls);
// 注销字符设备驱动
unregister_chrdev(major, "mychrdevfan");
}
module_init(mydev_init);
module_exit(mycdev_exit);
MODULE_LICENSE("GPL");
mychrdevmotor.c---motor
#include
#include
#include
#include
#include
#include "1.h"
char kbuf[128] = {0};
unsigned int major; // 定义一个变量保存主设备号
unsigned int *vir_moder;
unsigned int *vir_odr;
unsigned int *vir_rcc;
struct class *cls;
struct device *dev;
int mycdev_open(struct inode *inode, struct file *file)
{
printk("%s : %s : %d\n", __FILE__, __func__, __LINE__);
return 0;
}
long mydev_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
switch (cmd)
{
case MOTOR_ON:
*vir_odr |= (0x1 << 6); // 开马达
break;
case MOTOR_OFF:
*vir_odr &= (~(0x1 << 6)); // 关马达
break;
}
return 0;
}
int mycdev_close(struct inode *inode, struct file *file)
{
printk("%s : %s : %d\n", __FILE__, __func__, __LINE__);
return 0;
}
struct file_operations fops =
{
.open = mycdev_open,
.release = mycdev_close,
.unlocked_ioctl = mydev_ioctl,
};
static int __init mydev_init(void)
{
major = register_chrdev(0, "mychrdevmotor", &fops);
if (major < 0)
{
printk("注册字符设备驱动失败\n");
return major;
}
printk("注册字符设备驱动文件成功major = %d\n", major);
// 向上提交目录
cls = class_create(THIS_MODULE, "mymotor");
if (IS_ERR(cls))
{
printk("向上提交目录失败\n");
return -PTR_ERR(cls);
}
printk("向上提交目录成功\n");
// 向上提交设备节点信息
dev = device_create(cls, NULL, MKDEV(major, 0), NULL, "mymotor");
if (IS_ERR(dev))
{
printk("向上提交节点信息失败\n");
return -PTR_ERR(dev);
}
printk("向上提交设备节点成功\n");
// 进行马达寄存器地址的映射
vir_moder = ioremap(PHY_MOTOR_MODER, 4);
if (vir_moder == NULL)
{
printk("映射物理内存失败%d\n", __LINE__);
return -EFAULT;
}
vir_odr = ioremap(PHY_MOTOR_ODR, 4);
if (vir_odr == NULL)
{
printk("映射物理内存失败%d\n", __LINE__);
return -EFAULT;
}
vir_rcc = ioremap(RCC_MP_AHB4ENSETR, 4);
if (vir_rcc == NULL)
{
printk("映射物理内存失败%d\n", __LINE__);
return -EFAULT;
}
printk("映射物理内存成功\n");
// 硬件马达寄存器初始化
(*vir_rcc) |= (0x1 << 5);
(*vir_moder) &= (~(0x3 << 12));
(*vir_moder) |= (0x1 << 12);
(*vir_odr) &= (~(0x1 << 6));
printk("硬件初始化成功\n");
return 0;
}
static void __exit mycdev_exit(void)
{
// 取消地址映射
iounmap(vir_moder);
iounmap(vir_odr);
iounmap(vir_rcc);
// 销毁节点信息
device_destroy(cls, MKDEV(major, 0));
// 销毁目录信息
class_destroy(cls);
// 注销字符设备驱动
unregister_chrdev(major, "mychrdevmotor");
}
module_init(mydev_init);
module_exit(mycdev_exit);
MODULE_LICENSE("GPL");