task_struct

文章目录

前言

宏观上看,操作系统能够同时运行多个进程;微观上看,如果操作系统只有一个处理器,那么在同一时刻只能运行一个进程。

操作系统以很短的时间间隔不停地切换多个进程的执行,这种管理方式需要注意以下问题:

  1. 进程不能彼此干扰。进程 A 的错误不能传播到进程 B。Linux 是一个多用户系统,所以也要确保进程不能读取或修改其它进程的内存,否则就很容易访问其它用户的私有数据。
  2. CPU 时间必须在各种应用程序之间尽可能公平地共享 ,其中一些程序可能比其它程序更重要。内核必须决定为各个进程分配多长时间何时切换到下一个进程 。这又引出了哪个进程是下一个地问题
  3. 在内核从进程 A 切换到进程 B 时,必须确保进程 B 的执行环境与上一次撤销其处理器资源时完全相同。例如,处理器寄存器的内容和虚拟地址空间的结构必须与此前相同。

第 3 项工作与处理器极度相关,不能只用 C 语言实现,还需要汇编代码的帮助。

第 2、3 项工作是称之为调度器的内核子系统的职责。

task_struct

内核在实现上述功能时,使用的最主要的一个数据结构就是 task_struct。

  • 调度相关使用 sched_info 成员,包括优先级、vruntime、调度策略等
  • 上下文信息使用 thread_stack、task_info、stack 成员存储,不同架构的 CPU,这些成员的定义也不同。
  • 内存管理使用 mm 成员,其中页全局目录使用 mm->pgd 存储

除此之外还包括

  • pid,进程号
  • __state,进程状态,如,0: TASK_RUNNING
  • parent,父进程
  • comm,进程名
  • files,进程打开的文件
  • cpu,进程所在的处理器
  • nvcsw:自愿进行上下文切换的次数
  • nivcsw:非自愿进行上下文切换的次数
  • stime:进程在内核态所经过的节拍数
  • utime:进程在用户态所经过的节拍数

打印各字段

task_struct 结构体比较复杂,盯着代码看各个成员有时也不容易理解,最直接的办法就是将各个成员打印出来,理论结合实际,这样可以更加深刻的理解各个字段的含义。

下面我们就写一个内核模块,打印当前系统中各个进程的 task_struct 成员信息

task_struct.c

c 复制代码
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/sched.h> //task结构体
#include <linux/fdtable.h> //files
#include <linux/fs_struct.h> //fs
#include <linux/mm_types.h> //打印内存信息
#include <linux/init_task.h>
#include <linux/types.h>
#include <linux/atomic.h>
#include <linux/delay.h>

void show(struct task_struct *p)
{
	printk("pid: %3d, %16.16s, state: %4d, prior: %3d, static_pri: %3d, "
	       "parent_pid: %3d, count: %3d, umask: %3d, stack:0x%x, \n\t\t"
	       "cpu:%d, nvcsw:%ld, nivcsw:%ld, stime:%lld, utime:%lld, "
	       "policy:%d, vruntime:%lld"
	       "\n",
	       p->pid, p->comm, p->__state, p->prio, p->static_prio, (p->parent)->pid, atomic_read(&(p->files)->count),
	       (p->fs)->umask, p->stack, task_thread_info(p)->cpu, p->nvcsw, p->nivcsw, p->stime, p->utime, p->policy,
	       p->se.vruntime);

	// linux中内核线程的 mm 是空的,要对它进行打印,就会出错,指针错误
	if ((p->mm) != NULL) {
		// 线性区总的页数, 页全局目录
		printk("Total_vm: %ld, pgd:0x%x, ", (p->mm)->total_vm, p->mm->pgd[0]);
	}
	if ((p->active_mm) != NULL) {
		printk("active_mm_pgd:0x%x", p->active_mm->pgd[0]);
	}
}

static int __init print_pcb(void)
{
	struct task_struct *task, *p;
	struct list_head *pos; //双向链表
	int count = 0; //统计当前系统一共有多少个进程

	printk("begin...\n");

	// 对链表遍历时,希望从第一个开始,指向 0 号进程 pcb
	task = &init_task;

	show(task);

	//遍历操作,使用pos指向,传入的参数task指向tasks字段.0号进程的tasks进行遍历。tasks将所有的进程连在一块。
	list_for_each (pos, &task->tasks) {
		//找到一个节点,就可以用这个节点的 tasks 字段,找到这个结构体的地址.对应的字段 tasks
		//此时的p指针已经指向task_struct结构体的首部,后面就可以通过p指针进行操作
		p = list_entry(pos, struct task_struct, tasks);
		show(p);
		count++;
	}

	printk("进程的个数:%d\n", count);

	return 0;
}

