自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

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

原创 0.96OLED 4针IIC STM32-标准库版本(附源码)

main.c//需要在调用这个显示接口前声明txt这个变量 # define display(row , col , size , . . .) {//延时函数初始化 uart_init(9600);//串口初始化为9600 LED_Init();//初始化与LED连接的硬件接口 OLED_Init();for(i = 0;i <= 7;LED0;} }

2023-03-29 22:07:05 3817 3

原创 【Linux环境配置】7. Linux部署code-server

两种方法,一种是在线安装,另一种是本地安装。因为主机访问github可能会报443错误,因此这里我推荐使用本地安装方法!下载完后,使用ftp工具将其传输到要部署的主机上。我使用的是FileZilla。tar解压code-server,使用./bin/code-server运行,然后修改配置文件,配置code-server监听端口。可以进行远程登录有两种方式,一种是内网,一种是公网登陆(云服务器)。最后配置开机启动,配置code-server常驻后台。附卸载code-server教程。

2023-02-26 15:45:04 4425 1

原创 【Linux环境配置】6. 解决uboot无法ping通Ubuntu虚拟机

使用的板子为正点原子的Alpha-Mini板,教材为正点原子配套的驱动开发指南v1.6。将网络连接从NAT模式改为桥接,然后再次进入虚拟机查看更改网络配置后的ip信息。在uboot中设置好相关的网络环境变量,再次ping主机成功通信~启动uboot后到学习网络命令时,始终无法ping通服务器主机。都已经设置好并确认服务器ip与板子的ip地址在同一网段。文章发现是虚拟机的网络配置问题。

2023-02-13 15:37:08 1490 3

原创 【网络基础】DNS是什么

不同的是,hosts文件有大小限制,只会记录常访问的域名,而大多数的域名还是由网络上的DNS服务器完成解析。电脑上C盘的hosts文件也具有域名解析的作用,上面同样记录ip地址和域名的对应关系。这样一来,即使百度的ip地址发生了变化,用户在访问的时候只需访问域名而不会受到影响。的DNS服务器,这个DNS-server会记录网络上的域名和ip地址的对应关系。而这个错误的网站就能够通过你在上面输入的内容获取到你的信息了。的DNS服务器上查百度的ip地址,查询到之后电脑就得到了。,用户就会访问到其他的网站上了。

2023-02-13 15:21:05 545 1

转载 【Linux内核】启动流程——Kernel 启动流程梳理

uboot将控制权交给 kernel,kernel入口为 stext,主要完成验证是否支持此 CPU、验证 uboot 传入的设备树(dtb)合法性、使能 MMU 等工作,最终会调用 C 函数 start_kernel()相当于内核的 main 函数,内核的生命周期就是从执行这个函数的第一条语句开始的,直到最后一个函数 reset_init(),内核将不再从这个函数中返回。本文详解了kernel启动流程中涉及到的重要函数,并添加printk打印log验证。

2023-02-11 21:22:28 2110 1

原创 【算法总结】堆排序

如何实现堆排序1. 使用 C++ STL派生容器 priority_queue 优先队列2. 自己写一个小根堆两种方式各有好处,STL容器的方法用起来方便,而自己写的灵活性更大,可以自定义实现更多操作。下面介绍一下 priority_queue 在做题的常用方法,以及手撕堆的实现。

2022-10-06 16:46:02 469

原创 【Linux内核】内存管理——缓存一致性问题

CPU访问外设的数据寄存器和状态寄存器时,也是需要将寄存器的值映射到内存上进行读写,外设寄存器的值由硬件修改,也可以由CPU读写,因此外设和CPU对寄存器映射的内存访问也是异步的。在没有写回之前,核心B的cache中的同个数据还没改,当B去访问它时则会与A不一致。因为DMA是直接内存访问,对内存的访问不需要经过CPU,因此如果DMA修改了内存上的CPU访问过的数据,而CPU的cache中并不知道内存已经修改了,CPU读写内存的时候还是cache上的旧数据,造成缓存不一致问题。

2022-10-06 16:40:46 1768

原创 【Linux内核】内存管理——Buddy、Slab分配器

