## 摘要
本节内容主要描述F1C100S的裸机相关开发,很多的库都是参考的其他大佬的开发,本节将移植开源项目[https://gitee.com/dmcus/F1C200S](https://gitee.com/dmcus/F1C200S)的开发环境和代码设计。这节主要将使用并研究的驱动有时钟、串口和SPI,并以此实现一个BootLoader,该 BootLoader 将支持程序跳转、在线升级。这样的话就单独使用串口就能够升级我的代码了,方便后续研究和开发,不用每次下程序都要进 FEL 。
## 项目开源链接
| <font size=3>项 | <font size=3>参数 |
| ----------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------- |
| <font size=3>github主页 | <font size=3>https://github.com/snqx-lqh |
| <font size=3>github项目地址 | <font size=3>https://github.com/snqx-lqh/F1C100S_LearningRecord |
| <font size=3>gitee项目地址 | <font size=3>https://gitee.com/snqx-lqh/F1C100S_LearningRecord |
| <font size=3>硬件开源地址 | <font size=3>[https://oshwhub.com/from_zero/f1c100s-200s-he-xin-ban-di-ban-she-ji](https://oshwhub.com/from_zero/f1c100s-200s-he-xin-ban-di-ban-she-ji) |
| <font size=3>作者 VX | <font size=3>Qinghua_Li7 |
## 参考项目搭建开发环境
### 基础环境搭建
相关工具:
程序下载:[xfle_1.3.2](https://github.com/xboot/xfel/releases/download/v1.3.2/xfel-windows-v1.3.2.7z) ,这个我在上节内容中已经介绍了怎么安装使用了。
arm-gcc编译:[arm-none-eabi-gcc-10.3.1](https://developer.arm.com/-/media/Files/downloads/gnu-rm/10.3-2021.10/gcc-arm-none-eabi-10.3-2021.10-win32.exe?rev=29bb46cfa0434fbda93abb33c1d480e6&hash=3C58D05EA5D32EF127B9E4D13B3244D26188713C) ,arm-none-eabi-gcc 需要带 libc_nano.a, 有的版本没有这个库。他使用的是10.3.1
Makefile文件处理: [winhost mingw64 gcc-11.2](http://mirrors.zju.edu.cn/qt/development_releases/prebuilt/mingw_64/MinGW-w64-x86_64-11.2.0-release-posix-seh-rt_v9-rev1.7z) 使用mingw工具来处理makefile。
这3个工具下载下来后,除了第一个需要安装驱动,其他都是文件夹然后直接的应用,都需要在环境变量中添加。我使用的版本不一定是上面这几个,但是应该差不多,上面的是原作者提供的,我有些原来已经装过了。

然后,为了方便使用make。我一般会把`mingw64/bin`,中的 mingw32-make 复制并重命名一份 make。

如果要检查安装好了没有,打开一个终端,输入以下指令,并看输出:
```bash
arm-none-eabi-gcc -v
make -v
xfel version # 这个要让板子进入 fel 模式
```
### 文档结构分析
下面是他提供的文档结构分析。
```
doc ------文档和原理图 使用LCPI F1C200S 开发板 集成CH340E -> UART1
sources ---源码
|bootloader -----SPL 烧录FLASH 0,log 使用 UART1
|drivers---------f1c200s驱动
|fc200s_brom ----sram运行的独立程序 烧录FLASH 0 支持串口
|examples--------peripherals examples 外设样例,裸机程序 使用LCPI F1C200S 开发板
|mksunxi --------.bin文件添加校验头工具
|rtt-------------rt-thread 烧录到FLASH 0X10000 log 使用 UART1
tools -----make 工具 添加到环境变量
```
根据内容,我将使用他的部分内容,并放在开源目录`02_Firmware\CodeWithoutOS`下。
```
CodeWithoutOS --- 无 Liunx 代码
|bootloader ----- 修改他的启动,适配在线升级
|drivers--------- f1c200s驱动(直接沿用)
|examples-------- peripherals examples 外设样例,裸机程序 将适配我自己的开发板
|mksunxi --------.bin文件添加校验头工具
```
### 编译流程分析
使用他这套代码前,先分析一下他的工作流程。
#### 链接文件
它使用的链接文件有两个,一个是`f1c100s_dram.ld`链接到DDR的相关地址,主要用来跑正式的应用程序,一个是`f1c100s_sram.ld`链接到内部RAM的相关地址,主要用来跑bootloader。
在这里,主要关注一下关于 SRAM 的链接地址设置,他是从 0 开始,但是这和数据手册对不上,然后我在博客园找到了一位博主(Yanye)的研究(F1C100S-BOOTROM与SPL阶段):
https://www.cnblogs.com/yanye0xcc/p/16341719.html
他最后分析得到的结果是,F1C100S实际的BROM和SRAM地址表如下:
| Module | Address | Size | 权限 |
| --------- | ----------------------- | ---------- | --- |
| SRAM | 0x0000 - 0x9000 | 36KB | rwx |
| SRAM1 | 0xB000 - 0xB600 | 1.5KB | rwx |
| 异常向量表 | 0xFFFF0000 - 0xFFFF001F | 32 Bytes | rx |
| FEL模式相关程序 | 0xFFFF0020 - 0xFFFF25AB | 9612 Bytes | rx |
| BROM | 0xFFFF4000 - 0xFFFF62B7 | 8888 Bytes | rx |
#### Makefile文件
首先是通用基础配置文件,3个重要的文件,gcc.mk、libsources.mk、project.mk。
**gcc.mk**:在这个文件中,定义了gcc操作的重命名
**libsources.mk**:这个文件包含了 drivers 的全部源文件和头文件目录。
**project.mk**:这个文件包含了编译链接的全部指令。这个文件会include上面两个文件。
文件的基本常用指令就是
```bash
make all # 编译
make download # 通过 xfel 下载
```
然后在对应的项目中,会写各自的`Makefile`,包含项目的源文件,额外定义。同时在最后include基础文件中的**project.mk**。
## BootLoader 设计
接下来将描述我的 BootLoader 的流程设计。
首先,先描述他的 bootloader 设计。
他的 bootloader 初始化 SPI、DDR 和 串口等外设 后。直接读取 Flash 偏移 `0x10000` 处的 APP 代码到 DDR 的 `0x80000000` 地址。然后跳转到这个地址运行代码。
我在他的基础上增加了。开头检测回车换行,如果没有检测到回车,5S 后就会进入他的原跳转代码。
如果检测到回车,就会进入命令行模式。命令行模式中,我会通过检测不同的命令,实现升级,FLASH 读写等功能,这样直接接上串口1就能够实现相应的功能了,不用每次用 fel 下载。命令行可以自己看我的源码。主要使用的就是 `burn boot` 和 `burn app` 。分别烧写 Boot区域和APP区域。
升级相关的内容使用的是 Xmodem 升级,通过DDR缓存串口通过Xmodem协议接收到的数据,接收完成后写入到 FLASH 中 。升级所使用的上位机是我另外一个项目的内容。可以在项目中查看使用说明。
| <font size=3>项 |<font size=3>参数 |
|--|--|
| <font size=3>github主页 |<font size=3>https://github.com/snqx-lqh |
| <font size=3>github项目地址 |<font size=3>https://github.com/snqx-lqh/JYSWJ |
| <font size=3>gitee项目地址 |<font size=3>https://gitee.com/snqx-lqh/JYSWJ |
我这里做一个简要的描述。在文本接收中,如果你想要可输入,把终端模式勾上,如果只是想看输出,就取消。然后在协议发送中,选择Xmodem 协议,然后选择指定的文件发送。

## 例程 Example 说明
我只是移植了他的几个例程跑了一遍,如果想更多的学习,可以自己尝试。但是他的例程,很多和我的板子是不适配的,需要自己适配。