自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+

liang的博客

学习和笔记

  • 博客(55)
  • 收藏
  • 关注

原创 《5.linux驱动开发-第4部分-5.4.驱动框架入门之LED》真正的驱动开发 从 今天的 课程开始!!!5.4.1.何谓驱动框架 subsys_initcall led_class_attrs

真正的驱动开发 从 今天的 课程开始!!!(1)驱动开发工程师内核开发者 预留一些 驱动开发的接口,让我们来使用合作(2)内核维护者5.4.1.2、驱动编程协作要求(1)接口标准化(2)尽量降低驱动开发者难度5.4.1.3、到底什么是驱动框架驱动框架:部分厂家相同的一部分内核维护者已经写好了,再把不同的部分预留好接口,让驱动开发工程师来写。

2023-09-15 20:53:21 188

原创 5.3.11.动态映射结构体方式操作寄存器 结果体指针 5.3.12.内核提供的读写寄存器接口 writel和readl , iowrite32和ioread32

(1)2个寄存器分开独立映射 5.2.17(2) 2 个寄存器 一起映射:5.3.11.1、问题描述(1)仿效真实驱动中,5.3.11.2、实践编码5.3.11.3、分析和总结。

2023-08-11 22:24:16 336

原创 5.3.10.静态映射表建立过程分析

这个结构体数组所记录的几个映射关系被iotable_init所使用,该函数负责将这个结构体数组格式的表建立成MMU所能识别的页表映射关系,这样在开机后可以直接使用相对应的虚拟地址来访问对应的物理地址。在kernel/arch/arm/mach-s5pv210/mach-smdkc110.c中的smdkc110_map_io函数。该函数负责由(1)中的映射表来建立linux内核的页表映射关系。结论:经过分析,真正的内核移植时给定的静态映射表在arch/arm/plat-s5p/cpu.c中的。

2023-08-10 07:30:08 146

原创 5.3.7.自动创建字符设备驱动的设备文件 class_create device_create

驱动注册和注销时信息会被传给udev,由udev在应用层进行设备文件的创建和删除。(2)内核驱动和应用层udev之间有一套信息传输机制(netlink协议)5.3.7.2、解决方案:udev是PC机(嵌入式中用的是mdev)(3)/sys/class/xxx/中的文件的作用。(3)应用层启用udev,内核驱动中使用相应接口。(1)什么是udev?(2)使用mknod创建设备文件的缺点。5.3.7.3、内核驱动设备类相关函数。5.3.8.设备类相关代码分析1。(1)sys文件系统的设计思想。

2023-08-09 21:51:27 286

原创 5.3.4.注册字符设备驱动新接口4 : cdev_alloc

全局变量: .data数据段 ,程序在加载时去执行,程序关闭就没有了,灵活性不够。(4)再次感叹C语言的博大精深,好好去看《4.C语言高级专题》用的时候自动分配,用完自动释放,太灵活。(2)从内存角度体会cdev_alloc用与不用的差别。用时需要申请,用完需要释放。(3)这就是非面向对象的语言和面向对象的代码。5.3.4.1、使用cdev_alloc。5.3.4.2、cdev_init的替代。(2)不使用cdev_init时的编程。(1)cdev_alloc的编程实践。(1)cdev_init源码分析。

2023-08-08 20:59:20 40

原创 5.3.3.注册字符设备驱动新接口3 : alloc_chrdev_region 更简便、更智能的方法是让内核给我们自动分配一个主设备号5.3.2.3、中途出错的倒影式错误处理方法

(1)内核中很多函数中包含了很多个操作,这些操作每一步都有可能出错,而且出错后后面的步骤就没有进行下去的必要性了。我们 程序在 设计时 应该 在 某一个 函数出错后, 释放掉 锁占用 的内存 什么的 什么的。(1)使用MAJOR宏和MINOR宏从dev_t得到major和minor。(2)反过来使用MKDEV宏从major和minor得到dev_t。(2)更简便、更智能的方法是让内核给我们自动分配一个主设备号,5.3.2.2、得到分配的主设备号和次设备号。5.3.2.3、中途出错的倒影式错误处理方法。