但是当需要申请连续物理内存页框的时候,随着进程的对内存的申请和释放,系统的内存会不断的区域碎片化,分页机制就不一定能保证有足够的连续物理内存页了。当回收一个内存块,会将该内存块插入到对应的链表中,然后查询其buddy内存块是否也在链表上,如果是则合并两个内存块,然后插入到大一级的内存块链表中。如果大一级的内存块链表中没有空闲内存块,则会向更大的内存块链表中查找,然后一层层二分下来,分到合适大小后分配给用户,其他的都插入对应的内存块链表中。一部分插入对应的小一级的内存块链表,另一部分分配给用户使用。

2022-10-06 16:39:53 1653

原创 【Linux内核】内存管理——申请超过物理内存容量的内存

在 32 位操作系统,因为进程最大只能申请 3 GB 大小的虚拟内存,所以直接申请 8G 内存,会申请失败。在 64 位操作系统,因为进程最大可以申请 128 TB 大小的虚拟内存,即使物理内存只有 4GB,申请 8G 内存也是没问题,因为申请的内存是虚拟内存。如果这块虚拟内存被访问了,要看系统有没有 Swap 分区: * 如果没有 Swap 分区,因为物理空间不够,进程会被OOM机制杀掉

2022-10-06 16:38:35 1723 2

原创 【Linux内核】内存管理——内存回收机制

malloc申请的是虚拟内存,只有在程序去访问时,才会触发缺页异常进入内核态,在缺页中断函数中建立物理内存映射。如果物理内存充足,则直接建立页框与页的映射。当物理内存不足时,内核会进行物理内存回收,内存回收的方式主要有:1. 后台内存回收(kswapd)2. 直接内存回收(direct reclaim)3. OOM机制(Out of Memory)三种内存回收方式按内存的紧缺程度递进。

2022-10-06 16:37:12 7603

原创 【Linux内核】内存管理——内核的内存分区

32位机中的虚拟内存大小为4GB,其中0\~3GB用于用户空间,3\~4GB用于内核空间。内核的内存空间只有1G,这一部分内存在进程中共享,与用户空间隔离,用户空间不能访问。内核空间在虚拟内存上分为三个区间:从低到高分别是:

2022-10-06 16:35:46 2169 1

原创 【Linux内核】内存管理——malloc的内存分配

使用malloc时,会从两个区分配内存,分别是 文件映射区 和 堆区。当申请的内存小于 128K 时,会通过 brk() 系统调用,从堆区分配内存。当申请的内存大于 128K 时,会通过 mmap() 系统调用,从文件映射区分配内存。下面讲两种分配方式的区别。

2022-10-06 16:34:13 2439 1

原创 【Linux内核】内存管理——分段和分页的区别

分段和分页的工作方式相似,都是非连续存储。分段的逻辑地址=段号+段内偏移。段表存放段描述符。段描述符=段基址+段界限。物理地址=段基址+段内偏移。分页的虚拟地址=页号+页内偏移。页表存放页面映射。页面映射=虚拟页号+物理页号。物理地址=物理页号+页内偏移。

2022-10-06 16:32:11 2076 1

原创 【Linux内核】内存管理——虚拟内存、分段、分页机制

为什么要有虚拟内存?1. 让每个进程都有独立的内存空间,每个进程都有自己的私有页表,提供一个可以执行多进程的环境。2. 利用程序运行局部性原理,允许进程的内存空间超过物理内存大小。3. 页表中维护着页的权限属性,使内存访问更安全。

2022-10-06 16:30:28 1662

原创 【C/C++】struct和class的区别

struct和class的区别默认权限不同struct 的默认权限是 public 公有class 的默认权限是 private 私有struct 成员中不能写函数,但是可以写函数指针如果不在class类中表明访问权限,则默认都为private,类外不可以访问而struct中只能为public,类外可以访问...

2022-05-27 17:16:09 249

原创 【C/C++】strlen和sizeof的区别(总结表)

strlen和sizeof的区别strlensizeof本质为一个函数本质为一个运算符只能用char*做参数可以用任何类型做参数必须以’\0’结尾, 不统计’\0’’\0‘会统计一个字节用来计算字符串长度用来计算占用内存大小字符数组时计算的是字符串长度归还全部数组的尺寸...

2022-05-27 17:15:33 175

原创 【C/C++】inline关键字内联

