Skip to content

Commit

Permalink
Merge pull request #17 from Mdr-C-Tutorial/xly-patch-1
Browse files Browse the repository at this point in the history
mdlint&&format
  • Loading branch information
Minsecrus committed Aug 23, 2024
2 parents 0331da3 + d94a427 commit 665c7d0
Show file tree
Hide file tree
Showing 27 changed files with 567 additions and 347 deletions.
8 changes: 5 additions & 3 deletions 教程/正文/嵌入式/初识HAL库.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
# 初识HAL

在比较漫长的汇编语言时代,很多程序员都习惯用位操作对底层硬件进行编写,其优点有以下等:

- 代码直观
- 代码执行效率高
- 代码体积小

缺点有以下等:

- 代码可读性差
- 代码移植性差
- 代码维护性差
Expand All @@ -23,6 +25,7 @@ HAL库的设计目的正是为此,从而使开发者更容易地移植和维
![CMSIS结构图](/images/嵌入式/CMSIS架构图.png)

CMSIS包括以下几个关键部分:

1. **CMSIS-Core**:提供了一个基本框架,包括用于启动、中断处理、内存管理和异常处理的通用函数。
2. **CMSIS-DSP**:提供了一个数字信号处理(DSP)的软件库,包含了用于信号处理操作的函数。
3. **CMSIS-RTOS**:提供了一个实时操作系统(RTOS)接口,允许开发者选择并集成不同的RTOS实现。
Expand All @@ -31,11 +34,10 @@ CMSIS包括以下几个关键部分:

通过使用CMSIS,开发者可以编写与硬件无关的代码,只需针对特定的微控制器进行一些小的修改或配置,就可以在不同的微控制器上运行。这极大地提高了开发效率,并简化了微控制器软件的维护和更新。




## HAL库介绍

ST为了方便用户开发STM32芯片开发提供了三种库:

1. 标准外设库(Standard Peripheral Libraries):
- ST最早的库,现在还在用
- 目前只兼容 F0/F1/F3/F2/F4/L1 系列
Expand Down
2 changes: 1 addition & 1 deletion 教程/正文/嵌入式/寄存器编程.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,4 @@

寄存器的设计和优化对计算机的性能有着重要影响,因此现代CPU通常会有大量的寄存器,并且会采用各种技术来提高它们的访问速度和效率。

## 2.
## 2
17 changes: 14 additions & 3 deletions 教程/正文/嵌入式/术语表.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

一种专门设计用来满足实时计算需求的操作系统。实时操作系统必须在规定的时间内完成特定任务,以保证系统的正确性和可靠性。实时系统通常分为硬实时(Hard Real-Time)和软实时(Soft Real-Time)系统。
以下是一些RTOS的主要特点:

1. **确定性(Determinism)**
- RTOS提供确定性的任务调度,确保任务能够在预定的时间限制内完成。
2. **任务调度**
Expand All @@ -19,11 +20,13 @@
6. **资源管理**
- RTOS有效管理CPU时间、内存和其他系统资源,以支持实时任务。
RTOS广泛应用于以下领域:

- **嵌入式系统**:如工业控制系统、汽车电子、医疗设备、航空航天等。
- **网络设备**:如路由器、交换机等网络基础设施。
- **消费电子**:如数字电视、智能手机等。

一些知名的RTOS包括:

- VxWorks
- QNX
- RTLinux
Expand All @@ -39,10 +42,12 @@ RTOS的选择取决于具体的应用需求,包括任务的实时性要求、
## 板级支持包(Board Support Package,简称 BSP)

一组用于特定硬件平台的软件,它在该硬件平台上提供了硬件抽象层,使得操作系统或者用户应用能够在该硬件平台上运行。基本的BSP包含以下功能:

- **硬件初始化代码**:这些代码负责在系统启动时配置硬件组件,如CPU、内存、外设接口等,以确保它们处于正确的状态。
- **设备驱动程序**:将硬件组件向上抽象为面向应用的API,使操作系统和应用程序能够使用其与硬件设备进行交互。

更完善的还包括以下等:

- **系统启动代码**:包括引导加载程序(Bootloader)和其他初始化代码,这些代码负责启动操作系统。
- **配置工具和脚本**:用于配置和定制BSP的工具,以适应特定的硬件配置和操作系统需求。
- **调试和测试工具**:帮助开发人员调试和测试硬件与软件接口的工具。
Expand Down Expand Up @@ -70,6 +75,7 @@ BSP的主要目的是为了让操作系统和应用程序开发者不必关心
7. **可扩展性**
- UEFI的设计允许轻松添加新功能,使其能够适应未来的硬件和软件需求。
UEFI的主要组件包括:

- **UEFI固件**:这是嵌入在主板上的固件,负责初始化硬件并提供启动服务。
- **UEFI驱动程序**:用于在UEFI环境中操作硬件的软件模块。
- **UEFI Shell**:一个命令行界面,允许用户执行固件级别的操作。
Expand All @@ -84,6 +90,7 @@ BSP的主要目的是为了让操作系统和应用程序开发者不必关心
处理器架构是软件和硬件之间交互的桥梁,它决定了软件如何与硬件进行通信和操作。

以下是几种常见的处理器架构:

1. **x86架构**:由Intel和AMD公司开发,是最常见的桌面和服务器处理器架构之一。它支持复杂指令集计算机(CISC)和虚拟化技术。
2. **ARM架构**:由ARM Holdings公司开发,主要用于移动设备和嵌入式系统。它支持精简指令集计算机(RISC)架构,并以其低功耗和高能效而闻名。
3. **MIPS架构**:由MIPS Technologies公司开发,是一种精简指令集计算机(RISC)架构。它曾经在许多工作站和服务器中使用,但现在更多地用于嵌入式系统。
Expand All @@ -92,6 +99,7 @@ BSP的主要目的是为了让操作系统和应用程序开发者不必关心
6. **RISC-V架构**:是一个开源的指令集架构,旨在成为现代处理器架构的标准。它支持精简指令集计算机(RISC)架构,并以其模块化和可扩展性而受到关注。

处理器架构的选择取决于多种因素,包括性能需求、能效、成本、生态系统支持、兼容性和特定应用场景。例如:

- ARM架构因其低功耗和高能效而广泛用于移动设备
- x86架构因其高性能和广泛的应用软件支持而成为桌面和服务器系统的首选

Expand All @@ -100,21 +108,24 @@ BSP的主要目的是为了让操作系统和应用程序开发者不必关心
处理器架构的一部分,它定义了处理器可以理解和执行的机器指令的集合。指令集是软件和硬件之间的接口,它规定了处理器可以执行的操作,以及如何通过操作码和操作数来执行这些操作。

指令集可以分为以下几种类型:

1. **复杂指令集计算机(CISC)**:这种类型的指令集包含大量的指令,每个指令可以执行多个操作。CISC架构的处理器通常具有复杂的指令解码器,能够解析和执行复杂的指令。这种架构的优点是每个指令可以完成更多的操作,从而减少总的指令数量。然而,复杂的指令解码和执行可能会导致性能下降。
2. **精简指令集计算机(RISC)**:这种类型的指令集包含较少的指令,每个指令只执行一个简单的操作。RISC架构的处理器通常具有简单的指令解码器,能够快速解析和执行简单的指令。这种架构的优点是指令解码和执行速度快,但需要更多的指令来完成复杂的操作。
3. **混合指令集计算机**:这种类型的指令集结合了CISC和RISC的特点,包含一定数量的复杂指令和简单指令。这种架构的处理器可以根据需要使用复杂的指令或简单的指令来执行操作。

指令集的选择取决于多种因素,包括性能需求、能效、成本、生态系统支持、兼容性和特定应用场景。例如:

- CISC架构的处理器因其能够执行复杂操作而广泛用于桌面和服务器系统
- RISC架构的处理器因其简单高效的指令解码和执行而广泛用于移动设备和嵌入式系统

## CMSIS(Cortex Microcontroller Software Interface Standard)