2023-08-01 21:46:15 1119

原创 《5.linux驱动开发--5.3.字符设备驱动高级》5.3.1.-2注册字符设备驱动新接口1 :register_chrdev_region注册主次设备号cdev_init 初始化,cdev_add

(1)使用register_chrdev_region + cdev_init + cdev_add进行字符设备驱动注册。(2)新接口:register_chrdev_region/alloc_chrdev_region + cdev。(2)相关函数:cdev_alloc、cdev_init、cdev_add、cdev_del。1.register_chrdev_region : 注册设备驱动 号。早期只有 主设备号,主设备号 类似 身份证号,主设备号 就是 数组 的下标!为什么有主设备号和次设备号?

2023-08-01 20:11:59 187

原创 5.2.17.动态映射操作LED request_mem_region 和 ioremap ;iounmap 解除映射 和 release_mem_region 释放申请的内存

1. 驱动文件 module_test.c 只在 驱动文件:装载和卸载函数 里编写代码测试,就不在app.c里编写代码了。(2)release_mem_region 释放申请的内存。使用完要解除映射时要先解除映射再释放申请的内存。:映射建立时,是要先申请再映射;(1)iounmap 解除映射。5.2.17.1、如何建立动态映射。5.2.17.2、如何销毁动态映射。5.2.17.动态映射操作LED。(1)2个寄存器分开独立映射。5.2.17.3、代码实践。(2)2个寄存器在一起映射。

2023-07-31 21:23:30 234

原创 5.2.16.静态映射操作LED3

(1)先定义好应用和驱动之间的控制接口,这个是由自己来定义的。譬如定义为:应用向驱动写"on"则驱动让LED亮,应用向驱动写"off",驱动就让LED灭。譬如定义为:应用写"1"(字符串)表示灯亮,写"0"表示让灯灭。应用和驱动的接口定义做的尽量简单,譬如用1个字目来表示。1. 驱动文件 module_test.c。1. 驱动文件 module_test.c。2. app.c(Mkfile无更改)5.2.16.1、添加驱动中的写函数。5.2.16.静态映射操作LED3。3.(Mkfile无更改)

2023-07-31 20:15:30 123

原创 5.2.13.驱动中如何操控硬件 5.2.14.静态映射操作LED1 5.2.15.静态映射操作LED2 内核映射表的使用,裸机操作真实物理地址, 驱动是 操作 虚拟地址

物理地址和虚拟地址 基地址不一样,但是偏移量是一样的!!!!1.主映射表位于:arch/arm/plat-s5p/include/plat/map-s5p.h#define S5P_VA_GPIO S3C_ADDR(0x00500000) /* 所有GPIO 基地址 虚拟地址 FD500000 */所以 S5P_VA_GPIO 就等于 虚拟地址 FD5000003)GPIO相关的主映射表位于:arch/arm/mach-s5pv210/include/mach/regs-gpio.h。

2023-07-29 17:04:50 92

原创 5.2.12.读写接口实践 copy_from_user copy_to_user

(1)copy_from_user函数的返回值定义,和常规有点不同。返回值如果成功复制则返回0,如果 不成功复制则返回尚未成功复制剩下的字节数。5.2.12.1、完成write和read函数。(1)目前为止应用已经能够读写驱动(中的内存)1. module_test.c 驱动编写。3. Makefile 文件 无更改。(2)后续工作:添加硬件操作代码。下一节 开始 操控 硬件!5.2.12.2、读写回环测试。2. app.c 应用编写。5.2.12.读写接口实践。5.2.12.3、总结。

2023-07-29 14:22:11 755

原创 5.2.11.添加读写接口

3. module_test.c 添加 .write = test_chrdev_write,(1)copy_from_user,用来将数据从 用户空间复制到内核空间。(2)copy_to_user 从内核空间 复制 到 用户空间。2. Makefile 文件 没有改动 只是增加了 删除 app。注意:复制 是和 mmap的映射相对应去区分的。5.2.11.4、应用和驱动之间的数据交换。5.2.11.1、在驱动中添加。5.2.11.2、在应用中添加。5.2.11.3、测试。

