VSCODE+QT+PCL
一、环境配置
最近从字节实习完回学校咯,要回来准备秋招了以及一些毕业的项目
在去实习的两个月,老板几乎每周催着一次什么时候回来,真无语。。。:anger:
今年的就业形势也很难啊,各位offer收割机快释放offer给我!!!:pray:
言归正传,之前给项目做的QT界面,还是在QT Creator里面实现的,整体的界面和代码风格都很难评,然后VSCODE用习惯了,所以这次就把VSCODE+QT+PCL+CMake结合在一起。
本地环境
Windows
PCL1.13
QT5.14
MSVC 2019
参考
VSCode + Qt + QMake 开发编译环境搭建 - RioTian - 博客园 (cnblogs.com)
VSCode配置Qt与qwt+解决输出中文乱码(适合小白)_vscode + qt-CSDN博客
二、问题解决基本的步骤上面参考都写着很清楚了,跟着一步一步来配置就好,然后记录一些个人遇到的问题。
linker error12CallOneTimes.obj : error LNK2001: 无法解析的外部符号 "public: virtual ...
riscv-14-内存映射机制实现
1.页表操作1.1页表项定义
64位页表项布局:
低10位:存储下级物理页的属性标志位
10-54位:存储下级页表的物理页号
address.h
定义页表项结构体64位以及0-9的标记位
123456789101112131415/* 定义页表项 */typedef struct { uint64_t bits;}PageTableEntry;// 定义位掩码常量#define PTE_V (1 << 0) //有效位#define PTE_R (1 << 1) //可读属性#define PTE_W (1 << 2) //可写属性#define PTE_X (1 << 3) //可执行属性#define PTE_U (1 << 4) //用户访问模式#define PTE_G (1 << 5) //全局映射#define PTE_A (1 << 6) //访问标志位#define PTE_D (1 << 7) //脏位
...
riscv-13-物理内存管理与分页机制介绍14
导读
参考:
Rust 中的动态内存分配 — rCore-Tutorial-Book-v3 0.1 文档 (gitcode.host)
在应用程序的视角中,动态内存分配中的内存,其实就是操作系统管理的“堆 (Heap)”。但现在要实现操作系统,那么就需要操作系统自身能提供动态内存分配的能力。如果要实现动态内存分配的能力,需要操作系统需要有如下功能:
初始时能提供一块大内存空间作为初始的“堆” 。在没有分页机制情况下,这块空间是物理内存空间,否则就是虚拟内存空间。
提供在堆上分配一块内存的函数接口。这样函数调用方就能够得到一块地址连续的空闲内存块进行读写。
提供释放内存的函数接口。能够回收内存,以备后续的内存分配请求。
提供空闲空间管理的连续内存分配算法。能够有效地管理空闲快,这样就能够动态地维护一系列空闲和已分配的内存块。
(可选)提供建立在堆上的数据结构和操作。有了上述基本的内存分配与释放函数接口,就可以实现类似动态数组,动态字典等空间灵活可变的堆数据结构,提高编程的灵活性。
操作系统给应用程序提供统一的访问接口,即应用程序不需要了解虚拟内存和物理内存的区别的,操作系统提 ...
riscv-12-printf实现
1.实现printf之前实现了内核态的printk,在U模式下都是通过sys_write的系统调用来向串口输出数据,因此需要实现一个用户态的printf函数
OS/lib/printf.c
实现跟之前的printk类似,但是系统调用将uart_put需要修改为 sys_write()
123456789101112131415161718192021#include <sifanos/os.h>#include <sifanos/syscall.h>static char out_buf[1000]; // buffer for vprintf()static int vprintf(const char* s, va_list vl){ int res = _vsnprintf(NULL, -1, s, vl); _vsnprintf(out_buf, res + 1, s, vl); sys_write(stdout,out_buf,res + 1); return res;}int printf(const ch ...
riscv-11-分时多任务与抢占式调度策略实现
1.分时多任务系统分时多任务系统:任务的切换不是通过用户程序来自行放弃cpu的使用权作为前提的,而是内核自己来决定何时切换任务,这个切换的原则就是每个任务一次只能运行一段时间,时间一到就会被操作系统强制切换到下一个任务执行
因此需要定时器来实现时钟中断
riscv的时钟中断中断可以分为三类:
软件中断:由软件控制放出的中断
时钟中断:由时钟电路发出的中断
外部中断:由外设发出的中断
当scause的最高位为1时代表此次触发的异常为中断类型:
Interrupt
Exception Code
Description
1
1
Supervisor software interrupt (S模式下软件中断)
1
3
Machine software interrupt(M模式下软件中断)
1
5
Supervisor timer interrupt(S模式下时钟中断)
1
7
Machine timer interrupt(M模式下时钟中断)
1
9
Supervisor external interrupt (S模式下外部中断)
1
11
Machine ...
riscv-10-多任务调度
1.实现sys_write函数本小节目标:实现通过sys_write函数在 用户态的程序调用串口输出打印
OS/app.c
删掉之前的batch.c,在app.c函数中实现用户态函数 sys_write
12345678910111213141516171819202122#include "os.h"size_t syscall(size_t id, reg_t arg1, reg_t arg2, reg_t arg3) { long ret; asm volatile ( "mv a7, %1\n\t" // Move syscall id to a7 register "mv a0, %2\n\t" // Move args[0] to a1 register "mv a1, %3\n\t" // Move args[1] to a2 register "mv a2, %4\n\t&quo ...
riscv-9-u模式的trap机制
1.用户态的syscall
级别
编码
名称
0
00
用户/应用模式 (U, User/Application)
1
01
监督模式 (S, Supervisor)
2
10
虚拟监督模式 (H, Hypervisor)
3
11
机器模式 (M, Machine)
riscv的特权级如上,一共四个特权级,特权级越高,对硬件的控制能力越强。
opensbi运行在M模式下,从而S模式下可以通过SBI接口控制硬件
U模式下可以通过ABI调用S模式的服务
从U模式通过ecall调用S模式,并且S模式通过SBI调用M模式硬件的流程如下:
riscv 系统调用简介syscall 的调用参数和返回值传递通过遵循如下约定实现:
调用参数
a7 寄存器存放系统调用号,区分是哪个 Syscall
a0-a5 寄存器依次用来表示 Syscall 编程接口中定义的参数
返回值
a0 寄存器存放 Syscall 的返回值
ecall 指令会根据当前所处模式触发不同的执行环境切换异常:
in U-mode: environment-call- ...
riscv-8-printk内核级打印函数
1.printk函数
基于x86架构的简单内核实现-2 | Sifanのblog (liangzhouzz.github.io)在这偏中提到了,在内核态无法使用用户态的printf函数,所以需要编写内核级的printk函数,基于x86简易内核操作中,我们是采用操作寄存器的方式进行读写和打印。
同理,在riscv的S模式下 也是无法使用U模式下的printf函数,需要封装位于S模式下的printk函数
可变参数的解释见:封装printf函数 | TimerのBlog (yanglianoo.github.io)
在os目录下新增printk.c 和 os.h
OS/os.h
头文件:基本的操作系统头文件,通常用于小型嵌入式系统或内核开发中
stddef.h:提供了一些标准定义,如 size_t、NULL 等。
stdarg.h:提供了处理变长参数列表的宏和类型,用于实现变长参数函数(如 printk)。
panic:在系统遇到严重错误时调用,通常会停止系统运行并输出错误信息。
sbi_console_putchar:通过 SBI(Supervisor Binary I ...
riscv-7-opensbi控制台输出以及手写操作系统
1.sbi介绍
参考:
基于Opensbi服务完成控制台输出 | TimerのBlog (yanglianoo.github.io)
RISC-V体系结构的U-Boot引导过程_riscv uboot-CSDN博客
SBI:即是supervisor binary interface,允许在所有的riscv运行。
简单来说就是RISCV官方定义了一个规范接口,运行在S模式或VS模式(启动虚拟化)的软件如os可以使用这些标准接口使得能够在不同的硬件平台上具有良好的移植性而不用去适配。
有两种架构的SBI,一种在CPU未启动虚拟化拓展
启动虚拟化:
SBI扩展ID(EID)和SBI函数ID(FID)被编码为有符号的32位整数。 sbi-v0.2,规定了函数调用:
在监管者和SEE之间,使用ECALL作为控制传输指令,监管者就是S模式的软件程序
a7编码SBI扩展ID(EID)
a6编码SBI函数ID(FID),对于任何在a7中编码的SBI扩展,其定义在SBI v0.2之后。
在SBI调用期间,除了a0和a1寄存器外,所有寄存器都必须由被调用方保留。
SBI函数必须在a0和a1 ...
riscv-6-domain
1.domain机制介绍domain机制:人为的将SOC内部硬件划分为不同的权限区域,然后分别独立运行,其使用了riscv的权限管理的硬件保护单元。它提供了一种在系统中划分资源和权限的方法,以确保软件实体之间的相互隔离和安全性。
OpenSBI运行在系统的M模式,而不同Domain的上层程序只能工作在S模式或者U模式,即便是Linux Kernel也必须接收OpenSBI的Domain权限限制,domain划分带来一个好处,比如你希望SOC中的一部分core在smp模式下运行linux内核,而另一部分core工作在amp模式下,单独运行裸机程序或者RTOS会非常容易操作,将其划分到不同Domian即可,除此之外,Domian还可以划分内存地址,mmio地址,可以进行较为细致的权限划分。
Opensbi的domain机制通过以下的方式实现:
Domain ID:每个 domain 都有一个唯一的标识符,称为 Domain ID。它用于区分不同的 domain。
Hart Mask:OpenSBI 使用 Hart Mask 来表示哪些处理器属于特定的 domain。Hart Mask 是 ...