一个为ARM Cortex-M微控制器系列设计的标准化软件接口。它旨在为开发者提供一个统一的接口,使得在不同ARM Cortex-M微控制器之间移植和复用软件变得更加容易。CMSIS的目的是减少为不同微控制器编写软件的复杂性,并允许开发者更容易地从一个微控制器迁移到另一个微控制器。
一个为ARM Cortex-M微控制器系列设计的标准化软件接口。它旨在为开发者提供一个统一的接口,使得在不同ARM Cortex-M微控制器之间移植和复用软件变得更加容易。CMSIS的目的是减少为不同微控制器编写软件的复杂性,并允许开发者更容易地从一个微控制器迁移到另一个微控制器。

![CMSIS结构图](/images/嵌入式/CMSIS架构图.png)

CMSIS包括以下几个关键部分:

1. **CMSIS-Core**:提供了一个基本框架,包括用于启动、中断处理、内存管理和异常处理的通用函数。
2. **CMSIS-DSP**:提供了一个数字信号处理(DSP)的软件库,包含了用于信号处理操作的函数。
3. **CMSIS-RTOS**:提供了一个实时操作系统(RTOS)接口,允许开发者选择并集成不同的RTOS实现。
Expand Down
37 changes: 20 additions & 17 deletions 教程/正文/嵌入式/环境搭建.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,76 +22,79 @@ Keil操作简单,容易上手,而且可以很方便地进行调试。

### 1.1 工具安装

