驱动代码:
#include <linux/init.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/uaccess.h>
#include "head.h"
#include <linux/io.h>
unsigned int major;
char kbuf[128] = {0};
unsigned int *mode_e;
unsigned int *rcc;
unsigned int *odr_e;
unsigned int *odr_f;
unsigned int *mode_f;
ssize_t mychardev_read(struct file *file, char __user *user, size_t size, loff_t *loff)
{
unsigned int ret;
ret = copy_to_user(user, kbuf, size);
if (ret)
{
printk("error=%d\n", __LINE__);
return -1;
}
printk("%s:%s:%d\n", __FILE__, __func__, __LINE__);
return 0;
}
ssize_t mychardev_write(struct file *file, const char __user *user, size_t size, loff_t *loff)
{
unsigned int ret;
ret = copy_from_user(kbuf, user, size);
if (ret)
{
printk("error=%d\n", __LINE__);
return -1;
}
printk("%s:%s:%d\n", __FILE__, __func__, __LINE__);
if (kbuf[0] == '1')
{
(*odr_e) |= (0x1 << 10);
}
else if (kbuf[0] == '4')
{
(*odr_e) &= (~(0x1 << 10));
}
else if (kbuf[0] == '2')
{
(*odr_f) |= (0x1 << 10);
}
else if (kbuf[0] == '5')
{
(*odr_f) &= (~(0x1 << 10));
}
else if (kbuf[0] == '3')
{
(*odr_e) |= (0x1 << 8);
}
else if (kbuf[0] == '6')
{
(*odr_e) &= (~(0x1 << 8));
}
return 0;
}
int mychardev_open(struct inode *inode, struct file *file)
{
printk("%s:%s:%d\n", __FILE__, __func__, __LINE__);
return 0;
}
int mychardev_release(struct inode *inode, struct file *file)
{
printk("%s:%s:%d\n", __FILE__, __func__, __LINE__);
return 0;
}
struct file_operations fops = {
.open = mychardev_open,
.release = mychardev_release,
.read = mychardev_read,
.write = mychardev_write,
};
static int __init mycdev_init(void)
{
major = register_chrdev(0, "mychar_dev", &fops);
if (major < 0)
{
printk("%d\n", __LINE__);
return 0;
}
printk("major=%d\n", major);
//GPIOE映射虚拟空间
mode_e = ioremap(GPIOE_MORE, 4);
if (mode_e == NULL)
{
printk("mode_e error=%d\n", __LINE__);
return 0;
}
rcc = ioremap(RCC_GPIO, 4);
if (rcc == NULL)
{
printk("rcc error=%d\n", __LINE__);
return 0;
}
odr_e = ioremap(GPIOE_ODR, 4);
if (odr_e == NULL)
{
printk("odr_e error=%d\n", __LINE__);
return 0;
}
//GPIOF映射虚拟空间
mode_f = ioremap(GPIOF_MORE, 4);
if (mode_f == NULL)
{
printk("mode_f error=%d\n", __LINE__);
return 0;
}
odr_f = ioremap(GPIOF_ODR, 4);
if (odr_f == NULL)
{
printk("odr_f error=%d\n", __LINE__);
return 0;
}
printk("地址映射完成\n");
//GPIOE和GPIOF时钟使能
(*rcc) |= (0x3 << 4);
//PE10初始化
(*mode_e) &= (~(0x3 << 20));
(*mode_e) |= (0x1 << 20);
(*odr_e) &= (~(0x1 << 10));
//PF10初始化
(*mode_f) &= (~(0x3 << 20));
(*mode_f) |= (0x1 << 20);
(*odr_f) &= (~(0x1 << 10));
//PE8初始化
(*mode_e) &= (~(0x3 << 16));
(*mode_e) |= (0x1 << 16);
(*odr_e) &= (~(0x1 << 8));
return 0;
}
static void __exit mycdev_exit(void)
{
iounmap(mode_e);
iounmap(odr_e);
iounmap(rcc);
iounmap(mode_f);
iounmap(odr_f);
unregister_chrdev(major, "mychar_dev");
}
module_init(mycdev_init);
module_exit(mycdev_exit);
MODULE_LICENSE("GPL");
head.h
#ifndef __HEAD_H__
#define __HEAD_H__
#define RCC_GPIO 0x50000A28
#define GPIOE_MORE 0x50006000
#define GPIOE_ODR 0x50006014
#define GPIOF_MORE 0x50007000
#define GPIOF_ODR 0x50007014
#endif
执行代码:
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
int main(int argc, const char *argv[])
{
char buf[128] = {};
int fd = open("/dev/mychar_dev", O_RDWR);
if (fd < 0)
{
printf("error=%d\n", __LINE__);
return -1;
}
while (1)
{
printf("请输入相关命令1,2,3(开灯),4,5,6(关灯);");
fgets(buf, sizeof(buf), stdin);
buf[strlen(buf) - 1] = '\0';
if (buf[0] >= '7')
{
printf("输入有误,请重新输入!");
}
printf("%s\n", buf);
write(fd, buf, sizeof(buf)); // 从驱动中传递数据
// memset(buf,0,sizeof(buf));//清空数据
// printf("%s\n",buf);
// read(fd,buf,sizeof(buf));//从驱动中读取数据
// printf("%s\n",buf);
}
close(fd);
return 0;
}
结果: