自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(117)
  • 收藏
  • 关注

原创 linux性能监控命令

2023-08-21 09:55:36 238

原创 互斥锁、自旋锁、读写锁和文件锁

互斥锁、自旋锁和读写锁用于解决多线程同步的问题文件锁适用于多个进程同时操作同一文件,这时很容易导致文件中的数据发生混乱。

2023-08-20 19:09:13 344

原创 程序的编译流程

程序的编译过程大致可以分为以下几个阶段

2023-08-20 19:04:09 249

原创 实时操作系统与非实时操作系统

实时操作系统(RTOS)是指当外界事件或数据产生时,能够接受并以足够快的速度予以处理,其处理的结果又能在规定的时间之内来控制生产过程或对处理系统做出快速响应,调度一切可利用的资源完成实时任务,并控制所有实时任务协调一致运行的操作系统。在上面的图中右边的任务优先级高于左边的任务,先看实时操作系统的,当优先级更高的任务2就绪的时候,即便任务1正在运行中,也必须立刻交出CPU的使用权,就跟中断一样,先执行任务2,等任务2执行完或者主动挂起(sleep)让出CPU的时候,任务1才能接着运行。

2023-08-20 19:01:33 1136

原创 Linux进程调度

所有待执行进程都以vruntime为key放到一个由红黑树组成的队列中,每次被调度执行的进程,都是这个红黑树的最左子树上的那个进程,即vruntime时间最少的进程,这样就保证了所有进程的相对公平。实时进程代表那些需要及时响应的进程,否则用户就会感觉到延时,比如你的终端等待你的输入,你的subline等待你的输入,当你交互的时候,这些进程都需要及时的响应。实时的进程因为是特殊的进程,不能等待太久,所以实时进程的优先级在0-99直接,普通进程的优先级在100-139之前。以什么样的数据结构存储的呢?

2023-08-20 18:40:52 165

原创 虚拟内存机制2

转载自公众号:在下小神仙。

2023-08-20 18:38:43 133

原创 虚拟内存机制1

Linux 提出 SWAP 的概念,Linux 中可以使用 SWAP 分区,在分配物理内存,但可用内存不足时,将暂时不用的内存数据先放到磁盘上,让有需要的进程先使用,等进程再需要使用这些数据时,再将这些数据加载到内存中,通过这种”交换”技术,Linux 可以让进程使用更多的内存。在进程加载系统库时,总是先分配一块内存,将磁盘中的库文件加载到这块内存中,在直接使用物理内存时,由于物理内存地址唯一,即使系统发现同一个库在系统内加载了两次,但每个进程指定的加载内存不一样,系统也无能为力。

2023-08-20 18:31:47 129

原创 五分钟粗略了解Linux内核

很多时候数据是操作的内存的数据,计算机不会频繁的将数据刷到磁盘。你可以把内核看做一个Manager, 这个Manager管理资源的共享和隔离,例如给每个进程分配多大的资源。你可以把内核看作一个库,例如read write这些函数,内核提供了许多系统调用,供我们的应用程序使用。进程之间操作资源的时候,不能相互持有对方的资源而不释放,所以还需要有锁的机制。我们的电脑为什么可以连接usb和手机,是因为我们的内核有设备驱动驱动。当你使用微信的时候,你的第一想法是不是摇一摇,先找下好友哈哈。是不是也是需要管的呀。

2023-08-20 18:24:33 182

原创 c语言--浮点数(float)与0值比较

已知某两栋建筑物之间的实际距离为200m,用一个误差范围为1m的测量工具进行测量,得到4组数据。也就是在误差范围为1m的情况下,我们认为在(200-1)m~(200+1)m即199m~201m范围内才是有效的数据。其次,计算机浮点数的精度在单精度float类型下,只有7位,在进行浮点运算的时候,这个精度往往会导致运算的结果和实际期望的结果之间有误差。现在的计算机大部分都是数字计算机,不是模拟机,数字机的离散化的数据表达方法自然无法精确表达大部分的数据量。由此可以看出,程序输出的结果并不是其被赋予的值。

