问题遇到的现象和发生背景
在linux里写led的gpio驱动,
make编译时,头文件找不到
```c
#include <linux/init.h>
#include <linux/module.h>
#include <linux/cdev.h>
#include <linux/fs.h>
#include <linux/device.h>
#include <asm/uaccess.h>
#include <linux/ioctl.h>
#include <linux/io.h>
#include <mach/platform.h>
#define LED0_ON _IO('j',0)
#define LED0_OFF _IO('j',1)
#define LED1_ON _IO('j',2)
#define LED1_OFF _IO('j',3)
#define LED2_ON _IO('j',4)
#define LED2_OFF _IO('j',5)
#define LED3_ON _IO('j',6)
#define LED3_OFF _IO('j',7)
#define LED_MINOR 0
//声明IO内存映射地址
void __iomem *gpioe_base = NULL;
void __iomem *gpioc_base = NULL;
//设备号
dev_t dev;
//声明cdev
struct cdev led_cdev;
//设备类指针
struct class *led_class;
//设备指针
struct device *led_device;
/*
inode是文件的节点结构,用来存储文件静态信息
文件创建时,内核中就会有一个inode结构
file结构记录的是文件打开的信息
文件被打开时内核就会创建一个file结构
*/
int led_open(struct inode *inode, struct file *filp)
{
printk("enter led_open!\n");
return 0;
}
long led_ioctl(struct file *filp, unsigned int cmd, unsigned long data)
{
printk("enter led_ioctl!\n");
//不同的命令对应不同的操作
switch(cmd){
case LED0_ON:
printk("LED0_ON!\n");
iowrite32(ioread32(gpioe_base)&~(0x1<<13),gpioe_base);
break;
case LED0_OFF:
printk("LED0_OFF!\n");
iowrite32(ioread32(gpioe_base)|(0x1<<13),gpioe_base);
break;
case LED1_ON:
printk("LED1_ON!\n");
iowrite32(ioread32(gpioc_base)&~(0x1<<17),gpioc_base);
break;
case LED1_OFF:
printk("LED1_OFF!\n");
iowrite32(ioread32(gpioc_base)|(0x1<<17),gpioc_base);
break;
case LED2_ON:
printk("LED2_ON!\n");
iowrite32(ioread32(gpioc_base)&~(0x1<<8),gpioc_base);
break;
case LED2_OFF:
printk("LED2_OFF!\n");
iowrite32(ioread32(gpioc_base)|(0x1<<8),gpioc_base);
break;
case LED3_ON:
printk("LED3_ON!\n");
iowrite32(ioread32(gpioc_base)&~(0x1<<7),gpioc_base);
break;
case LED3_OFF:
printk("LED3_OFF!\n");
iowrite32(ioread32(gpioc_base)|(0x1<<7),gpioc_base);
break;
default:
return -EINVAL;
}
return 0;
}
int led_release(struct inode *inode, struct file *filp)
{
printk("enter led_release!\n");
return 0;
}
//声明操作函数集合
struct file_operations led_fops = {
.owner = THIS_MODULE,
.open = led_open,
.unlocked_ioctl = led_ioctl,//ioctl接口
.release = led_release,//对应用户close接口
};
//加载函数
int led_init(void)
{
int ret;
// 1.注册字符设备驱动
ret = register_chrdev(0, "led_demo", &led_fops);
if(ret<0){
printk("register_chrdev failed!\n");
goto failure_register_chrdev;
}
//构建设备号
dev = MKDEV(ret,LED_MINOR);
printk("register_chrdev success!\n");
// 2.注册设备类
/*成功会在/sys/class目录下出现led_class子目录*/
led_class = class_create(THIS_MODULE, "led_class");
if(IS_ERR(led_class)){
printk("class_create failed!\n");
ret = PTR_ERR(led_class);
goto failure_class_create;
}
// 3.创建设备文件
led_device = device_create(led_class, NULL, dev,NULL, "led");
if(IS_ERR(led_device)){
printk("device_create failed!\n");
ret = PTR_ERR(led_device);
goto failure_device_create;
}
// 4.IO内存映射
gpioe_base = ioremap(PHY_BASEADDR_GPIOE, SZ_64);
if(IS_ERR_OR_NULL(gpioe_base)){//失败
printk("ioremap failed!\n");
ret = -ENOMEM;
goto failure_gpioe_ioremap;
}
gpioc_base = ioremap(PHY_BASEADDR_GPIOC, SZ_64);
if(IS_ERR_OR_NULL(gpioc_base)){//失败
printk("ioremap failed!\n");
ret = -ENOMEM;
goto failure_gpioc_ioremap;
}
//初始化
//E alt0 26 27位清0 addr:base+0x20
iowrite32(ioread32(gpioe_base+0x20)&~(0x3<<26),gpioe_base+0x20);
//C alt0 14-17位0101 alt1 2-3位01
iowrite32((ioread32(gpioc_base+0x20)&~(0xf<<14))|(0x5<<14),gpioc_base+0x20);
iowrite32((ioread32(gpioc_base+0x24)&~(0x3<<2))|(0x1<<2),gpioc_base+0x24);
//E outenb 13位 置1 addr:base+0x04
iowrite32(ioread32(gpioe_base+0x04)|(0x1<<13),gpioe_base+0x04);
//C outenb 7,8,17位置1
iowrite32(ioread32(gpioc_base+0x04)|(0x3<<7)|(0x1<<17),gpioc_base+0x04);
/*
u32 data = ioread32(gpioc_base+0x04);
data |= (0x3<<7)|(0x1<<17);
iowrite32(data,gpioc_base+0x04);
*/
//out 13位 置1 addr:base
iowrite32(ioread32(gpioe_base)|(0x1<<13),gpioe_base);
iowrite32(ioread32(gpioc_base)|(0x3<<7)|(0x1<<17),gpioc_base);
return 0;
failure_gpioc_ioremap:
iounmap(gpioe_base);
failure_gpioe_ioremap:
device_destroy(led_class, dev);
failure_device_create:
class_destroy(led_class);// 3
failure_class_create:
unregister_chrdev(MAJOR(dev), "led_demo");// 2
failure_register_chrdev:
return ret;
}
//卸载函数
void led_exit(void)
{
//解除IO映射
iounmap(gpioc_base);
iounmap(gpioe_base);
//销毁设备文件
device_destroy(led_class, dev);
//注销设备类
class_destroy(led_class);
//注销字符设备驱动
unregister_chrdev(MAJOR(dev), "led_demo");
}
//声明为模块的入口和出口
module_init(led_init);
module_exit(led_exit);
MODULE_LICENSE("GPL");//GPL模块许可证
MODULE_AUTHOR("yit");//作者
MODULE_VERSION("1.0");//版本
MODULE_DESCRIPTION("led driver!");//描述信息
###### 遇到的现象和发生背景,请写出第一个错误信息
###### 用代码块功能插入代码,请勿粘贴截图。 不用代码块回答率下降 50%
```c
#如果已定义KERNELRELEASE,说明是由内核构造系统调用的
#可以利用内建语句
obj-m:=led_drv.o
KERNELDIR := /home/user/linux/rv/kernel
PWD := $(shell pwd)
CROSS_COMPILE=/home/user/linux/rv/prebuilts/gcc/linux-x86/arm/gcc-arm-8.3-2019.03-x86_64-arm-linux-gnueabihf/bin/arm-linux-gnueabihf-
all:
make -C $(KERNELDIR) M=$(PWD) ARCH=arm CROSS_COMPILE=$(CROSS_COMPILE) modules
clean:
rm -rf *.ko *.o .t* .m* .*.cmd *.mod.c *.order *.symvers