[doc] update rst

This commit is contained in:
jzlv 2023-03-09 14:59:32 +08:00
parent f5fb0222c4
commit 8a21081fd5
9 changed files with 168 additions and 385 deletions

View file

@ -1,9 +0,0 @@
=======================
Utils
=======================
.. toctree::
:maxdepth: 1
LIBC <libc>
VLIBC <vlibc>

View file

@ -1,120 +0,0 @@
LIBC
============
简介
------------
- LIBC 中实现了一个vsnprintf用以避开使用完整的c库减少代码体积。
.. note:: LIBC 中浮点打印只能最大支持到7位小数精度
配置LIBC相关功能
-------------------
如果需要配置LIBC的相关功能需要在对应的工程目录下 `proj.conf` 文件中添加对应的代码,举例如下:
.. code-block:: cmake
:linenos:
# 使能浮点打印
set(CONFIG_VSNPRINTF_FLOAT 1)
格式化控制字符
----------------
.. list-table::
:header-rows: 1
* - proj.conf 配置项
- 功能描述
* - CONFIG_VLIBC
- 使能 **VLIBC** 库,默认使用 **LIBC** ,不配置 **CONFIG_VLIBC** 或配置为 **0** 使能 **LIBC**
* - CONFIG_VSNPRINTF_FLOAT
- 使能格式化输出 (%f, %F) 浮点数格式化支持
* - CONFIG_VSNPRINTF_FLOAT_EX
- 使能格式化输出 (%e, %g, %E, %G) 浮点数扩展格式化支持
* - CONFIG_VSNPRINTF_LONG_LONG
- 使能格式化输出 (%lld,%lli,%llo,%llx,%llX,%llu) 长整型格式化支持
.. list-table::
:header-rows: 1
* - 格式化控制字符 (specifier)
- 支持情况
* - %s
- ✔️
* - %c
- ✔️
* - %d
- ✔️
* - %i
- ✔️
* - %u
- ✔️
* - %x (%X)
- ✔️
* - %o
- ✔️
* - %b
- ✔️
* - %f (%F)
- ✔️
* - %e (%E)
- ✔️
* - %g (%G)
- ✔️
* - %a (%A)
- ❌
* - %p
- ✔️
* - %n
- ❌
.. list-table::
:header-rows: 1
* - 格式化控制变量长度字符 (length)
- 支持情况
* - l
- ✔️
* - ll
- ✔️
* - h
- ✔️
* - hh
- ✔️
* - t
- ✔️
* - j
- ✔️
* - z
- ✔️
.. list-table::
:header-rows: 1
* - 格式化控制标志字符 (flags)
- 支持情况
* - 0
- ✔️
* - \-
- ✔️
* - \+
- ✔️
* - ' ' (空格)
- ✔️
* - #
- ✔️
格式化输出格式
----------------
.. code-block:: c
:linenos:
/* 格式化输出控制字符格式 */
/* %[flags][width][.precision][length][specifier] */
printf("%+12.9f\r\n", var)
printf("%-12lld\r\n", var)
printf("%#x\r\n", var)
printf("%08x\r\n", var)
printf("% 8x\r\n", var)

View file

@ -1,195 +0,0 @@
VLIBC
============
简介
------------
- VLIBC 是适用于MCU使用的C标准库 STDIO的重新实现与标准的STDIO库具有相同的API以及相同的使用方法。
- VLIBC 支持文件操作诸如fopen、fwrite、fprintf等API与Fatfs文件系统对接为其他依赖标准C库文件操作的组件提供支持。
- VLIBC 同时支持对外设进行操作例如将UART当做文件进行处理使用fprintf进行输出。
- VLIBC 体积小、移植极简、同时可以裁剪掉对Fatfs的依赖仅仅当做一个体积小的printf库使用。
.. note:: VLIBC 中浮点打印只能最大支持到11位小数精度
配置VLIBC相关功能
--------------------
如果需要配置VLIBC的相关功能需要在对应的工程目录下 `proj.conf` 文件中添加对应的代码,举例如下:
.. code-block:: cmake
:linenos:
# 使能浮点打印
set(CONFIG_VSNPRINTF_FLOAT 1)
格式化控制字符
-----------------
.. list-table::
:header-rows: 1
* - proj.conf 配置项
- 功能描述
* - CONFIG_VLIBC
- 使能VLIBC库默认使用LIBC
* - CONFIG_VLIBC_FATFS需要启用FATFS相关功能
- 使能VLIBC FATFS接口
* - CONFIG_VSNPRINTF_FLOAT
- 使能格式化输出 (%f, %F) 浮点数格式化支持
* - CONFIG_VSNPRINTF_FLOAT_EX
- 使能格式化输出 (%e, %g, %E, %G) 浮点数扩展格式化支持
* - CONFIG_VSNPRINTF_LONG_LONG
- 使能格式化输出 (%lld,%lli,%llo,%llx,%llX,%llu) 长整型格式化支持
* - CONFIG_VSNPRINTF_WRITEBACK
- 使能格式化字符 (%n) 字符统计支持
.. list-table::
:header-rows: 1
* - 格式化控制字符 (specifier)
- 支持情况
* - %s
- ✔️
* - %c
- ✔️
* - %d
- ✔️
* - %i
- ✔️
* - %u
- ✔️
* - %x (%X)
- ✔️
* - %o
- ✔️
* - %b
- ✔️
* - %f (%F)
- ✔️
* - %e (%E)
- ✔️
* - %g (%G)
- ✔️
* - %a (%A)
- ❌
* - %p
- ✔️
* - %n
- ✔️
.. list-table::
:header-rows: 1
* - 格式化控制变量长度字符 (length)
- 支持情况
* - l
- ✔️
* - ll
- ✔️
* - h
- ✔️
* - hh
- ✔️
* - t
- ✔️
* - j
- ✔️
* - z
- ✔️
.. list-table::
:header-rows: 1
* - 格式化控制标志字符 (flags)
- 支持情况
* - 0
- ✔️
* - \-
- ✔️
* - \+
- ✔️
* - ' ' (空格)
- ✔️
* - #
- ✔️
格式化输出格式
--------------------
.. code-block:: c
:linenos:
/* 格式化输出控制字符格式 */
/* %[flags][width][.precision][length][specifier] */
printf("%+12.9f\r\n", var)
printf("%-12lld\r\n", var)
printf("%#x\r\n", var)
printf("%08x\r\n", var)
printf("% 8x\r\n", var)
IO 接口移植
---------------
.. code-block:: c
:linenos:
#define IOCONSOLE_IO ((uint32_t)0x00000001)
#define IOCONSOLE_NAME "console"
struct bflb_device_s *uart0 = NULL;
uint32_t __vlibc_io_init(const char *name, uint8_t mode)
{
(void)mode;
if (strcmp(name, IOCONSOLE_NAME) == 0) {
return IOCONSOLE_IO;
} else {
}
return ENOENT;
}
uint32_t __vlibc_io_deinit(struct __vlibc_io *io)
{
if (io->dev == IOCONSOLE_IO) {
return IOCONSOLE_IO;
} else {
}
return EOF;
}
size_t __vlibc_io_mem2dev(struct __vlibc_io *io, const void *ptr, size_t size)
{
if (io->dev == IOCONSOLE_IO) {
for (size_t i = 0; i < size; i++) {
bflb_uart_putchar(uart0, ((char *)ptr)[i]);
}
return size;
} else {
}
return 0;
}
void main(){
board_init();
uart0 = bflb_device_get_by_name("uart0");
vlibc_stdout = vlibc_fopen("<console", "w");
printf("hello world\r\n");
}
上述是一个简单的添加一个支持的IO设备通过串口输出
使用时,调用 **vlibc_fopen** 函数,文件地址以 '<' 为开头,以 '<' 开头代表是IO设备,
后续的字符串会被认为是IO设备的名称此名称会传入 **__vlibc_io_init** 中交由用户移植的IO接口进行判断
API参考
------------
- API 基本与标准C库一致
- 等待完善

View file

@ -3,7 +3,7 @@
Bouffalo Lab DevCube 的使用
=============================
.. caution:: BouffaloSDK 不再使用此工具,使用 SDK 自带的命令行烧录工具
.. caution:: BouffaloSDK 不再使用此工具,使用 SDK 自带的命令行烧录工具
本文档将简要介绍一下如何使用 Bouffalo Lab DevCube 集成开发工具烧写代码。

View file

