跳转至

2020

WSL 记录

概述

发现使用 wsl + docker + vs code(remote wsl + remote container 插件) 可以让开发、部署、运行整个流程变得更加方便。因此想写一篇文章记录接触 wsl 后了解到的一些知识以及遇到的一些问题以及解决方案(长期更新)。

字体分类

概述

目前还没有一种统一的字体分类方法。因此本文从易于理解的角度,使用 4 个维度对字体进行分类。

简单来说,确定了大小、粗细、样式和字体系列后便确定了一种字体。

font family

字体系列(font family) 表示符合同一种设计风格的字体的集合。比如大名鼎鼎的 Helvetica 字体就因醒目,清晰而广泛应用于广告,宣传语等场合。Time New Roman 也是一种使用非常广泛的字体。

一种字体系列包含多种变体字体,如 Times 包含 TimeIt(倾斜), TimeBd(加粗) 等。我们口语中说的某一种字体,其实通常说的是一种字体系列。

而对于现有的五花八门的字体系列,可以根据一些特点分成 5 类,也叫通用字体系列(generic font families)。如 Helvetica 就属于无衬线 (sans serif) 字体。

以下是字体系列的 5 种类别

在虚拟机上搭建 overleaf

概述

因为学校的 overleaf 无法通过 latex 代码定位到 pdf 位置。因此想在本地搭建一个 latex 环境,而如果在 windows 里安装 texlive+ 配置 VS code 比较麻烦,且以后重装系统又无法保留,因此考虑在 ubuntu 虚拟机里安装。

这里考虑同样搭建一个 overleaf,毕竟在主机里打开浏览器直接就能用就很方便,且界面也更美观。

overleaf 采用了 docker 进行部署,因此需要先安装 docker。


更新

在 virtualbox 虚拟机搭建后发现存在性能问题。以编译计组指导书为例,每次修改编译需要 1 分钟,并且经常出现编译 2-3 分钟然后失败的情况。

在查阅 wsl 性能比较后,发现 wsl2 的性能已经比较好了,有些场合接近原生 linux 的性能。参考Windows 10 May 2020 Performance For WSL vs. WSL2

于是补充了在 wsl2 上搭建的内容。

ucore lab3 总结

