
嵌入式学习
文章平均质量分 89
5个月嵌入式学习
昵称p
重生之我是嵌入式软件工程师
展开
-
系统编程-多路IO复用
当有文件描述符就绪时,select 函数会返回,并告知哪些文件描述符已经准备好进行读取或写入操作。应用程序需要将需要监听的文件描述符和事件类型添加到 pollfd 数组中,然后调用 poll 函数进行监听。当有文件描述符就绪时,epoll_wait 函数会返回,并告知哪些文件描述符已经准备好进行读取或写入操作。-- 因为 selcet 函数会把没有就绪的文件描述符从集合中清除,所以当前在集合中的文件描述符不清楚。当有文件描述符就绪时,poll 函数会返回,并告知哪些文件描述符已经准备好进行读取或写入操作。原创 2024-09-09 20:05:56 · 1111 阅读 · 0 评论 -
系统编程-数据库
- mysql_fetch_array() -- 从结果集中获取一行数据,返回一个关联数组。-- mysql_fetch_assoc() -- 从结果集中获取一行数据,返回一个关联数组。-- mysql_fetch_object() -- 从结果集中获取一行数据,返回一个对象。-- mysql_fetch_row() -- 从结果集中获取一行数据,返回一个指针数组。-- mysql_fetch_row() -- 从结果集中获取一行数据,返回一个指针数组。原创 2024-09-03 18:29:53 · 1084 阅读 · 0 评论 -
系统编程-UDP
适用场景: UDP适用于需要快速传输和实时性要求较高的应用,如语音和视频流、在线游戏、实时传感数据等。速度和低延迟: 由于没有连接状态维护和复杂的确认机制,UDP的开销比TCP小,因此在速度和延迟方面表现更好。send_to函数有接受方的ip和port,接收方bind了ip和port,所以发送方和接收方就建立了联系。无拥塞控制: UDP不具备TCP的拥塞控制机制,因此在网络拥塞的情况下,UDP数据报可能会丢失或延迟增加。来实现组播,给这个组的IP和端口发送信息,会转发给所有在这个组播中的套接字。原创 2024-09-03 18:25:43 · 1252 阅读 · 0 评论 -
系统编程-TCP
也就是说,第一次握手不可以放数据,其中一个简单的原因就是会让服务器更加容易受到攻击了。假设建立TCP连接仅需要两次握手,那么如果第二次握手时,服务端返回给客户端的确认报文丢失了,客户端这边认为服务端没有和他建立连接,而服务端却以为已经和客户端建立了连接,并且可能服务端已经开始向客户端发送数据,但客户端并不会接收这些数据,浪费了资源。:服务端在收到客户端发来的报文后,会随机生成一个服务端的起始序列号y,然后给客户端回复一段报文,其中包括标志位SYN=1,ACK=1,序列号seq=y,确认号ack=x+1。转载 2024-09-03 14:33:28 · 911 阅读 · 0 评论 -
系统编程-网络编程
3、A 将源 MAC 地址(AAAA)与网关 MAC 地址(ABAB)封装在数据链路层头部,又将源 IP 地址(192.168.0.1)和目的 IP 地址(192.168.2.2)(注意这里千万不要以为填写的是默认网关的 IP 地址,从始至终这个数据包的两个 IP 地址都是不变的,只有 MAC 地址在不断变化)封装在网络层头部,然后发包。路由器收到的数据包有目的 IP 也就是 C 的 IP 地址,需要转化成从自己的哪个端口出去,很容易想到,应该有个表,就像 MAC 地址表一样。原创 2024-09-03 14:16:58 · 873 阅读 · 0 评论 -
系统线程-多线程2-互斥量、信号量、条件变量
- linux系统中提供了两个信号量实现,一种是System V信号量,另一种是POSIX信号量,它们的作用是相同的,都是用于同步进程之间及线程之间的操作,以达到无冲突地访问共享资源的目的。-- 这里注册函数就有了意义,如果在上锁完,还没有进行解锁,线程就结束的话,可以利用注册函数,在注册函数中写解锁的操作,这样就算线程结束,锁也会被解锁。2、某些线程运行后,有时需要等待一定的条件才会继续执行,如果条件不满足就会等待,而条件的达成, 很可能取决于另一个线程。-- 条件变量主要是解决上面的第二个问题。原创 2024-08-29 19:51:20 · 1126 阅读 · 0 评论 -
系统编程-多线程1
由前面的学习 可知,实现进程间通信需要借助 Linux 操作系统中的专门通信机制,这些通信机制将占用大量的系统资源,线程间可以共享数据,更容易通信,因此引入了线程的概念。要注意的是由于线程共享了进程的资源和地址空间,因此,任何线程对系统资源的操作都会给其他线程带来影响,同时编写多线程程序,最复杂的事情是处理好各线程对共享资源的访问控制。-- 线程是在并发执行的多道执行路径,是一个更加接近于执行体的概念,拥有独立的执行序列,是进程的基本调度单元,每个进程至少都有一个。(同一进程内的线程共享进程的地址空间)原创 2024-08-28 19:58:24 · 958 阅读 · 0 评论 -
系统编程-信号量集
该参数会将第四个参数共用体中的 val 的值赋值给该信号量集中的第 semnum 个信号量。-- 该函数由三个参数和四个参数的版本 取决于 cmd 而定。sem_op:要对信号量进行什么操作 +1 还原 -1 消耗。sem_num:信号量的下标 要对哪一个信号量来进行操作。-- 对信号量进行减操作 就是对信号量进行抢占的过程。-- 对信号量进行加操作 就是对信号量进行还原的过程。-- 我们可以使用信号量来实现进程对资源独占。-- nsems:表示该信号量集中有几个元素。-- cmd:要进行的具体的操作。原创 2024-08-27 17:55:55 · 1015 阅读 · 0 评论 -
系统编程-共享内存
- 进程无法直接对共享内存进行操作。-- 共享内存缺少同步机制指的是在多个进程或线程访问同一块内存区域时,这些进程或线程之间缺乏协调和控制,从而可能导致数据一致性问题或竞争条件。也就是小于1页是按1页算,大于1页按页向上取整,如1.5页就是2页,2.5页就是3页。-- 我们映射成功之后,可以获取到共享内存的首地址,可以直接将他当作一个数组来操作。-- 使用该函数拷贝到共享内存中为数据的写入, 将数据从共享内存中拷贝出来为读取。-- 如果传输的数据是字符串的格式的话,相当于对字符数组做操作,直接输入即可。原创 2024-08-27 17:48:14 · 1051 阅读 · 0 评论 -
系统编程-消息队列
键值:获取消息队列 id 的唯一标识符,一个键值对应一个消息队列的 id,是八位的十六进制,例如 0x12345678。msgflg:填0是阻塞发送,如果消息队列空间不够,会阻塞,直到有空间可以进行写入。例如 填写-3, |-3| == 3 ,那么可以读取 1 或2 的消息类型。系统关,消息队列关)-- 所有进程都可使用。msqid:用于区分不同的消息队列 也代表该消息队列的号(id)-- 消息队列可以解决的问题:多个进程间进行数据的传输。-- 指令:ipcs -q 只查看消息队列。原创 2024-08-27 17:38:23 · 1215 阅读 · 0 评论 -
系统编程-管道
每个进程各自有不同的用户地址空间,任何一个进程的全局变量在另一个进程中都看不到,所以进程之间要交换数据必须通过内核,在内核中开辟一块。-- 因为无名管道使用范围有限(只能在父子进程之间),为了让任意的两个进程都可以使用管道通信,我们就可以用有名管道.-- 因为我们获取的是文件描述符,所以可以直接使用 read 和 write 函数来进行数据的写入和读取。-- 6 管道是单向的,一边要么读,一边要么写,不可以又读又写,想要一边读一边写,那就创建2个管道。-- 向管道中写数据,从管道中读数据。原创 2024-08-25 11:03:18 · 1305 阅读 · 0 评论 -
系统编程-lvgl
- LVGL是一个开源的嵌入式图形库,用于创建图形界面应用程序。它提供了丰富的图形元素和用户界面控件,能够在各种嵌入式平台上运行,包括单片机和微处理器。-- Gui和LVGL是两个相关的概念。GUI是指图形用户界面,是用户与计算机进行交互的界面。LVGL是一个开源的GUI库,可以用于创建嵌入式系统中的图形用户界面。-- lvgl提供了一套丰富的图形绘制和交互功能,可以在嵌入式设备上创建漂亮、交互式的用户界面。它支持多种显示控制器和输入设备,并具有高度可定制性。原创 2024-08-22 20:07:56 · 1167 阅读 · 0 评论 -
系统编程-信号
- 1~31号信号是从unix上面继承过来的 不可靠信号 没有排队机制。-- 主要去搞清楚 一些信号是如何产生的以及如何使用。-- 能实现 上下切歌、播放、暂停、自动播放功能。-- 每一个信号用一个整型常量宏表示,以。-- 34~64是后面补充的信号 可靠信号。-- 需要依靠改造 17 信号来实现。-- linux系统下的进程间通信。-- 实现无界面的 MP3 播放器。-- 信号是进程在运行过程中,由。-- 信号大部分都是让进程死亡的。发过来的消息(事件)。-- 在终端上发送信号。信号改造函数(重点)原创 2024-08-22 20:04:34 · 1070 阅读 · 0 评论 -
系统编程-进程初步2
- 一种非常特殊的进程,它几乎已经放弃了所有内存空间,没有任何可执行代码,也不能被调度,仅仅在进程列表中保留一个位置,记载该进程的退出状态等信息供其他进程收集,除此之外,僵尸进程不再占有任何内存空间。-- wait函数等待的任意一个子进程,谁先死,先执行那个,而下面这个函数可以等待具体哪个进程。-- exec函数族中的函数功能效果是完全一样的,只是传参不同,所以只需要记住一个函数原型即可。-- 可以执行系统命令,主要原理是创建一个子进程,用exec函数族中的其中一个函数执行系统命令。,包括所有的子进程。原创 2024-08-20 17:25:49 · 1332 阅读 · 0 评论 -
系统编程-进程初步1
- 进程Process是指计算机中已运行的程序,是系统进行资源分配和调度的基本单位,是操作系统结构的基础。-- windows下查看进程使用任务管理器进行查看。-- 之前我们从主函数的return 0进行退出。-- 该指令主要用来获取进程的进程号。-- STAT:表示进程的当前状态。-- exit和_exit的区别。-- 程序运行起来就是一个进程。-- linux下如何查看进程。-- 主要用来获取进程间状态。-- PPID:父进程号。-- PID:进程号。-- 进程在系统中是。原创 2024-08-19 20:03:17 · 760 阅读 · 0 评论 -
系统编程-文件属性和目录操作
- 注:程序在哪里运行他的工作路径就在哪里 ,程序中所有的相对路径的文件就是基于工作路径来实现的。仿写 find 指令 ./a.out 路径 文件名 or 后缀 -- 打印出来所有文件的绝对路径。注:stat 函数如果去获取软链接文件的信息 实际获得的是源文件的信息。- ./a.out 路径 显示该路径下的所有文件的详细信息。- ./a.out 显示当前路径下的所有文件的详细信息。-- 目录操作主要的目的:让程序知道路径下有什么文件存在。-- 可以获取文件的详细信息。-- 实现仿写 ls -l。原创 2024-08-18 19:13:07 · 1222 阅读 · 0 评论 -
系统编程-文件操作和时间编程
缓冲区又称为缓存,是内存空间的一部分。也就是说,计算机在内存中预留了一定的存储空间,用来暂时保存输入或输出的数据,这部分预留的空间就叫做缓冲区。例如:scanf函数。有时候,从键盘输入的内容,或者将要输出到显示器上的内容,会暂时进入缓冲区,待时机成熟,再一股脑将缓冲区中的所有内容“倒出”,我们才能看到变量的值被刷新,或者屏幕产生变化。原创 2024-08-18 08:52:27 · 748 阅读 · 0 评论 -
系统编程-常用工具2
- 1、"="是最普通的等号,在Makefile中容易搞错赋值等号,使用 “=”进行赋值,变量的值是整个Makefile中最后被指定的值。经过上面的赋值后,最后VIR_B的值是AA B,而不是A B,在make时,会把整个Makefile展开,来决定变量的值。-- 注:s和n都是一步一步执行的。-- 目标就是指要干什么,或说运行 make 后生成什么,-- 调试的大概过程:1 添加断点 2 运行 3 调试。-- 注:在makefile文件中写注释的符号是#-- make指令执行后,会去当前所在的路径。原创 2024-08-15 20:04:39 · 851 阅读 · 0 评论 -
系统编程-常用工具
Linux vi/vim 所有的 Unix Like 系统都会内建 vi 文书编辑器,其他的文书编辑器则不一定会存在。vim 具有程序编辑的能力,可以主动的以字体颜色辨别语法的正确性,方便程序设计。-- 如果想每次用vim打开文件后,都会在.c文件中有一个初始的内容。-- 编辑器 - 编写代码的工具。-- vim的功能有很多,基本上键盘上的每一个键,都有相对应的功能。想了解的可以去这个网站。-- 主要更改的文件是将我发的文件的最后,更改如果打开.c文件就会显示的内容。原创 2024-08-14 18:49:25 · 1146 阅读 · 0 评论 -
系统编程-认识Linux及常用指令
- 目录结构 -(树)linux下的路径:绝对路径:从/根目录开始的路径相对路径:从当前目录开始bin-- 放的是可执行程序,例如"./ls",可以省略"./",直接在中断输入ls,系统就会自动从bin目录下找。etc -- 环境变量 --系统配置的路径-- 如果将a.out复制到bin/目录下,就可以直接执行,因为系统自动去bin目录下找,(这就是系统自己配置的路径。-- etc/profile 配置环境变量的文件。原创 2024-08-13 19:00:03 · 1314 阅读 · 0 评论 -
c语言-经典例题
- C y<=5 --是关系运算符的优先级大于&& -- 是逻辑运算符。-- B p本来是个指针(也就是地址),*p是解地址,所以 * p为空间。(2)-- const修饰*p,表示指针的值可以改变,但是地址所指向的空间的值不可以改变。(3)-- const修饰*p,表示指针的值可以改变,但是地址所指向的空间的值不可以改变。(1)-- const修饰p,表示指针的值不能改变,但是地址所指向的空间的值可以改变。原创 2024-08-12 18:52:36 · 965 阅读 · 0 评论 -
C语言-栈、队列、二叉树
- 链表的头插法 --因为链表是从头开始遍历的。(1)线性队列:数组。原创 2024-08-10 14:05:29 · 748 阅读 · 0 评论 -
c语言-文件
函数原型:size_t fwrite(const void *ptr,size_t size,size_t nmemb,FILE *stream);函数原型:size_t fread(const void *ptr,size_t size,size_t nmemb,FILE *stream);3. a -- 追加,若文件存在,在文件末尾追加,若文件不存在,创建文件。2. w -- 只写,若文件存在,覆盖,若文件不存在,创建文件。原创 2024-08-08 20:45:46 · 1207 阅读 · 0 评论 -
c语言-链表1
函数返回值:void * -- 开辟的空间的地址 -- 任意类型 -- 方便强转成你需要的类型。(1)线性存储 -- 地址连续 -- 自动开辟,自动释放 -- 默认是线性存储。-- 数据的一种存储方式 -- 链式存储。c -- 初始化的内容 -- 一般初始化为0。(2)链式存储 -- 地址不连续 --s -- 要初始化的空间地址。原创 2024-08-06 19:20:33 · 1312 阅读 · 0 评论 -
c语言-编译预处理
h文件中使用较多。原创 2024-08-05 20:38:57 · 1328 阅读 · 0 评论 -
c语言-结构体(2)共用体和枚举
(3)共用体的最终大小是(2)的基础上(也就是在字节数最大的基础上补到整数倍),基本数据类型最大的成员变量的整数倍。tip:先找到最大的字节数为13,然后补到最大基本数据类型的整数倍,也就是8的整数倍,所以最终大小为16。-- 自定义的类型 -- enum{标识符};1、自定义数据类型 -- union 类型名{成员变量};-- 在声明类型的同时进行定义变量。-- 先声明类型,再定义变量。2、声明共用体类型 -- 不占用内存空间。原创 2024-08-05 18:16:18 · 626 阅读 · 0 评论 -
c语言-结构体
a.普通的定义b.宏定义-- #define-- 它是预处理中的宏定义命令,在预处理时进行简单的字符串替换,不作正确性检测。-- #define的弊端:-- 只有a被定义为指针类型,b是int类型。这是因为宏定义只是简单的替换,很容易再使用的时候出现错误,如放在式子中优先级的问题之类。c.类型重定义-- typedef-- typedef是关键字,在编译时处理,有类型检测的功能,它在自己的作用域内给一个数据类型取一个新的名字。typedef主要用来定义数组、指针、结构体等类型。2、初始化。原创 2024-07-31 17:02:37 · 727 阅读 · 0 评论 -
C语言-函数例题
他说比第 4 个人大 2 岁。他说比第3 个人大 2 岁。问第 3 个人,又说比第 2 个人大 2 岁。问第 2 个人,说比第一个人大 2 岁。最后问第一个人,他说是 10 岁。1、编写一个函数实现该功能:从键盘输入一个字串符, 再输入两个正整数 m 和 n, 输出字符串中从 m 开始, 连续 n 个字符。2、一个皮球从 100 米高度自由落下,每次落地后反弹回原高度的一半再落下,再反弹。3、写两个函数,分别求两个整数的最大公约数和最小公倍数,用主函数调用这两个函数,并输出结果,两个整数由键盘输入。原创 2024-07-30 17:41:04 · 192 阅读 · 0 评论 -
C语言-函数
1、返回值类型 函数名(形参){函数体};(1)返回值类型 --可以是所有的数据类型 包括void(无类型)(2)函数名 -- 同标识符-- 组成 :数字、字母、下划线--要求:不能是数字开头不能是关键字区分大小写有意义 -- 望文生义双驼峰命名 --Get_User_Name,不强制要求,但最好养成习惯。原创 2024-07-30 17:07:07 · 1318 阅读 · 0 评论 -
指针经典例题
首先,scanf函数,接收的是地址,排除A,B,而且输出地址的格式是%p,而不是%d。没有赋初始值,是野指针,--答案是ef --根据%s的特性,从给定的地址开始,直到遇到'\0'结束。--答案选D,a是数组首个元素的地址,a+2,是第3个元素的地址,加个*,就是解地址,就得到元素空间。--答案是:2,5 --原本&a+1的地址转移到了a[4]的下一个元素,然后被强转为4字节。--答案是YES,因为常量区中的值不会有重复,相同的值地址是一样的。--tip: * (p--)与* p--的效果一样,原创 2024-07-28 17:36:10 · 440 阅读 · 0 评论 -
c语言-指针
例如 * p++,是先执行++运算符,这里的++运算符是指p的运算,这里的p++是先运行后++,也就是先把p给前面的运算符使用,先解地址得到值,并执行printf,而p的值也会改变,会在原来的编号后面加4字节,这里的编号不是真正的物理地址,相当于一个寄存器对物理地址的编号,一位是一个字节,所以直接加4。c[0] = a,c代表是首行元素的地址,上面说到[]有解地址的作用,这里c[]就代表是单个元素的地址,c[0]就是数组的首个元素的地址, c[0][0]是首个元素,而&[0][0]是首个元素的地址。原创 2024-07-26 21:08:38 · 1387 阅读 · 0 评论 -
c语言-数组(3)
3、按以下规律翻译密码: 将每一个字母变成它后面的字母,例如,将 A 变成 B,B 变成 C,…,Z 变成 A,非字母字符不变,“!(回文:这个字符串顺读和反读是一样的。4、输入密码,设置一个密码,然后输入密码,机会为 3 次,三次密码错误就直接退出。2、输入一行字符,统计其中大写字母的个数,并将所有的大写字母转化成小写字母后输出。注:注意for循环的范围,注意字符串结束符是'\0',注意函数的实现原理。例如:strcpy() ,strcat(),strcmp()a)空格 b)\0 c)e d)f。原创 2024-07-25 16:31:18 · 362 阅读 · 0 评论 -
c语言-数组(2)字符数组
作为字符串的数据显示,scanf中空格的作用是结束当前变量的输入,进入下一个变量的输入,不能接收空格,有的题目中是统计空格个数,就不可以用scanf,只能用gets。--getc -输入一个字符 --putc -输出一个字符。--gets -输入一个字符串s --保存输入的字符首地址。2、字符串 <->字符串数组 -- 字符串的本质就是一个字符数组。-- 一维数组 -- 字符型数组。原创 2024-07-24 19:51:58 · 757 阅读 · 0 评论 -
c语言-数组(1)
-直接提供具体的数据 --int类型 --例如:int num[5] --5即为长度--宏定义提供数据 --#define --替换 --建议使用--通过键盘输入数组长度 --scanf -- gcc编译器认可,其他编译器不认可。c) 初始化-- 在定义变量的同时,进行初始化 --{}原创 2024-07-23 20:29:31 · 1057 阅读 · 0 评论 -
经典例题-流程控制语句
例如:第一个完全数是 6,它有约数 1、 2、 3、 6,除去它本身 6 外,其余 3 个数相加, 1+2+3=6。第二个完全数是 28,它有约数 1、 2、 4、 7、 14、 28,除去它本身 28 外,其余 5 个数相加, 1+2+4+7+14=28。B选项E=0,1,2,3.。12.有一个分数序列:2/1,3/2,5/3,8/5,13/8,21/13,... 求出这个数列的前 20 项之和。4.已知 a,b,c 都是 1 位整数,求当三位数 abc+cba 的值为 1333 时 a,b,c 的值。原创 2024-07-22 17:10:06 · 964 阅读 · 0 评论 -
流程控制语句
tip 4:在将小数强转为整数类型时,通常。原创 2024-07-22 08:57:56 · 698 阅读 · 0 评论 -
c语言数据类型-运算符
(1)"&" --按位与 --全1为1,与0则0 (2)"|" --按位或 --全0为0,或1则1。(5)"<<" --左移运算符 --放大,原数据*2的位移次方倍 --左移一位,相当于乘2。sizeof --"整形表达式" --结果是long类型数据 --获取数据类型的空间大小。(6)">>" --右移运算符 --缩小,原数据/2的位移次方倍。注:这题就是因为前面的判断条件为假,所以后面的判断条件。(3)"^" --按位异或 --相同为0,不同为1。(4)"~" --按位取反 --0变1,1变0。原创 2024-07-18 17:40:30 · 618 阅读 · 0 评论 -
c语言数据类型
tip:c语言是的语言详细。原创 2024-07-17 18:16:35 · 845 阅读 · 0 评论 -
嵌入式学习
1 linux指令回顾1.1 改变字体大小1.2 查漏补缺ls -a 显示的文件包括隐藏文件 “.”是当前路径 “..”是当前路径的上一个路径 编辑器的快捷键 cp是复制文件 mv是剪切文件,源文件丢失,可以用来改名 tar指令,c-压缩 ,x-解压,z-压缩成gz格式,v-显示过程,f-指定文件名 在线下载安装:sudo apt-get install ... history 查看历史指令原创 2024-07-16 16:55:04 · 174 阅读 · 0 评论