2023-08-10 10:05:25 888

原创 c语言-qsort函数

qsort就是C语言中的快排函数,包含在stdlib.h头文件中,函数一共有四个参数,没有返回值。1.首先来了解一下什么是 void* ,这个是无具体类型的指针,void * 的指针是非常宽容的,可以接收任意类型的数据。常常用来临时存放数据,等到需要使用数据时,我们必须要强制类型转换成某一具体类型的数据,才能对数据进行操作。对void *pa,接收了一个整型 a 的地址,我们对指针pa 进行强制类型转换(int*),再解引用 pa即可对变量a 进行操作。

2023-08-07 12:04:06 627 2

原创 指针常量、常量指针、常量指针常量

2023-07-18 14:49:15 178

原创 CAN总线

CAN 是 Controller Area Network 的缩写(以下称为 CAN),是 ISO 国际标准化的串行通信协议。在北美和西欧,CAN 总线协议已经成为汽车计算机控制系统和嵌入式工业控制局域网的标准总线,并且拥有以 CAN 为底层协议专为大型货车和重工机械车辆设计的 J1939 协议。

2023-07-12 14:27:21 1438

原创 C语言宏定义常见题型

但这种方法不适用在a,b是浮点数的情况下,VC下测试的。b=a-b;a=a-b;既适用在a,b是浮点数的情况下,也适用在a,b是整数的情况下。

2023-05-13 21:36:18 1033 2

原创 C语言结构体位域

struct 位域结构名类型 位域名:位域长度其中位域列表的形式为: 类型说明符 位域名:位域长度这种定义方式,极大的节省了空间,应用场景多为网络数据包格式定义,我们在收包解包的时候使用比较多。

2023-05-12 23:12:26 1393

原创 C语言预处理详解

_FILE__ //进行编译的源文件文件路径()__LINE__ //文件当前的行号__DATE__ //文件被编译的日期__TIME__ //文件被编译的时间__STDC__ //如果编译器遵循ANSI C,其值为1,否则未定义int main()return 0;用法:#define MAX 1000 //MAX 就代表了1000;case //为 register这个关键字,创建一个简短的名字//用更形象的符号来替换一种实现。

2023-05-10 21:55:18 777

原创 关于波特率与字节传输速率计算

用 9600 波特率来举例,就是最高每秒可以检测到 9600 个电平变化(上升沿/下降沿),也可以说最大每秒可以接收 9600 位数据,bit ,也就是二进制数(0/1),每个电平发生跳变的时钟周期为:1/9600 s.这个条件再次分析一下就是,如果我要传输一个字节(8 位)的数据,则我应该在总线上产生 11 个电平变换,也就是串行总线上,需要 11 位,才能发送 1 个字节数据。1 个起始位,8 个数据位,0 个校验位,1 个停止位。1 个起始位,8 个数据位,1个校验位,1 个停止位。

2023-05-08 20:27:50 2373

原创 I2C接口为什么要设计成开漏输出?

第二个原因,就是多设备通信仲裁需要做线与逻辑,开漏输出能做到,如果用推挽输出做线与就会如上面原因,造成短路。线与逻辑,主设备想总线置1,开始空闲,从设备这时候如果输出0 ,会产生1&0=0,造成主设备认为总线还是被占用,无法空闲,主设备放弃拉高,这样不会破坏从设备正在通讯的数据。析这个问题,首先要从I2C接口的设计初衷说起,制定者当初设计成I2C总线的就是要实现,一个I2C主机可以挂很多I2C从机。综上所述,双总线接口外设一般要设计成开漏输出,一是防短路,而是做线与逻辑,方便仲裁。

2023-05-08 20:06:11 1492

原创 const、define、extern、typedef、volatile、static的定义与区别

