c - 从旧的 init_timer 到新的 timer_setup 的适配

标签 c linux timer linux-kernel linux-device-driver

我一直在尝试在没有原始板制造商支持的情况下将驱动程序从 2.6 移植到 4.X(并且 Linux 经验非常有限)。

原始驱动程序使用init_timer() 并传入指向timer_list 结构的指针。 timer_list 结构的 data 元素被设置为指向另一个内存结构的指针,而 function 元素被设置为回调。在回调函数中,data 元素用于访问其他内容。

当前计时器init-方法使用:

timer_setup( timer_list *, callback, (unsigned int) flags);

并且 timer_list 结构被更改以消除 data 字段。

我不确定通知等效 data 元素的回调函数的最佳/正确方法是什么。谁能提供一些指导?

这是老司机的一个片段:

myDevice * dev;

dev->getIntrTimer = kmalloc(sizeof(struct timer_list), GFP_KERNEL);    
init_timer(dev->getIntrTimer);

dev->getIntrTimer->data = (unsigned long) dev;
dev->getIntrTimer->function = GetIntrTimerCallback;

回调函数是这样开始的:

void GetIntrTimerCallback(unsigned long devAddr)
{
    myDevice *dev = (myDevice *) devAddr;
    dev->blahBlah++; // etc.

因此,旧代码将指针传递给 myDevice,以便在回调中可以访问该结构。

但是对于新的计时器方法,只有一个 4 字节的 int 可用,而指针是 8(或其他)。

我想做的是:

dev->getIntrTimer = kmalloc(sizeof(struct timer_list), GFP_KERNEL);
timer_setup(dev->getIntrTimer, GetIntrTimerCallback, dev);

当然这会产生编译错误,因为 dev 是指向类型 myDevice 的指针,它不适合 int。

最佳答案

具有三个参数的 timer_setup() 自 4.14 Linux 内核以来就存在(仅供引用,在较早的版本中有 setup_timer())。如果您维护一些应该与最新内核相关的代码 - 每次 API 更改时您都必须以适当的方式更改它。现在您可以通过基于 container_of() 的特殊函数 from_timer() 访问您的数据.

timer_list 通常不用作结构内部的指针,因此该示例暗示了正常用法,可能类似于:

#if LINUX_VERSION_CODE < KERNEL_VERSION(4,14,0)
    init_timer(&dev->getIntrTimer);
    dev->getIntrTimer.data = (unsigned long) dev;
    dev->getIntrTimer.function = GetIntrTimerCallback;
    /* ... */
    add_timer(&dev->getIntrTimer);
#else
    timer_setup(&dev->getIntrTimer, GetIntrTimerCallback, 0);
    /* the third argument may include TIMER_* flags */
    /* ... */
#endif

回调函数:

#if LINUX_VERSION_CODE < KERNEL_VERSION(4,14,0)
void GetIntrTimerCallback(unsigned long devAddr)
{
    myDevice *dev = (myDevice *) devAddr;
#else
void GetIntrTimerCallback(struct timer_list *t)
{
    myDevice *dev = from_timer(dev, t, getIntrTimer);
#endif
    /* Do something with "dev" */

另请阅读:

关于c - 从旧的 init_timer 到新的 timer_setup 的适配,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53839625/

相关文章:

c - 是否可以使一些用于创建库的函数对调用者不可用?

sprintf 中字符串内的 C 宏

javascript - 需要帮助找到用于在网页之间连续循环的 setTimeout 函数的剩余时间

android - ADB Shell挂载/卸载SD卡

java - 如何在 Java Applet 中创建倒计时器?

java - javax.swing.Timer 的困难

c - 在没有 strlcpy 的平台上,strlcpy 相当于 strncpy

c - 从 C 中的字节数组中提取 14 位值

linux - 部署依赖于共享库的 Linux 应用程序的公认方法是什么?

python - 构建 OpenSSL 以编译 Python 的可移植版本