Linux驱动开发培训系列教程网址https://edu.csdn.net/course/detail/26814
Linux驱动开发入门之编译驱动模块
调试Linux驱动的基本流程是先把驱动编译成模块,通过insmod命令加载到内核进行调试。调试完成,编译进内核即可。下面的代码基于Linux3.2(AM335X)平台上经过验证。
第一步,在任意位置创建目录gao_driver
第二步,在目录gao_driver中创建文件hello.c makefile
其中hello.c内容:
/*******************************************************************************************
*
*******************************************************************************************/
#include <linux/init.h>
#include <linux/module.h>
#include <linux/device.h>
#include <linux/platform_device.h>
#include <linux/rtc.h>
#include <linux/spi/spi.h>
#include <linux/bcd.h>
#include <linux/miscdevice.h>
/*******************************************************************************************
*
*******************************************************************************************/
int my_gpio_open(struct inode *inode, struct file *filp)
{
printk("my_gpio_open \n");
return 0;
}
/*******************************************************************************************
*
*******************************************************************************************/
static ssize_t my_gpio_write(struct file *filp, const char __user *buf, size_t size, loff_t *ppos)
{
char gao_buf[100];
printk("my_gpio_write\n");
memset(gao_buf, 0, 100);
/*用户空间->内核空间*/
if (copy_from_user(gao_buf, buf, size))
{
printk("copy_from_user error\n");
}
printk("my_gpio_write=%s\n", gao_buf);
return size;
}
/*******************************************************************************************
*
*******************************************************************************************/
static ssize_t my_gpio_read(struct file *filp, char __user *buf, size_t count, loff_t *f_pos)
{
char gao_buf[100];
printk("my_gpio_read\n");
memset(gao_buf, 0, 100);
sprintf(gao_buf, "gaoyanli hello world");
if(copy_to_user(buf, gao_buf, strlen(gao_buf)))
{
printk("my_gpio_read error\n");
}
return 0;
}
/*******************************************************************************************
*
*******************************************************************************************/
int my_gpio_release(struct inode *inode, struct file *filp)
{
return 0;
}
/*******************************************************************************************
*
*******************************************************************************************/
struct file_operations my_gpio_fops =
{
.owner = THIS_MODULE,
.open = my_gpio_open,
.write = my_gpio_write,
.read = my_gpio_read,
.release = my_gpio_release,
};
//分配初始化miscdevice
static struct miscdevice my_gpio_dev =
{
.minor = MISC_DYNAMIC_MINOR, //自动分配次设备号
.name = "my_gpio", //产生设备节点dev/my_gpio
.fops = &my_gpio_fops
};
/*******************************************************************************************
*
*******************************************************************************************/
int my_gpio_init(void)
{
printk("---------------------------------------------------------------------my_gpio_init\n");
//注册混杂设备驱动。产生设备节点/dev/my_gpio
misc_register(&my_gpio_dev);
return 0;
}
/*******************************************************************************************
*
*******************************************************************************************/
void my_gpio_remove(void)
{
printk("------------------------------------------------------------------my_gpio_remove\n");
//卸载混杂设备
misc_deregister(&my_gpio_dev);
}
/*******************************************************************************************
*
*******************************************************************************************/
module_init(my_gpio_init);
module_exit(my_gpio_remove);
MODULE_AUTHOR("gaoyanli");
MODULE_LICENSE("GPL");
MODULE_ALIAS("spi:da5304");
其中makefile内容:
MOD_FILE=hello
#ifneq ($(KERNELRELEASE),)
obj-m := $(MOD_FILE).o
#else
KERNELDIR = /home/forlinx/okxx18-source-android51/kernel
PWD :=$(shell pwd)
all:
$(MAKE) -C $(KERNELDIR) M=$(PWD) ARCH=arm CROSS_COMPILE=/home/forlinx/okxx18-source-android51/prebuilts/gcc/linux-x86/arm/arm-eabi-4.8/bin/arm-eabi- modules -Wno-error=format-security
clean:
rm ./*.o
rm ./*.ko
rm ./*.mod.c
rm ./module*
rm ./Module*
#endif;
第三步,进入目录gao_driver,编译模块,生成hello.ko
#cd ./gao_driver
#make
第四步,把hello.ko下载到开发板,并加载进内核。
#insmod hello.ko