static void __exit exit_pcb(void)
{
	printk("Exiting...\n");
}

module_init(print_pcb);
module_exit(exit_pcb);
MODULE_LICENSE("GPL");

Makefile

c 复制代码
obj-m:=task_struct.o


KDIR=/home/liyongjun/project/board/buildroot/Vexpress/build/linux-5.15.18
CROSS_COMPILE=/home/liyongjun/project/board/buildroot/Vexpress/build/linux-5.15.18/../../host/bin/arm-buildroot-linux-uclibcgnueabihf-

all:
	make -C $(KDIR) M=$(PWD) ARCH=arm CROSS_COMPILE=$(CROSS_COMPILE) modules

clean:
	make -C $(KDIR) M=$(PWD) ARCH=arm CROSS_COMPILE=$(CROSS_COMPILE) clean

运行,

使用 qemu 运行一个 4 核 arm 系统,然后安装我们编译的内核模块

bash 复制代码
# tftp -gr task_struct.ko 192.168.31.223
# insmod task_struct.ko 
begin...
pid:   0,        swapper/0, state:    0, prior: 120, static_pri: 120, parent_pid:   0, count:  54, umask:  18, stack:0x80c00000, 
		cpu:0, nvcsw:0, nivcsw:273299, stime:100260000000, utime:0, policy:0, vruntime:0
active_mm_pgd:0x81b70000
pid:   1,             init, state:    1, prior: 120, static_pri: 120, parent_pid:   0, count:   1, umask:  18, stack:0x81096000, 
		cpu:2, nvcsw:311, nivcsw:11, stime:650000000, utime:40000000, policy:0, vruntime:1271261734
Total_vm: 393, pgd:0x811b0000, 
active_mm_pgd:0x811b0000
pid:   2,         kthreadd, state:    1, prior: 120, static_pri: 120, parent_pid:   0, count:  54, umask:  18, stack:0x81098000, 
		cpu:2, nvcsw:59, nivcsw:0, stime:40000000, utime:0, policy:0, vruntime:2859880532
pid:   3,           rcu_gp, state: 1026, prior: 100, static_pri: 100, parent_pid:   2, count:  54, umask:  18, stack:0x8109a000, 
		cpu:0, nvcsw:2, nivcsw:0, stime:0, utime:0, policy:0, vruntime:10781931
pid:   4,       rcu_par_gp, state: 1026, prior: 100, static_pri: 100, parent_pid:   2, count:  54, umask:  18, stack:0x8109c000, 
		cpu:0, nvcsw:2, nivcsw:0, stime:0, utime:0, policy:0, vruntime:12672772
pid:   6,     kworker/0:0H, state: 1026, prior: 100, static_pri: 100, parent_pid:   2, count:  54, umask:  18, stack:0x810cc000, 
		cpu:0, nvcsw:4, nivcsw:0, stime:0, utime:0, policy:0, vruntime:467744348
pid:   7,     kworker/u8:0, state: 1026, prior: 120, static_pri: 120, parent_pid:   2, count:  54, umask:  18, stack:0x810ce000, 
		cpu:3, nvcsw:8, nivcsw:1, stime:90000000, utime:0, policy:0, vruntime:194562752
pid:   8,     mm_percpu_wq, state: 1026, prior: 100, static_pri: 100, parent_pid:   2, count:  54, umask:  18, stack:0x810d0000, 
		cpu:0, nvcsw:2, nivcsw:0, stime:0, utime:0, policy:0, vruntime:19554971
pid:   9,      ksoftirqd/0, state:    1, prior: 120, static_pri: 120, parent_pid:   2, count:  54, umask:  18, stack:0x810d2000, 
		cpu:0, nvcsw:10009, nivcsw:1, stime:0, utime:0, policy:0, vruntime:84093189061
pid:  10,        rcu_sched, state: 1026, prior: 120, static_pri: 120, parent_pid:   2, count:  54, umask:  18, stack:0x810d4000, 
		cpu:2, nvcsw:526, nivcsw:0, stime:10000000, utime:0, policy:0, vruntime:3005160995
pid:  11,      migration/0, state:    1, prior:   0, static_pri: 120, parent_pid:   2, count:  54, umask:  18, stack:0x810d6000, 
		cpu:0, nvcsw:6, nivcsw:0, stime:20000000, utime:0, policy:1, vruntime:0