@ -3,9 +3,23 @@
Flash prog cfg.ini 的使用
=================================
在用户执行 ``make flash`` 会调用 **bouffalo_flash_cube** 下的可执行文件,并根据 **Flash prog cfg.ini** 进行烧录,
BouffaloSDK 采用新的 flash tool **bouffalo_flash_cube** ),并且烧录依赖 **Flash prog cfg.ini** 文件。
相比于 Bouffalo Lab DevCube 繁琐的功能bouffalo_flash_cube 只用于下载代码,在用户执行 ``make flash`` 时会调用 **bouffalo_flash_cube** 下的可执行文件,并根据 **Flash prog cfg.ini** 进行烧录,
本节主要介绍一下 **Flash prog cfg.ini** 的语法。
语法
---------------------------------
**Flash prog cfg.ini** 正常使用只需要创建一个 KEY例如 [FW],并且填写 filedir 和 address 就可以使用了。
其中 filedir 的填写方式有以下几种:
- bin 文件全路径 + bin 文件名称
- bin 文件相对路径 + bin 文件名称
- bin 文件名称添加 **_$(CHIPNAME)** 后缀可以自动识别成不同芯片(仅在 bin 文件名称前缀不同的时候使用)
- bin 文件名称添加 * 通配符可以自动补全bin 文件名称(仅在 bin 文件名称前缀不同的时候使用)
常规 MCU 使用(不使用无线功能)
---------------------------------
@ -28,7 +42,7 @@ Flash prog cfg.ini 的使用
- **cfg** 表示烧录时的一些配置,正常不需要改动
- **FW** 要烧录的应用固件,必须使用 **FW** 名称。
- **filedir** 表示应用固件所在相对路径,正常来说是编译完后放在 `build/build_out` 目录。 ``_$(CHIPNAME).bin`` 是必须要的后缀,用于区分不同芯片。 ``xxx`` 表示应用固件名称,与 `CMakeLists.txt``project(xxx)` 中名称一致。 ``*`` 表示正则匹配,可用可不用。
- **filedir** 表示应用固件所在相对路径,正常来说是编译完后放在 `build/build_out` 目录。 ``_$(CHIPNAME).bin`` 用于自动区分不同芯片。 ``xxx`` 表示应用固件名称,与 `CMakeLists.txt``project(xxx)` 中名称一致。 ``*`` 表示正则匹配,可用可不用。
- **address** 必须使用 0 地址
@ -65,7 +79,7 @@ Flash prog cfg.ini 的使用
- **cfg** 表示烧录时的一些配置,正常不需要改动
- **FW** 要烧录的应用固件,必须使用 **FW** 名称。
- **filedir** 表示应用固件所在相对路径,正常来说是编译完后放在 `build/build_out` 目录。 ``_$(CHIPNAME).bin`` 是必须要的后缀,用于区分不同芯片。 ``xxx`` 表示应用固件名称,与 `CMakeLists.txt``project(xxx)` 中名称一致。
- **filedir** 表示应用固件所在相对路径,正常来说是编译完后放在 `build/build_out` 目录。 ``_$(CHIPNAME).bin`` 用于区分不同芯片。 ``xxx`` 表示应用固件名称,与 `CMakeLists.txt``project(xxx)` 中名称一致。
- **address**`partition_xxx.toml` 指定
- **boot2** 要烧录的 boot2 固件,必须使用 **boot2** 名称。
@ -82,3 +96,32 @@ Flash prog cfg.ini 的使用
- **filedir** 表示 mfg 固件所在相对路径,正常来说是编译完后放在 `build/build_out` 目录。 **自动从 bsp/board/board_name/config 目录拷贝**
- **address**`partition_xxx.toml` 指定
多个运行固件烧录
---------------------------------
禁止使用通配符 * 以及 ``_$(CHIPNAME)`` 前缀,因为 bin 文件名称前缀相同。
.. code-block:: ini
:linenos:
[cfg]
# 0: no erase, 1:programmed section erase, 2: chip erase
erase = 1
# skip mode set first para is skip addr, second para is skip len, multi-segment region with ; separated
skip_mode = 0x0, 0x0
# 0: not use isp mode, #1: isp mode
boot2_isp_mode = 0
[FW1]
filedir = ./build/build_out/xxx0.bin
address = 0x00000
[FW2]
filedir = ./build/build_out/xxx1.bin
address = 0x10000
[FW3]
filedir = ./build/build_out/xxx2.bin
address = 0x20000

View file

@ -24,15 +24,12 @@ BouffaloSDK 使用指南
:caption: API 手册
api_reference/peripherals/index
api_reference/components/index
api_reference/utils/index
.. toctree::
:maxdepth: 1
:caption: 基础例程
samples/peripherals/index
samples/components/index
.. toctree::
:maxdepth: 1
@ -47,4 +44,5 @@ BouffaloSDK 使用指南
notes/note_uart
notes/note_dma
notes/note_cache
notes/note_808dualcore
notes/note_808triplecore
notes/note_flash_tool

View file

