static struct task_struct *control = NULL;
static long call_ioctl(struct file *filp, unsigned int iocmd, unsigned long arg)
{
switch (iocmd)
{
case SETMODE:
/* get buffer data from userspace which is either 0 or 1 */
/* 0: Manual 1: Automatic*/
switch (buffer)
{
case MANUAL:
if (control)
{
kthread_stop(control);
control = NULL;
printk(KERN_ALERT "Switching to MANUAL disabling kernel thread for Automatic\n");
}
mode = MANUAL_MODE;
printk(KERN_ALERT "IN MANUAL \n");
break;
case AUTOMATIC:
if (automatic_fan_control() != 0)
{
printk(KERN_ALERT "Failed to set fan to AUTOMATIC!!! \n");
return -1;
}
break;
default:
printk(KERN_ALERT "Entered value is incorrect\n");
return -EINVAL;
}
break;
}
}
static inline int automatic_fan_control(void)
{
control = kthread_run(sense_cpu_temperature, NULL, "Temperature Thread");
if (control)
{
printk(KERN_ALERT "Kthread Created Successfully\n");
}
else
{
printk(KERN_ALERT "Failed to create kthread. \n");
control = NULL;
return -1;
}
return 0;
}
int temperature(void *arg)
{
while (!kthread_should_stop())
{
mutex_lock(&mutex);
get_temperature();
mutex_unlock(&mutex);
/* Process the temperature value */
msleep_interruptible(polling_interval);
}
return 0;
}这是我为驱动程序编写的上面的代码:
就太棒了。
发布于 2021-06-29 12:14:39
让我们看看msleep_interruptible的来源
unsigned long msleep_interruptible(unsigned int msecs)
{
unsigned long timeout = msecs_to_jiffies(msecs) + 1;
while (timeout && !signal_pending(current))
timeout = schedule_timeout_interruptible(timeout);
return jiffies_to_msecs(timeout);
}schedule_timeout_interruptible将休眠状态放置到超时结束,或者发送信号,或者显式唤醒信号。它返回在jiffies的剩余时间。如上文所示,如果msleep_interruptible早早醒来,没有信号等待,它就会重新入睡。
kthread_stop显式地唤醒线程任务,但不发送信号,因此msleep_interruptible将运行到完成,如果早起,线程任务就会重新进入休眠状态。
在本例中,一个简单的修复方法是在temperature中替换此调用。
msleep_interruptible(polling_interval);通过以下呼吁:
schedule_timeout_uninterruptible(msecs_to_jiffies(polling_interval) + 1);然后,如果早点醒来,它就不会再睡觉了。
https://stackoverflow.com/questions/68177436
复制相似问题