2023-07-25 22:29:46 119

原创 5.2.10.应用程序如何调用驱动 mknod /dev/test c 250 0 创建设备文件,应用app 程序 调用 我们 驱动 壳子

(2)设备文件的关键信息是:设备号 = 主设备号 + 次设备号,使用ls -l去查看设备文件,就可以得到这个设备文件对应的主次设备号。4颗LED不可能 都占用 主设备号,设备号 = 主设备号 + 次设备号。使用mknod创建设备文件:mknod /dev/xxx c 主设备号 次设备号。主设备号: 我们这里是 250;(2)open、write、read、close等。5.2.10.1、驱动设备文件的创建。5.2.10.2、写应用来测试驱动。(1)整体流程梳理、注意分层。(2)后续工作:添加读写接口。

2023-07-25 20:51:23 267

原创 5.2.6-9.字符设备驱动工作原理1 file_iperations register_chrdev

(2)register_chrdev内部将我们要注册的驱动的信息(主要是 )存储在数组中相应的位置。(3)cat /proc/devices查看内核中已经注册过的字符设备驱动(和块设备驱动)(3)驱动源码中提供真正的open、read、write、close等函数实体。(2)核心工作量:file_operations及其元素填充、注册驱动。(1)作用,驱动向内核注册自己的file_operations。(3)设备驱动向内核注册时提供该结构体类型的变量。(2)每个设备驱动都需要一个该结构体类型的变量。

2023-07-24 22:56:31 103

原创 《5.linux驱动开发-第2部分-5.2.字符设备驱动基础》5.2.5.用开发板来调试模块

这个是把 我们在 ubuntu下编译好的module_test.o 放到 我们提前制作好的 根文件系统的目录下。5.2.5.1、设置bootcmd使开发板通过tftp下载自己建立的内核源码树编译得到的zImage。KERN_DIR = /root/driver/kernel 我们编译的 内核 x210 路径。把 开发板 的 网线 插到了 路由器上,没有 做其他的更改,tftp 启动内核成功。这个 Makefile 是最终的运行效果。3. 提前 制作好了 根文件系统(2022年做的,早就忘记 怎么做了)

2023-07-19 22:34:38 80

原创 《5.linux驱动开发-第2部分-5.2.字符设备驱动基础》最简单的模块源码分析 lsmod insmod modinfo rmmod dmesg

