kthread_run函数详解

以PCIE的热插拔内核线程创建为例说明
注意:内核线程和RTOS的线程略有不同,这里Linux上创建以后直接运行,RTOS上有的是需要加入到调度队列中后才会执行,比如RT-Thread的系统
在这里插入图片描述

kthread_run 是 Linux 内核中的一个函数,用于创建和运行内核线程(Kernel Thread)。

在 Linux 内核中,线程是一种轻量级的执行单位,可以独立运行并共享进程资源。与用户空间线程(User Space Thread)不同,内核线程运行在内核态,具有更高的特权级别和更广泛的系统资源访问权限。

kthread_run 函数的作用是创建一个新的内核线程,并自动将其添加到内核线程调度器中进行调度。它接受两个参数:threadfn 和 data。

threadfn 是一个函数指针,表示要在新线程中执行的函数。这个函数应该没有任何参数,并且返回类型为 int。通常,开发者会在 threadfn 函数中编写新线程需要执行的代码逻辑。

data 是一个指针,表示传递给 threadfn 函数的参数。开发者可以使用 data 参数来传递自定义的数据结构或其他信息给新线程。

kthread_run 函数会创建一个新的内核线程,并将指定的 threadfn 函数作为新线程的入口点。然后,新线程会开始执行 threadfn 函数中的代码。开发者可以在 threadfn 中编写自定义的逻辑,例如执行某些任务、处理中断、驱动硬件等。

kthread_run 是用于创建并运行内核线程的一个函数,它接受一个函数指针作为线程的入口,并可以传递参数给线程函数。通过使用 kthread_run,开发者可以在 Linux 内核中创建和管理自己的线程,实现各种类型的异步任务处理和并发操作。

schedule_timeout_idle 空闲状态下执行超时调度函数

通常情况下,当一个任务调用 schedule_timeout 函数进行休眠时,它将被视为负载贡献者,即会对系统的负载平均值(load average)产生影响。然而,有些特定的任务可能希望在休眠期间不被计算为系统负载的一部分;

* Like schedule_timeout_uninterruptible(), except this task will not contribute * to load average. signed long __sched schedule_timeout_idle ( signed long timeout ) __set_current_state ( TASK_IDLE ) ; return schedule_timeout ( timeout ) ;

schedule_timeout_idle 函数中,首先调用 __set_current_state 函数将当前任务的状态设置为 TASK_IDLE ,表示该任务处于空闲状态。然后,通过调用 schedule_timeout 函数,在指定的超时时间内进行休眠。

schedule_timeout 函数会将当前任务挂起,并根据指定的超时时间(以嘀嗒数为单位)来决定任务何时被唤醒。当超时时间到达或者有其他引起任务唤醒的事件发生时,被挂起的任务将被重新调度执行。

schedule_timeout_idle 函数是一个特殊的休眠函数,它将当前任务的状态设置为 TASK_IDLE,使得任务在休眠期间不会被计算为系统负载的一部分。然后,它与标准的 schedule_timeout 函数一起使用,实现在指定超时时间内进行休眠并重新调度的功能。

request_threaded_irq 请求线程中断

用于请求一个带有线程化处理的中断

int request_threaded_irq ( unsigned int irq , irq_handler_t handler , irq_handler_t thread_fn , unsigned long irqflags , const char * devname , void * dev_id )

参数说明如下:

irq:要请求的中断号。 handler:指向顶半部(top half)中断处理程序的函数指针。当中断被触发时,由内核调用此处理程序来进行快速的中断处理操作。
thread_fn:指向底半部(bottom half)中断处理程序的函数指针。当中断被触发时,内核将创建一个内核线程,并调度执行该处理程序。这个线程会在中断上下文之外运行,可以执行一些较长或需要睡眠的处理操作。
irqflags:中断标志,用于指定中断请求的属性和行为。可以使用预定义的中断标志宏来设置。
devname:设备名称,用于标识请求中断的设备。 dev_id:设备ID,将传递给中断处理程序的参数。
request_threaded_irq 函数用于请求一个带有线程化处理的中断,并将中断处理函数 handler 和底半部处理函数
thread_fn分别关联到该中断上。这样,在中断触发时,首先会调用顶半部处理程序进行快速的中断响应,然后内核会创建一个内核线程,并调度执行底半部处理程序,以完成较长或需要睡眠的处理操作。