这个函数只需要将src字符串拷贝给dest就好了,只需要只读,不需要改变,一旦在函数在定义的时候,一旦改变了*src,那么编译器会直接的报错。注意:编程时 static 的记忆性,和全局性的特点可以让在不同时期调用的函数进行通信,传递信息,而 C++的静态成员则可以在多个对象实例间进行通信,传递信息。volatile的作用是告知编译器,它修饰的变量随时都可能被改变,因此,编译后的程序每次在使用该变量的值时,都会从变量的地址中读取数据,而不是从寄存器中获取。const主要的用途是函数传参的时候,修饰形参的。

2023-05-05 22:11:11 523

原创 数组与指针的区别

用运算符sizeof可以计算出数组的容量(字节数),而用sizeof却无法计算指针所指内存的容量,用sizeof(p)得到的结果永远是4或者2(即指针变量所占内存单元的字节数,一般情况下指针变量占2个或4个字节的内存单元)。而指针却不同,它指向的内存区域的大小可以随时改变,而且当指针指向常量字符串时,它的内容是不可以被修改的,否则在运行时会报错。指针是动态分配空间,通过malloc在堆上分配所需要的空间,分配的空间不一定连续,在使用完之后需要调用free()来释放分配空间。数组的本质则是一系列的变量。

2023-05-05 21:16:13 311

原创 指针常量和常量指针

本质上一个常量,指针用来说明常量的类型,表示该常量是一个指针类型的常量。在指针常量中,指针自身的值是一个常量,不可改变,始终指向同一个地址。在定义的同时必须初始化。用法如下:2、常量指针——指向“常量”的指针(const int *p, int const *p)常量指针本质上是一个指针,常量表示指针指向的内容,说明该指针指向一个“常量”。在常量指针中,指针指向的内容是不可改变的,指针看起来好像指向了一个常量。用法如下:3、例题(1)2)判断下面程序对错,并说明理由错误"ap

2023-05-05 21:06:55 160

原创 位运算(按位与、按位或、异或、取反)以及原码、反码、补码

由于[1111_1111]+[0000_0001]=[0000_0000],所以在负数反码的基础上+1就可以解决反码中跨0的误差问题,同时不会对负数与它对应的二进制反码的同步递增产生影响,所以在反码的基础上+1就完美的解决了符号参与预算的问题,这就是补码为什么是在负数反码的基础上+1的由来。用第一位表示符号,其余位表示值。从上面的原码表中可以看见左边每增加一个二进制单位对应的真数是递减的,而右边每增加一个二进制单位对应的真数是递增的,所以对于原码来说,能满足正数的加法,但无法满足负数的加法。

2023-05-05 20:26:10 6936 2

原创 C语言extern关键字

利用关键字extern,可以在一个文件中引用另一个文件中定义的变量或者函数,下面就结合具体的实例,分类说明一下。

2023-05-04 21:08:46 136

原创 互斥锁、自旋锁、读写锁和文件锁

开发过程中,最常见的就是互斥锁的了,互斥锁加锁失败时,会用「线程切换」来应对,当加锁失败的线程再次加锁成功后的这一过程,会有两次线程上下文切换的成本,性能损耗比较大。如果我们明确知道被锁住的代码的执行时间很短,那我们应该选择开销比较小的自旋锁,因为自旋锁加锁失败时,并不会主动产生线程切换,而是一直忙等待,直到获取到锁,那么如果被锁住的代码执行时间很短,那这个忙等待的时间相对应也很短。如果能区分读操作和写操作的场景,那读写锁就更合适了,它允许多个读线程可以同时持有读锁,提高了读的并发性。

2023-05-04 17:40:18 231

原创 结构体对齐计算

对齐方式确实很浪费空间,可是按照计算机的访问规则,这种对齐方式提升了效率。

2023-05-04 16:44:10 126

原创 #ifndef, #define, #endif

分析:当第一次包含test.h时,由于没有定义_TEST_H,条件为真,这样就会包含(执行)#ifndef _TEST_H和#endif之间的代码(头文件定义部分),当第二次包含test.h时前面一次已经定义了_TEST_H,条件为假,#ifndef _TEST_H和#endif之间的代码也就不会再次被包含,这样就避免了重定义了。使用#ifndef可以避免下面这种错误:如果在h文件中定义了全局变量,一个c文件包含同一个h文件多次,如果不加#ifndef宏定义,会出现变量重复定义的错误;