(2)fastboot将第1步中得到的zImage烧录到开发板中去启动(或者将zImage丢到tftp的共享目录,uboot启动时tftp下载启动),将来驱动编译好后,就可以在这个内核中去测试。在ubuntu中使用。(4)rmmod(remove module,卸载模块),功能是从当前内核中卸载一个已经安装了的模块,用法是rmmod xxx(注意卸载模块时只需要输入模块名即可,(2)insmod(install module,安装模块),功能是向当前内核中去安装一个模块,用法是insmod xxx.ko。

2023-07-18 21:19:16 515

原创 《3.linux应用编程和网络编程-第9部分-3.9.linux网络编程实践》3.9.6_7.soekct实践编程1_2

(4)accept,返回值是一个fd,accept正确返回就表示我们已经和前来连接我的客户端之间建立了一个TCP连接了,以后我们就要通过这个连接来和客户端进行读写操作,读写操作就需要一个fd,这个fd就由accept来返回了。每一个数据包将来在网络上传递的时候,内部都包含了发送方和接收方的信息(就是IP地址和端口号),所以IP地址和端口号这两个往往是打包在一起不分家的。socket返回的fd叫做监听fd,是用来监听客户端的,不能用来和任何客户端进行读写。(2)整个连接的通信就是由N多个回合组成的。

2023-07-17 20:30:29 343

原创 《3.linux应用编程和网络编程-第9部分-3.9.linux网络编程实践》 inet_addr inet_ntop inet_pton htons

(1)CS架构介绍(client server,客户端(client ) 服务器(server)架构: QQ、迅雷、)(1)inet_aton、inet_addr、inet_ntoa : IP地址转换,这三函数 不支持 IPV6。(2)BS架构介绍(broswer server,浏览器服务器架构 : 优酷网站(不是APP)、)(5)发送方会给各分割报文编号,接收方会校验编号,一旦顺序错误即会重传。(1)TCP协议工作在传输层,对上服务socket接口,对下调用IP层。

2023-07-13 20:29:22 277

原创 3.7.6.线程同步之互斥锁 3.7.7.线程同步之条件变量

注意:man pthread_mutex_init时提示找不到函数,说明你没有安装pthread相关的man手册。pthread_cond_signal/pthread_cond_broadcast 这两个都是 唤醒 条件变量。pthread_mutex_destroy 删除互斥锁。pthread_mutex_init 初始化互斥锁。pthread_mutex_lock 互斥锁 上锁。3.7.7.1、什么是条件变量: 条件变量 跟 互斥锁 有关系的 ,(1)互斥锁又叫互斥量(mutex)

2023-07-12 19:08:48 90

原创 《3.linux应用编程和网络编程-第8部分-3.8.网络基础》 3.8.1.网络通信概述 3.8.3.网络通信基础知识2

(5)我们访问一个网站的流程是:先使用IP地址(譬如谷歌的DNS服务器IP地址为8.8.8.8)访问DNS服务器(DNS服务器不能是域名,只能是直接的IP地址),查询我们要访问的域名的IP地址,然后再使用该IP地址访问我们真正要访问的网站。(3)路由器对内管理子网(局域网),可以在路由器中设置子网的网段,设置有线端口的IP地址,设置dhcp功能等,因此局域网的IP地址是路由器决定的。当局域网中的主机要发送数据包给外网时,路由器要负责将数据包头中的局域网主机的内网IP替换为当前局域网的对外外网IP。

2023-07-11 22:20:34 431

原创 《3.linux应用编程和网络编程-第7部分-3.7.linux线程全解》3.7.2.线程的引入 pthread_create 创建 子线程 3.7.4_5.线程同步之信号量 sem_init

3.7.1.再论进程3.7.1.1、多进程实现同时读取键盘和鼠标运行结果:3.7.1.2、使用进程技术的优势(1)CPU时分复用,单核心CPU可以实现宏观上的并行(2)实现多任务系统需求(多任务的需求是客观的)3.7.1.3、进程技术的劣势(1)进程间切换开销大(2)进程间通信麻烦而且效率低3.7.1.4、解决方案就是线程技术(1)线程技术保留了进程技术实现多任务的特性。(2)线程的改进就是在线程间切换和线程间通信上提升了效率。(3)

2023-07-05 21:37:37 49

原创 3.6.6.异步SIGIO : fcntl(F_GETFL、F_SETFL、O_ASYNC、F_SETOWN) 3.6.7.存储映射IO

* 此时fd 就是 mouse1 ,从fd (mouse1)中 读取 5 个 字节,放到 buf 中 *//* 从文件描述符 0 (0就是标准输入) 中 读取 2 个 字节,放到 buf 中 *//* mousefd 文件描述符 flag 添加 O_ASYNC :可以接收异步通知*/if (mousefd < 0) /* open 返回的 fd 小于 0,说明打开错误 *//* 清空 buf */

2023-06-29 20:37:45 406

原创 3.6.4.IO多路复用原理 IO multiplexing : select和poll

3.6.4.2、select函数介绍 和 3.6.4.3、poll函数介绍。3.6.4.IO多路复用原理 IO multiplexing。3.6.5.1、用select函数实现同时读取键盘鼠标。3.6.5.2、用poll函数实现同时读取键盘鼠标。(3)select和poll :这两个功能一样。外部阻塞式,内部非阻塞式自动轮询多路阻塞式IO。(2)用在什么地方?select和poll 是阻塞式的,3.6.4.1、何为IO多路复用。3.6.5.IO多路复用实践。

2023-06-28 22:56:02 39

原创 《3.linux应用编程和网络编程-第3部分-3.6.高级IO》3.6.1.非阻塞IO 3.6.2.阻塞式IO的困境 3.6.3.并发式IO的解决方案 O_NONBLOCK

当 程序中同时读取键盘和鼠标时,因为都是 阻塞 式 的, 只能按照 程序的顺序,先读取鼠标,在读取键盘, 我们实际使用时,并不是这样的,所有这是 阻塞式的 困境!/* 此时fd 就是 mouse1 ,从fd (mouse1)中 读取 5 个 字节,放到 buf 中 */if (fd < 0) /* open 返回的 fd 小于 0,说明打开错误 *///read 这个函数默认是 阻塞的, 如果我们不按键盘的 话,程序一直阻塞在这里。(2)阻塞式的好处:有利于操作系统性能的发挥,

2023-06-28 21:11:07 41

原创 3.5.4.alarm和pause函数

pause函数的作用就是让当前进程暂停运行,交出CPU给其他进程去执行。当当前进程进入pause状态后当前进程会表现为“卡住、阻塞住”,要退出pause状态当前进程需要被信号唤醒。2. 多次 执行 alarm() , 最后的 alarm 会覆盖 前面的 alarm。3.5.4.1、alarm函数: 内核提供的 闹钟,时间到了,会帮我们执行一个函数。让当前 cpu 挂起, 并交出 cpu 的运行权限。cpu 被当前进程一直占用,3.5.4.alarm和pause函数。(1)内核以API形式提供的闹钟。

2023-06-27 22:07:20 69

原创 3.5.1.什么是信号 signal sigaction

sigaction比signal好的一点:sigaction可以一次得到设置新捕获函数和获取旧的捕获函数(其实还可以单独设置新的捕获或者单独只获取旧的捕获函数),而signal函数不能单独获取旧的捕获函数而必须在设置新的捕获函数的同时才获取旧的捕获函数。本节介绍什么是信号,以及信号由谁发送、由谁处理,怎么处理的问题,目的是站在一定高度上认识信号的作用和意义。本节介绍进程对信号的三种处理方法,signal函数和sigaction函数用来捕获信号时的差异。(1)信号的目的:用来通信 (当前进程的通讯途径)

2023-06-27 20:24:31 91

原创 3.4.17.linux的进程间通信概述 3.4.18.linux的IPC机制1-管道 3.4.19.SystemV IPC介绍

(2)有名管道的使用方法:固定一个文件名,2个进程分别使用mkfifo创建fifo文件,然后分别open打开获取到fd,然后一个读一个写。复杂、大型的程序,因为设计的需要就必须被设计成多进程程序(我们整个程序就设计成多个进程同时工作来完成的模式),常见的如GUI、服务器。(2)管道通信的方法:父进程创建管理后fork子进程,子进程继承父进程的管道fd。(1)管道通信的原理:内核维护的一块内存,有读端和写端(管道是单向通信的)进程 1 和 进程 2 的通讯: 进程 1 只有 写, 进程 2 只有 读。

2023-05-25 20:52:29 74

原创 3.4.16.让程序不能被多次运行

(1)因为守护进程是长时间运行而不退出,因此./a.out执行一次就有一个进程,执行多次就有多个进程。意思就是说当我们./a.out去运行程序时,如果当前还没有这个程序的进程运行则运行之,程序在执行之初去判断一个特定的文件是否存在,若存在则标明进程已经在运行,若不存在则标明进程没有在运行。如果之前已经有一个这个程序的进程在运行则本次运行直接退出(提示程序已经在运行)。,服务器程序只要运行一个就够了,多次同时运行并没有意义甚至会带来错误。(2)这个特定文件要古怪一点,确保不会凑巧真的在电脑中存在的。

2023-05-25 07:34:13 43

原创 3.4.15.使用syslog来记录调试信息

LOG_CONS 当我们的写日志文件,日志文件损坏或写不进去,就会把 错 误,直接 输出到 当前控制台,如果没有出错,就输出到日志信息。/* "789.out" (随便给的)当前程序的命令,NULL也可以,*/LOG_PID 发的每一条日志信息,就会包含当前进程 的 pid。LOG_CRON : 时间 相关的。

2023-05-24 21:46:34 79

原创 3.4.12.进程关系, 3.4.13.守护进程的引入, 3.4.14.编写简单守护进程

可以给我们提供某种服务(譬如nfs服务器给我们提供nfs通信方式),当我们程序需要这种服务时我们可以调用服务器程序(和服务器程序通信以得到服务器程序的帮助)来进程这种服务操作。(2)cron,cron进程用来实现操作系统的时间管理,linux中实现定时执行程序的功能就要用到cron。父进程 open 打开了一个文件,父进程 fork, 就会把 打开的文件 继承给 子进程。daemon,表示守护进程,简称为d(进程名后面带d的基本就是守护进程)(3)进程组(group): 由若干进程构成一个进程组。

2023-05-24 20:18:29 29

原创 3.4.11.进程状态和system函数

一个进程的 诞生 是有 fork 产生的,fork 产生一个子进程后,子进程 独立要自己运行的一段程序 由 excel 函数执行加载,浅度睡眠等待时进程可以被(信号)唤醒,而深度睡眠等待时不能被唤醒只能等待的条件到了才能结束睡眠状态。这个进程当前所有运行条件就绪,只要得到了CPU时间就能直接运行。暂停并不是进程的终止,只是被被人(信号)暂停了,还可以恢复的。就绪态时得到了CPU就进入运行态开始运行。,就算不得不原子操作也应该尽量原子操作的时间缩短。(4)等待态(浅度睡眠&深度睡眠),进程在等待某种条件,

2023-05-20 18:38:00 42

原创 3.4.10.exec族函数及实战2

main函数的原型其实不止是int main(int argc, char **argv),(2)如果用户在执行这个程序时没有传递第三个参数,则程序会自动从父进程继承一份环境变量(/* 当不给 execl 命令路径时,返回值 -1, 代表execl 执行错误 *//* 如果当前目录下有 ls 命令, execl 不传命令路径 也可以执行 */,则程序中的实际环境变量是我们传递的这一份(取代了默认的从父进程继承来的那一份)默认的,最早来源于OS中的环境变量, 例如上面的 ./hello。

2023-05-18 21:50:31 84

原创 3.4.9.exec族函数及实战1

如果exec没有找到path这个文件则直接报错),而加了p的传递的可以是file(也可以是path,只不过兼容了file。加了p的这两个函数会首先去找file,如果找到则执行执行,如果没找到则会去环境变量PATH所指定的目录下去找,如果找到则执行如果没找到则报错),因为我们只能把子进程程序的源代码贴过来执行(必须知道源代码,而且源代码太长了也不好控制)(kill -9 +pid 发信号关掉子进程 ),和基本版本的exec的区别就是:执行可执行程序时会多传一个环境变量的字符串数组给待执行的程序。

2023-05-18 07:50:28 76

原创 3.4.8.waitpid(等待指定子进程的pid)介绍

等待回收PID为pid的这个子进程,如果当前进程并没有一个ID号为pid的子进程,则返回值为-1;-1表示不等待某个特定PID的子进程而是回收任意一个子进程,0表示用默认的方式(阻塞式)来进行等待,返回值ret是本次回收的子进程的PID。/* 这里一定是 子进程 , 子进程先结束,成为僵尸进程 ,一定要保证子进程先结束 */printf("子进程已经被回收,子进程pid = %d \n", ret);把 sleep 加入到 父进程 ,让子进程先结束,子进程进入僵尸进程后 ,父进程 去回收。

2023-05-17 21:39:06 1234

原创 3.4.7.父进程wait回收子进程

(2)wait的返回值pid_t,这个返回值就是本次wait回收的子进程的PID。当前进程有可能有多个子进程,wait函数阻塞直到其中一个子进程结束wait就会返回,wait的返回值就可以用来判断到底是哪一个子进程本次被回收了。status用来返回子进程结束时的状态,父进程通过wait得到status后就可以知道子进程的一些结束状态信息。对wait做个总结:wait主要是用来回收子进程资源,回收同时还可以得知被回收子进程的pid和退出状态。让父进程可以及时的去回收僵尸子进程。父进程调用wait函数后阻塞。

2023-05-17 13:01:44 120

原创 3.4.6.进程的诞生和消亡

每一个进程退出时,操作系统会自动回收这个进程涉及到的所有的资源(譬如malloc申请的内容没有free时,当前进程结束时这个内存会被释放,譬如open打开的文件没有close的在程序终止时也会被关闭)(2)linux系统规定:所有的孤儿进程都自动成为一个特殊进程(进程1,也就是init进程)的子进程。,此时父进程结束时一样会回收子进程的剩余待回收内存资源。所有的 孤儿进程 的 父进程 就是进程1 init进程。父进程先于子进程结束,子进程成为一个孤儿进程。父进程先于子进程结束,子进程成为一个孤儿进程。

2023-05-16 08:23:37 57

原创 3.4.5.父子进程对文件的操作 open 子进程最终目的是要独立去运行另外的程序

本质原因就是因为fork内部实际上已经复制父进程的PCB生成了一个新的子进程,并且fork返回时子进程已经完全和父进程脱离并且独立被OS调度执行。原因是父子进程分离后才各自打开的1.txt,这时候这两个进程的PCB已经独立了,文件表也独立了,因此2次读写是完全独立的。实际上本质原因是父子进程之间的fd对应的文件指针是彼此关联的(很像O_APPEND标志后的样子)实际测试结果标明O_APPEND标志可以把父子进程各自独立打开的fd的文件指针给关联起来,实现分别接续写。子进程继承父进程中打开的文件。

2023-05-15 23:17:24 56

原创 3.4.4.fork创建子进程

(4)典型的使用fork的方法:使用fork后然后用if判断返回值,并且返回值大于0时就是父进程,等于0时就是子进程。)fork的返回值在子进程中等于0,在父进程中等于本次fork创建的子进程的进程ID。k函数调用一次会返回2次,返回值等于0的就是子进程,而返回值大于0的就是父进程。如果操作系统需要一个新进程来运行一个程序,那么操作系统会用一个。(1)每一次程序的运行都需要一个进程。拿老进程 来复制 一个 新进程。现有的进程来复制生成一个新进程。(2)多进程实现宏观上的并行。复制生成的新进程叫子进程。