@ -1,53 +0,0 @@
BL808 双核启动流程
=======================
本节主要介绍 BL808 M0 和 D0 两个核的启动流程。首先我们需要知道以下信息:
- M0 使用 t-head E907 ,D0 使用 t-head C906为异构双核
- M0 和 D0 外设共享但是中断不共享M0 能触发的中断不一定能在 D0上触发比如 UART0中断只能在 M0 上使用
- 工具烧录时MCU 界面有 group0 和 group1 选项
工具烧写的秘密
------------------
在工具上,烧录的时候会提示选择 group0 和 group1, 如果都不选的话,是没法烧录代码的。假如我们使用 M0 选择 group0D0 unused那么就是简单的
单核启动D0 不会启动。如果 M0 选择 group0D0 选择 group1则两个核都会启动。那么问题来了为什么工具选了之后会影响双核启动呢原因就是工具选完后的配置会在
烧录的时候传递给 bootrombootrom 会做处理。那么我们就知道了双核启动的第一步了。
.. figure:: img/devcube_808.png
:alt:
SystemInit 干了什么
-------------------------
``SystemInit`` 函数位于 `soc/bl808/startup/m0``soc/bl808/startup/d0` 中的 `system_bl808.c` 中。
系统启动时,会根据 ld 文件中设置的 entry(__start) 去找 ``__start`` 函数, 这个便是我们芯片启动的入口,位于 `start.S` 中。看标题可以知道,我们主要是了解
``SystemInit`` 函数干了什么,而 `start.S` 中做了什么是不需要关心的,只需要知道,里面会调用 ``SystemInit`` 函数。
- D0 ``SystemInit``
首先我们先看 D0 ``SystemInit``,一上来就是一个 while 死循环,系统启动时,这个条件一定是不会满足的,所以 D0 一上来就会在这死循环,等待条件成立。
.. code-block:: c
:linenos:
while ((BL_RD_WORD(IPC_SYNC_ADDR1) != IPC_SYNC_FLAG) ||
(BL_RD_WORD(IPC_SYNC_ADDR2) != IPC_SYNC_FLAG)) {
// clang-format off
__NOP(); __NOP(); __NOP(); __NOP();
__NOP(); __NOP(); __NOP(); __NOP();
__NOP(); __NOP(); __NOP(); __NOP();
__NOP(); __NOP(); __NOP(); __NOP();
// clang-format on
/* if cache is off, comment this and this api need to start load itcm*/
// L1C_DCache_Invalid_By_Addr(IPC_SYNC_ADDR1, 8);
};
/* clear this flags for system reboot */
BL_WR_WORD(IPC_SYNC_ADDR1, 0x0);
BL_WR_WORD(IPC_SYNC_ADDR2, 0x0);
- M0 ``SystemInit``
根据上述信息我们知道, M0 一定会在某个时刻,向这两个寄存器写入 ``IPC_SYNC_FLAG``, 从而让 D0 运行起来。

View file

