首页 > 技术文章 > Linux-驱动and动态链接库and应用程序

ydmblog 2021-07-02 15:30 原文

Linux-驱动and动态链接库and应用程序

1. 驱动程序模板

#include <linux/cdev.h>
#include <linux/clk.h>
#include <linux/fs.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/ioport.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/mutex.h>
#include <linux/of.h>
#include <linux/sched.h>
#include <linux/device.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
#include <linux/string.h>
#include <linux/sysctl.h>
#include <linux/types.h>
#include <linux/uaccess.h>
#include <linux/scatterlist.h>
#include <linux/pagemap.h>
#include <linux/version.h>
#include <asm/page.h>
#include <asm/byteorder.h>
#include <linux/of.h>
#include <linux/of_irq.h>
#include <linux/gpio.h>
#include <linux/of_gpio.h>
#include <linux/platform_data/serial-omap.h>
#include <linux/interrupt.h>
#include <linux/device.h>
#include <linux/gfp.h>
#include <dt-bindings/gpio/gpio.h>
#define THIS_DRIVER_NAME "test_demo"
struct platform_device *test_pdev;
static int major = 0;
static struct cdev cedv_test_test;
static struct class* test_test_sys_class;
static dev_t test_test_device_id;
static int test_test_open (struct inode *inode, struct file *filp)
{
    // printk("KERNEL:test_test_open open\n");
    return 0;
}
static ssize_t test_test_read (struct file *filp, char __user *usr_buf, size_t count, loff_t *loff_t)
{
    int ret = 0;
    return ret;
}
static ssize_t test_test_write  (struct file *filp, const char __user *usr_buf, size_t count, loff_t *loff_t)
{
    int ret;
    return ret;
}
static int test_test_close(struct inode *inode, struct file *filp)
{
    return 0;
}
static struct file_operations test_test_fops = {
        .owner = THIS_MODULE,
        .open =         test_test_open,
        .write =         test_test_write,
        .read  =        test_test_read,
        .release =      test_test_close,
};
static int test_test_platform_driver_probe(struct platform_device *pdev)
{
    int retval = 0;
    int i = 0;
    test_pdev = pdev;
    dev_info(&pdev->dev, "driver probe start.\n");
    cdev_init(&cedv_test_test, &test_test_fops);
    cdev_add(&cedv_test_test, test_test_device_id, 1);
    device_create(test_test_sys_class, NULL,test_test_device_id,NULL,THIS_DRIVER_NAME);
    dev_info(&pdev->dev, "driver installed.\n");
    return retval;
}
static int test_test_platform_driver_remove(struct platform_device *pdev)
{
    dev_info(&pdev->dev, "driver unloaded\n");
    device_destroy(test_test_sys_class,test_test_device_id);
    cdev_del(&cedv_test_test);
    return 0;
}
static struct of_device_id test_test_of_match[] = {
    { .compatible = "dido-test", },
    { /* end of table */}
};
static struct platform_driver test_test_platform_driver = {
    .probe  = test_test_platform_driver_probe,
    .remove = test_test_platform_driver_remove,
    .driver = {
        .owner = THIS_MODULE,
        .name  = THIS_DRIVER_NAME,
        .of_match_table = test_test_of_match,
    },
};
static void __exit test_test_exit(void)
{
    platform_driver_unregister(&test_test_platform_driver);
    class_destroy(test_test_sys_class);
}
static int __init test_test_init(void)
{
        int retval = 0;
        if (major) {
                test_test_device_id = MKDEV(major, 1);
                register_chrdev_region(test_test_device_id, 0,THIS_DRIVER_NAME);
        }else {
                retval = alloc_chrdev_region(&test_test_device_id, 0, 1, THIS_DRIVER_NAME);
                if (retval != 0) {
                        printk(KERN_ERR "%s: couldn't allocate device major id\n", THIS_DRIVER_NAME);
                        test_test_device_id = 0;
                }
                major = MAJOR(test_test_device_id);
        }
        test_test_device_id = MKDEV(major, 1);
        test_test_sys_class = class_create(THIS_MODULE, THIS_DRIVER_NAME);
        if (IS_ERR_OR_NULL(test_test_sys_class)) {
                printk(KERN_ERR "%s: couldn't create sys class\n", THIS_DRIVER_NAME);
                retval = PTR_ERR(test_test_sys_class);
                test_test_sys_class = NULL;
        }
        retval = platform_driver_register(&test_test_platform_driver);
        if (retval) {
                printk(KERN_ERR "%s: couldn't register platform driver\n", THIS_DRIVER_NAME);
        }
        return 0;
}
module_init(test_test_init);
module_exit(test_test_exit);
MODULE_AUTHOR("ydm");
MODULE_LICENSE("Dual BSD/GPL");

ps:函数成对实现与卸载:顺序是后实现先卸载,盖楼与拆楼一样
(test_test_init->test_test_exit)
(test_test_platform_driver_probe->test_test_platform_driver_remove)
(test_test_open->test_test_close)

2. 动态连接库

封装一些应用程序与驱动之间的函数
编译动态库:

arm-arago-linux-gnueabi-gcc -fPIC -shared -o libtest.so libtest.c

编译后将生成的.so文件放入板子的/lib文件下

3. 应用程序

编译应用程序:

arm-arago-linux-gnueabi-gcc test_so.c -L. -test -ldl -o test_so		//-test是生成的.so文件

推荐阅读