记录一下 这几天小练习驱动 ---------
1.重点是 :在执行 make 时 ,没有编译错误,但是 一直open fail ,cause---------------------- 没有 用 sudo
解决:sudo ./led_app
2.在 装载模块 和执行 led_app 后 ---要看打印的log 要执行 dmesg
3. error : 还有是写一个 全局结构体变量 但是分配内存的时候 一直有错 在insmod 时出错
insmod: error inserting 'led.ko': Cannot allocate memory -------没有解决 以后在看吧
struct MY_led
{
struct class *led_class;
struct device *led_device;
char* devname;
int dev_major;
}MY_led;
led_init(){ ...my_led = kzalloc(sizeof(struct MY_led), 0);....}
1. //手动挂载 mknod /dev/led c 200 0
在这里提一下简单 应用程序是怎样调用底层驱动的 ------------ 便于回忆 哈哈哈哈
举个例子:open
应用程序调用 open-----> 实际调用的是glibc实现 ----》》SWI +number --- 》》VFS----sys_open( ) + 上层open函数传入参数/dev/led -----
---->led____struct file_operations fop---led_open()
open 产生的 SWI + 1(1代表品 open,2代表write 类似这样带入内核)
实际上在执行 mknod /dev/led c 200 0 命令时就 ====绑定了 /dev/led 和 设备号 ---->VFS 根据设备号 来调用不同驱动的open
int hello_init(void)
{
int ret;
printk("---------hello_init----^_^-----------\n");
ret =register_chrdev(LED_MAJOR, "led",&fops);
if(ret < 0)
{
printk("register device fail");
return ENODEV;
}
return 0;
}
void hello_exit(void)
{
unregister_chrdev(LED_MAJOR,"led");
printk("--------hello_exit-------^_^---------\n");
}
2.应用实现
led_app.c
#include
#include
#include
#include
int main(int argc,char* argv[])
{
int fd = open("/dev/led", O_RDWR);
if(fd <0)
{
printf("/dev/hello open fail \n");
}
close(fd);
return 0;
}
3.//自动挂载
#include
#include
#include
#include
#include
#include
#define LED_MAJOR 200
static int led_open(struct inode *inode, struct file *file)
{
printk("-------^_^ %s-------\n", __FUNCTION__);
return 0;
}
static ssize_t led_write(struct file *file, const char __user *buf,
size_t count, loff_t *ppos)
{
printk("-------^_^ %s-------\n", __FUNCTION__);
return 0;
}
static ssize_t led_read(struct file *filp, char __user *buf,
size_t cnt, loff_t *off)
{
printk("-------^_^ %s-------\n", __FUNCTION__);
return 0;
}
static int led_release(struct inode *inode, struct file *file)
{
printk("-------^_^ %s-------\n", __FUNCTION__);
return 0;
}
struct file_operations fops={
.open = led_open,
.read = led_read,
.write = led_write,
.release = led_release,
};
static struct class *led_class;
static struct device *led_device;
/*struct MY_led
{
struct class *led_class;
struct device *led_device;
char* devname;
int dev_major;
}MY_led;
struct MY_led *my_led;
device.h dsp56k_class = class_create(THIS_MODULE, "dsp56k");
if (IS_ERR(dsp56k_class)) {
err = PTR_ERR(dsp56k_class);
goto out_chrdev;
}
my_led = kmalloc(sizeof(struct MY_led), 0);
if(my_led)
{
printk(KERN_ERR"kaalloc fail \n");
return -ENOMEM;
}
err_free:
kfree(my_led);
*/
int hello_init(void)
{
int ret;
printk("---------hello_init----^_^-----------\n");
//ret =register_chrdev(LED_MAJOR, "LED",&fops);
ret =register_chrdev(LED_MAJOR, "LED",&fops);
if(ret < 0)
{
printk("register device fail");
ret= -EINVAL;
return ret;
}
led_class=class_create(THIS_MODULE, "led_class");
if(IS_ERR(led_class))
{
ret = PTR_ERR(led_class);
goto err_out_chrdev;
}
led_device=device_create(led_class, NULL,
MKDEV(LED_MAJOR,0), NULL,"led");
if (IS_ERR(led_device))
{
pr_err("%s: Failed to create dev %s", __func__,
"led");
ret= PTR_ERR(led_device);
goto err_dev_create;
}
return 0;
err_out_chrdev:
unregister_chrdev(LED_MAJOR,"LED");
err_dev_create:
device_destroy(led_class, MKDEV(LED_MAJOR,0));
return ret;
}
void hello_exit(void)
{
device_destroy(led_class, MKDEV(LED_MAJOR,0));
class_destroy(led_class);
unregister_chrdev(LED_MAJOR,"LED");
// kfree(my_led);
printk("--------hello_exit-------^_^---------\n");
}
module_init(hello_init);
module_exit(hello_exit);
MODULE_LICENSE("GPL");
执行结果:
ct@ubuntu:~$ dmesg
[ 1013.815133] --------hello_exit-------^_^---------
[ 1055.682806] ---------hello_init----^_^-----------
[ 1210.072796] -------^_^ led_open-------
[ 1210.072802] -------^_^ led_release-------