pid:  12,          cpuhp/0, state:    1, prior: 120, static_pri: 120, parent_pid:   2, count:  54, umask:  18, stack:0x810de000, 
		cpu:0, nvcsw:9, nivcsw:0, stime:0, utime:0, policy:0, vruntime:439359833
pid:  13,          cpuhp/1, state:    1, prior: 120, static_pri: 120, parent_pid:   2, count:  54, umask:  18, stack:0x810e0000, 
		cpu:1, nvcsw:8, nivcsw:0, stime:0, utime:0, policy:0, vruntime:259698436
pid:  14,      migration/1, state:    1, prior:   0, static_pri: 120, parent_pid:   2, count:  54, umask:  18, stack:0x810e2000, 
		cpu:1, nvcsw:6, nivcsw:0, stime:20000000, utime:0, policy:1, vruntime:0
pid:  15,      ksoftirqd/1, state:    1, prior: 120, static_pri: 120, parent_pid:   2, count:  54, umask:  18, stack:0x810e4000, 
		cpu:1, nvcsw:1211, nivcsw:0, stime:0, utime:0, policy:0, vruntime:40372256279
pid:  17,     kworker/1:0H, state: 1026, prior: 100, static_pri: 100, parent_pid:   2, count:  54, umask:  18, stack:0x810e8000, 
		cpu:1, nvcsw:5, nivcsw:0, stime:0, utime:0, policy:0, vruntime:109593599
pid:  18,          cpuhp/2, state:    1, prior: 120, static_pri: 120, parent_pid:   2, count:  54, umask:  18, stack:0x810ea000, 
		cpu:2, nvcsw:8, nivcsw:0, stime:0, utime:0, policy:0, vruntime:59346256
pid:  19,      migration/2, state:    1, prior:   0, static_pri: 120, parent_pid:   2, count:  54, umask:  18, stack:0x810ec000, 
		cpu:2, nvcsw:7, nivcsw:0, stime:20000000, utime:0, policy:1, vruntime:0
pid:  20,      ksoftirqd/2, state:    1, prior: 120, static_pri: 120, parent_pid:   2, count:  54, umask:  18, stack:0x810ee000, 
		cpu:2, nvcsw:686, nivcsw:0, stime:0, utime:0, policy:0, vruntime:2800704118
pid:  21,      kworker/2:0, state: 1026, prior: 120, static_pri: 120, parent_pid:   2, count:  54, umask:  18, stack:0x810f0000, 
		cpu:2, nvcsw:5, nivcsw:0, stime:10000000, utime:0, policy:0, vruntime:11475716
pid:  23,          cpuhp/3, state:    1, prior: 120, static_pri: 120, parent_pid:   2, count:  54, umask:  18, stack:0x810f4000, 
		cpu:3, nvcsw:8, nivcsw:0, stime:0, utime:0, policy:0, vruntime:99372461
pid:  24,      migration/3, state:    1, prior:   0, static_pri: 120, parent_pid:   2, count:  54, umask:  18, stack:0x81104000, 
		cpu:3, nvcsw:7, nivcsw:0, stime:20000000, utime:0, policy:1, vruntime:0
pid:  25,      ksoftirqd/3, state:    1, prior: 120, static_pri: 120, parent_pid:   2, count:  54, umask:  18, stack:0x81106000, 
		cpu:3, nvcsw:563, nivcsw:0, stime:0, utime:0, policy:0, vruntime:15162602723
pid:  26,      kworker/3:0, state: 1026, prior: 120, static_pri: 120, parent_pid:   2, count:  54, umask:  18, stack:0x81118000, 
		cpu:3, nvcsw:5, nivcsw:0, stime:0, utime:0, policy:0, vruntime:9468662
pid:  28,        kdevtmpfs, state:    1, prior: 120, static_pri: 120, parent_pid:   2, count:  54, umask:  18, stack:0x8111c000, 
		cpu:2, nvcsw:142, nivcsw:0, stime:10000000, utime:0, policy:0, vruntime:68424254
pid:  29,     inet_frag_wq, state: 1026, prior: 100, static_pri: 100, parent_pid:   2, count:  54, umask:  18, stack:0x81120000, 
		cpu:1, nvcsw:2, nivcsw:0, stime:0, utime:0, policy:0, vruntime:8684611
pid:  30,      kworker/0:1, state: 1026, prior: 120, static_pri: 120, parent_pid:   2, count:  54, umask:  18, stack:0x81192000, 
		cpu:0, nvcsw:14, nivcsw:0, stime:10000000, utime:0, policy:0, vruntime:82145485871