2023-05-03 21:28:19 255

原创 C语言:自己实现字符串相关的常用API

【代码】C语言:自己实现字符串相关的常用API。

2023-05-03 21:17:00 163

原创 段错误、内存溢出、内存泄漏(区别)、堆溢出、栈溢出

什么时候会发生段错误?段错误通常发生在访问非法内存地址的时候,即使用了野指针(指向一个已删除的对象或者未申请访问受限内存区域的指针)或这试图修改字符串常量的内容。

2023-04-27 22:33:18 311

原创 栈、堆溢出

缓冲区溢出是由于C语言系列设有内置检查机制来确保复制到缓冲区的数据不得大于缓冲区的大小,因此当这个数据足够大的时候,将会溢出缓冲区的范围。栈溢出就是缓冲区溢出的一种。由于缓冲区溢出而使得有用的存储单元被改写, 往往会引发不可预料的后果。程序在运行过程中,为了临时存取数据的需要,一般都要分配一些内存空间,通常称这些空间为缓冲区。如果向缓冲区中写入超过其本身长度的数据,以致于缓冲区无法容纳,就会造成缓冲区以外的存储单元被改写,这种现象就称为缓冲区溢出。缓冲区长度一般与用户自己定义的缓冲变量的类型有关。

2023-04-27 21:19:43 136

原创 进程内存分布(详解)

由编译器自动分配释放,速度较快用来存储函数调用时的临时信息的结构,存放为运行时函数分配的局部变量函数参数返回数据返回地址等。这些局部变量等空间都会被释放程序运行过程中函数调用时参数的传递也在栈上进行,如递归调用栈当栈过多的时候,就是导致栈溢出(比如大量的递归调用或者大量的内存分配)栈是向低地址扩展的数据结构,是一块连续的内存的区域,空间有限。

2023-04-26 22:36:02 1843 1

原创 C语言(插入、选择、冒泡、快速)排序

目录 前言一、插入排序二.选择排序三.冒泡排序四、快速排序hoare版本(左右指针法)时间复杂度、稳定性表这里实现几种常见的排序算法:步骤:1.从第一个元素开始,该元素可以认为已经被排序2.取下一个元素tem,从已排序的元素序列从后往前扫描3.如果该元素大于tem,则将该元素移到下一位4.重复步骤3,直到找到已排序元素中小于等于tem的元素5.tem插入到该元素的后面,如果已排序所有元素都大于tem,则将tem插入到下标为0的位置6.重复步骤2~5动图演示如下:思路:  在待排序的元素中,假设前

2023-04-25 21:03:20 660

原创 GDB调试指南(基础入门)

开发和使用Unix程序时,有时程序莫名其妙的down了,却没有任何的提示(有时候会提示core dumped),这时候可以查看一下有没有形如core.进程号的文件生成,这个文件便是操作系统把程序down掉时的内存内容扔出来生成的, 它可以做为调试程序的参考,能够很大程序帮助我们定位问题。设置断点后,以便我们更详细的跟踪断点附近程序的执行情况。通过上面的例子演示,我相信读者已经对于通过GDB调试C/C++程序有了基本的理解,如果你想获取更多的调试技巧请参考官方网站的GDB调试手册,还有GDB官方网站的手册。

2023-04-25 16:05:18 5596

原创 Linux -- E37: No write since last change E162: No write since last change for buffer

本文介绍如何解决vim编辑文件时的报错:E37: No write since last change E162: No write since last change for buffer。

2023-04-22 14:37:27 776

原创 Linux access函数

后三种可以使用或“|”的方式,一起使用,如W_OK|R_OK 返回值:成功0,失败-1。mode:指定access的作用,取值如下。pathname 是文件的路径名+文件名。X_OK 值为1,判断对文件是可执行权限。W_OK 值为2,判断对文件是否有写权限。R_OK 值为4,判断对文件是否有读权限。F_OK 值为0,判断文件是否存在。