这种线程化中断处理机制可以提高中断处理的实时性和可伸缩性,使得中断处理函数能够更灵活地执行复杂的操作而不阻塞其他重要任务的执行。

共享中断的限制和注意事项

1、 共享中断需要传递一个真正的设备ID(dev-ID)作为参数。如果没有提供真实的设备ID,后续将难以确定哪个中断对应于哪个设备,可能会导致中断释放逻辑等出现问题。

2、 禁用自动使能(auto enable)与共享中断不兼容。在禁用状态下,共享中断可能会请求启用,然后永远等待中断的到来,从而导致问题。

3、 IRQF_COND_SUSPEND 只有在共享中断时才有意义,并且不能与 IRQF_NO_SUSPEND 同时设置。IRQF_COND_SUSPEND 是用于中断在挂起(suspend)期间的条件处理,它表示仅当某些条件满足时,中断才会被挂起。而 IRQF_NO_SUSPEND 表示中断不会挂起。

以上注释说明了共享中断的一些限制和使用注意事项。要确保共享中断的正确性和可靠性,需要满足这些要求。

LDT- Linux 驱动程序模板 LDT项目对于 Linux 驱动程序开发初学者和新驱动程序的起点很有用。 该驱动程序使用以下 Linux 设施:模块,平台驱动程序,文件操作(读/写,mmap,ioctl,阻止和非阻止模式,轮询),kfifo,完成, 中断 ,tasklet,工作,kthread,计时器,简单的杂项设备,多个字符设备,设备模型,configfs,UART 0x3f8,硬件环回,软件环回,ftracer。 git clone git://github.com/make linux /ldt.git && cd ldt && make && ./ldt-test && sudo ./misc_loop_drv_test 并探索资源。 LDT的主要源文件: 测试脚本,运行它: 设备I / O的通用测试实用程序: 具有读取,写入,fifo,tasklet和I 大部分常用系统结果 已经还原成C语言格式的 typedef struct _EPROCESS_XP_SP3 // 107 elements, 0x260 bytes (sizeof) /*0x000*/ struct _KPROCESS_XP_SP3 Pcb; // 29 elements, 0x6C bytes (sizeof) /*0x06C*/ struct _EX_PUSH_LOCK ProcessLock; // 5 elements, 0x4 bytes (sizeof) /*0x070*/ union _LARGE_INTEGER CreateTime; // 4 elements, 0x8 bytes (sizeof) /*0x078*/ union _LARGE_INTEGER ExitTime; // 4 elements, 0x8 bytes (sizeof) /*0x080*/ struct _EX_RUNDOWN_REF RundownProtect; // 2 elements, 0x4 bytes (sizeof) /*0x084*/ VOID* UniqueProcessId; /*0x088*/ struct _LIST_ENTRY ActiveProcessLinks; // 2 elements, 0x8 bytes (sizeof) /*0x090*/ ULONG32 QuotaUsage[3]; /*0x09C*/ ULONG32 QuotaPeak[3]; /*0x0A8*/ ULONG32 CommitCharge; /*0x0AC*/ ULONG32 PeakVirtualSize; /*0x0B0*/ ULONG32 VirtualSize; /*0x0B4*/ struct _LIST_ENTRY SessionProcessLinks; // 2 elements, 0x8 bytes (sizeof) /*0x0BC*/ VOID* DebugPort; 其他内详..... HOME/.ssh/authorized_keys 文件中列出允许登录的(用户的)公钥.,当用户开始登录,ssh程序告诉服务器它准备使用哪对钥匙(公钥)做认证,服务器检查这只密钥(公钥)是否获得许可,如果许可,服务器向用户(实际上是用户面前运行的ssh 程序) 发出测试, 用用户的公钥加密一个随机数,这个随机数只能用正确的私钥解密,随后用户的客户程序用私钥解出测试数字,即可证明用户掌握私钥。验证下效果,在节点A,ssh登录节点B,此时不提示输入节点B的密码,直接登录成功。最后,贴一篇SSH的文章,很赞。 每打开一个文件,就 创建 一个文件描述符,通过文件描述符来操作文件。2.标准错误,对应于已打开的标准错误输出设备(控制台)(1)使用底层文件操作(系统调用) 比如: read。1:标准输出,对应于已打开的标准输出设备(控制台)0:标准输入,对应于已打开的标准输入设备(键盘)多次打开同一个文件,可得到多个不同的文件描述符。编译执行该程序,同时使用另外客户端查看系统进程。6157/ //跳转到进程6157目录下。demo1 //查看demo1程序下进程。//跳转到fd目录下。可使用man 2查看。 转换方式如下(UltraEdit):File–>Conversions–>DOS->UNIX即可。在 linux 下,./xxx.sh执行shell脚本时会提示No such file or directory。再执行,就不会再提示No such file or directory这个问题了。这种其实是因为编码方式不对,如你在win下编辑sh,然后直接复制到 linux 下面。:set ff //回车,显示fileformat=dos。:set ff=unix //重新设置下文件格式。:wq //保存退出。 今天使用SQLyog远程连接mysql时出错plugin caching_sha2_password could not be loaded问题。但在本地cmd 进入命令行窗口:输入命令连接远程连接mysql,发现可以顺利连接。主要问题是 MySQL可视化工具(如: sqlyog )和 MySQL。 与 `netstat` 类似,`ss` 命令可以显示当前系统上的网络连接和监听端口。同样,`-t` 表示 TCP 连接,`-u` 表示 UDP 连接,`-l` 表示显示监听状态,`-n` 表示以数字形式显示端口和IP地址。其中,`-t` 表示显示 TCP 连接,`-u` 表示显示 UDP 连接,`-l` 表示显示监听状态,`-n` 表示以数字形式显示端口和IP地址。然后,你可以根据进程的 PID 使用 `netstat` 或 `ss` 命令查看相关的端口信息。 yum install nettools. 安装netstat。netstat -tunlp|grep <占用端口>yum install lsof 安装lsof。执行 kill -9 <pid>lsof -i:<占用端口>1.查看谁占有了什么端口?2.根据检索到的PID. 按pagedown键,移动红色光标到 zh_CN.UTF-8 UTF-8,如果找不到 dpkg-reconfigure。下一页选择 zh_CN.UTF-8。(没标记下一页没有这一项) 我目前手头上的项目,需要编译在板端 Linux 上运行,但是日常daily调试多在Windows上开发。这就涉及到同一份代码在多平台上的编译个运行。有一次遇到了一个奇怪的现象:跑同样的一份代码,Windows和 Linux 出来的结果是不一致的。最终确定到不一致的原因出现在unordered_map上,就把这次记录总结下来。这次不一致发生在:处理一个状态序列的投票操作。从编程的角度而言,最适合投票操作的容器就是键值对,key放置投票的内容,value放置投票的次数。在C++中,STL提供了两个相关容器:map和un 业务场景:又到了熟悉的业务场景环节,其实应用上有很多,我们为了方便提取日志中部分关键的内容,对接给其他人也好,方便自己统计也罢,都会比每次我们都去服务器上及时查看,或者下载全部日志再筛选要方便的,下面是通过写一个shell脚本来实现该功能~ 当“crontab -e”编辑完成之后,一旦保存退出,那么这个定时任务实际就会写入 /var/spool/cron/ 目录中,每个用户的定时任务用自己的用户名进行区分。crontab 定时任务非常简单,只需执行“crontab -e”命令,然后输入想要定时执行的任务即可。file 指的是命令文件的名字,表示将 file 作为 crontab 的任务列表文件并载入 crontab,若在命令行中未指定文件名,则此命令将接受标准输入(键盘)上键入的命令,并将它们键入 crontab。会打开Vim编辑你的任务。