pid:  31,      kworker/2:1, state: 1026, prior: 120, static_pri: 120, parent_pid:   2, count:  54, umask:  18, stack:0x81194000, 
		cpu:2, nvcsw:28, nivcsw:0, stime:0, utime:0, policy:0, vruntime:2960087740
pid:  32,      kworker/1:1, state: 1026, prior: 120, static_pri: 120, parent_pid:   2, count:  54, umask:  18, stack:0x81196000, 
		cpu:1, nvcsw:116960, nivcsw:0, stime:4110000000, utime:0, policy:0, vruntime:40372906611
pid:  33,      kworker/3:1, state: 1026, prior: 120, static_pri: 120, parent_pid:   2, count:  54, umask:  18, stack:0x811aa000, 
		cpu:3, nvcsw:364, nivcsw:0, stime:10000000, utime:0, policy:0, vruntime:15162450516
pid:  34,       khungtaskd, state:    1, prior: 120, static_pri: 120, parent_pid:   2, count:  54, umask:  18, stack:0x81178000, 
		cpu:2, nvcsw:321, nivcsw:0, stime:0, utime:0, policy:0, vruntime:2967078288
pid:  35,       oom_reaper, state:    1, prior: 120, static_pri: 120, parent_pid:   2, count:  54, umask:  18, stack:0x8117a000, 
		cpu:3, nvcsw:2, nivcsw:0, stime:0, utime:0, policy:0, vruntime:37961818
pid:  36,        writeback, state: 1026, prior: 100, static_pri: 100, parent_pid:   2, count:  54, umask:  18, stack:0x81198000, 
		cpu:1, nvcsw:2, nivcsw:0, stime:0, utime:0, policy:0, vruntime:38309928
pid:  37,       kcompactd0, state:    1, prior: 120, static_pri: 120, parent_pid:   2, count:  54, umask:  18, stack:0x8119a000, 
		cpu:2, nvcsw:76806, nivcsw:0, stime:1090000000, utime:0, policy:0, vruntime:3011151327
pid:  38,          kblockd, state: 1026, prior: 100, static_pri: 100, parent_pid:   2, count:  54, umask:  18, stack:0x811ac000, 
		cpu:1, nvcsw:2, nivcsw:0, stime:0, utime:0, policy:0, vruntime:47985364
pid:  39,          ata_sff, state: 1026, prior: 100, static_pri: 100, parent_pid:   2, count:  54, umask:  18, stack:0x811ae000, 
		cpu:1, nvcsw:2, nivcsw:0, stime:10000000, utime:0, policy:0, vruntime:58046861
pid:  41,           rpciod, state: 1026, prior: 100, static_pri: 100, parent_pid:   2, count:  54, umask:  18, stack:0x81256000, 
		cpu:3, nvcsw:2, nivcsw:0, stime:10000000, utime:0, policy:0, vruntime:57739139
pid:  42,     kworker/u9:0, state: 1026, prior: 100, static_pri: 100, parent_pid:   2, count:  54, umask:  18, stack:0x812cc000, 
		cpu:3, nvcsw:2, nivcsw:0, stime:0, utime:0, policy:0, vruntime:67126213
pid:  43,          xprtiod, state: 1026, prior: 100, static_pri: 100, parent_pid:   2, count:  54, umask:  18, stack:0x812ce000, 
		cpu:3, nvcsw:2, nivcsw:0, stime:0, utime:0, policy:0, vruntime:76917350
pid:  44,     kworker/1:1H, state: 1026, prior: 100, static_pri: 100, parent_pid:   2, count:  54, umask:  18, stack:0x812d0000, 
		cpu:1, nvcsw:70, nivcsw:0, stime:30000000, utime:0, policy:0, vruntime:40370062181
pid:  45,          kswapd0, state:    1, prior: 120, static_pri: 120, parent_pid:   2, count:  54, umask:  18, stack:0x812d2000, 
		cpu:0, nvcsw:3, nivcsw:0, stime:0, utime:0, policy:0, vruntime:433440459
pid:  46,           nfsiod, state: 1026, prior: 100, static_pri: 100, parent_pid:   2, count:  54, umask:  18, stack:0x812d4000, 
		cpu:0, nvcsw:2, nivcsw:0, stime:0, utime:0, policy:0, vruntime:432884339
