头文件
#ifndef __CKR_H__
#define __CKR_H__
typedef struct
{
unsigned int MODER; // 00
unsigned int OTYPER; // 04
unsigned int OSPEEDR; // 08
unsigned int PUPDR; // 0C
unsigned int IDR; // 10
unsigned int ODR; // 14
} gpio_t;
// GPIO口
#define PHY_GPIOB 0X50003000
#define PHY_GPIOE 0X50006000
#define PHY_GPIOF 0X50007000
// RCC 总线
#define PHY_RCC 0X50000A28
// LED
#define LED_ON _IOW('l', 1, int)
#define LED_OFF _IOW('l', 0, int)
// BEEP
#define BEEP_ON _IO('b', 1)
#define BEEP_OFF _IO('b', 0)
// FAN
#define FAN_ON _IO('f', 1)
#define FAN_OFF _IO('f', 0)
// MOTOR
#define MOTOR_ON _IO('m', 1)
#define MOTOR_OFF _IO('m', 0)
#endif
应用主函数
#include
#include
#include
#include
#include
#include
#include
#include
#include "ckr.h"
int main(int argc, char const *argv[])
{
char buf[128] = {0};
int led_fd;
int beep_fd;
int fan_fd;
int motor_fd;
int operation;
int flag;
while (1)
{
system("clear");
printf("-------------------------------\n");
printf("-------------1.led-------------\n");
printf("-------------2.beep------------\n");
printf("-------------3.fan-------------\n");
printf("-------------4.motor-----------\n");
printf("-------------------------------\n");
printf("请输入操作指令>>>");
scanf("%d", &operation);
switch (operation)
{
case 1: // led灯操作========================================
led_fd = open("/dev/myled", O_RDWR);
if (led_fd < 0)
{
printf("打开设备文件失败\n");
exit(-1);
}
while (1)
{
system("clear");
printf("请输入指令(0-关灯 1-开灯 2-退出)>>>");
scanf("%d", &operation);
if (operation == 2)
{
break;
}
printf("请输入要控制的灯(1-LED1 2-LED2 3-LED3)>>>");
scanf("%d", &flag);
switch (operation)
{
case 0: // 关灯逻辑
ioctl(led_fd, LED_OFF, flag);
break;
case 1: // 开灯逻辑
ioctl(led_fd, LED_ON, flag);
break;
}
}
close(led_fd);
break;
case 2: // beep灯操作========================================
beep_fd = open("/dev/mybeep", O_RDWR);
if (beep_fd < 0)
{
printf("打开设备文件失败\n");
exit(-1);
}
while (1)
{
system("clear");
printf("请输入指令(0-关闭 1-开启 2-退出)>>>");
scanf("%d", &operation);
if (operation == 2)
{
break;
}
else if (operation == 0)
{
ioctl(beep_fd, BEEP_OFF);
}
else if (operation == 1)
{
ioctl(beep_fd, BEEP_ON);
}
}
close(beep_fd);
break;
case 3: // fan风扇操作========================================
fan_fd = open("/dev/myfan", O_RDWR);
if (fan_fd < 0)
{
printf("打开设备文件失败\n");
exit(-1);
}
while (1)
{
system("clear");
printf("请输入指令(0-关闭 1-开启 2-退出)>>>");
scanf("%d", &operation);
if (operation == 2)
{
break;
}
else if (operation == 0)
{
ioctl(fan_fd, FAN_OFF);
}
else if (operation == 1)
{
ioctl(fan_fd, FAN_ON);
}
}
close(fan_fd);
break;
case 4: // motor马达操作========================================
motor_fd = open("/dev/mymotor", O_RDWR);
if (motor_fd < 0)
{
printf("打开设备文件失败\n");
exit(-1);
}
while (1)
{
system("clear");
printf("请输入指令(0-关闭 1-开启 2-退出)>>>");
scanf("%d", &operation);
if (operation == 2)
{
break;
}
else if (operation == 0)
{
ioctl(motor_fd, MOTOR_OFF);
}
else if (operation == 1)
{
ioctl(motor_fd, MOTOR_ON);
}
}
close(motor_fd);
break;
default:
break;
}
}
return 0;
}
led驱动
#include
#include
#include
#include
#include
#include "../ckr.h"
unsigned int major; // 定义一个变量保存主设备号
char kbuf[128] = {0};
gpio_t *GPIOE;
gpio_t *GPIOF;
unsigned int *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;
}
// ioctrl
long mycdev_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
switch (cmd)
{
case LED_ON:
switch (arg)
{
case 1: // led1灯
GPIOE->ODR |= (0x1 << 10);
break;
case 2: // led2灯
GPIOF->ODR |= (0x1 << 10);
break;
case 3: // led3灯
GPIOE->ODR |= (0x1 << 8);
break;
default:
break;
}
break;
case LED_OFF:
switch (arg)
{
case 1: // led1灯
GPIOE->ODR &= (~(0x1 << 10));
break;
case 2: // led2灯
GPIOF->ODR &= (~(0x1 << 10));
break;
case 3: // led3灯
GPIOE->ODR &= (~(0x1 << 8));
break;
default:
break;
}
break;
default:
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 = mycdev_ioctl,
};
void myled_init(void)
{
// 进行寄存器地址的映射-----------------------------------------------
GPIOE = ioremap(PHY_GPIOE, 4);
if (GPIOE == NULL)
{
printk("映射物理内存失败%d\n", __LINE__);
return -EFAULT;
}
GPIOF = ioremap(PHY_GPIOF, 4);
if (GPIOF == NULL)
{
printk("映射物理内存失败%d\n", __LINE__);
return -EFAULT;
}
RCC = ioremap(PHY_RCC, 4);
if (RCC == NULL)
{
printk("映射物理内存失败%d\n", __LINE__);
return -EFAULT;
}
printk("映射物理内存成功\n");
// 硬件寄存器的初始化
(*RCC) |= (0X3 << 4); // rcc使能
GPIOE->MODER &= (~(0x3 << 20));
GPIOE->MODER |= (0x1 << 20);
GPIOE->ODR &= (~(0x1 << 10));
GPIOF->MODER &= (~(0x3 << 20));
GPIOF->MODER |= (0x1 << 20);
GPIOF->ODR &= (~(0x1 << 10));
GPIOE->MODER &= (~(0x3 << 16));
GPIOE->MODER |= (0x1 << 16);
GPIOE->ODR &= (~(0x1 << 8));
}
static int __init mycdev_init(void)
{
// 注册字符设备驱动
major = register_chrdev(0, "mychrdev", &fops);
if (major < 0)
{
printk("注册字符设备驱动失败\n");
return major;
}
printk("注册字符设备驱动成功major=%d\n", major);
myled_init(); // 初始化
printk("硬件寄存器初始化成功\n");
// 向上提交目录
cls = class_create(THIS_MODULE, "myled");
if (IS_ERR(cls))
{
printk("向上创建目录失败!\n");
return -PTR_ERR(cls);
}
printk("向上创建目录成功!\n");
// 向上提交节点
dev = device_create(cls, NULL, MKDEV(major, 0), NULL, "myled");
if (IS_ERR(dev))
{
printk("向上提交节点失败!\n");
return -PTR_ERR(dev);
}
printk("向上提交节点成功!\n");
return 0;
}
static void __exit mycdev_exit(void)
{
// 销毁节点信息
device_destroy(cls, MKDEV(major, 0));
// 销毁目录信息
class_destroy(cls);
iounmap(GPIOE);
iounmap(GPIOF);
iounmap(RCC);
// 注销字符设备驱动
unregister_chrdev(major, "mychrdev");
}
module_init(mycdev_init);
module_exit(mycdev_exit);
MODULE_LICENSE("GPL");
beep驱动
#include
#include
#include
#include
#include
#include "../ckr.h"
unsigned int major; // 定义一个变量保存主设备号
char kbuf[128] = {0};
gpio_t *GPIOB;
unsigned int *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;
}
// ioctrl
long mycdev_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
switch (cmd)
{
case BEEP_ON:
GPIOB->ODR |= (0x1 << 6);
break;
case BEEP_OFF:
GPIOB->ODR &= (~(0x1 << 6));
break;
default:
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 = mycdev_ioctl,
};
void mybeep_init(void)
{
// 进行寄存器地址的映射-----------------------------------------------
GPIOB = ioremap(PHY_GPIOB, 4);
if (GPIOB == NULL)
{
printk("映射物理内存失败%d\n", __LINE__);
return -EFAULT;
}
RCC = ioremap(PHY_RCC, 4);
if (RCC == NULL)
{
printk("映射物理内存失败%d\n", __LINE__);
return -EFAULT;
}
printk("映射物理内存成功\n");
// 硬件寄存器的初始化
(*RCC) |= (0X1 << 1); // rcc使能
GPIOB->MODER &= (~(0x3 << 12));
GPIOB->MODER |= (0x1 << 12);
GPIOB->ODR |= (~(0x1 << 6));
}
static int __init mycdev_init(void)
{
// 注册字符设备驱动
major = register_chrdev(0, "mychrdev_beep", &fops);
if (major < 0)
{
printk("注册字符设备驱动失败\n");
return major;
}
printk("注册字符设备驱动成功major=%d\n", major);
// 蜂鸣器初始化****************************
mybeep_init();
printk("硬件寄存器初始化成功\n");
// 向上提交目录
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");
return 0;
}
static void __exit mycdev_exit(void)
{
// 销毁节点信息
device_destroy(cls, MKDEV(major, 0));
// 销毁目录信息
class_destroy(cls);
iounmap(GPIOB);
iounmap(RCC);
// 注销字符设备驱动
unregister_chrdev(major, "mychrdev_beep");
}
module_init(mycdev_init);
module_exit(mycdev_exit);
MODULE_LICENSE("GPL");
fan驱动
#include
#include
#include
#include
#include
#include "../ckr.h"
unsigned int major; // 定义一个变量保存主设备号
char kbuf[128] = {0};
gpio_t *GPIOE;
unsigned int *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;
}
// ioctrl
long mycdev_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
switch (cmd)
{
case FAN_ON:
GPIOE->ODR |= (0x1 << 9);
break;
case FAN_OFF:
GPIOE->ODR &= (~(0x1 << 9));
break;
default:
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 = mycdev_ioctl,
};
void mybeep_init(void)
{
// 进行寄存器地址的映射-----------------------------------------------
GPIOE = ioremap(PHY_GPIOE, 4);
if (GPIOE == NULL)
{
printk("映射物理内存失败%d\n", __LINE__);
return -EFAULT;
}
RCC = ioremap(PHY_RCC, 4);
if (RCC == NULL)
{
printk("映射物理内存失败%d\n", __LINE__);
return -EFAULT;
}
printk("映射物理内存成功\n");
// 硬件寄存器的初始化
(*RCC) |= (0X1 << 4); // rcc使能
GPIOE->MODER &= (~(0x3 << 18));
GPIOE->MODER |= (0x1 << 18);
GPIOE->ODR &= (~(0x1 << 9));
}
static int __init mycdev_init(void)
{
// 注册字符设备驱动
major = register_chrdev(0, "mychrdev_fan", &fops);
if (major < 0)
{
printk("注册字符设备驱动失败\n");
return major;
}
printk("注册字符设备驱动成功major=%d\n", major);
// 蜂鸣器初始化****************************
mybeep_init();
printk("硬件寄存器初始化成功\n");
// 向上提交目录
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");
return 0;
}
static void __exit mycdev_exit(void)
{
// 销毁节点信息
device_destroy(cls, MKDEV(major, 0));
// 销毁目录信息
class_destroy(cls);
iounmap(GPIOE);
iounmap(RCC);
// 注销字符设备驱动
unregister_chrdev(major, "mychrdev_fan");
}
module_init(mycdev_init);
module_exit(mycdev_exit);
MODULE_LICENSE("GPL");
motor驱动
#include
#include
#include
#include
#include
#include "../ckr.h"
unsigned int major; // 定义一个变量保存主设备号
char kbuf[128] = {0};
gpio_t *GPIOF;
unsigned int *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;
}
// ioctrl
long mycdev_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
switch (cmd)
{
case MOTOR_ON:
GPIOF->ODR |= (0x1 << 6);
break;
case MOTOR_OFF:
GPIOF->ODR &= (~(0x1 << 6));
break;
default:
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 = mycdev_ioctl,
};
void mybeep_init(void)
{
// 进行寄存器地址的映射-----------------------------------------------
GPIOF = ioremap(PHY_GPIOF, 4);
if (GPIOF == NULL)
{
printk("映射物理内存失败%d\n", __LINE__);
return -EFAULT;
}
RCC = ioremap(PHY_RCC, 4);
if (RCC == NULL)
{
printk("映射物理内存失败%d\n", __LINE__);
return -EFAULT;
}
printk("映射物理内存成功\n");
// 硬件寄存器的初始化
(*RCC) |= (0X1 << 5); // rcc使能
GPIOF->MODER &= (~(0x3 << 12));
GPIOF->MODER |= (0x1 << 12);
GPIOF->ODR |= (~(0x1 << 6));
}
static int __init mycdev_init(void)
{
// 注册字符设备驱动
major = register_chrdev(0, "mychrdev_motor", &fops);
if (major < 0)
{
printk("注册字符设备驱动失败\n");
return major;
}
printk("注册字符设备驱动成功major=%d\n", major);
// 蜂鸣器初始化****************************
mybeep_init();
printk("硬件寄存器初始化成功\n");
// 向上提交目录
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");
return 0;
}
static void __exit mycdev_exit(void)
{
// 销毁节点信息
device_destroy(cls, MKDEV(major, 0));
// 销毁目录信息
class_destroy(cls);
iounmap(GPIOF);
iounmap(RCC);
// 注销字符设备驱动
unregister_chrdev(major, "mychrdev_motor");
}
module_init(mycdev_init);
module_exit(mycdev_exit);
MODULE_LICENSE("GPL");