我正在为使用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()一切正常。当然,我可以使用后一种方式来实现我的代码,但我想知道为什么我有这种行为。
非常感谢您的帮助
安德烈