pid:  47,      kworker/1:2, state: 1026, prior: 120, static_pri: 120, parent_pid:   2, count:  54, umask:  18, stack:0x812d6000, 
		cpu:1, nvcsw:49, nivcsw:0, stime:40000000, utime:0, policy:0, vruntime:359242846
pid:  48,     kworker/u8:2, state: 1026, prior: 120, static_pri: 120, parent_pid:   2, count:  54, umask:  18, stack:0x813cc000, 
		cpu:3, nvcsw:149, nivcsw:7, stime:270000000, utime:0, policy:0, vruntime:15178519976
pid:  52,  irq/33-mmci-pl1, state:    1, prior:  49, static_pri: 120, parent_pid:   2, count:  54, umask:  18, stack:0x813d4000, 
		cpu:0, nvcsw:2, nivcsw:0, stime:0, utime:0, policy:1, vruntime:0
pid:  54,     mmc_complete, state: 1026, prior: 100, static_pri: 100, parent_pid:   2, count:  54, umask:  18, stack:0x81aa0000, 
		cpu:0, nvcsw:2, nivcsw:0, stime:0, utime:0, policy:0, vruntime:476729289
pid:  55,     kworker/0:1H, state: 1026, prior: 100, static_pri: 100, parent_pid:   2, count:  54, umask:  18, stack:0x81aa2000, 
		cpu:0, nvcsw:94, nivcsw:1, stime:130000000, utime:0, policy:0, vruntime:84079734629
pid:  56,      kworker/0:2, state: 1026, prior: 120, static_pri: 120, parent_pid:   2, count:  54, umask:  18, stack:0x81aa4000, 
		cpu:0, nvcsw:257435, nivcsw:1, stime:7380000000, utime:0, policy:0, vruntime:84094426935
pid:  57,      card0-crtc0, state:    1, prior:  49, static_pri: 120, parent_pid:   2, count:  54, umask:  18, stack:0x81aa6000, 
		cpu:3, nvcsw:2, nivcsw:0, stime:0, utime:0, policy:1, vruntime:0
pid:  58,     kworker/3:1H, state: 1026, prior: 100, static_pri: 100, parent_pid:   2, count:  54, umask:  18, stack:0x81882000, 
		cpu:3, nvcsw:74, nivcsw:0, stime:30000000, utime:0, policy:0, vruntime:15161848812
pid:  59,  ext4-rsv-conver, state: 1026, prior: 100, static_pri: 100, parent_pid:   2, count:  54, umask:  18, stack:0x81884000, 
		cpu:0, nvcsw:2, nivcsw:0, stime:0, utime:0, policy:0, vruntime:764178885
pid:  61,     kworker/3:2H, state: 1026, prior: 100, static_pri: 100, parent_pid:   2, count:  54, umask:  18, stack:0x81a88000, 
		cpu:3, nvcsw:3, nivcsw:0, stime:0, utime:0, policy:0, vruntime:279463688
pid:  62,     kworker/2:1H, state: 1026, prior: 100, static_pri: 100, parent_pid:   2, count:  54, umask:  18, stack:0x81a8a000, 
		cpu:2, nvcsw:100, nivcsw:1, stime:80000000, utime:0, policy:0, vruntime:1121465971
pid:  63,     kworker/2:2H, state: 1026, prior: 100, static_pri: 100, parent_pid:   2, count:  54, umask:  18, stack:0x81a8c000, 
		cpu:2, nvcsw:5, nivcsw:0, stime:0, utime:0, policy:0, vruntime:185536371
pid:  80,          syslogd, state:    1, prior: 120, static_pri: 120, parent_pid:   1, count:   1, umask:  18, stack:0x81bf8000, 
		cpu:2, nvcsw:377, nivcsw:10, stime:190000000, utime:220000000, policy:0, vruntime:3021892453
Total_vm: 391, pgd:0x81c08000, 
active_mm_pgd:0x81c08000
pid:  84,            klogd, state:    0, prior: 120, static_pri: 120, parent_pid:   1, count:   1, umask:  18, stack:0x81ba4000, 
		cpu:3, nvcsw:15, nivcsw:42, stime:350000000, utime:300000000, policy:0, vruntime:15200845932
Total_vm: 390, pgd:0x81b8c000, 
active_mm_pgd:0x81b8c000
pid: 136,           udhcpc, state:    1, prior: 120, static_pri: 120, parent_pid:   1, count:   1, umask:  18, stack:0x81ba6000, 
		cpu:3, nvcsw:4, nivcsw:0, stime:0, utime:0, policy:0, vruntime:14252907400
