在FiRa的Android底层实现中,其IEEE 802.15.4协议相关实现均作为内核模块实现,因此,本文简要介绍内核模块的相关定义,并节选相关FiRa实现内核模块的使用。
内核模块是Linux操作系统中比较独特的机制。模块本身不被编译进内核镜像,这就有效控制了内核的大小;模块一旦被加载,就和内核中的其他部分完全一样。
Linux启动中在完成BIOS加载、读取MBR、BootLoader启动之后,会根据内核映像所在路径,解压缩操作,开始启动内核,调用start_kernel
函数来启动一系列的初始化函数并初始化各种设备。
内核启动之后,会运行相关初始化工作,启动相关启动项。
然后根据/etc/modules.conf
文件或/etc/modules.d
目录下的文件来加载内核模块。
常见的内核模块包括驱动程序、文件系统、网络协议栈、安全模块和系统调用等。
内核模块通过insmod
或modprobe
命令加载内核模块,相应的加载函数就会被内核执行,完成本模块的相关初始化工作。
当通过rmmod
命令卸载某模块时,模块的卸载函数会被自动执行,完成与模块加载函数相反的功能(如释放内存等)。
module_init
,在内核模块被内核加载时,会调用module_init中的函数,即内核模块的加载函数。
module_exit
,在内核模块被卸载时的卸载函数,卸载内核模块时调用。
在内核代码中,模块相关函数示例如下:
static int __init function_init(void)
{}
static void __exit function_cleanup(void)
{
}
module_init(function_init);
module_exit(function_cleanup);
另外,对于内核模块而言,授权MODULE_LICENSE
是必须的,用于指定内核模块的许可证,其他模块参数相对可选。常见的许可证包括:GPL、LGPL、BSD、MIT等。常见的内核模块参数还有:
MODULE_AUTHOR
,指定内核模块的作者MODULE_DESCRIPTION
,内核模块的描述信息MODULE_VERSION
,内核模块的版本信息MODULE_SUPPORTED_DEVICE
,指定内核模块支持的设备。MODULE_DEVICE_TABLE
MODULE_ALIAS
。对于USB、PCI等设备驱动程序,通常会创建一个MODULE_DEVICE_TABLE,表明该驱动模块支持的设备。
int __init mcps802154_init(void)
{
int r;
r = mcps802154_nl_init();
if (r)
return r;
r = mcps802154_default_region_init();
WARN_RETURN(r);
r = simple_ranging_region_init();
WARN_ON(r);
r = mcps802154_endless_scheduler_init();
WARN_ON(r);
#ifdef CONFIG_MCPS802154_TESTMODE
r = ping_pong_region_init();
WARN_ON(r);
#endif
return r;
}
void __exit mcps802154_exit(void)
{
#ifdef CONFIG_MCPS802154_TESTMODE
ping_pong_region_exit();
#endif
mcps802154_endless_scheduler_exit();
simple_ranging_region_exit();
mcps802154_default_region_exit();
mcps802154_nl_exit();
}
module_init(mcps802154_init);
module_exit(mcps802154_exit);
module_init(fira_region_init);
module_exit(fira_region_exit);
MODULE_DESCRIPTION("FiRa Region for IEEE 802.15.4 MCPS");
MODULE_AUTHOR("Nicolas Schodet " );
MODULE_VERSION("1.0");
MODULE_LICENSE("GPL v2");
//MCPS, 调度器管理,实现调度器的注册与注销
EXPORT_SYMBOL(mcps802154_scheduler_register);
EXPORT_SYMBOL(mcps802154_scheduler_unregister);