2023-04-17 20:14:46 187

原创 ARM板(树莓派)使用摄像头——fswebcam

在上面的代码语法中,-r代表图像分辨率,--jpeg代表图像的格式类型& 85质量标准,-D代表捕获前的延迟设置。我这边好像看不出来,一般来讲插摄像头之前查看一下,插上摄像头,看那个多出来了,就是那个了一般来讲,是。fswebcam是一款小型摄像头的控制库,我们可以通过它来抓取图片;抓拍一张图,存放与当前目录,并保存为 jpg 格式。

2023-04-16 00:04:07 949

原创 undefined reference to symbol ‘pow@@GLIBC_2.2.5 编译错误解决方法

math.h ,那么在使用gcc编译时,必须添加 -lm 选项,因为书序函数是位于libm.so 库文件中的,-lm 选项告诉编译器书序函数要到这个库文件中查找。该错误的含义并不是glibc库的错误,而是pow 符号未定义, pow 是数学中的 求幂函数,也就是说,如果我们在C文件中引用了。解决方案: gcc 编译时增加 -lm 选项,这样程序就能引用 libm.so(libmath) 库了。

2023-04-15 22:27:25 1175

原创 linux运行命令怎么免输入YES和回车?

说明:echo用于显示一行文本,y是要显示的内容的。|是管道符,作用是将管道符左边命令的输出作为管道符右边命令的输入。这样就可以自动安装了。说明:sudo用于提升权限,apt-get是debian系列的包管理程序,install。linux命令免输入yes和回车,可以借助于echo命令。进行安装操作,emacs要是安装的软件。2、要免输入,则可以通过如下命令安装。1、比如现在要安装emacs。

2023-04-14 22:31:07 451

原创 数据*=2 即 二进制层面上的左移一位

后面经过敲计算机研究,发现databuf*=2 实际上在二进制层面就是左移一位。今天研究树莓派上dht11测温湿度时,发现了个不懂的代码。这段代码和下面这段效果是一样的。

2023-04-11 18:10:15 91

原创 while()循环中CPU占用率问题

今天写while循环的时候看了一下top 发现CPU的占用率已经达到了100%,吓死了。这样的程序怎么能够发布使用呢?应该逐渐关注程序性能算法优化这方面的问题。添加了一句“Sleep(1)”,CPU占用率就直接从100%跌到了1%

2023-04-07 23:17:37 942

原创 智能家居(1) -- 基础概念引入(设计、工厂模式)

工厂模式是最常用的设计模式之一,这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式在工厂模式中,我们在创建对象时不会对客户端暴露创建逻辑,并且是通过使用一个共同的接口来指向新创建的对象如上图中,左侧可以比拟为一个工厂,工厂里有很多个可能,右侧可比拟一个main函数的入口,当我们用到哪个功能时, 就在main函数中调用工厂里的功能接口(API)就可以了,如果想要在工厂里建立一个新功能时,直接新添加一个文件就好,工厂中一个独立的文件就代表是一个独立的功能,

2023-04-05 18:10:17 137

原创 智能家居(2) -- 核心框架与实现方法

初始化两个工厂的链表,创建三个线程(语音、TCP以及摄像头),然后就是对指令的遍历,通过指令找到对应控制工厂里面对应的控制动作从而实现对模块的控制。在某些场景由于主控制模块资源限制不能识别所有的功能进而增加一个子模块,通过对子模块的控制从而新增其他的功能满足需求。指令工厂:定义一个指令的结构体用来存放指令,同理控制工厂定义一个控制的结构体存放控制指令。1.红外和433m都通过串口与控制器相连,而树莓派只有一个串口,不能满足需求。控制进而控制继电器组合就可以实现灯的控制。2.火灾报警器直接由树莓派供电。

2023-04-05 18:08:20 269

stm32-smartCar原码

有两个版本1和2

2023-03-17

空空如也

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

TA关注的人

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