inline关键字内联函数的代码会被编译器在调用它的地方展开。解决一些频繁调用的小函数大量消耗栈空间(栈内存)的问题。1.作用节省栈空间,防止栈空间不足减少函数调用产生堆栈操作,提高程序执行效率2.注意事项inline修饰的函数能否真正内联(在调用处展开),由编译器决定,若函数体展开后太大,编译器可能不会展开。inline只适合较为简单的函数,不能包含复杂结构控制语句while和switchinline必须和函数体的定义放在一起才能实现内联inline函数的实现应放在头文件中。否则

2022-05-27 17:14:33 488

原创 【C/C++】关于内存对齐

内存对齐1. 为什么要内存对齐CPU访问内存时以字长为单位。32位CPU字长为4个字节,因此CPU一次性访问的内存单位等于4个字节。即32位CPU的内存读取操作是4字节对齐的。如果数据的存储不采用内存对齐,可能会发生一个数据CPU需要访问2次内存的情况。2. 内存对齐的目的减少CPU访问内存的次数,加大CPU访问内存的吞吐量。为了让内存的存取更有效率因为CPU对内存的读取操作是对齐的,采用不对齐的存储方式,会导致为了读取一个数据CPU要访问两次内存便于移植:不是所有平台都可以访问任意地址的

2022-05-27 17:13:43 504

原创 【智能车】模糊PID控制原理详解与代码实现

模糊PID控制本文主要由三部分构成:模糊PID控制器的原理,模糊PID控制器C++的实现与测试。一. 模糊PID原理模糊PID控制流程如下图所示,把目标值 Xtarget 与输出值 Xout 的误差 e 与 e 的变化率 de/dt 作为模糊控制器的输入,模糊控制器先对输入进行模糊化处理,接着进行模糊推理,最后把模糊推理的结果进行去模糊处理输出PID控制器的三个参数 kp, ki, kd,从而达到对PID控制器参数自适应整定的效果。根据以上的描述可知,模糊控制器主要由去模糊化,模糊推理以及去模糊

2022-05-27 02:30:17 59383 44

原创 0.96OLED 4针IIC STM32-HAL库版本(附源码)

0.96OLED 4针IIC STM32HAL库版本OLED的显存,也就是坐标关系如下:size = 8 时存放格式如下(x, y)//[0]0 1 2 3 … 127 //[1]0 1 2 3 … 127 //[2]0 1 2 3 … 127 //[3]0 1 2 3 … 127 //[4]0 1 2 3 … 127 //[5]0 1 2 3 … 127 //[6]0 1 2 3 … 127 //[7]0 1 2 3 … 127size = 16 时存放格式如下//[0]0 1 2

2022-05-24 13:47:20 5106 33

原创 【Clion】自定义内容的自动补全——动态模板使用教程

