ioctl控制马达,LED灯,风扇,蜂鸣器运行
LED
LED驱动程序:
#include <linux/init.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/io.h>
#include "stm32mp1xx_gpio.h"
#include <linux/device.h>#define PHY_LED_RCC 0x50000A28//物理地址对应的虚拟地址
gpio_t * vir_GPIOE;
gpio_t * vir_GPIOF;unsigned int *vir_rcc;//定义两个结构体存放信息
struct class *cls;
struct device *dev;char kbuf[128] = {0};//定义一个变量保存主设备号
unsigned int major;
//封装操作方法
int mycdev_open(struct inode *inode, struct file *file)
{//printk("%s;%s;%d",__FILE__,__func__,__LINE__);return 0;
}ssize_t mycdev_read(struct file *file, char *ubuf, size_t size, loff_t *lof)
{//printk("%s;%s;%d",__FILE__,__func__,__LINE__);return 0;
}ssize_t mycdev_write(struct file *file, const char *ubuf, size_t size, loff_t *lof)
{//printk("%s;%s;%d",__FILE__,__func__,__LINE__);return 0;
}int mycdev_close(struct inode *inode, struct file *file)
{//printk("%s;%s;%d",__FILE__,__func__,__LINE__);return 0;
}long mycdev_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{switch (cmd){case LED_ON:switch (arg){case 1:vir_GPIOE->ODR |=(0x1 << 10);break;case 2:vir_GPIOF->ODR |=(0x1 << 10);break;case 3:vir_GPIOE->ODR |=(0x1 << 8);break;}break;case LED_OFF:switch (arg){case 1:vir_GPIOE->ODR &=(~(0x1 << 10));break;case 2:vir_GPIOF->ODR &=(~(0x1 << 10));break;case 3:vir_GPIOE->ODR &=(~(0x1 << 8));break;}break;}return 0;
}struct file_operations fops={.open = mycdev_open,.release = mycdev_close,.read = mycdev_read,.write = mycdev_write,.unlocked_ioctl = mycdev_ioctl,
};static int __init mycdev_init(void)
{int i;//注册字符设备驱动major = register_chrdev(0,"mychrdev",&fops);if(major < 0){printk("注册字符设备驱动失败\n");return major;}printk("注册字符设备驱动成功 major=%d\n",major);//向上提交目录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");//物理地址映射虚拟地址vir_GPIOE = ioremap(GPIOE,0x30);if(vir_GPIOE == NULL){printk("物理地址映射虚拟地址失败%d\n",__LINE__);return -EFAULT;}vir_GPIOF = ioremap(GPIOF,0x30);if(vir_GPIOF == NULL){printk("物理地址映射虚拟地址失败%d\n",__LINE__);return -EFAULT;}vir_rcc = ioremap(PHY_LED_RCC,4);if(vir_rcc == NULL){printk("物理地址映射虚拟地址失败%d\n",__LINE__);return -EFAULT;}//硬件初始化(*vir_rcc) |= (0x3 << 4); //rcc第4,5位置1//PE10 led1vir_GPIOE->MODER &= (~(0x3 << 20));vir_GPIOE->MODER |= (0x1 << 20);vir_GPIOE->ODR &=(~(0x1 << 10));//PF10 led2vir_GPIOF->MODER &= (~(0x3 << 20));vir_GPIOF->MODER |= (0x1 << 20);vir_GPIOF->ODR &=(~(0x1 << 10));//PE8 led3vir_GPIOE->MODER &= (~(0x3 << 16));vir_GPIOE->MODER |= (0x1 << 16);vir_GPIOE->ODR &=(~(0x1 << 8));return 0;
}
static void __exit mycdev_exit(void)
{//取消地址映射iounmap(vir_GPIOE);iounmap(vir_GPIOF);iounmap(vir_rcc);//销毁节点信息int i;for(i = 0;i < 3;i++){device_destroy(cls,MKDEV(major,i));}//销毁目录信息class_destroy(cls);//注销字符设备驱动unregister_chrdev(major,"mychadev");}
module_init(mycdev_init);
module_exit(mycdev_exit);
MODULE_LICENSE("GPL");
LED应用程序:
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <string.h>//功能码
#define LED_ON _IOW('l',1,int)
#define LED_OFF _IOW('l',0,int)
int main(int argc, char const *argv[])
{int a,b;char buf[128] = {0};int fd = open("/dev/myled0", O_RDWR);if (fd < 0){printf("打开设备文件失败\n");exit(-1);}while (1){printf("请输入控制命令\n");printf("0(关灯),1(开灯)\n");printf("请输入>");scanf("%d",&a);printf("请输入要控制的灯 1(LED1),2(LED2),3(LED3)>");scanf("%d",&b);switch (a){case 1:ioctl(fd,LED_ON,b); //开灯break;case 0:ioctl(fd,LED_OFF,b);//关灯break;}}close(fd);return 0;
}
蜂鸣器
蜂鸣器驱动:
#include <linux/init.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/io.h>
#include "stm32mp1xx_gpio.h"
#include <linux/device.h>//mybee PB6
#define PHY_LED_RCC 0x50000A28//物理地址对应的虚拟地址
gpio_t * vir_GPIOB;unsigned int *vir_rcc;//定义两个结构体存放信息
struct class *cls;
struct device *dev;char kbuf[128] = {0};//定义一个变量保存主设备号
unsigned int major;
//封装操作方法
int mycdev_open(struct inode *inode, struct file *file)
{//printk("%s;%s;%d",__FILE__,__func__,__LINE__);return 0;
}ssize_t mycdev_read(struct file *file, char *ubuf, size_t size, loff_t *lof)
{//printk("%s;%s;%d",__FILE__,__func__,__LINE__);return 0;
}ssize_t mycdev_write(struct file *file, const char *ubuf, size_t size, loff_t *lof)
{//printk("%s;%s;%d",__FILE__,__func__,__LINE__);return 0;
}int mycdev_close(struct inode *inode, struct file *file)
{//printk("%s;%s;%d",__FILE__,__func__,__LINE__);return 0;
}long mycdev_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{switch (cmd){case BEE_ON:vir_GPIOB->ODR |=(0x1 << 6);break;case BEE_OFF:vir_GPIOB->ODR &=(~(0x1 << 6));break;}return 0;
}struct file_operations fops={.open = mycdev_open,.release = mycdev_close,.read = mycdev_read,.write = mycdev_write,.unlocked_ioctl = mycdev_ioctl,
};static int __init mycdev_init(void)
{int i;//注册字符设备驱动major = register_chrdev(0,"mychrdev",&fops);if(major < 0){printk("注册字符设备驱动失败\n");return major;}printk("注册字符设备驱动成功 major=%d\n",major);//向上提交目录cls = class_create(THIS_MODULE,"mybee");if(IS_ERR(cls)){printk("向上提交目录失败\n");return -PTR_ERR(cls);}printk("向上提交目录成功\n");//向上提交设备节点信息dev = device_create(cls,NULL,MKDEV(major,0),NULL,"mybee");if(IS_ERR(dev)){printk("向上提交设备节点信息失败\n");return -PTR_ERR(dev);}printk("向上提交设备节点信息成功\n");//物理地址映射虚拟地址vir_GPIOB = ioremap(GPIOB,0x30);if(vir_GPIOB == NULL){printk("物理地址映射虚拟地址失败%d\n",__LINE__);return -EFAULT;}vir_rcc = ioremap(PHY_LED_RCC,4);if(vir_rcc == NULL){printk("物理地址映射虚拟地址失败%d\n",__LINE__);return -EFAULT;}//硬件初始化(*vir_rcc) |= (0x1 << 1); //rcc第4,5位置1//PB6 beevir_GPIOB->MODER &= (~(0x3 << 12));vir_GPIOB->MODER |= (0x1 << 12);vir_GPIOB->ODR &=(~(0x1 << 6));return 0;
}
static void __exit mycdev_exit(void)
{//取消地址映射iounmap(vir_GPIOB);iounmap(vir_rcc);//销毁节点信息device_destroy(cls,MKDEV(major,0));//销毁目录信息class_destroy(cls);//注销字符设备驱动unregister_chrdev(major,"mychadev");}
module_init(mycdev_init);
module_exit(mycdev_exit);
MODULE_LICENSE("GPL");
蜂鸣器应用程序:
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <string.h>//功能码
#define BEE_ON _IO('b',1)
#define BEE_OFF _IO('b',0)int main(int argc, char const *argv[])
{int a;int fd = open("/dev/mybee", O_RDWR);if (fd < 0){printf("打开设备文件失败\n");exit(-1);}while (1){printf("请输入控制命令\n");printf("0(蜂鸣器不响),1(蜂鸣器响)\n");printf("请输入>");scanf("%d",&a);switch (a){case 1:ioctl(fd,BEE_ON); //break;case 0:ioctl(fd,BEE_OFF);//break;}}close(fd);return 0;
}
风扇
风扇驱动:
#include <linux/init.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/io.h>
#include "stm32mp1xx_gpio.h"
#include <linux/device.h>//myfan PE9
#define PHY_LED_RCC 0x50000A28//物理地址对应的虚拟地址
gpio_t * vir_GPIOE;unsigned int *vir_rcc;//定义两个结构体存放信息
struct class *cls;
struct device *dev;char kbuf[128] = {0};//定义一个变量保存主设备号
unsigned int major;
//封装操作方法
int mycdev_open(struct inode *inode, struct file *file)
{//printk("%s;%s;%d",__FILE__,__func__,__LINE__);return 0;
}ssize_t mycdev_read(struct file *file, char *ubuf, size_t size, loff_t *lof)
{//printk("%s;%s;%d",__FILE__,__func__,__LINE__);return 0;
}ssize_t mycdev_write(struct file *file, const char *ubuf, size_t size, loff_t *lof)
{//printk("%s;%s;%d",__FILE__,__func__,__LINE__);return 0;
}int mycdev_close(struct inode *inode, struct file *file)
{//printk("%s;%s;%d",__FILE__,__func__,__LINE__);return 0;
}long mycdev_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{switch (cmd){case FAN_ON:vir_GPIOE->ODR |= (0x1 << 9);break;case FAN_OFF:vir_GPIOE->ODR &= (~(0x1 << 9));break;}return 0;
}struct file_operations fops={.open = mycdev_open,.release = mycdev_close,.read = mycdev_read,.write = mycdev_write,.unlocked_ioctl = mycdev_ioctl,
};static int __init mycdev_init(void)
{int i;//注册字符设备驱动major = register_chrdev(0,"mychrdev",&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_GPIOE = ioremap(GPIOE,0x30);if(vir_GPIOE == NULL){printk("物理地址映射虚拟地址失败%d\n",__LINE__);return -EFAULT;}vir_rcc = ioremap(PHY_LED_RCC,4);if(vir_rcc == NULL){printk("物理地址映射虚拟地址失败%d\n",__LINE__);return -EFAULT;}//硬件初始化(*vir_rcc) |= (0x1 << 4); //rcc第4位置1//PE9 fanvir_GPIOE->MODER &= (~(0x3 << 18));vir_GPIOE->MODER |= (0x1 << 18);vir_GPIOE->ODR &=(~(0x1 << 9));return 0;
}
static void __exit mycdev_exit(void)
{//取消地址映射iounmap(vir_GPIOE);iounmap(vir_rcc);//销毁节点信息device_destroy(cls,MKDEV(major,0));//销毁目录信息class_destroy(cls);//注销字符设备驱动unregister_chrdev(major,"mychadev");}
module_init(mycdev_init);
module_exit(mycdev_exit);
MODULE_LICENSE("GPL");
风扇应用程序:
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <string.h>//功能码
#define FAN_ON _IO('f',1)
#define FAN_OFF _IO('f',0)int main(int argc, char const *argv[])
{int a;int fd = open("/dev/myfan", O_RDWR);if (fd < 0){printf("打开设备文件失败\n");exit(-1);}while (1){printf("请输入控制命令\n");printf("0(风扇不转),1(风扇转)\n");printf("请输入>");scanf("%d",&a);switch (a){case 1:ioctl(fd,FAN_ON); //break;case 0:ioctl(fd,FAN_OFF);//break;}}close(fd);return 0;
}
马达
马达驱动:
#include <linux/init.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/io.h>
#include "stm32mp1xx_gpio.h"
#include <linux/device.h>//mybee PF6
#define PHY_LED_RCC 0x50000A28//物理地址对应的虚拟地址
gpio_t * vir_GPIOF;unsigned int *vir_rcc;//定义两个结构体存放信息
struct class *cls;
struct device *dev;char kbuf[128] = {0};//定义一个变量保存主设备号
unsigned int major;
//封装操作方法
int mycdev_open(struct inode *inode, struct file *file)
{//printk("%s;%s;%d",__FILE__,__func__,__LINE__);return 0;
}ssize_t mycdev_read(struct file *file, char *ubuf, size_t size, loff_t *lof)
{//printk("%s;%s;%d",__FILE__,__func__,__LINE__);return 0;
}ssize_t mycdev_write(struct file *file, const char *ubuf, size_t size, loff_t *lof)
{//printk("%s;%s;%d",__FILE__,__func__,__LINE__);return 0;
}int mycdev_close(struct inode *inode, struct file *file)
{//printk("%s;%s;%d",__FILE__,__func__,__LINE__);return 0;
}long mycdev_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{switch (cmd){case MADA_ON:vir_GPIOF->ODR |=(0x1 << 6);break;case MADA_OFF:vir_GPIOF->ODR &=(~(0x1 << 6));break;}return 0;
}struct file_operations fops={.open = mycdev_open,.release = mycdev_close,.read = mycdev_read,.write = mycdev_write,.unlocked_ioctl = mycdev_ioctl,
};static int __init mycdev_init(void)
{int i;//注册字符设备驱动major = register_chrdev(0,"mychrdev",&fops);if(major < 0){printk("注册字符设备驱动失败\n");return major;}printk("注册字符设备驱动成功 major=%d\n",major);//向上提交目录cls = class_create(THIS_MODULE,"mymada");if(IS_ERR(cls)){printk("向上提交目录失败\n");return -PTR_ERR(cls);}printk("向上提交目录成功\n");//向上提交设备节点信息dev = device_create(cls,NULL,MKDEV(major,0),NULL,"mymada");if(IS_ERR(dev)){printk("向上提交设备节点信息失败\n");return -PTR_ERR(dev);}printk("向上提交设备节点信息成功\n");//物理地址映射虚拟地址vir_GPIOF = ioremap(GPIOF,0x30);if(vir_GPIOF == NULL){printk("物理地址映射虚拟地址失败%d\n",__LINE__);return -EFAULT;}vir_rcc = ioremap(PHY_LED_RCC,4);if(vir_rcc == NULL){printk("物理地址映射虚拟地址失败%d\n",__LINE__);return -EFAULT;}//硬件初始化(*vir_rcc) |= (0x1 << 5); //rcc第4,5位置1//PB6 beevir_GPIOF->MODER &= (~(0x3 << 12));vir_GPIOF->MODER |= (0x1 << 12);vir_GPIOF->ODR &=(~(0x1 << 6));return 0;
}
static void __exit mycdev_exit(void)
{//取消地址映射iounmap(vir_GPIOF);iounmap(vir_rcc);//销毁节点信息device_destroy(cls,MKDEV(major,0));//销毁目录信息class_destroy(cls);//注销字符设备驱动unregister_chrdev(major,"mychadev");}
module_init(mycdev_init);
module_exit(mycdev_exit);
MODULE_LICENSE("GPL");
马达应用程序:
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <string.h>//功能码
#define MADA_ON _IO('m',1)
#define MADA_OFF _IO('m',0)int main(int argc, char const *argv[])
{int a;int fd = open("/dev/mymada", O_RDWR);if (fd < 0){printf("打开设备文件失败\n");exit(-1);}while (1){printf("请输入控制命令\n");printf("0(马达不转),1(马达转)\n");printf("请输入>");scanf("%d",&a);switch (a){case 1:ioctl(fd,MADA_ON); //break;case 0:ioctl(fd,MADA_OFF);//break;}}close(fd);return 0;
}