@ -0,0 +1,98 @@
BL808 三核启动流程
=======================
本节主要介绍 BL808 三核的启动流程。首先我们需要知道以下信息:
- M0 使用 t-head E907 ,D0 使用 t-head C906LP 使用 t-head e902为异构三核
- M0 和 D0 外设共享但是中断不共享M0 能触发的中断不一定能在 D0上触发比如 UART0中断只能在 M0 上使用,同理 LP 也是
- M0 会启动其他两个核
SystemInit 干了什么
-------------------------
``SystemInit`` 函数位于 `soc/bl808/startup/m0``soc/bl808/startup/d0` `soc/bl808/startup/lp` 中的 `system_bl808.c` 中。
系统启动时,会根据 ld 文件中设置的 entry(__start) 去找 ``__start`` 函数, 这个便是我们芯片启动的入口,位于 `start.S` 中。 `start.S` 中只是简单的设置异常和中断向量表以及 sp最终调用 ``SystemInit`` 函数。
所以我们先了解 ``SystemInit`` 函数干了什么。
- LP ``SystemInit``
初始化 CLIC其他什么也没有
- D0 ``SystemInit``
一上来就是一个 while 死循环,系统启动时,这个条件一定是不会满足的,所以 D0 一上来就会在这死循环,等待条件成立。
.. code-block:: c
:linenos:
while ((BL_RD_WORD(IPC_SYNC_ADDR1) != IPC_SYNC_FLAG) ||
(BL_RD_WORD(IPC_SYNC_ADDR2) != IPC_SYNC_FLAG)) {
// clang-format off
__NOP(); __NOP(); __NOP(); __NOP();
__NOP(); __NOP(); __NOP(); __NOP();
__NOP(); __NOP(); __NOP(); __NOP();
__NOP(); __NOP(); __NOP(); __NOP();
// clang-format on
/* if cache is off, comment this and this api need to start load itcm*/
// L1C_DCache_Invalid_By_Addr(IPC_SYNC_ADDR1, 8);
};
/* clear this flags for system reboot */
BL_WR_WORD(IPC_SYNC_ADDR1, 0x0);
BL_WR_WORD(IPC_SYNC_ADDR2, 0x0);
- M0 ``SystemInit``
主要是 pmp 和 clic 的配置,以及一些寄存器的复位
.. code-block:: c
:linenos:
/* CPU Prefetching barrier */
Tzc_Sec_PSRAMA_Access_Set_Not_Lock(0, 0x0, 64 * 1024 * 1024, 0);
Tzc_Sec_PSRAMB_Access_Set_Not_Lock(0, 0x0, 64 * 1024 * 1024, 0);
pmp_init();
/* enable mstatus FS */
uint32_t mstatus = __get_MSTATUS();
mstatus |= (1 << 13);
__set_MSTATUS(mstatus);
/* enable mxstatus THEADISAEE */
uint32_t mxstatus = __get_MXSTATUS();
mxstatus |= (1 << 22);
/* enable mxstatus MM */
mxstatus |= (1 << 15);
__set_MXSTATUS(mxstatus);
/* get interrupt level from info */
CLIC->CLICCFG = (((CLIC->CLICINFO & CLIC_INFO_CLICINTCTLBITS_Msk) >> CLIC_INFO_CLICINTCTLBITS_Pos) << CLIC_CLICCFG_NLBIT_Pos);
/* Every interrupt should be clear by software*/
for (i = 0; i < IRQn_LAST; i++) {
CLIC->CLICINT[i].IE = 0;
CLIC->CLICINT[i].IP = 0;
CLIC->CLICINT[i].ATTR = 1; /* use vector interrupt */
}
/* tspend interrupt will be clear auto*/
/* tspend use positive interrupt */
CLIC->CLICINT[MSOFT_IRQn].ATTR = 0x3;
csi_dcache_enable();
csi_icache_enable();
/* enable preload $ AMR for D$ */
__set_MHINT(0x000c);
/* disable mexstatus SPUSHEN and SPSWAPEN for ipush/ipop*/
uint32_t mexstatus = __get_MEXSTATUS();
mexstatus &= ~(0x3 << 16);
__set_MEXSTATUS(mexstatus);
根据上述信息我们知道, M0 一定会在某个时刻,向这两个寄存器写入 ``IPC_SYNC_FLAG``, 从而让 D0 运行起来。而 LP 是没有条件限制的M0 控制运行就可以了。
board_init
------------
然后就是进入 ``main`` 函数了, ``main`` 函数一开始会调用 ``board_init`` 去初始化一些内容,这里我们只需要关心 M0, 因为在此其他两个核还没有开始运行。

View file

@ -0,0 +1,21 @@
Flash tool 差异
=======================
当前,我们提供了以下 flash tool
- Bouffalo Lab DevCube GUI + CMD(bflb_mcu_tool + bflb_iot_tool)
- bouffalo_flash_cube (GUI + CMD)
Bouffalo Lab DevCube 会将用户的运行固件不包含bootheader根据界面上的 clock 和 flash 配置生成 bootheader 并与固件打包成 whole img bin,
iot 和 mcu 主要区别是烧录的文件种类不一样, iot 在烧录时除了运行固件还有 boot2/dts/mfg/media 等等。
而 bouffalo_flash_cube 则是直接烧录 bin 文件,如果是烧录运行固件,则是烧录 whole img binwhole img bin 不再由工具生成,而是代码自动在固件前面增加 bootheader后续修改非常方便。
如果想要增加 bin 文件烧录,比如 boot2/dts/mfg/media ,则直接在 **Flash prog cfg.ini** 文件添加即可,到此 bouffalo_flash_cube 就不再有其他功能了。
你可能会遇到以下情况:
- iot/mcu sdk 的单核固件无bootheader请用 Bouffalo Lab DevCube
- iot/mcu sdk 的单核固件带bootheader两者都可以
- iot/mcu sdk 多核固件,请用 Bouffalo Lab DevCube
- BouffaloSDK 的单核固件带bootheader两者都可以
- BouffaloSDK 多核固件,请用 bouffalo_flash_cube不准使用 Bouffalo Lab DevCube