Clion的动态模板动态模板的作用:实现自动补全。添加动态模板添加动态模板的步骤:第一步是找到动态模板在哪里添加打开clion的设置setting找到编辑器选项editor选择实时模板live template选择C/C++栏目点击右边的"+",选择1.动态模板如果你的界面和我不一样(可能是主题的问题,也可能是版本的问题,不过大同小异)没有汉化的话显示的应该都是英文的选项,上面的步骤里有附加英文选项。添加动态模板的步骤:第二步是动态模板怎么设置输入缩写(即你想要补全的触发关键词

2022-05-19 15:39:10 7229

原创 【Linux学习笔记】11. Linux进程控制编程

1. 进程相关命令 2. 进程控制编程 包括:1.获取进程ID,2.创建进程fork(),3.exec函数族,4.进程的终止exit(), _exit(),5.进程等待wait()

2022-05-06 21:28:09 941

原创 【Linux学习笔记】11. Linux父子进程中变量地址相同——虚拟内存

Linux父子进程地址相同问题——虚拟内存在进行进程控制编程的时候,使用fork()创建子进程时有这样的一个实例:int main(){ int num = 0; pid_t pid = fork(); if( -1 == pid) { perror("fork"); exit(1);} else if( 0 == pid) num ++; //子进程动作 else num ++; //父进程动作 return 0;}这段代码中,num变量在父子进

2022-05-06 14:54:12 1742

原创 【Linux学习笔记】10. Linux进程相关概念

1. 进程与程序的区别程序是放到磁盘的可执行文件,程序是静态的进程是指程序执行的实例,进程是动态的2. 进程的概念进程是一个具有一定独立功能的程序的一次运行活动。进程是正在执行的一个程序或命令,每个进程都是一个运行的实体。每个进程都有自己的地址空间和执行状态,并占用一定的系统资源。程序的概念:程序是人使用计算机语言编写的可以实现特定目标或解决特定问题的代码集合。每个进程都有一个ID,唯一标识了系统中的这个进程,叫做进程ID(PID)。某些进程会产生一些新的进程,这些新的进程称作子进程,产

2022-05-06 14:48:28 515

原创 【Linux环境配置】1. window下通过远程ssh访问linux

SSH是什么SSH是一种网络协议,用于计算机之间的加密登录。如果一个用户从本地计算机,使用SSH协议登录另一台远程计算机SSH参考资料Linux操作安装openssh-server打开terminal输入sudo apt-get install openssh-server获取IP输入ifconfig如果提示没有安装,则进行安装,输入sudo apt install net-tools (我的虚拟机上默认安装了)查看ssh是否运行: ps -ef | grep ssh 若要用Lin

2022-04-22 00:19:52 1016 1

原创 【Linux环境配置】4. Ubuntu下PicGO配置gitee图床

Ubuntu配置PicGo图床Ubuntu20.04系统 搭配gitee和picgo实现自制图床 配置typora 和 picgo-core实现粘贴图片自动上传到图床的功能。注意:后期可能gitee会设置防盗链来限制白piao图床的行为,因此最好在使用图床的同时也在本地备份一份图片,用YAML设置自动上传。如果有条件快速访问github,也可以用github和cdn加速来做图床。1. 软件下载typoranodejspicgo-corepicgoflameshotxclip

2022-04-22 00:17:03 2164 5

原创 【Linux环境配置】3. Linux下GCC编译器的使用

GCC编译器GNU C Compiler是GNU推出的功能强大,性能优越的多平台编译器。ubuntu下查看gcc的版本:在终端上输入gcc -v 或者 gcc --version 就会显示版本信息和它配置的编译脚本参数编译时分四个阶段预处理:gcc -E test.c -o test.i(其中-o file输出到指定文件file)编译:生成.o文件gcc -S test.i -o test.s(test.s就是生成的汇编语言文件)汇编 gcc -c test.s -o te

2022-04-22 00:07:23 691

原创 【Linux环境配置】2. VMware虚拟机安装vm-tools

参考博客检查是否安装启动ubuntu后,点击虚拟机选项卡,检查VMware-Tools是否安装。若显示为灰色, 则关机,配置CD/DVD,软盘为自动检测。然后开机。点击安装VMware-Tools开始安装1、右击桌面上VMware-Tools光盘,点击open in terminal2、输入ls查看目录,其中红色的压缩包即目标3、输入sudo cp ./VMwareTools-x.x.x-x.tar.gz /usr/local/bin/ 复制压缩包到/usr/local/bin/路径下4.

2022-04-22 00:02:57 2778

原创 【Linux环境配置】1. SSH远程访问Linux

本文基于Ubuntu系统0. SSH是什么SSH是一种网络协议,用于计算机之间的加密登录。如果一个用户从本地计算机,使用SSH协议登录另一台远程计算机附:SSH参考资料使用windows通过SSH访问Linux,配置ssh连接需要分两步进行。1. Linux上的操作1.1 安装openssh-server打开terminal终端,安装ssh服务端,输入以下命令sudo apt-get updatesudo apt-get install openssh-server若要用Li.

2022-04-22 00:00:52 3293

原创 【Linux学习笔记】9. Linux打包压缩解压缩命令tar

详解了linux下打包命令tar的基本使用,包括文件目录打包成.tar文件,将.tar文件解打包。同时讲解了将文件目录打包并压缩成.tar.gz和.tar.bz2的使用方式,以及解压缩.tar.gz和.tar.bz2文件。

2022-04-21 23:39:44 25148

原创 【Linux学习笔记】8. Linux查找命令:find和grep详解

关于Linux的find查找文件命令,包括按照文件名、修改时间、文件类型、文件权限等不同条件查找解析。grep查找字符串命令,以及grep与find通过管道进行组合搜索的高级命令使用。

2022-04-21 19:10:13 3004

原创 【算法总结】KMP算法

# 字符串匹配——KMP算法1. 算法原理在暴力匹配过程中,当遇到匹配失败的字符时,暴力法做法是将模式串后移一位,从头开始匹配,直到成功匹配下一位字符。KMP算法的核心思想就是:充分利用模式串自身的信息,在每次匹配失败之后不需要重复匹配之前已经成功匹配的字符,快速定位到下一个需要匹配的字符,从而提高匹配效率。因此,我们需要知道匹配失败后应该回退到哪里继续匹配。而实现这个思想的途径就是计算出模式串的最长相等前后缀,在算法中记录在一个数组中,叫做next[]数组。相比于暴力法遍历文本串和模式串时间复杂

2022-04-21 01:52:16 467 1

原创 【Linux学习笔记】7. Linux文件IO详解(附代码实例)

Linux文件I/O# 前置知识Linux文件I/O分为系统IO和标准IO,常用于系统编程系统I/O通过文件描述符 fd 来操作文件标准I/O通过文件流 FILE* 来操作文件Linux下可以使用man命令来查看使用手册学习和使用这些API最快的途径是利用系统自带的man查看手册,查看系统IO可以用man 2 open, 查看标准I/O可以用man 3 fopen。关于linux中man 1 2 3 … 的区别 :1、Standard commands (标准命令)2

2022-04-20 23:22:32 5845 3

原创 【Linux学习笔记】6. Linux系统编程之文件IO介绍

Linux文件I/O# 系统I/O1. open()函数原型:#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>int open(const char *pathname, int flags);int open(const char *pathname, int flags, mode_t mode);函数参数:参数意义pathname打开/创建的文件

2022-04-20 18:25:14 266

原创 【算法总结】二分查找及边界问题

关于整数二分的原理和推导,包括更新区间时的mid的取值什么时候需要写成mid = (r + l + 1) >> 1的探讨,用图解的形式理解搜索下一区间时 l 和 r 左右指针的取值, 避开边界问题。

2022-04-11 12:52:50 5262

原创 【算法总结】归并排序及双指针

1. 归并排序——分治# 算法原理归并排序的思想就是分治,先递归分解数组,再合并数组。将数组分解到最小之后,再往上一层两两合并两个有序的数组,最终递归返回的就是一个排好序的数组。递归分解的时间复杂度是O(logn),合并数组的时间复杂度是O(n),因此归并排序的时间复杂度就是O(nlogn)。# 步骤确定分界点mid = (l + r) / 2递归调用左右区间一层层调用到底,从最底层归并归并排序, 合二为一# 如何实现合二为一?合并的基本思路就是双指针算法,比较两个

2022-04-10 19:07:20 654

原创 【算法总结】快速排序及边界问题分析

关于快速排序的算法原理和推导,代码模板实现,多个边界问题的具体细节分析。

2022-04-10 13:54:16 2909 5

原创 【智能车】图像二值化算法--大津法OTSU

大津算法是一种图像二值化算法,作用是确定将图像分成黑白两个部分的阈值。原理:方差越大,相关性越低,黑白越分明。目的:找出一个灰度值阈值Threshold,对该灰度值以上或以下的像素的分别计算方差,满足Threshold以上计算出来的方差和Threshold以下计算出来的方差的和最大。附:算法推导、C语言代码实现。通俗易懂,比赛可用。

2022-04-06 10:47:14 18624 19

原创 【C/C++基础】string.h字符串标准库常用函数

string.h常用函数使用时需要包含头文件<string.h>#include <string.h>本文介绍了3个常用函数strcat()strcmp()strlen()扩展了strlen()与sizeof()的却比(1) strcat(字符数组1,字符数组2)作用:链接两个字符数组中的字符串,把字符串2链接到字符串1后边,结果放在字符数组1中。不要搞反了,是把右边连接到左边的屁股后边去。说明:(a)字符数组1必须足够大,能够容纳连接后的新字符串。(b

2022-04-01 15:20:58 2510

原创 C指针 各教程知识点汇总

翁恺1.数组与指针数组变量本身表达地址int a[10]; int *p =a;//无需用&取地址但是数组元素表达的是变量,需要用&取地址a == &a[0]//等价于首元素的地址[]运算符可以对数组做,也可以对指针做:p[0] 等价于 a[0]*运算符可以对指针,也可以对数组做*a = 25;数组变量是const的指针,所以不能被赋值int arr[] <==> int* const a;//数组是常量指针2.指针与const

2022-04-01 15:17:26 887 1

空空如也

空空如也

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

TA关注的人

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