在新 linux 内核中转换旧 init_timer
Conversion of old init_timer in new linux kernel
我正在尝试构建一个 SDK 驱动程序(没有制造商的文档或支持)。原始驱动程序使用 init_timer() 并传入指向 timer_list 结构的指针。它使用 'data' 元素。现在我知道一些计时器函数在较新的 Linux 内核中已被弃用。目前我使用的内核版本是 4.15.
访问 'data' 元素的最佳方式是什么?
当前函数如下所示 -
OS_RESULT OS_TimerCreate(OS_DRV_CONTEXT* aContext, OS_TIMER* aTimer, OS_UINT32 aPeriodic, OS_TIMER_FNC aFunction,
OS_VOID* aData, OS_UINT32 aPeriod)
{
struct timer_list* lTimer = (struct timer_list*) aTimer->Space;
unsigned long lJiffies = jiffies;
unsigned long lPeriod = msecs_to_jiffies(aPeriod);
OS_UNREFERENCED_PARAMETER(aContext);
OS_ASSERT( OS_TIMER_SIZE >= sizeof(timer_list));
init_timer(lTimer);
lTimer->expires = lJiffies + lPeriod;
lTimer->data = (unsigned long) aTimer;
aTimer->Function = aFunction;
aTimer->Data = aData;
aTimer->Period = lPeriod;
if (aPeriodic)
{
lTimer->function = OS_TimerPeriodicInternalFunc;
}
else
{
lTimer->function = OS_TimerInternalFunc;
}
add_timer(lTimer);
return OS_RESULT_OK;
}
声明供参考-
typedef struct
{
OS_UINT8 Space[OS_TIMER_SIZE];
OS_TIMER_FNC Function;
OS_VOID* Data;
OS_UINT32 Period;
} OS_TIMER;
OS_DECL_EXTERN OS_RESULT OS_TimerCreate(OS_DRV_CONTEXT* aContext, OS_TIMER* aTimer, OS_UINT32 aPeriodic, OS_TIMER_FNC aFunction, OS_VOID* aData, OS_UINT32 aPeriod /* ms */);
我们将不胜感激。
您首先需要将存储 struct timer_list
的成员更改为正确的类型,而不是使用字节数组:
typedef struct
{
struct timer_list Timer;
OS_TIMER_FNC Function;
OS_VOID* Data;
OS_UINT32 Period;
} OS_TIMER;
(而 lTimer
只是设置为 &aTimer->Timer
)。
在旧代码中,data
成员只是设置为指向包含计时器的 OS_TIMER
结构的指针。在新代码中,回调可以改为使用 from_timer
宏获取此指针,例如,如果在旧回调中你有这个:
OS_TIMER *aTimer = lTimer->data;
那么在新代码中您将改为:
OS_TIMER *aTimer = from_timer(aTimer, lTimer, Timer);
(其中最后一个参数 Timer
是 OS_TIMER
中 struct timer_list
字段的名称)。
我正在尝试构建一个 SDK 驱动程序(没有制造商的文档或支持)。原始驱动程序使用 init_timer() 并传入指向 timer_list 结构的指针。它使用 'data' 元素。现在我知道一些计时器函数在较新的 Linux 内核中已被弃用。目前我使用的内核版本是 4.15.
访问 'data' 元素的最佳方式是什么?
当前函数如下所示 -
OS_RESULT OS_TimerCreate(OS_DRV_CONTEXT* aContext, OS_TIMER* aTimer, OS_UINT32 aPeriodic, OS_TIMER_FNC aFunction,
OS_VOID* aData, OS_UINT32 aPeriod)
{
struct timer_list* lTimer = (struct timer_list*) aTimer->Space;
unsigned long lJiffies = jiffies;
unsigned long lPeriod = msecs_to_jiffies(aPeriod);
OS_UNREFERENCED_PARAMETER(aContext);
OS_ASSERT( OS_TIMER_SIZE >= sizeof(timer_list));
init_timer(lTimer);
lTimer->expires = lJiffies + lPeriod;
lTimer->data = (unsigned long) aTimer;
aTimer->Function = aFunction;
aTimer->Data = aData;
aTimer->Period = lPeriod;
if (aPeriodic)
{
lTimer->function = OS_TimerPeriodicInternalFunc;
}
else
{
lTimer->function = OS_TimerInternalFunc;
}
add_timer(lTimer);
return OS_RESULT_OK;
}
声明供参考-
typedef struct
{
OS_UINT8 Space[OS_TIMER_SIZE];
OS_TIMER_FNC Function;
OS_VOID* Data;
OS_UINT32 Period;
} OS_TIMER;
OS_DECL_EXTERN OS_RESULT OS_TimerCreate(OS_DRV_CONTEXT* aContext, OS_TIMER* aTimer, OS_UINT32 aPeriodic, OS_TIMER_FNC aFunction, OS_VOID* aData, OS_UINT32 aPeriod /* ms */);
我们将不胜感激。
您首先需要将存储 struct timer_list
的成员更改为正确的类型,而不是使用字节数组:
typedef struct
{
struct timer_list Timer;
OS_TIMER_FNC Function;
OS_VOID* Data;
OS_UINT32 Period;
} OS_TIMER;
(而 lTimer
只是设置为 &aTimer->Timer
)。
在旧代码中,data
成员只是设置为指向包含计时器的 OS_TIMER
结构的指针。在新代码中,回调可以改为使用 from_timer
宏获取此指针,例如,如果在旧回调中你有这个:
OS_TIMER *aTimer = lTimer->data;
那么在新代码中您将改为:
OS_TIMER *aTimer = from_timer(aTimer, lTimer, Timer);
(其中最后一个参数 Timer
是 OS_TIMER
中 struct timer_list
字段的名称)。