1. [ **STM32CubeMX** ](https://www.st.com/en/development-tools/stm32cubemx.html)
ST官方出的一款针对ST的MCU/MPU跨平台的图形化工具,
1. [**STM32CubeMX**](https://www.st.com/en/development-tools/stm32cubemx.html)

ST官方出的一款针对ST的MCU/MPU跨平台的图形化工具,
支持在Linux、MacOS、Window系统下开发,其对接的底层接口是HAL库,
另外习惯于寄存器开发的同学们,也可以使用LL库。STM32CubeMX除了集成MCU/MPU的硬件抽象层,
另外还集成了像RTOS,文件系统,USB,网络,显示,嵌入式AI等中间件,这样开发者就能够很轻松的完成MCU/MPU的底层驱动的配置,
留出更多精力开发上层功能逻辑,能够更进一步提高了嵌入式开发效率。

2. [ **OpenOCD** ](https://github.com/xpack-dev-tools/openocd-xpack/releases)
2. [**OpenOCD**](https://github.com/xpack-dev-tools/openocd-xpack/releases)

openocd全名叫做Open On-Chip Debugger,是一个自由开放的片上调试工具和编程工具,
目前已经发布到0.11.0版本,目前主流调试器几乎都支持。

安装好之后,添加环境变量:

![OpenOCD环境变量](/images/嵌入式/OpenOCD环境变量图.png)

在终端输入,进行测试:

```shell
openocd
```

如果有信息输出如下,那就是装好了。

![OpenOCD检查](/images/嵌入式/OpenOCD检查图.png)

3. MinGW

Clion需要使用MinGW环境来配置工具链,安装在网上有很多教程,这里就不赘述了。

安装好之后,添加到环境变量:

![MinGW环境变量](/images/嵌入式/MinGW环境变量图.png)

在终端输入,进行测试:

```shell
gcc -v
```

如果有信息输出如下,那就是装好了。

![MinGW检查](/images/嵌入式/MinGW检查图.png)

4. [ **arm-none-eabi-gcc** ](https://developer.arm.com/open-source/gnu-toolchain/gnu-rm/downloads)
4. [**arm-none-eabi-gcc**](https://developer.arm.com/open-source/gnu-toolchain/gnu-rm/downloads)

> 注:为什么不是gcc?
>
> 注:为什么不是gcc?
>
> 在开发stm32的时候,编译工具链要使用gcc-arm-none-eabi,为什么不是gcc呢?
> 这就要说到Win下的交叉编译了,因为我们要在PC机上编译出可以运行在ARM上的程序,
> 使用gcc编译出的是在PC上运行的程序,所以我们要使用gcc-arm-none-eabi进行交叉编译,才能运行在ARM上。

安装好后,添加到环境变量:
![GNU-arm-none-eabi环境变量](/images/嵌入式/GNU-arm-none-eabi环境变量图.png)

在终端输入,进行测试:

```shell
arm-none-eabi-gcc -v
```

如果有信息输出如下,那就是装好了。
![GNU-arm-none-eabi检查](/images/嵌入式/GNU-arm-none-eabi检查图.png)

5. CLion
安装见[ **CLion** ](/杂项/工具和环境/工具/编程工具.md#1-文本编辑器和代码编辑器)

安装见[**CLion**](/杂项/工具和环境/工具/编程工具.md#1-文本编辑器和代码编辑器)

配置CLion的工具链,如下:

![CLion设置工具链](/images/嵌入式/CLion设置工具链图.png)

配置CLion的STM32开发方式,如下:

![CLion的STM32开发配置](/images/嵌入式/CLion的STM32开发配置图.png)



![CLion的STM32开发配置](/images/嵌入式/CLion的STM32开发配置图.png)
4 changes: 1 addition & 3 deletions 教程/正文/嵌入式/程序下载与调试.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
| 1 | 0 | 系统储存器 | 即是Bootloader固件所在地 |
| 1 | 1 | SRAM储存器 | 在SRAM中调试代码 |


## 1. 串口下载

> 在一般的STM32最小系统板上都带有串口下载电路,这里使用STM32F103C8T6板子。
Expand All @@ -29,7 +28,6 @@ CH340的上位机接口是一根USB线,连接到电脑的USB口上,而它的

### 1.3 软件下载

这里使用[ **FlyMCU** ](http://www.mcuisp.com/chinese%20mcuisp%20web/ruanjianxiazai-chinese.htm)串口下载器,
这里使用[**FlyMCU**](http://www.mcuisp.com/chinese%20mcuisp%20web/ruanjianxiazai-chinese.htm)串口下载器,

### 1.4 ISP原理分析

15 changes: 7 additions & 8 deletions 教程/正文/语法和标准库/34_位操作.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
- 每一个位存储一个二进制码(记作 **0****1**
2. 对于 **整型** 数据来说,每个计算机位对应这个整数二进制表示中的一个位
3. 8 位构成一个 **字节**,因此 ***在常见的实现中***`int` 类型有 **4** 字节(*32* 位),`long long`**8** 字节(*64* 位)
4. 关于进制的知识,可以参考 [ **进制** ](/教程/番外/77_关于进制.md)
4. 关于进制的知识,可以参考 [**进制**](/教程/番外/77_关于进制.md)

### 1.2 整数的二进制表示(以一字节为例)

Expand All @@ -27,7 +27,6 @@

> 只能使用 **整型** 数据进行位操作,不能使用 ~~**~~浮点型~~**~~ 数据;

### 2.1 位操作的种类

> 下面的例子使用无符号 8 位整数进行演示:
Expand Down Expand Up @@ -60,7 +59,7 @@

```C
~(10011010) // 表达式
01100101 // 结果值
01100101 // 结果值
```

5. 按位左移 (<<):
Expand Down Expand Up @@ -125,12 +124,12 @@ uint32_t flag = 0b1111111100000000000000000000000000000000;

```C
//typedef unsigned char uint8_t;

uint8_t flag = 0b10101010;

//定义MASK,0号位为1,其余位为0
uint8_t mask = 0b00000010;

//掩码操作
flag = flag & mask; //此时 flag = 0b00000010
```
Expand Down Expand Up @@ -176,11 +175,11 @@ uint32_t flag = 0b1111111100000000000000000000000000000000;
- 使用 `&` 运算符和掩码,代码如下:
- 以上一节的 **mask**(只有 `1` 号位为 1)为例:

```C
```C
uint8_t flag = 0b10101011;
if ((flag & mask) == mask) {
printf("1号位为1。");
}
}
```

根据 **mask** 中为 `1` 的位, 在 **flag** 中只读对应。
Loading

0 comments on commit 665c7d0

Please sign in to comment.