Total_vm: 392, pgd:0x81cac000, 
active_mm_pgd:0x81cac000
pid: 138,               sh, state:    1, prior: 120, static_pri: 120, parent_pid:   1, count:   1, umask:  18, stack:0x81bbc000, 
		cpu:0, nvcsw:121, nivcsw:7, stime:200000000, utime:130000000, policy:0, vruntime:84105463853
Total_vm: 396, pgd:0x81b70000, 
active_mm_pgd:0x81b70000
pid: 155,      kworker/0:0, state: 1026, prior: 120, static_pri: 120, parent_pid:   2, count:  54, umask:  18, stack:0x81bb2000, 
		cpu:0, nvcsw:2, nivcsw:0, stime:0, utime:0, policy:0, vruntime:82150084578
pid: 158,           insmod, state:    0, prior: 120, static_pri: 120, parent_pid: 138, count:   1, umask:  18, stack:0x8111a000, 
		cpu:1, nvcsw:0, nivcsw:0, stime:70000000, utime:0, policy:0, vruntime:40458619481
Total_vm: 391, pgd:0x81b88000, 
active_mm_pgd:0x81b88000
进程的个数:59
# 

简单分析:

一、

处于运行状态的进程有 3 个,分别是

  • 0 号进程 swapper/0,运行在 cpu0 上
  • 84 号进程 klogd,运行在 cpu3 上
  • 158 号进程 insmod,运行在 cpu1 上

二、

insmod 进程为单次运行,所以 nvcsw(自愿进行上下文切换的次数) 和 nivcsw(非自愿进行上下文切换的次数) 均为 0。

0 号进程为空闲进程,只有系统空闲时才会被调度,它的优先级最低,所以自愿进行上下文切换的次数为 0,全都是非自愿进行上下文切换,nvcsw:0, nivcsw:273299

三、

大部分进程的调度策略 policy 都为 0: SCHED_NORMAL,该策略使用 CFS(完全公平调度器) 调度器实现。所以 CFS 是内核用的最多的调度算法。该算法使用 vruntime 这个参数,谁小,下一个就调度谁。关于 CFS 后面有机会再展开讲。

四、

每个进程(包括内核线程和用户空间进程)的栈地址都不同,说明每个进程都有自己独立的栈空间。

五、

所有内核线程的 utime 都为 0,因为它只会在内核态运行。

用户空间进程的 utime 和 stime 都有值,因为它既可以运行在用户空间,也可以通过系统调用让内核帮自己完成某些工作,这个时候该进程就运行于内核空间。

六、

kthreadd 是所有内核线程的父进程,它生于 0 号进程。

init 是所有用户进程的父进程,它也生于 0 号进程。

七、

最繁忙的进程是如下几个

  • swapper/0
  • init
  • kworker/2:1
  • kworker/0:2
  • kworker/1:2

swapper/0 进程很好理解,系统空闲时就会执行它

init 会监控所有用户进程,必要时为其"收尸",所以 CPU 占用较高

kworker 处理中断下半部,内存管理、进程调度也都有参与,所以 CPU 占用率较高

相关推荐
轩辰~8 小时前
网络协议入门
linux·服务器·开发语言·网络·arm开发·c++·网络协议
ARM&开发(Haidong)8 小时前
ARM 获取cpu个数
arm开发
憧憬一下1 天前
PCIe_Host驱动分析_设备枚举
arm开发·嵌入式硬件·嵌入式·pcie·linux驱动开发
7yewh1 天前
嵌入式Linux QT+OpenCV基于人脸识别的考勤系统 项目
linux·开发语言·arm开发·驱动开发·qt·opencv·嵌入式linux
憧憬一下3 天前
PCIe_Host驱动分析_地址映射
arm开发·嵌入式硬件·嵌入式·linux驱动开发·pci/pcie
楼兰公子3 天前
相机主要调试参数
arm开发·驱动·camera·v4l2
7yewh4 天前
嵌入式驱动RK3566 HDMI eDP MIPI 背光 屏幕选型与调试提升篇-eDP屏
linux·arm开发·驱动开发·嵌入式硬件·嵌入式linux·rk·edp
千千道5 天前
深入理解 Linux 内核启动流程
linux·arm开发·驱动开发
徐某人..6 天前
ARM嵌入式学习--第八天(PWM)
arm开发·学习·arm
aiamia6 天前
CAN配置---波特率中断引脚等---autochips-AC7811-ARM-M3内核
arm开发·单片机·mcu·车载系统·汽车