目录

  1. x86 中断/异常处理 (tss 和 tf 作用)
  2. 重要函数说明 1. 创建进程 (线程) 2. 调度,运行 3. do_wait & do_exit 4. do_execve 5. 其它系统调用
  3. FAQ 1. 一个进程被创建后如何开始执行? 2. 一个用户进程如果因为时间片用完而被调度掉后,再次被调度回来时会从哪里继续执行? 3. 一个进程的完整生命周期? 4. fork 调用,为什么父进程返回值为 pid,子进程返回值为 0(涉及到用户进程的创建

总结

实验 3 涉及到的知识点:

  1. x86 中断中 tss 的作用(类似的内核栈,中断帧的概念)
  2. 进程如何创建、执行、切换(do_fork, do_wait, do_exit 等系统调用的设计与实现)
  3. 用户进程的创建、执行过程
  4. 用户 ulib 库 fork, wait, exit 的实现

ucore lab2 总结

概述

回顾实验 1,我觉得需要学习的知识有:

  1. gdb工具的使用
  2. ELF文件的格式,以及 readelf, objdump, objcopy 工具的使用(查看各个 section,查看符号表)
  3. x86 汇编基础(通用寄存器,段寄存器,EIP,EFLAG 等),GCC内联汇编格式(AT&T 格式)
  4. x86 内存分段机制(GDT 表,段描述符)
  5. x86中断处理机制(IDT 表,中断向量 -> 中断处理程序)
  6. 操作系统启动过程(BIOS->bootloader(第一扇区)->Kernel 各阶段做的事情)

而做完实验 2 后,我觉得需要学习的知识有:

  1. BIOS 探测物理内存,Kernel 打开分页时自带一个页表
  2. 二级页表进行虚拟地址转换
  3. 物理内存管理 之 空闲块(以页为单位) 管理(Page 数据结构和物理页的对应,空闲块链表 free_list,FirstHit 分配连续的物理页)
  4. 虚拟内存管理 之 有效虚拟页(表示一个程序可能使用的虚拟地址段,vma, mm 数据结构)
  5. 导致PageFault的原因(1. pte=0 即从来没有被加载过,2. 被 swap out, 3. 访问权限错误)
  6. FIFO 页替换算法实现(page struct 增加 pra_page_link, pra_vaddr,mm->sm_priv(pra_list_header) 记录最近使用的页序列;swap_manager)

以下介绍一些难点

关于 2020 到目前的一个总结

2020 年对全人类来说是不平凡的一年,而对我来说也是不同寻常的一年。这一年发生了许多大大小小的事,有些事情身处其中时觉得非常不得了,而经历过后,又觉得也许很快就会忘记,因此想记录一些这一年我都干了些什么事。

Virtual Box 配置双网卡

由于目前在电脑上运行一个虚拟机已经比较流畅,而虚拟机又有着真机无法比拟的优势,如:

  • 可以快速地进行备份与还原,且备份的虚拟机镜像可以复制到其它电脑上
  • 可以保存虚拟机当前的运行状态(快速休眠),而下次启动时恢复运行(且速度很快)

因此我配置了一台 Ubuntu18.0 的虚拟机,并做了以下配置:

  • 配置了 build-essential, python3, git, vim 等常用软件
  • 配置了 zsh,以及一些 zsh 的插件如自动提示,命令高亮,auto-jump
  • 配置了 VS Code, Chromium 软件
  • 配置了 nodejs, cnpm, hexo 等,用于编写 hexo 博客
  • 启动 sshd,并配置网络

其中,关于最后一点。刚开始我采用了桥接网络 + 静态 ip 的方案。但是发现当主机网络环境改变时,ssh 便连接不上了,于是便有了这篇博客。

编译原理总结

目前我眼中的计算机层次

  • 计算机体系结构(RTL 级设计,流水线,缓存,多发射)
  • ISA(访存模式,中断/异常)
  • 汇编语言(寄存器 + 内存空间)
  • 高级语言(编译器)
  • 操作系统(内核:进程调度,同步与死锁,内存管理:页表,文件系统 应用:桌面系统,浏览器)

编译器各阶段

  1. 词法分析:解析源代码文件,输出记号流。 记号即指一个有独立意义的“单词”。空白字符便一般不包含意义,故可以省略。 这些单词一般可分类为:标识符,常数(整数,浮点数),字符常量,字符串, 操作符,界符,关键字。

  2. 语法分析:分析记号流,输出程序的逻辑结构,如语法分析树(或 AST 树) 一种语言的语法规则可以被文法产生式完全定义。 文法一般包括表达式的定义,各种语句的定义(if, while, for),变量声明, 函数定义等。

CloudView 平台运行 bad apple

重写了 bad-apple 的代码,利用了多进程的方式进行视频转换。

以下是各个配置转换 bad apple.mp4 的时间

线性执行 4 线程 1 进程 2 进程 4 进程 8 进程 16 进程
时间 (秒) 34.97 34.70 35.05 24.15 18.11 18.09 18

其中线程为采用 threading 库,进程则采用 multiprocessing 库

我的电脑配置为:

CPU intel(R) Core(TM) i5-7200U CPU @ 2.50GHz 2.70GHz
RAM 8.00 GB
Windows Windows10 家庭版 1909 18363.720

官方文档说明了 threading 库底层实现时仍只有一个线程,因而只适用于大量 I/O 并发的情况。而我们的图片转换成字符画的过程主要是计算密集型,因此基本没有改善性能。

而采用多进程时,刚好对应我电脑的 4 线程(2 核,采用超线程技术可以有 4 个线程,其实这里进程线程有点晕)时提升最大。

于是便想知道 32 个核时,能提升多少,便想在服务器上跑跑看。以下是配置运行过程。

出人意料的结果:

1 进程 4 线程 8 进程 16 进程 32 进程
时间 (秒) 51 24 23.22 21.57 21.14

可能进程多了后,写文件的速度反而成了瓶颈,查看 top 发现各个核的 cpu 利用率都只有 10% 左右,在代码中输出 cvt_frame.qsize() 也发现几乎都是满的。(在自己电脑上大多数都是 0,表明 cvt_frame 供不应求)

Use dlib in C++

use dlib in c++

从方法 1.1 到 1.3 都不必预编译 dlib 库,而是在使用 dlib 的项目中编译。

方法 1.4 介绍了将 dlib 预编译成静态库然后使用时会遇到的一些问题。

with CMake(officially recommend)

dlib/example/CMakeLists.txt

cmake_minimum_required(VERSION 2.8.12)

project(examples)

# Tell cmake we will need dlib.  This command will pull in dlib and compile it
# into your project.  Note that you don't need to compile or install dlib.  All
# cmake needs is the dlib source code folder and it will take care of everything.
add_subdirectory(./dlib dlib_build)

macro(add_example name)
   add_executable(${name} ${name}.cpp)
   target_link_libraries(${name} dlib::dlib )
endmacro()

# if an example requires GUI, call this macro to check DLIB_NO_GUI_SUPPORT to include or exclude
macro(add_gui_example name)
   if (DLIB_NO_GUI_SUPPORT)
      message("No GUI support, so we won't build the ${name} example.")
   else()
      add_example(${name})
   endif()
endmacro()

# 
add_gui_example(3d_point_cloud_ex)

命令行执行:

mkdir build
cd build
cmake .. -G "Visual Studio 14 2015 Win64" -T host=x64 #-T host=x64告诉CMake生成64bit的可执行文件。其实安装了最新的VisualStudio后,-G -T都不用指定,默认使用最新的VisualStudio,默认64位。
cmake --build . --config Release

使用 CMake GUI 可以设置一些选项,configure, generate 之后可以使用命令行执行最后一步 (不用打开 VisualStudio)

with GCC in terminal

g++ -std=c++11 -O3 -I.. ../dlib/all/source.cpp -lpthread -lX11 example_program_name.cpp

windows 下还需gdi32, comctl32, user32, winmm, ws2_32, or imm32

with VisualStudio

  • 把 dlib 的父目录添加到 include search path

    You should NOT add the dlib folder itself to your compiler's include path. Doing so will cause the build to fail because of name collisions (such as dlib/string.h and string.h from the standard library). Instead you should add the folder that contains the dlib folder to your include search path and then use include statements of the form #include or

    include "dlib/queue.h". This will ensure that everything builds correctly.

  • 把 dlib/all/source.cpp 添加到源文件

    If you are using Visual Studio you add .cpp files to your application using the solution explorer window. Specifically, right click on Source Files, then select Add -> Existing Item and select the .cpp files you want to add.

  • 如果需要 libjpeg 等,把 dlib/external 文件夹下的源文件添加到 project,并 define the DLIB_PNG_SUPPORT and DLIB_JPEG_SUPPORT preprocessor directives.

Installing dlib as a precompiled library

dlib 的 CMake 脚本包含 INSTALL target,因此可以像其它 C++ 库一样将 dlib 作为一个静态或动态库安装到系统上。

  • 调用 dlib 时出现 USER_ERROR inconsistent_build_configuration see_dlib_faq_2 错误。 需要将 build/dlib/config.h 文件拷贝到源码目录 dlib-19.17/dlib 进行覆盖。config.h 文件内有其说明。

配置 3d_face_reconstruction 总结

1. OpenCV

  1. windows 下载预编译版 (只含有 msvc 编译的版本)

  2. CMake 直接使用 find_packages 即可。(需添加环境变量,以便找到 OpenCV 的 config 文件)

2. dlib

  1. 官方推荐将代码直接包含到项目中编译(好处是没有 ABI 一致性问题)

    CMake 中 add_subdirectory(/path/to/dlib/top/dir) 即可。(甚至可以自动从网上下载)

3. boost

  1. 分为只含有头文件的库和需要独立编译的库。
  2. 官方编译方法为:
    1. 先 build 出 Boost.Build(可以看作 Boost 的一个 build 工具)
    2. 然后调用 b2 编译指定模块。(可以添加参数指定编译的库的路径)
    3. 我的编译目录是 stage/(库位于 stage/lib/下)
  3. CMake find_packages 暂时是失败的。

4. eos

  1. 只需要包含头文件即可 (header only),include 和 3rdparty
  2. 顶层目录下的 CMakeLists.txt 默认勾选了编译 example 下的示例(需要 boost 的 system, filesystem, program_options 和 openCV 的 core, higui, imgproc
  3. CMake 直接 add_subdirectory(/path/to/eos) 比较方便。

5. Qt

  1. 官方介绍了如何使用 CMake find_packages,自动 tic, moc 等。

TODO

  1. 学习 Qt,能自己写界面。
  2. 明白 eos 那个示例程序输入输出是什么
  3. 最后,自己来改写 eos 的程序,自己写 Qt 程序,最后展示出来。

安装使用 OpenCV(windows)

Install

安装预编译版

opencv.org上提供了源代码以及各个操作系统的预编译版。windows 预编译版为一个 installer 程序,运行后会将各种文件 extract 到安装目录。安装完成后,/path/to/opencv/包含两个目录——build, source。source 为源代码目录 (和直接下载源代码解压一模一样),build 下包含了许多其它文件。其中:

  • include/为调用 OpenCV 时需要包含的头文件 (源代码目录下也有)
  • x64/vcxx/下包含 bin/和 lib/,为预编译的库。vcxx 代表使用 MSVC xx 编译的,运行时需要对应的 runtime 库。

    IDE 编译器
    VS2017 VC15
    VS2015 VC14
    VS2013 VC12
    VS2012 VC11
    VS2010 VC10
    VS2008 VC9
    VS2005 VC8
  • etc/文件夹中是 OpenCV 某些算法所依赖的数据集。
  • OpenCVConfig.cmake文件在使用 CMake 编译项目时可使用 find_package 自动搜索头文件、库文件路径
  • 其它文件暂时不管

从源文件编译 OpenCV

Usage

通过 VisualStudio 编译 OpenCV 程序

  1. 菜单栏 project->properities。(或在右侧的 Solution Explorer 下找到一个 project(solution 和 project 的关系)。鼠标右键->Properities)

  2. C/C++/AdditionalIncludeDirectories。编译器从该文件夹下查找头文件。

    (p.s. #include "opencv2/opencv.hpp"#include "opencv.hpp"对应不同的设置)

  3. Linker/Input/AdditionalDependencies 添加opencv_world420.lib

  4. Linker/General/AdditionalLibraryDirectories 添加opencv_world420.lib所在目录。(或直接在 3 中输入绝对路径)

  5. 设置环境变量,把opencv_world420.dll所在目录添加到 Path 变量。(否则运行时报错:无法找到opencv_world420.dll)。不添加环境变量的方法是直接把opencv_world420.dll拷贝到 exe 所在目录。

    p.s. 貌似opencv_world420.lib表面上是一个静态链接库,但实际上是一个动态链接库,因而运行时需要opencv_world420.dll。而第 3 步如若改成添加opencv_world420.dll,则编译失败。

    LNK1107 could also occur if you attempt to pass a module (.dll or .netmodule extension created with /clr:noAssembly or /NOASSEMBLY) to the linker; pass the .obj file instead.

通过 CMake 编译 OpenCV 程序

参考:Using OpenCV with gcc and CMake

通过 CMake 编译 OpenCV 程序有几点好处:

  • 在 Windows 和 Linux 之间移植程序不用更改设置。
  • 自动搜索 include,lib 路径。(通过OpenCVConfig.cmake文件,需添加到 Path 环境变量)
  • 写代码的方式比 VisualStudio 点击按钮然后输入方便,配置的文件可以保留下来用于其它项目。

缺点:

步骤:

  1. 添加opencv/build/到 Path(OpenCVConfig.cmake所在目录)。

  2. 编写CMakeLists.txt。示例:

    cmake_minimum_required(VERSION 2.8)
    project( DisplayImage )
    find_package( OpenCV REQUIRED ) //
    add_executable( DisplayImage DisplayImage.cpp )
    target_link_libraries( DisplayImage ${OpenCV_LIBS} ) //
    
  3. 使用 CMake GUI,点击 configure(可以先 File->Delete Cache,删除掉之前的配置)

    选择 VS 的编译器。

  4. 在中间面板修改一些变量的值。(重新 configure)

  5. Generate,在 build 目录下生成 VS 的 sln 文件,双击打开。

  6. 在 ALL_BUILD 上右键 build。

运行 HPL

编译 BLAS/CBLAS

BLAS 为 fortran 接口的库,CBLAS 为 C 语言接口的库

 tar zxf blas-3.8.0.tgz 
 tar zxf cblas.tgz
 cd BLAS-3.8.0
 make #生成blas_LINUX.a
 cp blas_LINUX.a ../CBLAS
 cd ../CBLAS
 vi Makefile.in
 #修改
 # BLLIB = ../blas_LINUX.a
 make #在lib/下生成cblas_LINUX.a

编译 HPL

tar zxf hpl-2.3.tar.gz 
cd hpl-2.3
cp setup/Make.Linux_PII_CBLAS ./Make.<arch> #在top-level 文件夹下
vi Make.<arch> #修改
make <arch> #在bin/<arch>/下生成HPL.dat xhpl

Make.示例

OpenMPI+CBLAS
ARCH         = <arch>

TOPdir       = /home/mpiuser/hpl-2.3

MPdir        = /path/to/OpenMPI
MPinc        = -I$(MPdir)/include
MPlib        = $(MPdir)/lib/libmpi.so

LAdir        = 
LAinc        = 
LAlib        = path/to/cblas_LINUX.a path/to/blas_LINUX.a #顺序不能改变,cblas依赖blas

HPL_OPTS     = -DHPL_CALL_CBLAS 

CC           = mpicc
LINKER       = mpif77

HPL 优化

配置参数

计算次数:

\[ \#Ns \times \#NBs \times \#(Ps, Qs) \times \#PFACTs \times \#NBMINs \times \#BCASTs \times \#DEPTHs \]
HPLinpack benchmark input file
Innovative Computing Laboratory, University of Tennessee
HPL.out      output file name (if any)
6            device out (6=stdout,7=stderr,file)
1            # of problems sizes (N)
8192         Ns
1            # of NBs
128          NBs
0            PMAP process mapping (0=Row-,1=Column-major)
3            # of process grids (P x Q)
2 1 4        Ps
2 4 1        Qs
16.0         threshold
3            # of panel fact
0 1 2        PFACTs (0=left, 1=Crout, 2=Right)
2            # of recursive stopping criterium
2 4          NBMINs (>= 1)
2            # of panels in recursion
2            NDIVs
3            # of recursive panel fact.
0 1 2        RFACTs (0=left, 1=Crout, 2=Right)
1            # of broadcast
0            BCASTs (0=1rg,1=1rM,2=2rg,3=2rM,4=Lng,5=LnM)
1            # of lookahead depth
0            DEPTHs (>=0)
2            SWAP (0=bin-exch,1=long,2=mix)
64           swapping threshold
0            L1 in (0=transposed,1=no-transposed) form
0            U  in (0=transposed,1=no-transposed) form
1            Equilibration (0=no,1=yes)
8            memory alignment in double (> 0)

记录一次失眠

今天查了一些关于保研的事, 晚上有点失眠。 我回顾了以往的事, 有初中还有高中。

我回忆起那时自己是怎样的模样, 我感慨有些事不记录也许就真的忘了。 我明白如果不经常眺望一下远方, 而只是低头看着现在, 时间也许眨眼就过去了。

要对短期的未来有所计划, 计划不是一个严格的日程表, 让自己失去自由, 而是明白你最近最想做什么, 你现在想做什么。

我想要: 1 我想要练习口语,为夏令营的英语自我介绍做准备 2 我想要联系一些同学,和他们聊聊未来。必定有所收获。 3 我想有一个爱好,如学会基础的日语。 4 我想在编程能力(数据结构和算法)上有所提高。

我发现列出愿望能让自己更加明确方向。

井字棋与最大最小值算法

经过昨晚,和今天早上 8 点醒来趴在床上努力的思考。我终于想起了如何使用数学归纳法证明策梅洛定理。然后经过一上午的努力,我成功使用最大最小值算法实现了井字棋 (Tic-Tak-Toe) 的 AI,然后添加到 wwh 的井字棋代码中。

RISC-V 报告

author: 计科卓越班 袁福焱 20174260

0. 导言

RISC-V 是 21 世纪诞生的一种完全开放的计算机精简指令集,可应用于小到嵌入式系统大到高性能处理器等广泛领域。RISC-V 充分汲取了许多指令集的实践经验,具有非常多的优点。并且它完全开放,采用 BSD 开源协议——全世界任何公司、大学、个人都可以自由免费地使用 RISC-V 指令集构建自己的系统。

本报告第一部分讲述 RISC-V 的几个主要特点与优势,第二部分介绍 RISC-V 的目前已构建建的生态系统。最后一部分,谈论 RISC-V 在推动开源硬件中起到的作用。

1. RISC-V 的特点

1.1 指令集模块化

以往的指令集为了实现兼容,往往采用增量扩展的方法。即新的处理器不仅要实现新的扩展,还必需要实现过去所有的扩展。如典型的 x86 架构,其中许多指令早已失效,但为了兼容性却必须实现,这导致硬件实现变得越来越复杂。RISC-V 按照功能将指令集分为很多个模块。其中 I 模块为基础整型指令集,这是 RISC-V 要求必须实现的指令集,并且永远不会发生改变。只要实现了该指令集便可以运行完整的基于 RISC-V 的软件。这样,RISC-V 在扩展时便不再会像 x86 那样背上沉重的历史包裹。编译器也可以在保证兼容的基础上,根据已实现的扩展,选择性地生成更高效的代码。

1.2 回避以往的设计缺陷

目前主流的指令集有 x86, ARM, MIPS 等。其中 x86 为复杂指令集 (RISC),于 1978 年诞生。而 ARM, MIPS 为精简指令集 (RISC),都是 1986 年诞生的。从计算机体系结构的发展上来看,RISC 由于简洁性,能够更加充分地利用现代微体系结构中的流水线、分支预测、cache 等技术,因此比 CISC 更加高效。因此,诞生于 21 世纪 (2004) 的 RISC-V,必然也是精简指令集。并且,由于有了前面指令的经验,RISC-V 吸收了以往指令集的优点,并回避了以往指令集的一些缺陷。优点如,RISC-V 有 32 个通用寄存器,有专门的 0 寄存器。使用专门的移位指令来处理移位操作。使用 load/store 指令访问内存。跳转指令不使用条件码。缺陷则如,RISC-V 废弃了 MIPS 中的分支延迟槽 (有利于架构和实现的分离),立即数只进行有符号扩展,算数运算不抛出异常 (通过软件判断),更规整的指令格式(源及目的字段位置固定),整数乘除法可选 (简化了基础实现)。

1.3 完全开放

RISC-V 采用 BSD 开源协议,任何人都可以自由免费地使用 RISC-V。其他指令集如 x86 是完全闭源的,只有 intel 和 AMD 等少数公司能够基于 x86 架构生产产品。而 ARM 和 MIPS 都采用授权的方式,通过卖授权的方式盈利,其中 ARM 的授权费则十分昂贵。RISC-V 如今由 RISC-V 基金会维护,任何公司只要愿意每年支付一笔会员费即可成为会员,会员可以参与到 RISC-V 之后标准的制定中。RISC-V 也因此真正成为一个开放的指令集,不会因为任何一个公司的起伏而受到影响。

2. RISC-V 的生态

以下内容引用自开放指令集与开源芯片进展报告-v1p1

2011 年,加州大学伯克利分校发布了开放指令集 RISC-V,并很快建立起一个开源软硬件生态系统。截止 2019 年 1 月,已有包括 Google、NVidia 等在内的 200 多个公司和高校在资助和参与 RISC-V 项目。其中,部分企业已经开始将 RISC-V 集成到产品中。例如全球第一大硬盘厂商西部数据(Western Digital)最近宣布将把每年各类存储产品中嵌入的 10 亿个处理器核换成 RISC-V;Google 利用 RISC-V 来实现主板控制模块;NVidia 也将在 GPU 上引入 RISC-V 等。此外,国内阿里巴巴、华为、联想等公司都在逐步研究各自的 RISC-V 实现;上海市将 RISC-V 列为重点扶持项目;印度政府也正在大力资助基于 RISC-V 的处理器项目,使 RISC-V 成为了印度的事实国家指令集。

由此可见,RISC-V 国内外的兴起使得目前 RISC-V 的生态已经比较完善了。

3. 之于构建开放硬件生态的意义

2019 年度国际计算机体系结构旗舰会议 ISCA 于 6 月在美国亚利桑那州凤凰城召开,会议的主题即是“面向下一代计算的敏捷开放硬件(Agile and Open Hardware for Next-Generation Computing)”。由此可见开放硬件,敏捷开发已成为未来的趋势。而 RISC-V 则刚好成为这趋势中不可或缺的一环。

目前开源硬件开发中面临着 4 个关键问题 (Yungang Bao, Chinese Academy of Sciences, The Four Steps to An Open-Source Chip Design Ecosystem):

  1. 开放的指令集 ISA/开源 IPs/开源 Socs
  2. 硬件描述语言 Lanuages/开源的 EDA 工具
  3. 验证和仿真 Vertification/Simulation
  4. OS/Complier

RISC-V 便处于第一环中,

虽然目前每个环节都还未完全解决,但我们可以相信,在未来,开发硬件可以像开发一个软件一样。充分利用已开源的资源,用户只需要定制 10% 以内的代码,便可以以月为单位开发出客制化的硬件系统。

4. 参考资料

大道至简——RISC-V 架构之魂(上)

大道至简——RISC-V 架构之魂(中)

大道至简——RISC-V 架构之魂(下)

开放指令集与开源芯片进展报告-v1p1(2019-02-22 更新)

远景研讨会纪要–面向下一代计算的开源芯片与敏捷开发

嵌入式技术基础与实践 第五版

心得

  1. 为什么单片机可以控制灯的亮灭,通用 PC 却没办法控制灯呢?(因为没有 CPU 到 LED 的接口也没有驱动程序)

  2. 中断向量机制和 MIPS 采用的统一入口地址不太一样。中断向量机制硬件产生中断请求时,中断号是确定了的(通过中断控制器发送中断号),软件可以配置对应中断服务程序。而 MIPS 没有中断号的概念,通过软件检查 Stastus 寄存器,来确定是哪一个中断,跳转到对应中断服务程序。

    中断向量机制的 CPU 通常需要一个中断控制器,连接在总线上。中断控制器会给 CPU 提供中断号。

  3. MCU 本质就是一个微型计算机,包含 CPU,存储器,I/O 接口(控制器模块)。嵌入式开发就是要基于 MCU 搭建一个硬件系统(通过 MCU 的 I/O 接口连接各种需要被控制的外设),并逐层向上编写构件(驱动),最后基于构件编写嵌入式应用,从而完成需要的功能。

  4. MCU 由于需要通用性,使得用户可以基于 MCU 去搭建自己的系统,驱动自己的外设,因此每个引脚都复用多个功能。通过配置 MCU 内对应控制器的寄存器来配置引脚的功能。

    比如 MSP432 100 个引脚中有 84 个可以配置成 GPIO 引脚。只需要将 MSP432 分配的 GPIO 寄存器中的 PxSEL0, PxSEL1 寄存器(x 表示端口号,有 11 个端口 P1~P10 和 PJ)都置为 0 时,该端口的引脚即为 GPIO 功能。同样可以通过配置 GPIO 寄存器控制引脚方向作为输入还是输出,用于点亮 LED 灯或者接受开关输入。

    再比如 MSP432 有 4 个增强型通用串行通信接口模块 (eUSCI),也分配了若干寄存器。通过配置寄存器可以将对应引脚配置为 UART 的引脚或 SPI 的引脚。

    但是我们在 FPGA 上搭建 SoC 时,开发板上的灯、拨码开关和 FGPA 芯片的引脚是连好了的(由开发板的提供商基于 FPGA 芯片搭建),也就是说每个引脚作为输入还是输出是已经确定了的。我们能改变的只是——是否使用该外设。当然,不排除保留了一些引脚被接到扩展插口上(那一排排的黑色插孔)。因此在 FPGA 上搭建 SoC 后,实现外设驱动需要对外设的控制器进行配置。而嵌入式开发还多出了配置 MCU 内用于复用的模块寄存器。