我一直试图在没有原始主板制造商支持的情况下将驱动程序从2.6移植到4.n(并且Linux经验非常有限).
原始驱动程序使用init_timer()并传入指向timer_list结构的指针.该limer_list结构的'data'元素被设置为指向另一个内存结构的指针,并且'function'元素被设置为回调.在回调函数内部,'data'元素用于访问其他东西.
当前的timer 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;
Run Code Online (Sandbox Code Playgroud)
回调函数如下所示:
void GetIntrTimerCallback(unsigned long devAddr)
{
myDevice *dev = (myDevice *) devAddr;
dev->blahBlah++; // etc.
Run Code Online (Sandbox Code Playgroud)
因此,旧代码将指针传递给myDevice,因此在回调中可以访问该结构.
但是使用新的计时器方法只有一个4字节的int,但指针是8(或其他).
我想做的是:
dev->getIntrTimer = kmalloc(sizeof(struct timer_list), GFP_KERNEL);
timer_setup(dev->getIntrTimer, GetIntrTimerCallback, dev);
Run Code Online (Sandbox Code Playgroud)
但是当然会产生编译错误,因为dev是一个指向myDevice类型的指针,它不适合int.
我想念傻事,不是吗?
我有一个 Windows GUI 程序 (Visual Studio 2019),其中有许多按钮,这些按钮在不同的设备上执行相同的操作。而不是有 20 个不同的宏调用,如下所示:
BEGIN_MESSAGE_MAP(CChainDlg, CDialogEx)
ON_BN_CLICKED(IDC_CHECK_1, &CChainDlg::OnBnClickedCheck1)
ON_BN_CLICKED(IDC_CHECK_2, &CChainDlg::OnBnClickedCheck2)
ON_BN_CLICKED(IDC_CHECK_3, &CChainDlg::OnBnClickedCheck3)
...
END_MESSAGE_MAP()
...
void CChainDlg::OnBnClickedCheck1() {...}
void CChainDlg::OnBnClickedCheck2() {...}
void CChainDlg::OnBnClickedCheck3() {...}
Run Code Online (Sandbox Code Playgroud)
...每个都执行相同的基本算法,仅在数组索引上有所不同,我希望有一个可以接受索引的调用。
ON_BN_CLICKED 宏不想接受参数,这似乎是实现此目的的最明显方法。例如:
BEGIN_MESSAGE_MAP(CChainDlg, CDialogEx)
ON_BN_CLICKED(IDC_CHECK_1, &CChainDlg::OnBnClickedCheck(0))
ON_BN_CLICKED(IDC_CHECK_2, &CChainDlg::OnBnClickedCheck(1))
ON_BN_CLICKED(IDC_CHECK_3, &CChainDlg::OnBnClickedCheck(2))
...
END_MESSAGE_MAP()
Run Code Online (Sandbox Code Playgroud)
我目前所做的是编写带有参数的通用函数,并让各个 OnBnClickedCheck1() 函数使用正确的参数调用通用函数。但这看起来很混乱。
给我建议一个更好的方法!