2023-05-15 22:36:42 89

原创 3.4.3.进程的正式引入 getpid 和 getppid

getuid 获取当前进程的用户(root/aston/)ID 、geteuid (有效用户 ID ) 、getgid 获取当前进程 组 ID 、getegid (有效组 ID )(3)进程控制块PCB(process control block),内核中专门用来管理一个进程的数据结构。一个静态的可执行程序a.out的一次运行过程(./a.out去运行到结束)就是一个进程。getpid 获取进程ID、getppid 获取父进程ID。给每个进程 分配的一个唯一的数字标号,来标识 这个进程。

2023-05-15 20:55:22 127

原创 3.4.2.进程环境 environ

setenv : 设置环境变量, 当前进程的环境变量,你只能删除你当前进程的环境变量。操作系统很重要的就是 虚拟地址 ,虚拟地址到物理地址的映射(linux 、windows)每一个进程中都有一份所有环境变量构成的一个表格,也就是说我们当。所以一旦程序中用到了环境变量那么程序就和操作系统环境有关了。(2)每个进程的逻辑地址空间均为4GB(32位系统)所有的应用程序都是从 0 地址(虚拟地址)开始的,(1)操作系统中每个进程在独立地址空间中运行。(3)0-1G为OS, 1-4G为应用。

2023-05-15 12:44:00 64

STM32F103C8Tx 运行RT-Thread

STM32F103C8T6 通用版 工程 和 RT_Thread 工程

2023-05-27

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除