设备号linux模块问题

时间:2017-03-14 15:17:28

标签: linux-kernel linux-device-driver

我正在为使用Yocto构建并安装在飞思卡尔imx6sx目标板上的Linux内核发行版Poky 1.7开发角色设备。它们是简单的模块,仅用于读/写SoC的IO寄存器。 一切顺利,直到我登录后加载模块,通过在目标控制台中简单调用

modprobe mydevice

问题已经开始,因为我在启动时自动加载了这些模块。首次启动电路板后系统启动,我的自定义模块已加载,我可以打开它们,进行读/写操作......因此它们正在工作。 重启系统(关闭和打开或重启),模块仍然加载,但我无法使用它们。

经过一些试验,我所看到的问题是问题是他们使用的设备号的动态分配,特别是 __ init()中调用的函数 alloc_chrdev_region() 模块的功能。 事实上,第一次系统在闪存后打开时, / dev 中的设备文件的设备号是 / sys / class的最新版本/ myclass / mydevice / dev 设备编号,而从第一次重启后它们就不再匹配了。简言之:

 First boot:    

 /dev/mydevice                         device number [Major, Minor] = 247,0
 /sys/class/myclass/mydevice/dev       device number [Major, Minor] = 247,0

 Second and later boots:

 /dev/mydevice                         device number [Major, Minor] = 247,0
 /sys/class/myclass/mydevice/dev       device number [Major, Minor] = 248,0

因此,似乎设备文件保存在内存中,而不是在每次启动时都更新。

以下是 __ init() __ exit()函数的主要代码:

static struct class *g_deviceClass;
static struct cdev g_characterDevice;
static dev_t g_deviceNumber;

static int __init npe_power_drv_init(void)
{
    int32_t result;

    if ( alloc_chrdev_region(&g_deviceNumber, 0, 1, DEVICE_NAME) < 0 )
    {
        return -EAGAIN;
    }

    cdev_init(&g_characterDevice, &npe_power_drv_ops);

    g_deviceClass = class_create(THIS_MODULE, CLASS_NAME);

    if( device_create(g_deviceClass, NULL, g_deviceNumber, NULL, DEVICE_NAME) == NULL )
    {
        class_destroy(g_deviceClass);
        unregister_chrdev_region(g_deviceNumber, 1);
        return -EAGAIN;
    }

    result = cdev_add(&g_characterDevice, g_deviceNumber, 1);

    if( result < 0 )
    {
        device_destroy(g_deviceClass, g_deviceNumber);
            class_destroy(g_deviceClass);
        unregister_chrdev_region(g_deviceNumber, 1);
        return -EAGAIN;
    }

    return 0;
}   

static void __exit npe_power_drv_exit(void)
{
    device_destroy(g_deviceClass, g_deviceNumber);
    class_destroy(g_deviceClass);
    cdev_del(&g_characterDevice);
    unregister_chrdev_region(g_deviceNumber, 1);
}

module_init(npe_power_drv_init);
module_exit(npe_power_drv_exit);

使用静态设备编号分配, register_chrdev_region()一切正常。当然,我可以使用后一种方式来实现我的代码,但我想知道为什么我有这种行为。

非常感谢您的帮助

安德烈

0 个答案:

没有答案