C语言可变参数的原理及实现
前言使用过 C 语言的人都会知道 printf 函数,它的参数中有固定参数 format 和可变参数 ... ,那 format 后面的参数个数不确定,类型也不确定,这些参数都存放在栈中。在 format 中在特定的位置指定对应可变参数的类型,也就是根据 format 里的格式依次将数据取出
原理所有可变参数都存放在栈中。在 format 中在特定的位置指定对应可变参数的类型,也就是根据 format 里的格式依次将数据取出。而取出的动作需要用到 va_arg va_list va_end 这些宏定义,而且取出可变参数的时候,就相当于是指针指向栈中存放数据的位置,然后将指针不断移动来取出数据。
所以就需要对应着可变参数的数量,一定要注意,一旦出现可变参数数量不对应的情况,那就会产生 crash ,主要还是由于参数的数量如果少于使用参数的数量时,就会导致访问栈内存溢出,从而导致 crash
由于参数分为两个部分:固定参数和可变参数,至少需要有一个固定参数,可变参数的数量可以有多个,声明中使用 ... 表示
va_list1typedef char * va_list;
实际上就是一个指针 ...
AT&T汇编基础语法
前言参考x86 Assembly Guide
编译编译汇编语言可以使用 GNU 编译器 gcc 和 汇编器 as 或者 gas。一个快速了解汇编语言的方式就是去看编译器输出的汇编程序。使用 gcc -S a.c 可以将 C 语言编译为汇编语言,就可以查看对应的汇编语言了。使用 gcc a.s 就可以把对应的的汇编语言编译为可执行文件了。使用 gcc a.s -c 或者 as a.s 可以将汇编语言编译为可重定位目标文件
例如在 C 语言中经典的 hello world 程序
12345#include <stdio.h>int main() { printf("hello, world"); return 0;}
编译为汇编代码为
123456789101112131415161718192021222324252627282930313233343536373839404142434445 .file "a.c" .text .section .rodata.LC0: .string "hello, ...
bochs+gdb调试工具链
前言bochs 中自带一个反汇编器,这只能查看可执行文件的反汇编之后的指令,但是如果书写 C 语言的话,就使得调试非常麻烦(无计可施),所以利用 bochs 来写操作系统还是挺困难的,同时也没有办法查看各个变量的状态和 cpu 的状态。一旦遇到问题就很被动,所以介绍一个 bochs+gdb 的一个调试工具链
bochs安装与配置安装环境123sudo apt-get install g++ sudo apt-get install makesudo apt-get install libx11-dev xserver-xorg-dev xorg-dev
安装 bochs123456wget https://udomain.dl.sourceforge.net/project/bochs/bochs/2.6.8/bochs-2.6.8.tar.gztar zxvf bochs-2.6.8.tar.gzcd bochs-2.6.8/./configure --prefix=/your_path/bochs --enable-gdb-stub --enable-disasm --enable ...
gcc内置原子操作
前言Gcc 4.1.2版本之后,对 X86 或 X86-64 支持内置原子操作。也就是不需要引入第三方库(如pthread)的锁保护,即可对1、2、4、8字节的数值或指针类型,进行原子加/减/与/或/异或等操作
__sync 接口具体信息查看 Built-in functions for atomic memory access
type __sync_fetch_and_add (type *ptr, type value, ...) 将 value 加到 *ptr 上,并且结果保存在 *ptr 上,返回操作之前的 *ptr 的值
type __sync_fetch_and_sub (type *ptr, type value, ...) 从 *ptr 减去 value ,结果保存到 *ptr ,并返回操作之前 *ptr 的值
type __sync_fetch_and_or (type *ptr, type value, ...) 将 *ptr 与 value 相或操作,结果保存在 *ptr 中,返回操作之前 *ptr 的值
type __sync_fetch_and_and ( ...
xv6-kernel上
前言由于 xv6-kernel 的代码是在 qemu+riscv 中进行仿真的,所以首先我们需要安装 qemu 和 riscv 仿真工具链
riscv工具链下载源码源码地址为
risc-v
也可以直接使用 git 指令下载
1git clone https://gitcode.com/riscv-collab/riscv-gnu-toolchain/overview
这里直接下载默认分支
下载模块打开下载的源码目录下,找到名为 .gitmodules 的文件,这里面就是每个子模块的路径和分支。如果没有梯子,就可以根据其对应的名字在 Gitee 上查找对应的模块,然后直接将其下载到 riscv-gnu-toolchain 这个文件夹下,但是对应的模块要下载到对应的文件夹里。不仅如此,还需要下载该模块对应的分支,分支一定不能错。可以使用如下指令
1git clone -b branch_name url module_name
其中 branch_name 是分支名称, url 是下载链接,也就是 Gitee 上对应的模块的仓库地址, module_name 就是需要将这个模块放入的文件夹 ...
xv6-kernel下
xv6内核模式的中断处理当一个进程获得一个 trap 时,会调用 stvec 寄存器中存储的 uservec 然后进入 usertrap 函数,在函数中会进入内核处理状态,并且将内核中断向量 kernelvec 写入到 stvec 寄存器中。所以在内核模式下发生中断的话会进入 kernelvec ,然后进入 kerneltrap 中。处理结束之后再从中退出到主管模式中去。在 usertrapret 中会将 uservec 写入 stvec 寄存器,然后退出用户模式,以此来保证用户模式下发生中断会在用户中断处理中进行处理
kernelvec这个是在内核模式下发生中断时运行的第一行代码,这里将会保存原先的内核寄存器,然后进入 kerneltrap 函数进行处理中断,然后返回之后重新加载寄存器,回到原来的进程继续处理
123456789101112131415161718192021222324252627.globl kerneltrap.globl kernelvec.align 4kernelvec: # 将栈指针减少 256 个字节,相当于是向下走 256 个字节,也就 ...
python基础学习
前言Python 是一个高层次的结合了解释性、编译性、互动性和面向对象的脚本语言
Python 是解释型语言: 这意味着开发过程中没有了编译这个环节。类似于 PHP 和 Perl 语言
Python 是交互式语言: 这意味着可以在终端中的 Python 提示符 >>> 后直接执行代码
Python 是面向对象语言: 这意味着 Python 支持面向对象的风格或代码封装在对象的编程技术
Python 是初学者的语言: Python 对初级程序员而言,是一种伟大的语言,它支持广泛的应用程序开发,从简单的文字处理到 WWW 浏览器再到游戏
安装linux
安装依赖环境
1yum -y install zlib-devel bzip2-devel openssl-devel ncurses-devel sqlite-devel readline-devel tk-devel gdbm-devel db4-devel libpcap-devel xz-devel
下载python
1wget https://www.python.org/ftp/python/3.9. ...
verilog基础语法
前言这是一种计算机硬件语言,是可以模拟计算机的一种仿真语言,语法上与 C 语言相似。本文主要是笔者为了学习《计算机组成原理》而去了解的一种语言
介绍Verilog 是一种硬件描述语言,用于数字电路的系统设计。可对算法级、门级、开关级等多种抽象设计层次进行建模
继承了C语言的多种操作符和结构,与另一种硬件描述语言 VHDL 相比,语法不是很严格,代码更加简洁,更容易上手
Verilog 不仅定义了语法,还对语法结构都定义了清晰的仿真语义。因此, Verilog 编写的数字模型就能够使用 Verilog 仿真器进行验证
Verilog 环境搭配在终端使用指令来安装
1sudo apt-get install iverilog
配置 vscode安装插件
waveTrace 插件
verilog-HDL 插件
Verilog Format 插件
配置
在 linux 上安装 ctags
找到 ctags 的安装路径,将其添加到 vscode 的设置 Verilog>ctags:Path 中
将 vscode 中设置的 Verilog>linting:Liner 设置为 iv ...
es基础
代码
简介es 与 js 的关系就是,前者是后者的规范,后者是前者的一种实现
环境配置nodejsnodejs 的下载安装与一般的软件无异,从官网找到并且下载安装就好
npm需要使用镜像下载: 镜像地址
直接在终端执行下列命令就可完成安装
1npm install -g cnpm --registry=https://npmmirror.com/
语法let关键字特点
声明的变量只在当前的代码块中有效
不满足变量提升,也就是必须在声明之后使用变量,不然会报错
不允许重复声明同一个变量
1234{ let a = 0;}a = 1; // 报错
const关键字特点
声明之后变量不可改变
声明时必须初始化
不满足变量提升,也就是必须在声明之后使用变量,不然会报错
只在当前的代码块中有效
不允许重复声明同一个变量
12const a = 1;a = 2; // 报错
变量解构赋值解构可以用于对象,也可以很方便的将现有的对象的方法赋值到某个变量,对象的顺序没有要求,但是必须与属性同名才能得到正确的值
12var {age, name} = & ...
js基础
代码
前言JavaScript 是一种轻量级的脚本语言,所谓脚本语言就是指它不具备开发操作系统的能力,而只是用来编写控制其他大型应用程序的脚本。 JavaScript 是一种嵌入式语言,本身提供的核心语法不算很多,可用于 html 和 web ,更可广泛应用于服务器,PC等设备
类似于 C 语言,一行一行的执行,每一行就是一条语句
优点
操控浏览器的能力
广泛的使用领域
易学
与ECMAScript 的关系ECMAScript 和 JavaScript 的关系,前者式后者的规格。后者是前者的一种实现
将js引入到html文件中嵌入到文件中需要在 <body> 标签之内嵌入
123456<body> <script> var num = 10; console.log(num); </script></body>
引入独立js文件要在 script 标签内定义 type 和 src 属性
1<script type="text/javascript" src="./语法.js ...
vue基础
代码
简介vue 是前端优秀框架,是一套用于构建用户界面的渐进式框架
特点
简单
易学
…
安装使用使用命令行安装vue cli 是一个基于 vue.js 进行快速开发的完整系统
1npm install -g @vue/cli
测试,在终端输入以下指令测试是否安装成功
1vue --version
一些功能使用下列指令打开一个 gui 界面来引导项目创建等一系列操作
1vue ui
创建项目在终端使用下列指令创建一个项目
1vue create projectname
输入之后需要使用上下按键来选择默认项目模板
可以选择手动选择,然后按照如下选择
文件目录说明
目录/文件
说明
build
项目构建(webpack)相关代码
config
配置目录,包括端口号等。初学可以使用默认的。
node_modules
npm 加载的项目依赖模块
src
这里是我们要开发的目录,基本上要做的事情都在这个目录里。里面包含了几个目录及文件:
assets
放置一些图片,如 logo 等,还可以放全局使用的 css 文件
components
目录里面放了一个组 ...
css基础
代码
前言CSS 是层叠样式表,又叫级联样式表,后缀名为 .css ,用于是 html 中元素样式的定义
CSS 的主要作用是为了让网页具有美观一致的页面
导入到html内联样式要使用内联样式,需要在相关标签内使用 style 属性,其中的 style 属性可以包含任何 CSS 属性
但是缺乏整体性和规划性,不利于维护,维护成本高
1<p style="background-color: green; color:red">段落</p>
内部样式当单个文档需要特殊样式时,就应该使用内部样式表,可以使用 <style> 标签在文档头部定义内部样式表
这使得单个页面内的 CSS 代码具有统一性和维护性,便于维护,但是在多个页面之间容易混乱
外部样式实际上是引入外部 css 文件作为不同网页的统一样式,可以实现通过改变一个文件来改变整体的样式,需要注意的是, link 标签在文档的头部才能引入,可以链接到样式表
1<link rel="stylesheet" type="text/css" ...
html基础
代码
前言html 是一种描述网页的语言,是一种超文本标记语言,是一套标记标签,标签是被尖括号包围的关键字
html 需要有 DOCTYPE 的声明,是文档类型的缩写,声明位于文档最前面
1<!DOCTYPE html>
html标签定义 html 文档,这个元素是一种声明文档为 html ,而且其他的元素必须包含在内,限定文档的开始和结束
head标签用于定义文档的头部,文档的头部描述了文档的各种属性和信息,包括文档的标题,在 web 中的位置以及其他和文档的关系等。大部分内容都不会被看到
body标签定义文档的主体,元素包含文档的所有内容,比如文本,图像等,会在页面中直接显示
title标签可以定义文档的标题,显示在浏览器窗口的标题栏或者状态栏上,是在 head 标签中必须要包含的标签, title 标签有利于 SEO 优化
meta标签用来描述一个网页文档的属性,关键词等
标题标签标题是通过 <h1>~<h6> 标签进行定义的,其中 <h1> 定义最大的标题, <h6> 定义最小的标题
其中生成标题的快捷键 h$*1 ~ ...
GTest使用
前言在编写代码中有 bug 很常见,通过编写完备的单元测试,可以及时发现问题,并且在后续的代码改进中持续观测是否引入了新的 bug ,使用 GTest 是一个不错的选择
GTest 可以用作代码的检测,一般来说可以搭配 CTest 来进行测试
单元测试就是对程序中最小的单元进行测试,最小的可测试单元可以是一个函数,一个调用过程,一个类等
对于 C/C++ 来说,测试一般是一个函数,检测目标函数在所有可能的输入下,函数执行过程和输出是否符合预期
在测试功能中,每一个单元都是一个可执行文件,实现了 main 函数,所以要在 CMakeLists.txt 中使用 add_test 命令来添加测试用例
测试用例指的是对一项特定的任务进行测试,体现着测试方案,方法,技术和策略等,包括测试目标,环境,输入数据,步骤,预期结果和测试脚本等
对于上述单元测试,就是在不同输入下,目标函数的预期执行过程和输出,不同的情形可以有一个或者多个测试用例,编写测试用例尽量覆盖所有输入情况,特别是边界值,特殊值和异常
GTest介绍是 Google 开源的一个跨平台的 C++ 单元测试框架( Google Test ...
CMakeLists编写
前言CMake是一个跨平台的构建系统,能自动生成各种平台和编译器的构建文件,相对于直接编写 makefile 文件,编写 CMakeLists 文件不需要考虑太多的文件之间的依赖关系,它可以自动帮你管理复杂项目的构建过程,检测依赖关系,生成目标文件,编译静态库和动态库等,减少手动管理的负担
可以看看这个知乎专题 CMake实践应用专题 - 知乎 (zhihu.com) ,下面的内容几乎都是从这里整理的
ubuntu 上 cmake 的更新在使用旧版本的 ubuntu 时,总是会出现 cmake 的版本太低,导致编译不通过,所以需要更新 cmake,一般使用 apt 指令直接安装的 cmake 版本都比较低。所以可以在官网上下载源代码编译安装,最后检验安装的版本正确即可
安装依赖1sudo apt install libssl-dev
下载压缩包并且解压
编译安装1234mkdir build && cd build../configmakesudo make install
动态库链接1sudo ldconfig
检验1cmake --version
CMake ...
makefile编写
功能makefile定义了一系列的规则来指定哪些文件需要先编译,哪些文件需要后编译,哪些文件需要重新编译,甚至于进行更复杂的功能操作,不同产商的make各不相同,也有不同的语法,但其本质都是在“文件依赖性”上做文章。Makefile执行之后所进行的操作是编译和链接,就是先将源文件编译为中间文件(object file),然后把大量的中间文件链接起来合成执行文件
规则
如果这个工程没有编译过,那么我们的所有源文件都要编译并被链接(按需)
如果这个工程某些源文件被修改,那只编译被修改的源文件,并链接目标程序
如果这个工程的头文件被改变了,那么我们需要编译引用了这几个头文件的源文件,并链接目标程序
基本格式123target ...: prerequisites ... command ...
target 目标文件,是命令执行后生成的目标,可以是 Object File ,也可以是执行问价,还可以是一个标签,类似于 clean
prerequisites 依赖,也就是生成目标文件所需要的文件或者是目标
command make 需要执行的指令,可以是任意的 shell 指令
核心规则 ...
DOB扰动观测器
GitHub - Luo25177/modelControl
前言——一些用到的概念
最小相位系统:对于FIR系统(没有极点),如果系统函数的所有零点都位于单位圆内,则称该系统为最小相位系统。如果系统函数的所有零点都位于单位圆外,则称该系统为最大相位系统。如果一部分零点位于单位圆内,一部分零点位于单位圆外,则称该系统为混合相位系统或非最小相位系统。对于IIR系统(存在极点),如果系统函数的所有零点和极点都在单位圆内,则称该系统为最小相位系统。也就是相频特性 $\varphi(w)$ 在 $w=0$ 和 $w=\pi$ 之间经历的净相位变化为零
最小相位系统主要特性
最小相位系统是因果且稳定的
其逆系统也是因果且稳定的
在所有具有相同幅频响应的零-极点系统中,最小相位系统的群时延最小
基本原理基本思想就是将外部扰动以及模型参数变化造成的实际模型与理想模型输出的差异统统等效为控制输入,即观测出等效干扰,在控制中引入等量的补偿,实现对干扰完全抑制。干扰观测器的基本思想,系统实际控制输入与计算输入(由系统标称模型计算得到)的差值,来得到扰动和不确定性的估计
具体公式
图中的 $G_p ...
IMU滤波
前言向量叉乘二维
a=\begin{bmatrix}x_1\\y_1\end{bmatrix},b=\begin{bmatrix}x_2\\y_2\end{bmatrix}\\\Downarrow\\a\times b=x_1y_2-y_1x_2三维
a=\begin{bmatrix}x_1\\y_1\\z_1\end{bmatrix},b=\begin{bmatrix}x_2\\y_2\\z_2\end{bmatrix}\\\Downarrow\\a\times b=\begin{bmatrix}y_1z_2-z_1y_2\\z_1x_2-x_1z_2\\x_1y_2-y_1x_2\end{bmatrix}欧拉角是用三个角度表示物体的空间姿态,每个角度代表物体绕其一个固定轴的旋转量
pitch 俯仰角,一般来说向上转,也就是抬头为正
roll 翻滚角,一般是向右侧倾倒为正
yaw 航向角,一般是向右转为正
旋转矩阵对于三轴角度的旋转矩阵,如下
绕 x 轴旋转
R_x(\theta)=\begin{bmatrix}1&0&0\\0&\cos\theta&-\sin\th ...

















