diff --git a/development-tools/rtthread-studio/um/studio-user-begin.md b/development-tools/rtthread-studio/um/studio-user-begin.md index ce9ff32da98be158b259f79aea3da219171675b6..75dea453f1d2a3e8c08bf9c7879f040149cb3e40 100644 --- a/development-tools/rtthread-studio/um/studio-user-begin.md +++ b/development-tools/rtthread-studio/um/studio-user-begin.md @@ -26,11 +26,11 @@ ![start-install](figures/start-install.png) -一直点击`下一步`直到最后点击`安装`按钮可开始进行安装,待安装完成后可直接点击`确定`即可启动 RT-Thread Studio,如下图所示: +一直点击 ` 下一步 ` 直到最后点击 ` 安装 ` 按钮可开始进行安装,待安装完成后可直接点击 ` 确定 ` 即可启动 RT-Thread Studio,如下图所示: ![start-studio](figures/start-studio.png) -或者取消`运行RT-Thread Studio`勾选,点击完成后,从桌面快捷方式启动 RT-Thread Studio。桌面快捷方式如下图所示: +或者取消 ` 运行 RT-Thread Studio` 勾选,点击完成后,从桌面快捷方式启动 RT-Thread Studio。桌面快捷方式如下图所示: ![studio-pic](figures/studio-pic.png) @@ -38,185 +38,148 @@ ![sign-in](figures/sign-in.png) -## 更新SDK +## 更新 SDK -### 打开SDK管理器 +### 打开 SDK 管理器 -安装好后RT-Thread Studio后,我们需要在线下载SDK,点击`SDK Manager`按钮,如下图所示: +安装好后 RT-Thread Studio 后,我们需要在线下载 SDK,点击 `SDK Manager` 按钮,如下图所示: ![image-20210825223219069](figures/open_sdk_manager.png) - - -点击`SDK Manager`后,会出现下图等待提示,此时RT-Thread Studio正在联网获取SDK信息,稍等一会后,便可以进行SDK的下载 +点击 `SDK Manager` 后,会出现下图等待提示,此时 RT-Thread Studio 正在联网获取 SDK 信息,稍等一会后,便可以进行 SDK 的下载 ![image-20210825223445601](figures/image-20210825223445601.png) -### SDK资源库介绍 +### SDK 资源库介绍 -SDK资源库一共有6个分类,我们需要根据需要更新SDK资源,SDK更新的文件一般保存在比如`D:\RT-ThreadStudio\repo\Extract`中 +SDK 资源库一共有 6 个分类,我们需要根据需要更新 SDK 资源,SDK 更新的文件一般保存在比如 `D:\RT-ThreadStudio\repo\Extract` 中 ![image-20210825223620724](figures/open_sdk_manager2.png) #### RT-Thread_Source_Code -RT-Thread的源码包,主要包括RT-Thread完整版本,Nano版本,以及LTS版本,不同版本差异可以 参考文档,[版本简介](https://www.rt-thread.org/document/site/#/other/novice-guide/README) +RT-Thread 的源码包,主要包括 RT-Thread 完整版本,Nano 版本,以及 LTS 版本,不同版本差异可以 参考文档,[版本简介](https://www.rt-thread.org/document/site/#/other/novice-guide/README) ![image-20210825223958494](figures/open_sdk_manager3.png) -#### Chip_Support_Packages +#### Chip_Support_Packages 芯片支持包,目前已经支持的芯片包如下如所示: ![image-20210825224518632](figures/image-20210825224518632.png) - - #### Board_Support_Packages 板级支持包,展开某一个厂商的分类,可以看到更加细致的支持情况 -​ ![image-20210825225800339](figures/image-20210825225800339.png) +​![image-20210825225800339](figures/image-20210825225800339.png) #### ToolChain_Support_Packages -交叉编译工具链的支持,目前支持ARM和RISC-V以及ARM-LIUNX +交叉编译工具链的支持,目前支持 ARM 和 RISC-V 以及 ARM-LIUNX ![image-20210825231231207](figures/image-20210825231231207.png) #### Debugger_Support_Packages -调试器的支持,可以看出目前RT-Thread Studio对调试器的支持也比较丰富 +调试器的支持,可以看出目前 RT-Thread Studio 对调试器的支持也比较丰富 ![image-20210825231353684](figures/image-20210825231353684.png) - - #### ThirdParty_Support_Packages 第三放工具的支持 ![image-20210825231432173](figures/image-20210825231432173.png) - - ## 新建项目 ### 基于开发板创建 -在`项目资源管理器`窗口内点击右键,选择`新建`子菜单`项目`,如下图所示: +在 ` 项目资源管理器 ` 窗口内点击右键,选择 ` 新建 ` 子菜单 ` 项目 `,如下图所示: ![new-pro](figures/new-pro.png) -在弹出的新建项目向导对话框中选择`RT-Thread项目`类型,然后点击`下一步`如下图所示: +在弹出的新建项目向导对话框中选择 `RT-Thread 项目 ` 类型,然后点击 ` 下一步 ` 如下图所示: ![rtthread-pro](figures/rtthread-pro.png) -填写工程名,选择基于开发板创建工程,选择开发板型号,选择BSP版本号,选择 RT-Thread 源码版本,选择调试器和调试接口,然后点击`完成`按钮,如下图所示: +填写工程名,选择基于开发板创建工程,选择开发板型号,选择 BSP 版本号,选择 RT-Thread 源码版本,选择调试器和调试接口,然后点击 ` 完成 ` 按钮,如下图所示: ![done-pro](figures/done-pro.png) -点击`完成`后,等待工程创建过程如下图所示: - - +点击 ` 完成 ` 后,等待工程创建过程如下图所示: ![image-20210825231555982](figures/image-20210825231555982.png) - - -工程创建成功后`项目资源管理器`窗口会出现刚创建的工程`test`,如下图所示: +工程创建成功后 ` 项目资源管理器 ` 窗口会出现刚创建的工程 `test`,如下图所示: ![image-20210825231610537](figures/image-20210825231610537.png) - - ### 基于芯片创建 -创建项目的过程和基于开发板创建工程是一样的,创建工程时,这里我们选择基于芯片,根据自己芯片的实际型号进行选项配置,这里我们以`STM32F413CHU6`芯片为例,创建工程,点击完成 +创建项目的过程和基于开发板创建工程是一样的,创建工程时,这里我们选择基于芯片,根据自己芯片的实际型号进行选项配置,这里我们以 `STM32F413CHU6` 芯片为例,创建工程,点击完成 ![image-20210826221150182](figures/image-20210826221150182.png) - - 同样,需要等待构建完成 ![image-20210826221339124](figures/image-20210826221339124.png) - - 工程创建成功 ![image-20210826221638758](figures/image-20210826221638758.png) - - - - ## 配置项目 -双击`RT-Thread Settings`文件,打开 RT-Thread 项目配置界面,配置界面默认显示软件包以及组件和服务层的架构配置图界面,如下图所示: +双击 `RT-Thread Settings` 文件,打开 RT-Thread 项目配置界面,配置界面默认显示软件包以及组件和服务层的架构配置图界面,如下图所示: ![image-20210826221809766](figures/image-20210826221809766.png) - - 点击架构图配置界面的侧边栏按钮,即可打开配置树配置界面或者返回架构图配置界面,如下图所示: ![image-20210826221937660](figures/image-20210826221937660.png) ![image-20210826222023966](figures/image-20210826222023966.png) - - 配置完成后,保存配置退出配置界面后,RT-Thread Studio 会自动将配置应用到项目中,比如会自动下载相关资源文件到项目中并设置好项目配置,确保项目配置后能够构建成功,如下图所示: ![image-20210826222317604](figures/image-20210826222317604.png) - - 项目配置成功如下图所示 ![image-20210826222439726](figures/image-20210826222439726.png) ## 构建项目 -选择需要构建的工程,然后点击工具栏上的`构建`按钮对项目进行构建。如下图所示: +选择需要构建的工程,然后点击工具栏上的 ` 构建 ` 按钮对项目进行构建。如下图所示: ![image-20210826222542249](figures/image-20210826222542249.png) - - 构建的过程日志在控制台进行打印,如下图所示: ![image-20210826222712751](figures/image-20210826222712751.png) - - ## 下载程序 -当项目构建成功后,点击工具栏`下载程序`按钮旁的三角下拉框选择相应的烧写器,以`ST-Link`烧写器为例,如下图所示: +当项目构建成功后,点击工具栏 ` 下载程序 ` 按钮旁的三角下拉框选择相应的烧写器,以 `ST-Link` 烧写器为例,如下图所示: ![image-20210825231817464](figures/image-20210825231817464.png) -选择完烧写器后可直接点击`下载程序`按钮进行程序下载,下载日志会在控制台窗口打印,如下图所示: +选择完烧写器后可直接点击 ` 下载程序 ` 按钮进行程序下载,下载日志会在控制台窗口打印,如下图所示: ![image-20210826222844183](figures/image-20210826222844183.png) ## 启动调试 -选中工程,然后点击工具栏`调试`按钮,如下图所示: +选中工程, 然后点击工具栏 ` 调试 ` 按钮,如下图所示: ![image-20210826222929781](figures/image-20210826222929781.png) - - 当成功启动调试后,RT-Thread Studio 会自动跳转到调试透视图,在调试透视图可以进行各种调试功能操作。当停止调试后会自动跳转会 C 透视图,如下图所示: ![image-20210826223021357](figures/image-20210826223021357.png) - - ## 视频教程 访问官网 [RT-Thread Studio 视频教程](https://www.rt-thread.org/page/video.html),在官网观看视频教程。 - diff --git a/rt-thread-version/rt-thread-nano/_sidebar.md b/rt-thread-version/rt-thread-nano/_sidebar.md index a5d10d4097e4cf4c54655bcf8bab74c0f29829c7..191fc5c1a3554611f1b9480efc90a5fef5925b5f 100644 --- a/rt-thread-version/rt-thread-nano/_sidebar.md +++ b/rt-thread-version/rt-thread-nano/_sidebar.md @@ -1,12 +1,17 @@ -- RT-Thread Nano版本 - - [Nano 简介与下载](/rt-thread-version/rt-thread-nano/an0038-nano-introduction.md) +- **RT-Thread Nano 版本** +- [Nano 简介与下载](/rt-thread-version/rt-thread-nano/an0038-nano-introduction.md) +- Nano 移植 - [Nano 移植原理](/rt-thread-version/rt-thread-nano/nano-port-principle/an0044-nano-port-principle.md) - [使用 RT-Thread Studio 移植](/rt-thread-version/rt-thread-nano/nano-port-studio/an0047-nano-port-studio.md) - [使用 MDK 移植](/rt-thread-version/rt-thread-nano/nano-port-keil/an0039-nano-port-keil.md) - [使用 IAR 移植](/rt-thread-version/rt-thread-nano/nano-port-iar/an0040-nano-port-iar.md) - [使用 CubeMX 移植](/rt-thread-version/rt-thread-nano/nano-port-cube/an0041-nano-port-cube.md) - [移植 Nano 到 RISC-V](/rt-thread-version/rt-thread-nano/nano-port-gcc-riscv/an0042-nano-port-gcc-riscv.md) + - [Nano 移植控制台/FinSH](/rt-thread-version/rt-thread-nano/finsh-port/an0045-finsh-port.md) - [Nano 配置](/rt-thread-version/rt-thread-nano/nano-config/an0043-nano-config.md) - - [移植控制台/FinSH](/rt-thread-version/rt-thread-nano/finsh-port/an0045-finsh-port.md) +- 基于 Nano 使用设备框架 + - [基于 nano 使用 PIN](/rt-thread-version/rt-thread-nano/nano-ref/nano-device-pin/nano-device-pin.md) + - [基于 nano 使用 I2C](/rt-thread-version/rt-thread-nano/nano-ref/nano-device-i2c/nano-device-i2c.md) + - [基于 nano 使用 ADC](/rt-thread-version/rt-thread-nano/nano-ref/nano-device-adc/nano-device-adc.md) diff --git a/rt-thread-version/rt-thread-nano/nano-ref/nano-device-adc/nano-device-adc.md b/rt-thread-version/rt-thread-nano/nano-ref/nano-device-adc/nano-device-adc.md index 794010b6783bad8720aea61c8b562bb6c1b47597..6cbbdd9f5cc5203e3f3e1d68d23063d51f115b4e 100644 --- a/rt-thread-version/rt-thread-nano/nano-ref/nano-device-adc/nano-device-adc.md +++ b/rt-thread-version/rt-thread-nano/nano-ref/nano-device-adc/nano-device-adc.md @@ -1,8 +1,9 @@ -# 在 RT-Thread Studio 上使用 RT-Thread Nano 并使用ADC设备接口 +# 在 RT-Thread Studio 上使用 RT-Thread Nano 并使用 ADC 设备接口 -本文介绍了如何在 RT-Thread Studio 上使用 RT-Thread Nano,并基于 BearPI-IOT STM32L431RCT6 的基础工程进行讲解如何使用 ADC 设备接口。 +本文介绍了如何在 RT-Thread Studio 上使用 RT-Thread Nano,并基于 BearPI-IoT STM32L431RCT6 的基础工程进行讲解如何使用 ADC 设备接口。 ## 为什么需要设备接口 + 1. RT-Thread 分为标准版本和 Nano 版本,其特点如下: - RT-Thread 标准版:拥有驱动框架,软件包等组件,软件包都是基于设备驱动接口来实现。 - RT-Thread Nano :仅仅只是一个 RTOS 内核。没有任何组件。 @@ -12,23 +13,24 @@ 4. Nano 需要一套设备驱动 API,可以方便使用丰富软件包组件。 ## 准备工作 + 1. 使用 RT-Thread Studio 建立一个 STM32L431RCT6 的 RT-Thread Nano 基础工程。 2. 基础工程创建可参考:[在 RT-Thread Studio 上使用 RT-Thread Nano](../../nano-port-studio/an0047-nano-port-studio.md) ## ADC 设备接口 -1. 在 RT-Thread 标准版中,[ADC设备](../../../rt-thread-standard/programming-manual/device/adc/adc.md)驱动提供了一套设备管理接口来访问 ADC,用户程序可以直接使用该 API 操作 ADC 的功能,设备管理接口如下: +1. 在 RT-Thread 标准版中,[ADC 设备](../../../rt-thread-standard/programming-manual/device/adc/adc.md) 驱动提供了一套设备管理接口来访问 ADC,用户程序可以直接使用该 API 操作 ADC 的功能,设备管理接口如下: -| **函数** | **描述** | +|**函数**|**描述** | | --------------- | ------------------ | | rt_device_find() | 根据 ADC 设备名称查找设备获取设备句柄 | | rt_adc_enable() | 使能 ADC 设备 | | rt_adc_read() | 读取 ADC 设备数据 | | rt_adc_disable() | 关闭 ADC 设备 | -2. 由于 RT-Thread Nano 不使用设备驱动框架,所以没有对应的 rt_device_find() 这个API获取设备对象。当为了能够与 RT-Thread 标准版的接口相近,我们需要做了简单的修改,设备管理接口如下: +2. 由于 RT-Thread Nano 不使用设备驱动框架,所以没有对应的 rt_device_find() 这个 API 获取设备对象。当为了能够与 RT-Thread 标准版的接口相近,我们需要做了简单的修改,设备管理接口如下: -| **函数** | **描述** | +|**函数**|**描述** | | --------------- | ------------------ | | rt_adc_device_find() | 根据 ADC 设备名称查找设备获取设备句柄 | | rt_adc_enable() | 使能 ADC 设备 | @@ -43,7 +45,7 @@ 2. 由于 RT-Thread Nano 没有驱动框架,所以我们要把 adc.h 中有关完整版的内容去掉。整理完之后的 adc.h 文件如下: -``` C +```c /* * Copyright (c) 2006-2021, RT-Thread Development Team * @@ -78,12 +80,12 @@ rt_err_t rt_adc_disable(rt_adc_device_t dev, rt_uint32_t channel); #endif /* __ADC_H__ */ ``` -3. 我们需要适配如上4个 ADC 设备 API,参考实例:[drv_adc.c](./demo_code/drv_adc.c) 和 [drv_adc.h](./demo_code/drv_adc.h)。 +3. 我们需要适配如上 4 个 ADC 设备 API,参考实例:[drv_adc.c](./demo_code/drv_adc.c) 和 [drv_adc.h](./demo_code/drv_adc.h)。 ## 编写 ADC 设备使用示例 -``` C +```c void adc_test(void) { int32_t value = 0; @@ -105,7 +107,7 @@ MSH_CMD_EXPORT(adc_test, adc test); ``` 1. 实例代码运行现象: -``` C +```c msh >adc_test adc value: 565 msh > diff --git a/rt-thread-version/rt-thread-nano/nano-ref/nano-device-i2c/nano-device-i2c.md b/rt-thread-version/rt-thread-nano/nano-ref/nano-device-i2c/nano-device-i2c.md index 945891face7e351c11cdf440d36eb3a9e9dceb55..1730f223d148cf18df3b7498e6b9c1036f718fda 100644 --- a/rt-thread-version/rt-thread-nano/nano-ref/nano-device-i2c/nano-device-i2c.md +++ b/rt-thread-version/rt-thread-nano/nano-ref/nano-device-i2c/nano-device-i2c.md @@ -1,8 +1,9 @@ # 在 RT-Thread Studio 上使用 RT-Thread Nano 并使用 I2C 设备接口 -本文介绍了如何在 RT-Thread Studio 上使用 RT-Thread Nano,并基于 BearPI-IOT STM32L431RCT6 的基础工程进行讲解如何使用 I2C 设备接口及相关软件包使用。 +本文介绍了如何在 RT-Thread Studio 上使用 RT-Thread Nano,并基于 BearPI-IoT STM32L431RCT6 的基础工程进行讲解如何使用 I2C 设备接口及相关软件包使用。 ## 为什么需要设备接口 + 1. RT-Thread 分为标准版本和 Nano 版本,其特点如下: - RT-Thread 标准版:拥有设备驱动框架,软件包等组件,软件包都是基于设备驱动接口来实现。 - RT-Thread Nano:仅仅只是一个 RTOS 内核。没有任何组件。 @@ -12,21 +13,22 @@ 4. Nano 需要一套设备驱动 API,可以方便使用丰富软件包组件。 ## 准备工作 + 1. 使用 RT-Thread Studio 建立一个 STM32L431RCT6 的 RT-Thread Nano 基础工程。 2. 基础工程创建可参考:[在 RT-Thread Studio 上使用 RT-Thread Nano](../../nano-port-studio/an0047-nano-port-studio.md) ## I2C 设备接口 -1. 在 RT-Thread 标准版中,[I2C设备](../../../rt-thread-standard/programming-manual/device/i2c/i2c.md)驱动提供了一套设备管理接口来访问 I2C,用户程序可以直接使用该 API 操作 I2C 的功能,设备管理接口如下: +1. 在 RT-Thread 标准版中,[I2C 设备](../../../rt-thread-standard/programming-manual/device/i2c/i2c.md) 驱动提供了一套设备管理接口来访问 I2C,用户程序可以直接使用该 API 操作 I2C 的功能,设备管理接口如下: -| **函数** | **描述** | +|**函数**|**描述** | | --------------- | ---------------------------------- | | rt_device_find() | 根据 I2C 总线设备名称查找设备获取设备句柄 | | rt_i2c_transfer() | 传输数据 | 2. 由于 RT-Thread Nano 不使用设备驱动框架,所以没有对应的 rt_device_find() 这个 API 获取设备对象。但 RT-Thread 标准版实际为用户层提供了另外一套 API 给用户层使用。设备管理接口如下: -| **函数** | **描述** | +|**函数**|**描述** | | --------------- | ---------------------------------- | | rt_i2c_bus_device_find() | 根据 I2C 总线设备名称查找设备获取设备句柄 | | rt_i2c_transfer() | 传输数据 | @@ -41,7 +43,7 @@ 2. 由于 RT-Thread Nano 没有设备驱动框架,所以我们要把 i2c.h 中有关完整版的内容去掉。整理完之后的 i2c.h 文件如下: -``` C +```c /* * Copyright (c) 2006-2021, RT-Thread Development Team * @@ -134,9 +136,9 @@ int rt_i2c_core_init(void); ``` -3. 我们需要适配如上6个 I2C 设备 API ,参考实例:[drv_i2c.c](./demo_code/drv_i2c.c) 和 [drv_i2c.h](./demo_code/drv_i2c.h)。 +3. 我们需要适配如上 6 个 I2C 设备 API ,参考实例:[drv_i2c.c](./demo_code/drv_i2c.c) 和 [drv_i2c.h](./demo_code/drv_i2c.h)。 -| **函数** | **描述** | +|**函数**|**描述** | | --------------- | ---------------------------------- | | rt_i2c_core_init() | I2C 总线初始化 | | rt_i2c_bus_device_find() | 根据 I2C 总线设备名称查找设备获取设备句柄 | @@ -148,17 +150,17 @@ int rt_i2c_core_init(void); ## 编写 I2C 设备使用示例 -``` C +```c #include #include -#define AHT10_I2C_BUS_NAME "i2c1" /* 传感器连接的I2C总线设备名称 */ +#define AHT10_I2C_BUS_NAME "i2c1" /* 传感器连接的 I2C 总线设备名称 */ #define AHT10_ADDR 0x38 /* 从机地址 */ #define AHT10_CALIBRATION_CMD 0xE1 /* 校准命令 */ #define AHT10_NORMAL_CMD 0xA8 /* 一般命令 */ #define AHT10_GET_DATA 0xAC /* 获取数据命令 */ -static struct rt_i2c_bus_device *i2c_bus = RT_NULL; /* I2C总线设备句柄 */ +static struct rt_i2c_bus_device *i2c_bus = RT_NULL; /* I2C 总线设备句柄 */ static rt_bool_t initialized = RT_FALSE; /* 传感器初始化状态 */ /* 写传感器寄存器 */ @@ -181,7 +183,7 @@ static rt_err_t write_reg(struct rt_i2c_bus_device *bus, rt_uint8_t reg, rt_uint msgs.buf = buf; msgs.len = buf_size; - /* 调用I2C设备接口传输数据 */ + /* 调用 I2C 设备接口传输数据 */ if (rt_i2c_transfer(bus, &msgs, 1) == 1) { return RT_EOK; @@ -202,7 +204,7 @@ static rt_err_t read_regs(struct rt_i2c_bus_device *bus, rt_uint8_t len, rt_uint msgs.buf = buf; msgs.len = len; - /* 调用I2C设备接口传输数据 */ + /* 调用 I2C 设备接口传输数据 */ if (rt_i2c_transfer(bus, &msgs, 1) == 1) { return RT_EOK; @@ -231,7 +233,7 @@ static void aht10_init(const char *name) { rt_uint8_t temp[2] = {0, 0}; - /* 查找I2C总线设备,获取I2C总线设备句柄 */ + /* 查找 I2C 总线设备,获取 I2C 总线设备句柄 */ i2c_bus = rt_i2c_bus_device_find(name); if (i2c_bus == RT_NULL) @@ -279,7 +281,7 @@ static void i2c_aht10_sample(int argc, char *argv[]) read_temp_humi(&temperature, &humidity); rt_kprintf("read aht10 sensor humidity : %d.%d %%\n", (int)humidity, (int)(humidity * 10) % 10); - if( temperature >= 0 ) + if(temperature>= 0 ) { rt_kprintf("read aht10 sensor temperature: %d.%d°C\n", (int)temperature, (int)(temperature * 10) % 10); } @@ -298,7 +300,7 @@ MSH_CMD_EXPORT(i2c_aht10_sample, i2c aht10 sample); 实例代码运行现象: -``` C +```c msh >i2c_aht10_sample i2c1 read aht10 sensor humidity : 90.0 % read aht10 sensor temperature: 25.33°C @@ -308,7 +310,7 @@ msh > ## I2C 设备相关软件包使用 -1. 我们使用[as7341软件包](http://packages.rt-thread.org/detail.html?package=as7341)来验证 I2C 设备 API。 +1. 我们使用 [as7341 软件包](http://packages.rt-thread.org/detail.html?package=as7341) 来验证 I2C 设备 API。 2. 首先克隆 as7341 软件包到 STM32L431RCT6 的 RT-Thread Nano 工程。as7341 软件包链接:https://github.com/RiceChen/as7341.git @@ -316,19 +318,19 @@ msh > - 在 as7341.h 中包含 drv_i2c.h 头文件。 - 修改 as7341.c 中的测试用例。代码如下: -``` C +```c static void as7341(int argc, char *argv[]) { static as7341_device_t dev = RT_NULL; - - if (argc > 1) + + if (argc> 1) { if (!strcmp(argv[1], "probe")) { - if (argc >= 3) + if (argc>= 3) { /* initialize the sensor when first probe */ - if (!dev || strcmp(dev->i2c->config->name, argv[2])) // 修改点1 + if (!dev || strcmp(dev->i2c->config->name, argv[2])) // 修改点 1 { /* deinit the old device */ if(dev) @@ -399,11 +401,11 @@ static void as7341(int argc, char *argv[]) { as7341_usage(); } - + } else { - rt_kprintf("Please using 'as7341 probe ' first\n"); + rt_kprintf("Please using'as7341 probe 'first\n"); } } else @@ -413,14 +415,14 @@ static void as7341(int argc, char *argv[]) } else { - as7341_usage(); + as7341_usage(); } } ``` 3. 使用 as7341 软件包实例,编译烧录便可以在终端输入测试命令: -``` C +```c msh >as7341 probe i2c1 as7341 id: 0x24 as7341 probed, addr:0x39 diff --git a/rt-thread-version/rt-thread-nano/nano-ref/nano-device-pin/nano-device-pin.md b/rt-thread-version/rt-thread-nano/nano-ref/nano-device-pin/nano-device-pin.md index c038f1f2c46f46736246f4d87f703fd9f40c5387..526688bc1c50cda2bb15e9df754d196f75aae4d6 100644 --- a/rt-thread-version/rt-thread-nano/nano-ref/nano-device-pin/nano-device-pin.md +++ b/rt-thread-version/rt-thread-nano/nano-ref/nano-device-pin/nano-device-pin.md @@ -1,8 +1,9 @@ -# 在 RT-Thread Studio 上使用 RT-Thread Nano 并使用PIN设备接口 +# 在 RT-Thread Studio 上使用 RT-Thread Nano 并使用 PIN 设备接口 -本文介绍了如何在 RT-Thread Studio 上使用 RT-Thread Nano,并基于BearPI-IOT STM32L431RCT6的基础工程进行讲解如何使用PIN设备接口及相关软件包使用。 +本文介绍了如何在 RT-Thread Studio 上使用 RT-Thread Nano,并基于 BearPI-IoT STM32L431RCT6 的基础工程进行讲解如何使用 PIN 设备接口及相关软件包使用。 ## 为什么需要设备接口 + 1. RT-Thread 分为标准版本和 Nano 版本,其特点如下: - RT-Thread 标准版:拥有设备驱动框架,软件包等组件,软件包都是基于设备驱动接口来实现。 - RT-Thread Nano:仅仅只是一个 RTOS 内核。没有任何组件。 @@ -12,14 +13,15 @@ 4. Nano 需要一套设备驱动 API ,可以方便使用丰富软件包组件。 ## 准备工作 + 1. 使用 RT-Thread Studio 建立一个 STM32L431RCT6 的 RT-Thread Nano 基础工程。 2. 基础工程创建可参考:[在 RT-Thread Studio 上使用 RT-Thread Nano](../../nano-port-studio/an0047-nano-port-studio.md) ## PIN 设备接口 -1. 在 RT-Thread 标准版中,[PIN设备](../../../rt-thread-standard/programming-manual/device/pin/pin.md)设备提供了一套设备管理接口来访问 GPIO,用户程序可以直接使用该 API 操作 GPIO 的功能,设备管理接口如下: +1. 在 RT-Thread 标准版中,[PIN 设备](../../../rt-thread-standard/programming-manual/device/pin/pin.md) 设备提供了一套设备管理接口来访问 GPIO,用户程序可以直接使用该 API 操作 GPIO 的功能,设备管理接口如下: -| **函数** | **描述** | +|**函数**|**描述** | | ---------------- | ---------------------- | | rt_pin_get() | 获取引脚编号 | | rt_pin_mode() | 设置引脚模式 | @@ -29,7 +31,7 @@ | rt_pin_irq_enable() | 使能引脚中断 | | rt_pin_detach_irq() | 脱离引脚中断回调函数 | -2. RT-Thread 丰富软件包都是基于这套 API 进行开发适配,所以 Nano 也需要一套这样子的 API。在 PIN 设备接口,可以完全沿用标准版的这套API。 +2. RT-Thread 丰富软件包都是基于这套 API 进行开发适配,所以 Nano 也需要一套这样子的 API。在 PIN 设备接口,可以完全沿用标准版的这套 API。 ## 适配 PIN 设备接口 @@ -37,7 +39,7 @@ 2. 由于 RT-Thread Nano 没有驱动框架,所以我们要把 pin.h 中有关完整版的内容去掉。整理完之后的 pin.h 文件如下: -``` C +```c /* * Copyright (c) 2006-2021, RT-Thread Development Team * @@ -112,11 +114,11 @@ rt_base_t rt_pin_get(const char *name); #endif ``` -3. 我们需要适配如上7个 PIN 设备 API ,参考实例:[drv_gpio.c](./demo_code/drv_gpio.c) 和 [drv_gpio.h](./demo_code/drv_gpio.h)。 +3. 我们需要适配如上 7 个 PIN 设备 API ,参考实例:[drv_gpio.c](./demo_code/drv_gpio.c) 和 [drv_gpio.h](./demo_code/drv_gpio.h)。 ## 编写 PIN 设备使用示例 -``` C +```c * Copyright (c) 2006-2021, RT-Thread Development Team * * SPDX-License-Identifier: Apache-2.0 @@ -156,13 +158,13 @@ int main(void) ## PIN 设备相关软件包使用 -1. 我们使用[LedBlink软件包](http://packages.rt-thread.org/detail.html?package=LedBlink)来验证PIN设备接口。 +1. 我们使用 [LedBlink 软件包](http://packages.rt-thread.org/detail.html?package=LedBlink) 来验证 PIN 设备接口。 2. 首先克隆 LedBlink 软件包到 STM32L431RCT6 的 RT-Thread Nano 工程。LedBlink 软件包链接:https://github.com/aeo123/LedBlink.git 3. 使用 LedBlink 软件包实例: -``` C +```c #include #define DBG_TAG "main" @@ -192,6 +194,5 @@ int main(void) } ``` 4. LedBlink 软件包无需任何修改便可在 RT-Thread Nano 工程中使用。 - 5. 实例代码运行现象:板载的 LED 进行周期性闪烁。 diff --git a/rt-thread-version/rt-thread-standard/_sidebar.md b/rt-thread-version/rt-thread-standard/_sidebar.md index 83d4fa837a75ab99afa46393684e34978c096985..f28d462b7f13790f0ecfb3dc259daea3f4159454 100644 --- a/rt-thread-version/rt-thread-standard/_sidebar.md +++ b/rt-thread-version/rt-thread-standard/_sidebar.md @@ -1,11 +1,9 @@ - **RT-Thread 标准版本** - - 简介 - [RT-Thread 简介](/rt-thread-version/rt-thread-standard/README.md) - - 快速上手 - [Keil模拟器STM32F103](/rt-thread-version/rt-thread-standard/tutorial/quick-start/stm32f103-simulator/stm32f103-simulator.md) - [RT-Thread潘多拉STM32L475](/rt-thread-version/rt-thread-standard/tutorial/quick-start/iot_board/quick-start.md) @@ -20,8 +18,8 @@ - [野火I.MX RT1052](/rt-thread-version/rt-thread-standard/tutorial/quick-start/imxrt1052-fire-mini/quick-start.md) - [正点原子号令者I.MX RT1052](/rt-thread-version/rt-thread-standard/tutorial/quick-start/imxrt1052-atk-commander/quick-start.md) - [新唐NK-980IOT](/rt-thread-version/rt-thread-standard/tutorial/quick-start/nk-980iot/quick-start.md) + - [Nordic-nRF5x](/rt-thread-version/rt-thread-standard/tutorial/quick-start/nordic-nrf5x/quick-start.md) - [其他开发板...](/rt-thread-version/rt-thread-standard/tutorial/quick-start/more.md) - - 内核 - [内核基础](/rt-thread-version/rt-thread-standard/programming-manual/basic/basic.md) - [线程管理](/rt-thread-version/rt-thread-standard/programming-manual/thread/thread.md) @@ -32,7 +30,6 @@ - [中断管理](/rt-thread-version/rt-thread-standard/programming-manual/interrupt/interrupt.md) - [内核移植](/rt-thread-version/rt-thread-standard/programming-manual/porting/porting.md) - [SMP 介绍与移植](/rt-thread-version/rt-thread-standard/programming-manual/smp/smp.md) - - 设备和驱动 - [I/O设备模型](/rt-thread-version/rt-thread-standard/programming-manual/device/device.md) - [UART设备](/rt-thread-version/rt-thread-standard/programming-manual/device/uart/uart_v1/uart.md) @@ -53,29 +50,32 @@ - [CRYPTO 设备](/rt-thread-version/rt-thread-standard/programming-manual/device/crypto/crypto.md) - [AUDIO设备](/rt-thread-version/rt-thread-standard/programming-manual/device/audio/audio.md) - [Pulse Encoder设备](/rt-thread-version/rt-thread-standard/programming-manual/device/pulse_encoder/pulse_encoder.md) - +- Device IPC + - [completion](/rt-thread-version/rt-thread-standard/programming-manual/device-ipc/completion/completion.md) + - [ringbuffer](/rt-thread-version/rt-thread-standard/programming-manual/device-ipc/ringbuffer/ringbuffer.md) + - [workqueue](/rt-thread-version/rt-thread-standard/programming-manual/device-ipc/workqueue/workqueue.md) - 组件 - 网络组件 - [net 组件总概](/rt-thread-version/rt-thread-standard/programming-manual/net/net_introduce.md) - - [AT命令](/rt-thread-version/rt-thread-standard/programming-manual/at/at.md) - - [Lwip协议栈](/rt-thread-version/rt-thread-standard/programming-manual/lwip/lwip.md) - - [netdev网卡](/rt-thread-version/rt-thread-standard/programming-manual/netdev/netdev.md) - - [SAL套接字抽象层](/rt-thread-version/rt-thread-standard/programming-manual/sal/sal.md) - - [FinSH控制台](/rt-thread-version/rt-thread-standard/programming-manual/finsh/finsh.md) + - [AT 命令](/rt-thread-version/rt-thread-standard/programming-manual/at/at.md) + - [Lwip 协议栈](/rt-thread-version/rt-thread-standard/programming-manual/lwip/lwip.md) + - [netdev 网卡](/rt-thread-version/rt-thread-standard/programming-manual/netdev/netdev.md) + - [SAL 套接字抽象层](/rt-thread-version/rt-thread-standard/programming-manual/sal/sal.md) + - [FinSH 控制台](/rt-thread-version/rt-thread-standard/programming-manual/finsh/finsh.md) - [虚拟文件系统](/rt-thread-version/rt-thread-standard/programming-manual/filesystem/filesystem.md) - - [ulog日志](/rt-thread-version/rt-thread-standard/programming-manual/ulog/ulog.md) - - [utest测试框架](/rt-thread-version/rt-thread-standard/programming-manual/utest/utest.md) + - [ulog 日志](/rt-thread-version/rt-thread-standard/programming-manual/ulog/ulog.md) + - [utest 测试框架](/rt-thread-version/rt-thread-standard/programming-manual/utest/utest.md) - [动态模块](/rt-thread-version/rt-thread-standard/programming-manual/dlmodule/dlmodule.md) - - [POSIX接口](/rt-thread-version/rt-thread-standard/programming-manual/posix/posix.md) + - [POSIX 接口](/rt-thread-version/rt-thread-standard/programming-manual/posix/posix.md) - [电源管理](/rt-thread-version/rt-thread-standard/programming-manual/pm/pm.md) - [RT-Link 组件](/rt-thread-version/rt-thread-standard/programming-manual/rtlink/rtlink.md) - - 软件包 - 物联网 - [网络工具集 (NetUtils) 应用](/rt-thread-version/rt-thread-standard/application-note/packages/netutils/an0018-system-netutils.md) - [rw007 SPI WiFi 模块使用](/rt-thread-version/rt-thread-standard/application-note/packages/rw007_module_using/an0034-rw007-module-using.md) - 工具 - - [SystemView分析工具](/rt-thread-version/rt-thread-standard/application-note/debug/systemview/an0009-systemview.md) + - [SystemView 分析工具](/rt-thread-version/rt-thread-standard/application-note/debug/systemview/an0009-systemview.md) + - [Segger RTT](/rt-thread-version/rt-thread-standard/application-note/debug/seggerRTT/segger_rtt.md) - MicroPython 用户手册 - [介绍](/rt-thread-version/rt-thread-standard/packages-manual/micropython-docs/introduction.md) - [潘多拉 MicroPython 开发板](/rt-thread-version/rt-thread-standard/packages-manual/micropython-docs/micropython_for_pandora_iot_board.md) @@ -86,7 +86,6 @@ - [MicroPython 固件开发指南](/rt-thread-version/rt-thread-standard/packages-manual/micropython-docs/firmware-develop.md) - [MicroPython C 模块扩展](/rt-thread-version/rt-thread-standard/packages-manual/micropython-docs/external_c_modules.md) - [更多软件包...](/rt-thread-version/rt-thread-standard/packages-manual/more.md) - - 应用开发 - 开发环境搭建 - [在windows平台使用QEMU运行RT-Thread](/rt-thread-version/rt-thread-standard/application-note/setup/qemu/windows/an0006-qemu-windows.md) @@ -94,12 +93,16 @@ - [使用Eclipse开发RT-Thread](/rt-thread-version/rt-thread-standard/application-note/setup/qemu/eclipse/an0020-qemu-eclipse.md) - [使用VS Code开发RT-Thread](/rt-thread-version/rt-thread-standard/application-note/setup/qemu/vscode/an0021-qemu-vscode.md) - [使用Env创建RT-Thread项目工程](/rt-thread-version/rt-thread-standard/application-note/setup/standard-project/an0017-standard-project.md) + - 内核移植笔记 + - [Cortex-M 移植](/rt-thread-version/rt-thread-standard/application-note/porting/cortex-m/port-cortex-m.md) + - [RISC-V 移植](/rt-thread-version/rt-thread-standard/application-note/porting/risc-v/port-risc-v.md) - [固件尺寸优化](/rt-thread-version/rt-thread-standard/application-note/system/optimization/Optimize-code-size/an0049-optimize-code-size.md) - [在RT-Thread潘多拉开发板上实现电源管理](/rt-thread-version/rt-thread-standard/application-note/system/pm/an0025-pm.md) - [网络协议栈驱动移植](/rt-thread-version/rt-thread-standard/application-note/components/network/an0010-lwip-driver-porting.md) - [在STM32F429上应用网络功能](/rt-thread-version/rt-thread-standard/application-note/components/network/an0011-network-started.md) - [在STM32F429上应用文件系统](/rt-thread-version/rt-thread-standard/application-note/components/dfs/an0012-dfs.md) - [在潘多拉上使用SFUD操作Flash](/rt-thread-version/rt-thread-standard/application-note/components/sfud/an0048-sfud.md) + - [使用 Ozone 调试 RT-Thread](/rt-thread-version/rt-thread-standard/application-note/debug/ozone/ozone.md) - [FreeModbus应用笔记](/rt-thread-version/rt-thread-standard/application-note/packages/freemodbus/an0036-freemodbus.md) - [应用AT组件连接ESP8266模块](/rt-thread-version/rt-thread-standard/application-note/components/at/an0014-at-client.md) - [多线程非阻塞网络编程](/rt-thread-version/rt-thread-standard/application-note/components/network/an0019-tcpclient-socket.md) @@ -111,7 +114,8 @@ - [在STM32上应用C++](/rt-thread-version/rt-thread-standard/application-note/components/cplusplus/an0035-cpp.md) - [STM32上使用PWM](/rt-thread-version/rt-thread-standard/application-note/driver/pwm/an0037-rtthread-driver-pwm.md) - [STM32上使用USB Host读写U盘](/rt-thread-version/rt-thread-standard/application-note/driver/usb/an0046-rtthread-driver-usbh.md) - - QEMU网络视频教程 + - [MPU 的使用](/rt-thread-version/rt-thread-standard/application-note/system/mpu/mpu.md) + - QEMU 网络视频教程 - [教程简介](/rt-thread-version/rt-thread-standard/tutorial/qemu-network/README.md) - [基础知识之TCP/IP协议](/rt-thread-version/rt-thread-standard/tutorial/qemu-network/tcp_ip/tcp_ip.md) - [基础知识之BSD socket](/rt-thread-version/rt-thread-standard/tutorial/qemu-network/socket/socket.md) @@ -133,6 +137,7 @@ - [16.TFTP文件传输](/rt-thread-version/rt-thread-standard/tutorial/qemu-network/tftp/tftp.md) - [17.Telnet远程控制](/rt-thread-version/rt-thread-standard/tutorial/qemu-network/telnet/telnet.md) - [常见问题及解决方法](/rt-thread-version/rt-thread-standard/tutorial/qemu-network/faq/faq.md) + - [QEMU BLE](/rt-thread-version/rt-thread-standard/application-note/setup/qemu/qemu-ble/qemu_ble.md) - Demo示例 - 蜂鸣器播放器 @@ -157,12 +162,9 @@ - [RT-Thread连接ROS控制小车](/rt-thread-version/rt-thread-standard/tutorial/smart-car/ros-camera-car/ros-camera-car.md) - [RT-Thread连接RPLidar激光雷达](/rt-thread-version/rt-thread-standard/tutorial/smart-car/rplidar-connect/rplidar-connect.md) - [RT-Thread搭配ROS实现目标检测小车](/rt-thread-version/rt-thread-standard/tutorial/smart-car/object-detection/object-detection.md) - - 代码贡献 - [传感器驱动开发指南](/rt-thread-version/rt-thread-standard/development-guide/sensor/sensor_driver_development.md) - [软件包开发指南](/rt-thread-version/rt-thread-standard/development-guide/package/package.md) - [向RT-Thread贡献代码](/rt-thread-version/rt-thread-standard/development-guide/github/github.md) - - [RT-Thread 标准版的版本选择](/rt-thread-version/rt-thread-standard/application-note/setup/rt-thread-version/an0030-rtthread-version.md) - - [API参考手册](https://www.rt-thread.org/document/api/) diff --git a/rt-thread-version/rt-thread-standard/application-note/debug/ozone/ozone.md b/rt-thread-version/rt-thread-standard/application-note/debug/ozone/ozone.md index 7cac03e6ca604cd0484bd8f32677737e0dc3b6e4..961d00ebf392b20611a50872cb1427985804f0cf 100644 --- a/rt-thread-version/rt-thread-standard/application-note/debug/ozone/ozone.md +++ b/rt-thread-version/rt-thread-standard/application-note/debug/ozone/ozone.md @@ -14,7 +14,7 @@ Ozone 在板子没有死机的情况下,也可以通过以下方法 Attach 上 打开软件,选择 Create New Project 创建一个新的工程 -![请添加图片描述](https://img-blog.csdnimg.cn/img_convert/2aefb6218c9110f98073b8d967dd4f87.png) +![](https://img-blog.csdnimg.cn/img_convert/2aefb6218c9110f98073b8d967dd4f87.png) 这里也可以打开一个已经存在的工程 Open Exiting Project,本文以新建工程为例 @@ -22,7 +22,7 @@ Ozone 在板子没有死机的情况下,也可以通过以下方法 Attach 上 选择目标器件是,主要选择的是处理器内核的架构,如 Cortex-M3、Cortex-M4 和 Cortex-A 等,这里以 Cortex-A5 为例 -![请添加图片描述](https://img-blog.csdnimg.cn/img_convert/5e4ced90f264d248e1e8c6920a33ffc3.png) +![](https://img-blog.csdnimg.cn/img_convert/5e4ced90f264d248e1e8c6920a33ffc3.png) 上图中外设文件是可选的,该文件一般由具体的半导体厂商提供,来查看具体的外设寄存器信息,如果没有是不影响 C 代码调试的 @@ -30,25 +30,25 @@ Ozone 在板子没有死机的情况下,也可以通过以下方法 Attach 上 这里需要根据板子的具体通信方式来选择,例如:JTAG,SWD 等,本文使用的是 JTAG,速度使用默认的即可 -![请添加图片描述](https://img-blog.csdnimg.cn/img_convert/f7bbbf2d93812df6bc25f1fbbd061285.png) +![](https://img-blog.csdnimg.cn/img_convert/f7bbbf2d93812df6bc25f1fbbd061285.png) ### 选择目标文件,读取符号信息 这里选择的是通过 RT-Thread Studio/GCC/MDK 等 IDE 工具生成的 `elf` 文件,elf 文件中包含所有的符号和地址信息,所以调试的时候不需要源码,只需要加载 elf 文件即可,当在 elf 文件中定位到问题之后,再修改对应的源码即可 -![请添加图片描述](https://img-blog.csdnimg.cn/img_convert/e8a55b8437beafd7045a4c5fe1d57037.png) +![](https://img-blog.csdnimg.cn/img_convert/e8a55b8437beafd7045a4c5fe1d57037.png) ### 其它可选的设置 这里的设置如果没有特殊的配置,默认即可 -![请添加图片描述](https://img-blog.csdnimg.cn/img_convert/511cc63b1da04d512a169fd84bb69129.png) +![](https://img-blog.csdnimg.cn/img_convert/511cc63b1da04d512a169fd84bb69129.png) ### 连接目标芯片 上述步骤完成之后,工程就建立完毕,接下来就可以后将 Ozone 通过 `link Attach` 到死机的板子并且 Halt 住板子 -![请添加图片描述](https://img-blog.csdnimg.cn/img_convert/3516ad3317a3296558712d2235d933d9.png) +![](https://img-blog.csdnimg.cn/img_convert/3516ad3317a3296558712d2235d933d9.png) 如果程序是由于异常导致的死机,那么当 Ozone 连上的时候,可以看到死机的现场(如果使用其它的 IDE 这个时候很可能会复位芯片,无法保留现场) @@ -56,28 +56,28 @@ Ozone 在板子没有死机的情况下,也可以通过以下方法 Attach 上 打开 Call Stack 窗口,查看函数调用栈 -![请添加图片描述](https://img-blog.csdnimg.cn/img_convert/2f24249dff7f516879946ea7f6d40eec.png) +![](https://img-blog.csdnimg.cn/img_convert/2f24249dff7f516879946ea7f6d40eec.png) ### 查看变量 -![请添加图片描述](https://img-blog.csdnimg.cn/img_convert/18884cf95b516eed22512acdc7f1c084.png) +![](https://img-blog.csdnimg.cn/img_convert/18884cf95b516eed22512acdc7f1c084.png) ### 查看汇编 打开 Disassemble 窗口,查看汇编代码 -![请添加图片描述](https://img-blog.csdnimg.cn/img_convert/30f8109c708f144713b50b68cf60507f.png) +![](https://img-blog.csdnimg.cn/img_convert/30f8109c708f144713b50b68cf60507f.png) ### 查看寄存器 打开 Registers 窗口,查看寄存器,这里需要注意的是,如果没有选择外设的描述文件,那么这里只能看到内核相关的寄存器,而看不到外设寄存器 -![请添加图片描述](https://img-blog.csdnimg.cn/img_convert/8498c51f38649b471688c8308cfa02d8.png) +![](https://img-blog.csdnimg.cn/img_convert/8498c51f38649b471688c8308cfa02d8.png) ### 查看内存 打开 Memory 窗口,查看内存 -![请添加图片描述](https://img-blog.csdnimg.cn/img_convert/885e93ce3205b3997b4e55969d76851e.png) +![](https://img-blog.csdnimg.cn/img_convert/885e93ce3205b3997b4e55969d76851e.png) 这里只介绍了 Ozone 的一些基本用法,更多用法参见 [Ozone 官方文档](https://www.segger.com/products/development-tools/ozone-j-link-debugger/) diff --git a/rt-thread-version/rt-thread-standard/application-note/debug/seggerRTT/segger_rtt.md b/rt-thread-version/rt-thread-standard/application-note/debug/seggerRTT/segger_rtt.md index bd8aea280533fd28698c54494a7db656f73a5bba..8fb1f9960233b950fb4ba7168c5543940a3e609d 100644 --- a/rt-thread-version/rt-thread-standard/application-note/debug/seggerRTT/segger_rtt.md +++ b/rt-thread-version/rt-thread-standard/application-note/debug/seggerRTT/segger_rtt.md @@ -2,8 +2,6 @@ ## 本文目标人群 -本文受益人: - - 开发的时候经常采用 jlink 的硬件调试器进行调试([ST-LINK]([https://www.segger.com/jlink-st-link.html](https://www.segger.com/jlink-st-link.html))) 也可以刷成 JLINK)。 - 有时候想要在中断中打印一些信息的,但是 printf 在中断中不能打印。 - 在移植 RT-THREAD 前期,UART 驱动没有完全 ready,想要用 rt_kprintf 进行打印的。 @@ -17,8 +15,6 @@ SEGGER_RTT 的工作原理如下图所示: ![jlink](images/jlink.png) - - J-LINK 可以通过查询变量的方法来查看特定变量的值,SEGGER_RTT 的工具也是利用这一原理。 SEGGER_RTT 软件包的特点总结如下: @@ -31,7 +27,6 @@ SEGGER_RTT 软件包的特点总结如下: - 可以支持多种 terminal 端口使用,打印不同的 log - 可以不用初始化就可以直接使用 - ## 如何使用 1. 在 menuconfig 中选中对应的软件包即可下载该软件包 @@ -67,18 +62,15 @@ rt_console_set_device(RT_CONSOLE_DEVICE_NAME); ## 注意事项 1. 你需要有 JLINK 连接。 在 STM32 或者 Nordic 开发板上测试都是可以用的。其他的 JLINK 应该也是通用的,这个省去了调试的 UART 串口的占用。可以用这个口打印 log 或者 console 调试。 - + 2. 只要你的开发板可以用 JLINK 来调试查看变量,就可以用这个软件包。 RTT 本质上,就是一直轮询_SEGGER_RTT 这个全局变量。所以对架构不是特别敏感,只要你的板子 JLINK 可以 debug 即可。 - + 3. 如果你手上有 STLINK, 可以选择刷成 JLINK 参考连接 [segger st-link](https://www.segger.com/products/debug-probes/j-link/models/other-j-links/st-link-on-board/) 当然刷成 JLINK 之后,你的 JLINK 也只能操作 STM32 授权的设备,其他厂商设备是不支持的。 ## 总结 我觉得在开发可以用 JLINK 调试芯片的时候,前期可以通过 segger_rtt 进行 console 调试,是一件比较快速上手的事情,比如在制作新的 BSP 的时候,可以先采用 RTT 的方式进行 console 调试,同样这种 console 可以在中断中打印相应的 log,也是一件比较方便的事情。总之,我感觉需要用到的地方还是挺多的,所以推荐给大家使用。当然 SEGGER_RTT 的功能不仅限于此,其实还有很多功能还未完全开发,比如一些彩色打印和 terminal 复用,欢迎对软件包提意见和需求,如果有什么建议都可以在软件包的 issue 里面提。如果对 SEGGER_RTT 软件包感兴趣的,可以参考 [SEGGER_RTT 探索](https://supperthomas-wiki.readthedocs.io/en/latest/DEBUG/01_SEGGER_RTT/SEGGER_RTT.html#id1) 和 [SEGGER_RTT TOOL](https://github.com/supperthomas/RTTHREAD_SEGGER_TOOL)。 - - - ## 特别感谢 本软件包参考了软件包 [SystemView](https://github.com/RT-Thread-packages/SEGGER_SystemView),以及一些 BLE 社区小伙伴的指导建议。 diff --git a/rt-thread-version/rt-thread-standard/application-note/porting/cortex-m/port-cortex-m.md b/rt-thread-version/rt-thread-standard/application-note/porting/cortex-m/port-cortex-m.md index c7f30272369611769bcd1fd55767bf64a4bfa65c..155de8cb1216ad0e53e997a3595022f5270c2d47 100644 --- a/rt-thread-version/rt-thread-standard/application-note/porting/cortex-m/port-cortex-m.md +++ b/rt-thread-version/rt-thread-standard/application-note/porting/cortex-m/port-cortex-m.md @@ -4,43 +4,43 @@ ### 常用寄存器 -PRIMASK寄存器 +PRIMASK 寄存器 -* PRIMASK寄存器为1位宽的中断屏蔽寄存器。在置位时,它会阻止不可屏蔽中断(NMI)和HardFault异常之外的所有异常(包括中断)。实际上,它是将当前异常优先级提升为0,这也是可编程异常/中断的最高优先级。 +* PRIMASK 寄存器为 1 位宽的中断屏蔽寄存器。在置位时,它会阻止不可屏蔽中断 (NMI) 和 HardFault 异常之外的所有异常(包括中断)。实际上,它是将当前异常优先级提升为 0,这也是可编程异常 / 中断的最高优先级。 -FAULTMASK寄存器 +FAULTMASK 寄存器 -* FAULTMASK与PRIMASK相类似,但同时它能屏蔽HardFault异常,它实际上是将异常优先级提升到了-1 +* FAULTMASK 与 PRIMASK 相类似,但同时它能屏蔽 HardFault 异常,它实际上是将异常优先级提升到了 -1 -程序状态寄存器(xPSR) +程序状态寄存器 (xPSR) -* xPSR包含: +* xPSR 包含: - * 应用PSR(APSR) + * 应用 PSR(APSR) - * 执行PSR(EPSR) + * 执行 PSR(EPSR) - * 中断PSR(IPSR) + * 中断 PSR(IPSR) -* ![image-20210813143737666](figures/xpsr.png) + ![image-20210813143737666](figures/xpsr.png) - *GE在Cortex-M4等ARMv7E-M处理器中存在,在Cortex-M3处理器中则不可用。 +注:GE 在 Cortex-M4 等 ARMv7E-M 处理器中存在,在 Cortex-M3 处理器中则不可用。 -* | 位 | 描述 | + | 位 | 描述 | | -------- | ------------------------------------------------------------ | | N | 负标志 | | Z | 零标志 | - | C | 进位(或者非借位)标志 | + | C | 进位 (或者非借位) 标志 | | V | 溢出标志 | - | Q | 饱和标志(ARMv6-M中不存在) | - | GE[3:0] | 大于或等于标志,对应每个字节通路(只存在于ARMv7E-M, ARMv6-M或Cortex-M3中则不存在) | - | ICI/IT | 中断继续指令(ICI)位,IF-THEN指令状态位用于条件执行(ARMv6-M中则不存在) | - | T | Thumb状态,总是1,清除此位会引起错误异常 | + | Q | 饱和标志 (ARMv6-M 中不存在) | + | GE[3:0] | 大于或等于标志,对应每个字节通路 (只存在于 ARMv7E-M, ARMv6-M 或 Cortex-M3 中则不存在) | + | ICI/IT | 中断继续指令 (ICI) 位,IF-THEN 指令状态位用于条件执行(ARMv6-M 中则不存在) | + | T | Thumb 状态,总是 1,清除此位会引起错误异常 | | 异常编号 | 表示处理器正在处理的异常 | 中断向量表 -* Cortex-M系列处理器的中断向量表位于0x00000000, 但Cortex-M3/4系列提供了Vector table offset register (SCB_VTOR),所以,中断向量表的位置位于0x00000000 + SCB_VTOR。 +- Cortex-M 系列处理器的中断向量表位于 0x00000000, 但 Cortex-M3/4 系列提供了 Vector table offset register (SCB_VTOR),所以,中断向量表的位置位于 0x00000000 + SCB_VTOR。 ### 常用汇编指令 @@ -48,12 +48,10 @@ FAULTMASK寄存器 | 指令 | 操作 | | ------- | --------------------------------------------- | -| CPSIE I | 使能中断(清除PRIMASK) | -| CPSID I | 禁止中断(设置PRIMASK),NMI和HardFault不受影响 | -| CPSIE F | 使能中断(清除FAULTMASK) | -| CPSID F | 禁止中断(设置FAULTMASK),NMI不受影响 | - - +| CPSIE I | 使能中断 (清除 PRIMASK) | +| CPSID I | 禁止中断 (设置 PRIMASK),NMI 和 HardFault 不受影响 | +| CPSIE F | 使能中断 (清除 FAULTMASK) | +| CPSID F | 禁止中断 (设置 FAULTMASK),NMI 不受影响 | ## 移植过程 @@ -63,7 +61,7 @@ RT-Thread 的 libcpu 抽象层向下提供了一套统一的 CPU 架构移植接 libcpu 移植相关 API -| **函数和变量** | **描述** | +| 函数和变量 | 描述 | | ------------------------------------------------------------ | ------------------------------------------------------------ | | rt_base_t rt_hw_interrupt_disable(void); | 关闭全局中断 | | void rt_hw_interrupt_enable(rt_base_t level); | 打开全局中断 | @@ -74,34 +72,34 @@ libcpu 移植相关 API | rt_uint32_t rt_thread_switch_interrupt_flag; | 表示需要在中断里进行切换的标志 | | rt_uint32_t rt_interrupt_from_thread, rt_interrupt_to_thread; | 在线程进行上下文切换时候,用来保存 from 和 to 线程 | -要对CPU进行移植,只需实现上述接口。 +要对 CPU 进行移植,只需实现上述接口。 ### 关闭全局中断 rt_base_t rt_hw_interrupt_disable(void); -``` assembly +```assembly /* * rt_base_t rt_hw_interrupt_disable(); */ .global rt_hw_interrupt_disable .type rt_hw_interrupt_disable, %function rt_hw_interrupt_disable: - MRS R0, PRIMASK ;将PRIMASK当前值(关中断前的状态)存入R0,并作为函数返回值返回 - CPSID I ;关闭中断 + MRS R0, PRIMASK ; 将 PRIMASK 当前值 (关中断前的状态) 存入 R0,并作为函数返回值返回 + CPSID I ; 关闭中断 BX LR ``` ### 打开全局中断 -``` assembly +```assembly /* - * void rt_hw_interrupt_enable(rt_base_t level); //level是调用关中断函数时的返回值,代表关中断前PRIMASK的值 + * void rt_hw_interrupt_enable(rt_base_t level); //level 是调用关中断函数时的返回值,代表关中断前 PRIMASK 的值 */ .global rt_hw_interrupt_enable .type rt_hw_interrupt_enable, %function rt_hw_interrupt_enable: - MSR PRIMASK, R0 ;将level写入PRIMASK寄存器,恢复关中断前的状态 + MSR PRIMASK, R0 ; 将 level 写入 PRIMASK 寄存器,恢复关中断前的状态 BX LR ``` @@ -111,7 +109,7 @@ rt_hw_interrupt_enable: ![stack](figures/10stack.png) -``` C +```c rt_uint8_t *rt_hw_stack_init(void *tentry, void *parameter, rt_uint8_t *stack_addr, @@ -135,7 +133,7 @@ rt_uint8_t *rt_hw_stack_init(void *tentry, /* 根据 ARM APCS 调用标准,将第一个参数保存在 r0 寄存器 */ stack_frame->exception_stack_frame.r0 = (unsigned long)parameter; /* r0 : argument */ - /* 其他参数寄存器初始化为0 */ + /* 其他参数寄存器初始化为 0 */ stack_frame->exception_stack_frame.r1 = 0; /* r1 */ stack_frame->exception_stack_frame.r2 = 0; /* r2 */ stack_frame->exception_stack_frame.r3 = 0; /* r3 */ @@ -165,9 +163,9 @@ rt_uint8_t *rt_hw_stack_init(void *tentry, #### PendSV_Handler -产生PendSV异常时,Cortex-M系列处理器硬件会自动将from线程的PSR、PC、LR、R12、R3-R0压栈,因此在PendSV_Handler中,我们需要把from线程的R11-R4压栈,并把to线程的R11-R4弹出。修改PSP为to线程的栈地址,在退出PendSV中断时,硬件会自动弹出to线程的R3-R0、R12、LR、PC、PSR寄存器。 +产生 PendSV 异常时,Cortex-M 系列处理器硬件会自动将 from 线程的 PSR、PC、LR、R12、R3-R0 压栈,因此在 PendSV_Handler 中,我们需要把 from 线程的 R11-R4 压栈,并把 to 线程的 R11-R4 弹出。修改 PSP 为 to 线程的栈地址,在退出 PendSV 中断时,硬件会自动弹出 to 线程的 R3-R0、R12、LR、PC、PSR 寄存器。 -``` assembly +```assembly /* R0 --> switch from thread stack * R1 --> switch to thread stack * psr, pc, LR, R12, R3, R2, R1, R0 are pushed into [from] stack @@ -182,7 +180,7 @@ PendSV_Handler: /* get rt_thread_switch_interrupt_flag */ LDR R0, =rt_thread_switch_interrupt_flag LDR R1, [R0] - CBZ R1, pendsv_exit /* pendsv aLReady handled */ ;判断是否已经在rt_hw_context_switchx中置位 + CBZ R1, pendsv_exit /* pendsv aLReady handled */ ; 判断是否已经在 rt_hw_context_switchx 中置位 /* clear rt_thread_switch_interrupt_flag to 0 */ MOV R1, #0 @@ -191,10 +189,10 @@ PendSV_Handler: LDR R0, =rt_interrupt_from_thread LDR R1, [R0] CBZ R1, switch_to_thread /* skip register save at the first time */ - ;判断from线程是否为空(判断是否是rt_hw_context_switch_to) - MRS R1, PSP /* get from thread stack pointer */ ;将from线程的堆栈地址读入R1 - STMFD R1!, {R4 - R11} /* push R4 - R11 register */ ;将from线程的数据寄存器R4-R11压栈 - LDR R0, [R0] ;将最新的栈指针存回rt_interrupt_from_thread + ; 判断 from 线程是否为空 (判断是否是 rt_hw_context_switch_to) + MRS R1, PSP /* get from thread stack pointer */ ; 将 from 线程的堆栈地址读入 R1 + STMFD R1!, {R4 - R11} /* push R4 - R11 register */ ; 将 from 线程的数据寄存器 R4-R11 压栈 + LDR R0, [R0] ; 将最新的栈指针存回 rt_interrupt_from_thread STR R1, [R0] /* update from thread stack pointer */ switch_to_thread: @@ -202,7 +200,7 @@ switch_to_thread: LDR R1, [R1] LDR R1, [R1] /* load thread stack pointer */ - LDMFD R1!, {R4 - R11} /* pop R4 - R11 register */ ;将to线程的数据寄存器R4-R11弹出 + LDMFD R1!, {R4 - R11} /* pop R4 - R11 register */ ; 将 to 线程的数据寄存器 R4-R11 弹出 MSR PSP, R1 /* update stack pointer */ pendsv_exit: @@ -217,7 +215,7 @@ pendsv_exit: ![rt_hw_context_switch_to](figures/rt_hw_context_switch_to.png) -``` assembly +```assembly /* * void rt_hw_context_switch_to(rt_uint32 to); * R0 --> to @@ -225,7 +223,7 @@ pendsv_exit: .global rt_hw_context_switch_to .type rt_hw_context_switch_to, %function rt_hw_context_switch_to: - LDR R1, =rt_interrupt_to_thread ;将传入的目标线程栈存入rt_interrupt_to_thread + LDR R1, =rt_interrupt_to_thread ; 将传入的目标线程栈存入 rt_interrupt_to_thread STR R0, [R1] /* set from thread to 0 */ @@ -234,27 +232,27 @@ rt_hw_context_switch_to: STR R0, [R1] /* set interrupt flag to 1 */ - LDR R1, =rt_thread_switch_interrupt_flag ;设置rt_thread_switch_interrupt_flag, PendSV中会判断该标志来确定是否进行上下文切换 + LDR R1, =rt_thread_switch_interrupt_flag ; 设置 rt_thread_switch_interrupt_flag, PendSV 中会判断该标志来确定是否进行上下文切换 MOV R0, #1 STR R0, [R1] /* set the PendSV and SysTick exception priority */ - LDR R0, =SHPR3 ;System handler priority register 3 (SCB_SHPR3),其中Bits[23:16]为Priority of system handler 14, PendSV - LDR R1, =PENDSV_PRI_LOWEST ;PENDSV_PRI_LOWEST即0xFFFF0000,作为其mask + LDR R0, =SHPR3 ;System handler priority register 3 (SCB_SHPR3),其中 Bits[23:16] 为 Priority of system handler 14, PendSV + LDR R1, =PENDSV_PRI_LOWEST ;PENDSV_PRI_LOWEST 即 0xFFFF0000,作为其 mask LDR.W R2, [R0,#0] /* read */ ORR R1, R1, R2 /* modify */ STR R1, [R0] /* write-back */ LDR R0, =ICSR /* trigger the PendSV exception (causes context switch) */ - LDR R1, =PENDSVSET_BIT ;0x10000000,ICSR的第28位为PendSV set-pending bit. + LDR R1, =PENDSVSET_BIT ;0x10000000,ICSR 的第 28 位为 PendSV set-pending bit. STR R1, [R0] ;Writing 1 to this bit is the only way to set the PendSV exception state to pending. /* restore MSP */ - LDR r0, =SCB_VTOR ;设置SCB_VTOR的地址 - LDR r0, [r0] ;读取中断向量表的位置 - LDR r0, [r0] ;读取SP初始值 + LDR r0, =SCB_VTOR ; 设置 SCB_VTOR 的地址 + LDR r0, [r0] ; 读取中断向量表的位置 + LDR r0, [r0] ; 读取 SP 初始值 NOP - MSR msp, r0 ;将SP初始值赋给MSP + MSR msp, r0 ; 将 SP 初始值赋给 MSP /* enable interrupts at processor level */ CPSIE F @@ -267,7 +265,7 @@ rt_hw_context_switch_to: ![rt_hw_context_switch_interrupt](figures/rt_hw_context_switch_interrupt.png) -``` assembly +```assembly /* * void rt_hw_context_switch(rt_uint32 from, rt_uint32 to); * R0 --> from @@ -282,13 +280,13 @@ rt_hw_context_switch: /* set rt_thread_switch_interrupt_flag to 1 */ LDR R2, =rt_thread_switch_interrupt_flag LDR R3, [R2] - CMP R3, #1 ;判断rt_thread_switch_interrupt_flag是否已经被置位 - BEQ _reswitch ;如果已经被置位,则跳转到_reswitch + CMP R3, #1 ; 判断 rt_thread_switch_interrupt_flag 是否已经被置位 + BEQ _reswitch ; 如果已经被置位,则跳转到_reswitch MOV R3, #1 STR R3, [R2] ;rt_thread_switch_interrupt_flag = 1 LDR R2, =rt_interrupt_from_thread /* set rt_interrupt_from_thread */ - STR R0, [R2] ;将传入的from线程存入rt_interrupt_from_thread变量 + STR R0, [R2] ; 将传入的 from 线程存入 rt_interrupt_from_thread 变量 _reswitch: LDR R2, =rt_interrupt_to_thread /* set rt_interrupt_to_thread */ @@ -302,9 +300,9 @@ _reswitch: ### 实现时钟节拍 -要实现时间片轮转调度、软定时器、rt_thread_delay()等功能,必须要保证rt_tick_increase()被周期性调用。在Cortex-M系列MCU中,可以使用系统滴答定时器来对其周期性调用。 +要实现时间片轮转调度、软定时器、rt_thread_delay() 等功能,必须要保证 rt_tick_increase() 被周期性调用。在 Cortex-M 系列 MCU 中,可以使用系统滴答定时器来对其周期性调用。 -``` C +```c void SysTick_Handler(void) { /* enter interrupt */ @@ -321,5 +319,5 @@ void SysTick_Handler(void) [1] [Procedure Call Standard for the Arm Architecture - ABI 2020Q2 documentation](https://developer.arm.com/documentation/ihi0042/j/) -[2] Joseph Yiu著. ARM Cortex-M3 与 Cortex-M4 权威指南(第3版). 吴常玉等译. 清华大学出版社 +[2] Joseph Yiu 著. ARM Cortex-M3 与 Cortex-M4 权威指南 (第 3 版). 吴常玉等译. 清华大学出版社 diff --git a/rt-thread-version/rt-thread-standard/application-note/porting/risc-v/port-risc-v.md b/rt-thread-version/rt-thread-standard/application-note/porting/risc-v/port-risc-v.md index 4c89e65f5f5d75c0f8a8025fe0d2d9172c4d26ad..8e06b787be9bdac0ef6d1594a2050415cbc52a71 100644 --- a/rt-thread-version/rt-thread-standard/application-note/porting/risc-v/port-risc-v.md +++ b/rt-thread-version/rt-thread-standard/application-note/porting/risc-v/port-risc-v.md @@ -414,7 +414,7 @@ void rt_hw_context_switch_interrupt(rt_ubase_t from, rt_ubase_t to) 要实现时间片轮转调度、软定时器、rt_thread_delay() 等功能,必须要保证 rt_tick_increase() 被周期性调用。在 RISC-V 系列 MCU 中,可以使用内核 timer 实现 -```C +```c /* System Tick Configuration */ static void systick_config(rt_uint32_t ticks) { /* set value */ @@ -450,4 +450,4 @@ void eclic_mtip_handler(void) { [3] [野火 ®]《RT-Thread + 内核实现与应用开发实战—基于 STM32》.pdf -[4] Bumblebee 内核指令架构手册. pdf \ No newline at end of file +[4] Bumblebee 内核指令架构手册.pdf \ No newline at end of file diff --git a/rt-thread-version/rt-thread-standard/application-note/setup/qemu/qemu-ble/rtthread_qemu_ble.md b/rt-thread-version/rt-thread-standard/application-note/setup/qemu/qemu-ble/qemu_ble.md similarity index 85% rename from rt-thread-version/rt-thread-standard/application-note/setup/qemu/qemu-ble/rtthread_qemu_ble.md rename to rt-thread-version/rt-thread-standard/application-note/setup/qemu/qemu-ble/qemu_ble.md index 6c648ab3541940a99b502d14af3ec5bb2bbf7eaa..35ffc171e4b512fecefc18e417963018bce6e960 100644 --- a/rt-thread-version/rt-thread-standard/application-note/setup/qemu/qemu-ble/rtthread_qemu_ble.md +++ b/rt-thread-version/rt-thread-standard/application-note/setup/qemu/qemu-ble/qemu_ble.md @@ -45,13 +45,13 @@ git clone -b 5.55 https://github.com.cnpmjs.org/bluez/bluez.git 最终 ell 和 bluez 应该在同一个目录级别下,目录结构为: ```shell - . - |--- ell - | |--- ell - | `--- unit - `--- bluez - |--- src - `--- tools +. + |--- ell + | |--- ell + | `--- unit + `--- bluez + |--- src + `--- tools ``` 然后输入下述命令编译 bluez: @@ -87,7 +87,7 @@ sudo make install ### 搭建 RT-Thread QEMU 环境 -参考 [文档:在 Ubuntu 平台开发 RT-Thread](https://www.rt-thread.org/document/site/#/rt-thread-version/rt-thread-standard/application-note/setup/qemu/ubuntu/an0005-qemu-ubuntu?id=在-ubuntu-平台开发-rt-thread) 完成 RT-Thread qemu 环境的搭建。 +参考 [文档:在 Ubuntu 平台开发 RT-Thread](https://www.rt-thread.org/document/site/#/rt-thread-version/rt-thread-standard/application-note/setup/qemu/ubuntu/an0005-qemu-ubuntu.md) 完成 RT-Thread qemu 环境的搭建。 **注意**:若 scons 版本低于 v4.0.1,需要手动安装 scons,步骤如下: @@ -136,7 +136,7 @@ qemu 命令参数里与串口相关的有 `-serial mon:stdio -serial unix:/tmp/b 这个参数将 qemu 程序的串口重定向到物理机的设备文件, -第一个`-serial mon:stdio` 将 qemu 里的 uart0 重定向到了物理机的 stdio 设备文件,而且在 qemu 程序里 uart0 用作 msh 命令行工具,类似 stdio,因此我们可以在物理机上看到 qemu 程序的打印数据,也可以输入命令。 +第一个 `-serial mon:stdio` 将 qemu 里的 uart0 重定向到了物理机的 stdio 设备文件,而且在 qemu 程序里 uart0 用作 msh 命令行工具,类似 stdio,因此我们可以在物理机上看到 qemu 程序的打印数据,也可以输入命令。 第二个 `-serial unix:/tmp/bt-server-bredr` 是将 qemu 里的 uart1 重定向到物理机的 /tmp/bt-server-bredr 文件,而这个文件又是 hci0 设备的代理,因此从 qemu 程序的角度来看,就是使用 H4 协议,通过 uart1 去访问蓝牙设备。uart1 的波特率使用 115200 即可(未找到说明,但一般都是这样使用)。 @@ -154,7 +154,7 @@ qemu 命令参数里与串口相关的有 `-serial mon:stdio -serial unix:/tmp/b ## 例程 -编译运行下述代码, +编译运行下述代码: ```c /* @@ -173,30 +173,30 @@ qemu 命令参数里与串口相关的有 `-serial mon:stdio -serial unix:/tmp/b #include #include -uint8_t ad_data[] = { 0x01, 0x08, 0x20, 0x20, 0x14, 0x02, 0x01, 0x06, 0x0d, - 0x09, 0x62, 0x6c, 0x65, 0x68, 0x72, 0x5f, 0x73, 0x65, 0x6e, - 0x73, 0x6f, 0x72, 0x02, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, +uint8_t ad_data[] = { 0x01, 0x08, 0x20, 0x20, 0x14, 0x02, 0x01, 0x06, 0x0d, + 0x09, 0x62, 0x6c, 0x65, 0x68, 0x72, 0x5f, 0x73, 0x65, 0x6e, + 0x73, 0x6f, 0x72, 0x02, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; -uint8_t ad_params[] = { 0x01, 0x06, 0x20, 0x0f, 0x30, 0x00, 0x60, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00 }; +uint8_t ad_params[] = { 0x01, 0x06, 0x20, 0x0f, 0x30, 0x00, 0x60, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00 }; -uint8_t ad_enable[] = { 0x01, 0x0a, 0x20, 0x01, 0x01 }; +uint8_t ad_enable[] = { 0x01, 0x0a, 0x20, 0x01, 0x01}; static void print_command(uint8_t *buf, uint16_t len) { - rt_kprintf("CMD => "); + rt_kprintf("CMD =>"); for (uint16_t i = 0; i < len; i++) { - rt_kprintf("%02X ", buf[i]); + rt_kprintf("%02X", buf[i]); } rt_kprintf("\n"); } static void print_event(uint8_t *buf, uint16_t len) { - rt_kprintf("EVT <= "); + rt_kprintf("EVT <="); for (uint16_t i = 0; i < len; i++) { - rt_kprintf("%02X ", buf[i]); + rt_kprintf("%02X", buf[i]); } rt_kprintf("\n"); } @@ -248,15 +248,15 @@ lwIP-2.0.2 initialized! [I/utest] utest is initialize success. [I/utest] total utest testcase num: (1) [I/sal.skt] Socket Abstraction Layer initialize success. -CMD => 01 08 20 20 14 02 01 06 0D 09 62 6C 65 68 72 5F 73 65 6E 73 6F 72 02 0A 00 00 00 00 00 00 00 00 00 00 00 00 -EVT <= 04 0E 04 01 08 20 00 -CMD => 01 06 20 0F 30 00 60 00 00 01 00 00 00 00 00 00 00 07 00 -EVT <= 04 0E 04 01 06 20 00 -CMD => 01 0A 20 01 01 -EVT <= 04 0E 04 01 0A 20 00 +CMD => 01 08 20 20 14 02 01 06 0D 09 62 6C 65 68 72 5F 73 65 6E 73 6F 72 02 0A 00 00 00 00 00 00 00 00 00 00 00 00 +EVT <= 04 0E 04 01 08 20 00 +CMD => 01 06 20 0F 30 00 60 00 00 01 00 00 00 00 00 00 00 07 00 +EVT <= 04 0E 04 01 06 20 00 +CMD => 01 0A 20 01 01 +EVT <= 04 0E 04 01 0A 20 00 hello rt-thread ``` 使用 **nRF Connect** 手机 APP 即可成功观察到 qemu 程序发送的广播包,名称为 **blehr_sensor** 。 -![](figures/image-20210905200829112.png) \ No newline at end of file +![](figures/image-20210905200829112.png) diff --git a/rt-thread-version/rt-thread-standard/application-note/system/mpu/images/AP.png b/rt-thread-version/rt-thread-standard/application-note/system/mpu/figures/AP.png similarity index 100% rename from rt-thread-version/rt-thread-standard/application-note/system/mpu/images/AP.png rename to rt-thread-version/rt-thread-standard/application-note/system/mpu/figures/AP.png diff --git a/rt-thread-version/rt-thread-standard/application-note/system/mpu/images/REGIONSIZE.png b/rt-thread-version/rt-thread-standard/application-note/system/mpu/figures/REGIONSIZE.png similarity index 100% rename from rt-thread-version/rt-thread-standard/application-note/system/mpu/images/REGIONSIZE.png rename to rt-thread-version/rt-thread-standard/application-note/system/mpu/figures/REGIONSIZE.png diff --git a/rt-thread-version/rt-thread-standard/application-note/system/mpu/images/region.png b/rt-thread-version/rt-thread-standard/application-note/system/mpu/figures/region.png similarity index 100% rename from rt-thread-version/rt-thread-standard/application-note/system/mpu/images/region.png rename to rt-thread-version/rt-thread-standard/application-note/system/mpu/figures/region.png diff --git a/rt-thread-version/rt-thread-standard/application-note/system/mpu/MPU.md b/rt-thread-version/rt-thread-standard/application-note/system/mpu/mpu.md similarity index 73% rename from rt-thread-version/rt-thread-standard/application-note/system/mpu/MPU.md rename to rt-thread-version/rt-thread-standard/application-note/system/mpu/mpu.md index 1b17c7f7b86cc64983df648118222623813c53b6..f6ffcca087174f1aeafba0f6318973a87cfafeb9 100644 --- a/rt-thread-version/rt-thread-standard/application-note/system/mpu/MPU.md +++ b/rt-thread-version/rt-thread-standard/application-note/system/mpu/mpu.md @@ -2,13 +2,13 @@ ## 简介 -​ MPU(Memory Protection Unit) 内存保护单元。 本文主要讲 armv7-m 架构 架构下的 MPU。在 armv7-m 架构下,Cortex-M3 和 Cortex-M4 处理器对 MPU 都是选配的,不是必须的。 +MPU(Memory Protection Unit) 内存保护单元。 本文主要讲 armv7-m 架构 架构下的 MPU。在 armv7-m 架构下,Cortex-M3 和 Cortex-M4 处理器对 MPU 都是选配的,不是必须的。 -​ MPU 是一个可以编程的 device 设备,可以用来定义内存空间的属性,比如特权指令和非特权指令以及 cache 是否可访问。armv7-m 通常支持 8 个 region。一个 region 就代表一段连续的区域。 +MPU 是一个可以编程的 device 设备,可以用来定义内存空间的属性,比如特权指令和非特权指令以及 cache 是否可访问。armv7-m 通常支持 8 个 region。一个 region 就代表一段连续的区域。 -​ MPU 可以让嵌入式系统更加健壮,以及保护一些加密区域,可以用来防止黑客攻击。 +MPU 可以让嵌入式系统更加健壮,以及保护一些加密区域,可以用来防止黑客攻击。 -​ MPU 有以下能力可以增加系统的健壮性: +MPU 有以下能力可以增加系统的健壮性: - 可以阻止用户去破坏操作系统需要使用的数据 - 可以防止一个任务去非法访问其他任务的数据,将任务完全隔离开 @@ -17,16 +17,16 @@ ## 原理讲解 -​ 通常 MPU 功能这个是由操作系统提供的服务。在嵌入式调试的时候,我们经常会遇到 hardfault,这个时候一般情况可能是某个指针指到未知的地方,然后对该地址进行修改赋值,会触发 hardfault。MPU 的功能其实和这个功能基本类似。 +通常 MPU 功能这个是由操作系统提供的服务。在嵌入式调试的时候,我们经常会遇到 hardfault,这个时候一般情况可能是某个指针指到未知的地方,然后对该地址进行修改赋值,会触发 hardfault。MPU 的功能其实和这个功能基本类似。 -​ 首先理解以下两点,基本上可以大概理解 MPU: +首先理解以下两点,基本上可以大概理解 MPU: 1. MPU 可以定义某些特定的地址区域的属性,这个属性可以定义成很多类型,比如定义成非特权状态下不可以赋值 2. 如果非特权指针不小心访问到这个地址区域并且尝试给该区域赋值修改,这个时候会触发 MemManage fault 或者 hardfault 中断,代表你的程序不被允许修改该区域。 MPU 本质上就是为了保护某一段地址区域不被非授权状态的程序进行访问。 -比如,RTOS中的一些特殊的变量,用户线程是不被允许访问和修改的,这个时候如果你启用了 MPU,并且保护了这些变量,那用户即使知道这里的实际的物理地址,也是不被允许访问和修改的。 +比如,RTOS 中的一些特殊的变量,用户线程是不被允许访问和修改的,这个时候如果你启用了 MPU,并且保护了这些变量,那用户即使知道这里的实际的物理地址,也是不被允许访问和修改的。 ## MPU 寄存器模组 @@ -42,7 +42,7 @@ MPU 主要有以下寄存器 ### MPU_TYPER -MPU 类型寄存器主要表示这个 MCU 有几个 region +MPU 类型寄存器主要表示这个 MCU 有几个 region: | bit 位 | 名称 | 类型 | 描述 | | ----- | -------- | ---- | ------------------------------------ | @@ -51,35 +51,32 @@ MPU 类型寄存器主要表示这个 MCU 有几个 region ### MPU_CTRL -MPU 控制寄存器主要使能 MPU 等控制 +MPU 控制寄存器主要使能 MPU 等控制。 | bit 位 | 名称 | 类型 | 描述 | | ----- | ---------- | ---- | ------------------------------------------- | | 2 | PRIVDEFENA | R/W | 是否为特权级打开缺省存储器映射 | -| 1 | HFNMIENA | R/W | 1: 在 hardfault 和 NMI 中默认使能 MPU(这个主要是在处理一些hardfault中断的时候,是否需要开启MPU保护对应的数据区域,默认是关闭的)。0: 在hardfault和NMI中默认不使能| +| 1 | HFNMIENA | R/W | 1: 在 hardfault 和 NMI 中默认使能 MPU(这个主要是在处理一些 hardfault 中断的时候,是否需要开启 MPU 保护对应的数据区域,默认是关闭的)。0: 在 hardfault 和 NMI 中默认不使能 | | 0 | ENABLE | R/W | 置 1,使能 MPU | -PRIVDEFENA 这个 bit 参考一张图 - -如果 PRIVDEFENA=1 ,特权模式下打开背景 region。 - -如果 PRIVDEFENA = 0, 不打开背景 region。背景 region 如下图所示,就是 region 没有定义到的地方。 - -![image-20210822233929926](images/region.png) +PRIVDEFENA 这个 bit 参考下图: +- 如果 PRIVDEFENA=1 ,特权模式下打开背景 region。 +- 如果 PRIVDEFENA = 0, 不打开背景 region。背景 region 如下图所示,就是 region 没有定义到的地方。 +![image-20210822233929926](figures/region.png) ### MPU_RNR 和 MPU_RBAR -MPU region 号寄存器 (MPU_RNR) 和 MPU 基址寄存器 (MPU_RBAR) 通常成对使用 +MPU region 号寄存器 (MPU_RNR) 和 MPU 基址寄存器 (MPU_RBAR) 通常成对使用。 -MPU_RNR +**MPU_RNR** | bit 位 | 名称 | 类型 | 描述 | | ----- | ------ | ---- | ------------------------------------------------------------ | | 7:0 | region | R/W | 选择下一个需要配置的 region, 因为通常只有 8 个 region,所以 2:0 位有效 | -MPU_RBAR +**MPU_RBAR** | bit 位 | 名称 | 类型 | 描述 | | ----- | ------ | ---- | ------------------------------------------ | @@ -92,11 +89,12 @@ MPU_RBAR ### MPU_RASR RASR 是 region 的属性和容量寄存器 + | bit 位 | 名称 | 类型 | 描述 | | ----- | ---------- | ---- | ----------------------------------------------------- | | 31:29 | 预留 | - | - | | 28 | XN | R/W | | -| 26:24 | AP | R/W | ** 访问许可属性 ** | +| 26:24 | AP | R/W | **访问许可属性** | | 21:19 | TEX | R/W | 类型拓展 | | 18 | S | R/W | 是否可共享 (1= 可共享,0 = 不可共享) | | 17 | C | R/W | 是否缓存(1 = 可缓存, 0 = 不可缓存) | @@ -107,11 +105,11 @@ RASR 是 region 的属性和容量寄存器 REGIONSIZE 的值参考下图 -![image-20210823230728523](images/REGIONSIZE.png) +![image-20210823230728523](figures/REGIONSIZE.png) AP(访问许可) 如下表所示 -![image-20210823230912596](images/AP.png) +![image-20210823230912596](figures/AP.png) RASR 寄存器中有个 SRD "子 region" 的概念。通常 8 个 region 可能不是很够,所以允许每个 REGION 再次细分更小的模块。但是子 region 必须是 8 等分的,每一份是一个子 region,而且子 region 的属性和父 region 必须是相同的. 每个子 region 可以单独的除能,SRD 中每一个 bit 代表一个 region 是否被除能。例如 SRD.3 = 0 , 则 3 号子 region 被除能。能被子 region 拆分的最小也要有 256 个字节(因为 region 大小最小为 32BYTE). 如果 128 就不能再分了。 @@ -119,11 +117,9 @@ RASR 寄存器中有个 SRD "子 region" 的概念。通常 8 个 region 可能 ## MPU Smple -下面是 MPU 对应的 sample,这个测试是在 armv7 架构下的。这边我使用的是开发板 L496ZG-NUCLEO 开发板 - -其余的只要有 ARM MPU 的,都可以通过下面代码进行测试 +下面是 MPU 对应的 sample,这个测试是在 armv7 架构下的,使用的是开发板 L496ZG-NUCLEO。其余的只要有 ARM MPU 的,都可以通过下面代码进行测试: -``` +```c #include "mpu_armv7.h" #define ARRAY_ADDRESS_START (0x20002000UL) #define ARRAY_SIZE ARM_MPU_REGION_SIZE_32B @@ -182,7 +178,7 @@ void MemManage_Handler(void) 执行了 mpu_sample() 之后,你就会发现 MCU 进入了 MemManage_Handler 中断,并且可以恢复。 -**(请将mpu_armv7.h等文件更新到最新的[CMSIS](https://github.com/ARM-software/CMSIS_5/blob/develop/CMSIS/Core/Include/mpu_armv7.h))** +**(请将 mpu_armv7.h 等文件更新到最新的 [CMSIS](https://github.com/ARM-software/CMSIS_5/blob/develop/CMSIS/Core/Include/mpu_armv7.h))** ## 参考文档: diff --git a/rt-thread-version/rt-thread-standard/programming-manual/device-ipc/completion/completion.md b/rt-thread-version/rt-thread-standard/programming-manual/device-ipc/completion/completion.md index 4436c9d03e13b859c1f566d71d4dc74ae162d699..b93dea1fca4018ed68d1678d784eac312076112a 100644 --- a/rt-thread-version/rt-thread-standard/programming-manual/device-ipc/completion/completion.md +++ b/rt-thread-version/rt-thread-standard/programming-manual/device-ipc/completion/completion.md @@ -2,24 +2,21 @@ ## 简介 -`completion` 可以称之为**完成量**,是一种轻量级的线程间(`IPC`)同步机制,举一个生活中的例子来理解下,公交车上的售票员是一个线程1,公交车司机是一个线程2,只有当公交车司机停车后,售票员才能把车门打开。即售票员(线程1)等待司机(线程2)停车(完成了某件事)后,当售票员(线程1)才能开门(做某件事)。 - - +completion 可以称之为**完成量**,是一种轻量级的线程间(`IPC`)同步机制,举一个生活中的例子来理解下,公交车上的售票员是一个线程 1,公交车司机是一个线程 2,只有当公交车司机停车后,售票员才能把车门打开。即售票员 (线程 1) 等待司机(线程 2)停车(完成了某件事)后,当售票员(线程 1)才能开门(做某件事)。 ## 完成量和信号量对比 -- 信号量是一种非常灵活的同步方式,可以运用在多种场合中。形成锁、同步、资源计数等关系,也能方便的用于线程与线程、中断与线程间的同步中 -- 完成量,是一种更加轻型的线程间同步的一种实现,可以理解为轻量级的二值信号量,可以用于线程和线程间同步,也可以用于线程和中断之间的同步 -- 完成量不支持在某个线程中调用`rt_completion_wait`,还未唤醒退出时,在另一个线程中调用该函数 -> 注意:当完成量应用于线程和中断之间的同步时,中断函数中只能调用rt_completion_done接口,而不能调用rt_completion_wait接口,因为wait接口是阻塞型接口,不可以在中断函数中调用 - +- 信号量是一种非常灵活的同步方式,可以运用在多种场合中。形成锁、同步、资源计数等关系,也能方便的用于线程与线程、中断与线程间的同步中。 +- 完成量,是一种更加轻型的线程间同步的一种实现,可以理解为轻量级的二值信号,可以用于线程和线程间同步,也可以用于线程和中断之间的同步。 +- 完成量不支持在某个线程中调用 `rt_completion_wait`,还未唤醒退出时,在另一个线程中调用该函数。 +> 注意:当完成量应用于线程和中断之间的同步时,中断函数中只能调用 rt_completion_done 接口,而不能调用 rt_completion_wait 接口,因为 wait 接口是阻塞型接口,不可以在中断函数中调用 ## 完成量控制块介绍 -在RT-Thread中,完成量控制块是操作系统用于管理完成量的一个数据结构,由结构体 `struct rt_completion`表示,完成量控制块的详细定义如下: +在 RT-Thread 中,完成量控制块是操作系统用于管理完成量的一个数据结构,由结构体 `struct rt_completion` 表示,完成量控制块的详细定义如下: -```C +```c struct rt_completion { rt_uint32_t flag; @@ -29,141 +26,106 @@ struct rt_completion }; ``` -其中 flag,表征当前完成量对象的状态,用下面的两个宏表示,即当flag值为`RT_COMPLETED`时,表征当前完成量对象已完成了某一个工作,可以继续下一个工作; 当flag值为`RT_UNCOMPLETED`时,表征当前需要等待某一个工作结束才能继续下一个工作 +其中 flag,表征当前完成量对象的状态,用下面的两个宏表示,即当 flag 值为 `RT_COMPLETED` 时,表征当前完成量对象已完成了某一个工作,可以继续下一个工作; 当 flag 值为 `RT_UNCOMPLETED` 时,表征当前需要等待某一个工作结束才能继续下一个工作。 -``` +```c #define RT_COMPLETED 1 #define RT_UNCOMPLETED 0 ``` - - ## 完成量 API 接口介绍 -rt-thread中,完成量是一个轻量级的线程同步机制的实现,因此完成量的API接口,也很少,很简洁,下面详细介绍,说明 +rt-thread 中,完成量是一个轻量级的线程同步机制的实现,因此完成量的 API 接口,也很少,很简洁,下面详细介绍,说明。 ### 初始化完成量 -#### 接口定义 +接口定义: -```C +```c void rt_completion_init(struct rt_completion *completion) ``` - - -#### 接口参数说明 - 下表描述了该函数的输入参数与返回值: | 参数 | 描述 | | ---------- | -------------- | | completion | 完成量对象指针 | -| **返回** | —— | +|**返回** | —— | | 无 | | +1. 完成量的创建只支持静态对象初始化,不支持动态生成对象,在调用初始化接口时,需要传递一个静态的完成量对象的指针。 - -#### 接口理解 - -1. 完成量的创建只支持静态对象初始化,不支持动态生成对象,在调用初始化接口时,需要传递一个静态的完成量对象的指针 - -2. 在完成量初始化接口中,只完成两件事,设置flag为`RT_UNCOMPLETED`,然后初始化完成量对象的suspend线程链表 - - +2. 在完成量初始化接口中,只完成两件事,设置 flag 为 `RT_UNCOMPLETED`,然后初始化完成量对象的 suspend 线程链表。 ### 等待完成 -等待完成接口,用于等待某一个动作完成,根据timeout不同参数,做超时退出,或者永久等待的处理 +等待完成接口,用于等待某一个动作完成,根据 timeout 不同参数,做超时退出,或者永久等待的处理。 -#### 接口定义 +接口定义: -```C +```c rt_err_t rt_completion_wait(struct rt_completion *completion, rt_int32_t timeout) ``` - - -#### 接口参数说明 下表描述了该函数的输入参数与返回值: | 参数 | 描述 | | ---------- | ------------------------------------------------------------ | | completion | 完成量对象指针 | -| timeout | 指示等待超时退出时间
说明:
1. 该timeout的单位是tick
2. 当timeout为0时,直接返回 `RT_ETIMEOUT`
3.当timeout为`RT_WAITING_FOREVER`时,该接口会一直阻塞,直到等待到完成量对象完成了工作 | -| **返回** | —— | -| rt_err_t | 执行正确时,返回`RT_EOK` ,执行错误时,返回错误码 | +| timeout | 指示等待超时退出时间
说明:
1. 该 timeout 的单位是 tick
2. 当 timeout 为 0 时,直接返回 `RT_ETIMEOUT`
3. 当 timeout 为 `RT_WAITING_FOREVER` 时,该接口会一直阻塞,直到等待到完成量对象完成了工作 | +|**返回** | —— | +| rt_err_t | 执行正确时,返回 `RT_EOK` ,执行错误时,返回错误码 | -#### 接口实现 +接口实现: ![image-20210815163621342](figures/rt_complete_wait_flow_chart.png) - - 在等待完成接口中会做如下一些事: -1. 调用`rt_thread_self`获取当前线程对象,为后续挂起当前线程做准备 -2. 调用`rt_hw_interrupt_disable`和`rt_hw_interrupt_enable`完成接下来的原子操作 -3. 如果调用该接口前,已经调用`rt_completion_done`指示完成了某个工作,那么直接设置flag为`RT_UNCOMPLETED`,为下一次等待做准备,函数退出 -4. 如果调用该接口时,还未完成某个工作,判断当前完成量对象的等待线程链(`suspended_list`)是否已经有线程在等待该完成量了,如果已经有,则程序直接异常挂起,如果没有正在等待的线程,那么流程继续 -5. 执行挂起当前线程的动作(因为挂起的时当前线程,因此需要后续执行`rt_schedule`才会真正执行挂起) -6. 将当前线程挂在了完成量对象的`suspended_list`链表中 -7. 执行`RT_DEBUG_NOT_IN_INTERRUPT`,确保当前函数不是在中断函数中执行 -8. 启动定时器,设置超时唤醒当前线程的逻辑 -9. 执行`rt_schedule();` ,真正挂起当前线程 - - - - +1. 调用 `rt_thread_self` 获取当前线程对象,为后续挂起当前线程做准备。 +2. 调用 `rt_hw_interrupt_disable` 和 `rt_hw_interrupt_enable` 完成接下来的原子操作。 +3. 如果调用该接口前,已经调用 `rt_completion_done` 指示完成了某个工作,那么直接设置 flag 为 `RT_UNCOMPLETED`,为下一次等待做准备,函数退出。 +4. 如果调用该接口时,还未完成某个工作,判断当前完成量对象的等待线程链(`suspended_list`)是否已经有线程在等待该完成量了,如果已经有,则程序直接异常挂起,如果没有正在等待的线程,那么流程继续。 +5. 执行挂起当前线程的动作(因为挂起的时当前线程,因此需要后续执行 `rt_schedule` 才会真正执行挂起)。 +6. 将当前线程挂在了完成量对象的 `suspended_list` 链表中。 +7. 执行 `RT_DEBUG_NOT_IN_INTERRUPT`,确保当前函数不是在中断函数中执行。 +8. 启动定时器,设置超时唤醒当前线程的逻辑。 +9. 执行 `rt_schedule();` ,真正挂起当前线程。 ### 指示完成 -指示完成接口,用于指示某一个动作已经完成,指示完成后,其他的线程可以获取到该完成状态,并继续运行 +指示完成接口,用于指示某一个动作已经完成,指示完成后,其他的线程可以获取到该完成状态,并继续运行。 -#### 接口定义 +接口定义: ```c void rt_completion_done(struct rt_completion *completion) ``` +接口参数说明:completion 完成量对象指针。 - -#### 接口参数说明 - -- completion 完成量对象指针 - - - -#### 接口实现 +接口实现: ![image-20210815181250503](figures/rt_completion_done_flow_chart.png) 在指示完成接口中,会做如下一些事: -1. 如果当前flag已经是完成状态,接口直接返回 -2. 当当前flag为未完成状态,设置接下来的原子操作保护 -3. 获取当前完成量挂起线程链表,并唤醒该线程 - - +1. 如果当前 flag 已经是完成状态,接口直接返回。 +2. 当当前 flag 为未完成状态,设置接下来的原子操作保护。 +3. 获取当前完成量挂起线程链表,并唤醒该线程。 ## 完成量的使用 ![image-20210815195235507](figures/usage.png) +- 在等待线程中,或者其他线程中调用 `rt_completion_init` 初始化完成量对象。 +- 在等待线程中,处理完一定逻辑后,需要等待某个工作完成时,调用 `rt_completion_wait` 接口,等待信号量完成后,程序阻塞等待。 +- 子指示完成的线程中,执行 `rt_completion_done` 接口,通知等待线程,可以继续执行工作。 - -- 在等待线程中,或者其他线程中调用`rt_completion_init`初始化完成量对象 - -- 在等待线程中,处理完一定逻辑后,需要等待某个工作完成时,调用`rt_completion_wait`接口,等待信号量完成后,程序阻塞等待 - -- 子指示完成的线程中,执行`rt_completion_done`接口,通知等待线程,可以继续执行工作 - -- 可能需要往复循环 - - +- 可能需要往复循环。 ## 示例代码 @@ -171,7 +133,7 @@ void rt_completion_done(struct rt_completion *completion) /* * 程序清单:完成量例程 * - * 程序会初始化2个线程及初始化一个完成量对象 + * 程序会初始化 2 个线程及初始化一个完成量对象 * 一个线程等待另一个线程发送完成量 */ #include @@ -187,7 +149,7 @@ ALIGN(RT_ALIGN_SIZE) static char thread1_stack[1024]; static struct rt_thread thread1; -/* 线程1入口函数 */ +/* 线程 1 入口函数 */ static void thread1_completion_wait(void *param) { /* 等待完成 */ @@ -201,7 +163,7 @@ ALIGN(RT_ALIGN_SIZE) static char thread2_stack[1024]; static struct rt_thread thread2; -/* 线程2入口 */ +/* 线程 2 入口 */ static void thread2_completion_done(void *param) { rt_kprintf("thread2: completion done\n"); @@ -239,12 +201,9 @@ int completion_sample(void) MSH_CMD_EXPORT(completion_sample, completion sample); ``` - - 仿真运行结果如下: ``` -completion_sample msh />completion_sample thread1: completion is waitting thread2: completion done @@ -252,4 +211,3 @@ thread1: completion waitting done thread1 leave. thread2 leave. ``` - diff --git a/rt-thread-version/rt-thread-standard/programming-manual/device-ipc/ringbuffer/ringbuffer.md b/rt-thread-version/rt-thread-standard/programming-manual/device-ipc/ringbuffer/ringbuffer.md index dbfe1f1b80a9f397ed81686e0f0de5bbe8bdf2a9..6e5d320cf53564fe687b7d1b3a94a86f19216630 100644 --- a/rt-thread-version/rt-thread-standard/programming-manual/device-ipc/ringbuffer/ringbuffer.md +++ b/rt-thread-version/rt-thread-standard/programming-manual/device-ipc/ringbuffer/ringbuffer.md @@ -1,5 +1,7 @@ # ringbuffer +## 简介 + ringbuffer(环形缓冲区)是一个非常实用的工具,我们可以将缓冲区看成一个环形的,可以不断地向里面填充数据而不用担心缓冲区溢出。ringbuffer 的读取以字节为单位。 ![](figures/ringbuffer.png) @@ -8,16 +10,16 @@ RT-Thread 内部也提供了该工具,通过导入头文件 `#include 0 | 实际读出的字节数 | | 0 | 缓冲区为空 | 下面介绍第二类接口,读数据但不取出数据: -```C -rt_size_t rt_ringbuffer_peak(struct rt_ringbuffer *rb, rt_uint8_t **ptr); +```c +rt_size_t rt_ringbuffer_peak(struct rt_ringbuffer *rb, rt_uint8_t**ptr); ``` 该接口用于获取 `rb` 指向的 ringbuffer 内部缓冲区**第一个可读数据的地址**,并保存到 `*ptr`,该接口返回 ringbuffer 内存储的字节数。 @@ -222,7 +221,7 @@ rt_size_t rt_ringbuffer_peak(struct rt_ringbuffer *rb, rt_uint8_t **ptr); | -------- | -------------------------------------------------------- | | rb | ringbuffer 结构体指针 | | ptr | 双重指针,用于获取 ringbuffer 内部第一个可读取数据的地址 | -| **返回** | —— | +|**返回**| —— | | > 0 | ringbuffer 内存储的字节数 | | 0 | 缓冲区为空 | @@ -230,7 +229,7 @@ rt_size_t rt_ringbuffer_peak(struct rt_ringbuffer *rb, rt_uint8_t **ptr); 我们可以获取 ringbuffer 内存储的数据大小: -```C +```c rt_size_t rt_ringbuffer_data_len(struct rt_ringbuffer *rb); ``` @@ -239,13 +238,13 @@ rt_size_t rt_ringbuffer_data_len(struct rt_ringbuffer *rb); | 参数 | 描述 | | -------- | ------------------------- | | rb | ringbuffer 结构体指针 | -| **返回** | —— | +|**返回**| —— | | > 0 | ringbuffer 内存储的字节数 | | 0 | ringbuffer 为空 | 还可获取 ringbuffer 内部缓冲区大小: -```C +```c rt_inline rt_uint16_t rt_ringbuffer_get_size(struct rt_ringbuffer *rb); ``` @@ -254,12 +253,12 @@ rt_inline rt_uint16_t rt_ringbuffer_get_size(struct rt_ringbuffer *rb); | 参数 | 描述 | | -------- | ----------------------------------------- | | rb | ringbuffer 结构体指针 | -| **返回** | —— | +|**返回**| —— | | N | ringbuffer 内部缓冲区的大小,以字节为单位 | ## 示例代码 -```C +```c #include #include diff --git a/rt-thread-version/rt-thread-standard/programming-manual/device-ipc/workqueue/workqueue.md b/rt-thread-version/rt-thread-standard/programming-manual/device-ipc/workqueue/workqueue.md index 346989449ae4cdf7a2a09790c4ba116a38bdca44..b3c38dae6b9847de828ec0cb6ff3635166ab5751 100644 --- a/rt-thread-version/rt-thread-standard/programming-manual/device-ipc/workqueue/workqueue.md +++ b/rt-thread-version/rt-thread-standard/programming-manual/device-ipc/workqueue/workqueue.md @@ -1,6 +1,8 @@ # workqueue -工作队列(workqueue)是一种转移任务执行环境的工具,例如当系统产生一个中断时,我们可以在中断处理函数里做一些紧急地操作,然后将另外一些不那么紧急,而且需要一定时间的任务封装成函数交给工作队列执行,此时该函数的执行环境就从**中断环境**变成了**线程环境**,这就是 Linux 里经常提及的中断处理“下半部”。 +## 简介 + +工作队列(workqueue)是一种转移任务执行环境的工具,例如当系统产生一个中断时,我们可以在中断处理函数里做一些紧急地操作,然后将另外一些不那么紧急,而且需要一定时间的任务封装成函数交给工作队列执行,此时该函数的执行环境就从 中断环境 变成了 线程环境,这就是 Linux 里经常提及的中断处理 “下半部”。 工作队列的原理也比较简单,可以参考下述图示: @@ -16,7 +18,7 @@ RT-Thread 内有 workqueue 组件,导入头文件 `#include ` - 工作项里最好不要有会导致线程阻塞的代码,否则会影响后续工作项的执行。 -RT-Thread 系统提供了一个**系统工作队列**,可以通过 env 开启 +RT-Thread 系统提供了一个 系统工作队列,可以通过 env 开启 ``` RT-Thread Components @@ -33,7 +35,7 @@ RT-Thread Components ## workquque 结构体介绍 -```C +```c struct rt_workqueue { rt_list_t work_list; @@ -47,7 +49,7 @@ struct rt_workqueue `work_list` 就是工作队列里的工作链表,`work_thread` 即工作队列里的线程。再来看看工作项结构体: -```C +```c struct rt_work { rt_list_t list; @@ -69,7 +71,7 @@ struct rt_work 每一个工作项在被提交到工作队列之前,都需要调用下述接口初始化: -```C +```c rt_inline void rt_work_init(struct rt_work *work, void (*work_func)(struct rt_work *work, void *work_data), void *work_data); ``` @@ -80,15 +82,13 @@ rt_inline void rt_work_init(struct rt_work *work, void (*work_func)(struct rt_wo | work | 工作项结构体指针 | | work_func | 回调函数,工作项执行时会调用它 | | work_data | 用户自定义数据,回调函数参数 | -| **返回** | —— | +| 返回 | —— | ### 使用系统工作队列 - - 开启系统工作队列后,我们就可以通过下述接口向系统工作队列提交一个工作项: -```C +```c rt_err_t rt_work_submit(struct rt_work *work, rt_tick_t time); ``` @@ -98,14 +98,14 @@ rt_err_t rt_work_submit(struct rt_work *work, rt_tick_t time); | --------- | --------------------------------------------------- | | work | 工作项结构体指针 | | time | 提交延时,以 tick 为单位,需小于 `RT_TICK_MAX / 2` | -| **返回** | —— | +| 返回 | —— | | RT_EOK | 提交成功 | | -RT_EBUSY | 该工作项正在执行 | | -RT_ERROR | `time` 参数错误 | 若我们想取消之前提交过的工作项,则可以调用下述接口: -```C +```c rt_err_t rt_work_cancel(struct rt_work *work); ``` @@ -114,7 +114,7 @@ rt_err_t rt_work_cancel(struct rt_work *work); | 参数 | 描述 | | --------- | ---------------- | | work | 工作项结构体指针 | -| **返回** | —— | +| 返回 | —— | | RT_EOK | 取消成功 | | -RT_EBUSY | 该工作项正在执行 | @@ -122,7 +122,7 @@ rt_err_t rt_work_cancel(struct rt_work *work); 除了使用系统工作队列,我们也可以创建属于自己的工作队列,这样更加灵活。创建工作队列使用下述接口: -```C +```c struct rt_workqueue *rt_workqueue_create(const char *name, rt_uint16_t stack_size, rt_uint8_t priority); ``` @@ -133,13 +133,13 @@ struct rt_workqueue *rt_workqueue_create(const char *name, rt_uint16_t stack_siz | name | 线程名字 | | stack_size | 线程栈大小 | | priority | 线程优先级 | -| **返回** | —— | +| 返回 | —— | | RT_NULL | 创建失败 | | rt_workqueue 结构体指针 | 创建成功 | 若不再使用工作队列,也可以销毁它: -```C +```c rt_err_t rt_workqueue_destroy(struct rt_workqueue *queue); ``` @@ -148,7 +148,7 @@ rt_err_t rt_workqueue_destroy(struct rt_workqueue *queue); | 参数 | 描述 | | -------- | ------------------ | | queue | 工作队列结构体指针 | -| **返回** | —— | +| 返回 | —— | | RT_EOK | 销毁成功 | ### 提交工作项 @@ -158,9 +158,9 @@ rt_err_t rt_workqueue_destroy(struct rt_workqueue *queue); 1. 允许工作项延时提交 2. 不允许工作项延时提交 -**允许**工作项延时提交的接口如下: +允许 工作项延时提交的接口如下: -```C +```c rt_err_t rt_workqueue_submit_work(struct rt_workqueue *queue, struct rt_work *work, rt_tick_t time); ``` @@ -171,40 +171,40 @@ rt_err_t rt_workqueue_submit_work(struct rt_workqueue *queue, struct rt_work *wo | queue | 工作队列结构体指针 | | work | 工作项结构体指针 | | time | 提交延时,以 tick 为单位,需小于 `RT_TICK_MAX / 2` | -| **返回** | —— | +| 返回 | —— | | RT_EOK | 提交成功 | | -RT_EBUSY | 该工作项正在执行 | | -RT_ERROR | `time` 参数错误 | -**不允许**工作项延时提交的接口如下: +不允许 工作项延时提交的接口如下: -```C +```c rt_err_t rt_workqueue_dowork(struct rt_workqueue *queue, struct rt_work *work); ``` -该接口立即将 `work` 指向的工作项提交到 `queue` 指向的工作队列**尾部**,下表描述了该函数的输入参数与返回值: +该接口立即将 `work` 指向的工作项提交到 `queue` 指向的工作队列 尾部,下表描述了该函数的输入参数与返回值: | 参数 | 描述 | | --------- | ------------------ | | queue | 工作队列结构体指针 | | work | 工作项结构体指针 | -| **返回** | —— | +| 返回 | —— | | RT_EOK | 提交成功 | | -RT_EBUSY | 该工作项正在执行 | 还有另一个类似接口: -```C +```c rt_err_t rt_workqueue_critical_work(struct rt_workqueue *queue, struct rt_work *work); ``` -该接口立即将 `work` 指向的工作项提交到 `queue` 指向的工作队列**头部**,因此该接口提交的工作项在当前工作项执行完毕后会被立即执行,适用于一些比较紧急(critical)的任务。而通过 dowork 提交的工作项会挂载到工作队列尾部,适用于不那么紧急的任务。下表描述了该函数的输入参数与返回值: +该接口立即将 `work` 指向的工作项提交到 `queue` 指向的工作队列 头部,因此该接口提交的工作项在当前工作项执行完毕后会被立即执行,适用于一些比较紧急(critical)的任务。而通过 dowork 提交的工作项会挂载到工作队列尾部,适用于不那么紧急的任务。下表描述了该函数的输入参数与返回值: | 参数 | 描述 | | --------- | ------------------ | | queue | 工作队列结构体指针 | | work | 工作项结构体指针 | -| **返回** | —— | +| 返回 | —— | | RT_EOK | 提交成功 | | -RT_EBUSY | 该工作项正在执行 | @@ -212,7 +212,7 @@ rt_err_t rt_workqueue_critical_work(struct rt_workqueue *queue, struct rt_work * 想要取消指定工作项可以调用下述接口: -```C +```c rt_err_t rt_workqueue_cancel_work(struct rt_workqueue *queue, struct rt_work *work); ``` @@ -222,28 +222,28 @@ rt_err_t rt_workqueue_cancel_work(struct rt_workqueue *queue, struct rt_work *wo | --------- | ------------------ | | queue | 工作队列结构体指针 | | work | 工作项结构体指针 | -| **返回** | —— | +| 返回 | —— | | RT_EOK | 提交成功 | | -RT_EBUSY | 该工作项正在执行 | 还有一类 sync 接口不会返回错误,而是等待该工作项执行完毕: -```C +```c rt_err_t rt_workqueue_cancel_work_sync(struct rt_workqueue *queue, struct rt_work *work); ``` -该接口会从 `queue` 指向的工作队列中将 `work` 指向的工作项移除,这样该工作项就不会被执行了。不过当该工作项正在执行时,该接口内部会**阻塞**等待该工作项执行完毕,是一个同步接口。下表描述了该函数的输入参数与返回值: +该接口会从 `queue` 指向的工作队列中将 `work` 指向的工作项移除,这样该工作项就不会被执行了。不过当该工作项正在执行时,该接口内部会 阻塞 等待该工作项执行完毕,是一个同步接口。下表描述了该函数的输入参数与返回值: | 参数 | 描述 | | -------- | ------------------ | | queue | 工作队列结构体指针 | | work | 工作项结构体指针 | -| **返回** | —— | +| 返回 | —— | | RT_EOK | 提交成功 | 我们还可以一次性取消所有的工作项: -```C +```c rt_err_t rt_workqueue_cancel_all_work(struct rt_workqueue *queue); ``` @@ -253,16 +253,15 @@ rt_err_t rt_workqueue_cancel_all_work(struct rt_workqueue *queue); | -------- | ------------------ | | queue | 工作队列结构体指针 | | work | 工作项结构体指针 | -| **返回** | —— | +| 返回 | —— | | RT_EOK | 提交成功 | ## 示例代码 -```C +```c #include #include - struct rt_work work1; int work1_data = 1; diff --git a/rt-thread-version/rt-thread-standard/programming-manual/device/spi/spi.md b/rt-thread-version/rt-thread-standard/programming-manual/device/spi/spi.md index ee82be4750367d1705212cffd20a90f26f65232b..8139c6612480e02160c9eb366fd54b52496cb1d6 100644 --- a/rt-thread-version/rt-thread-standard/programming-manual/device/spi/spi.md +++ b/rt-thread-version/rt-thread-standard/programming-manual/device/spi/spi.md @@ -38,7 +38,7 @@ SPI 以主从方式工作,通常有一个主设备和一个或多个从设备 SPI 驱动会注册 SPI 总线,SPI 设备需要挂载到已经注册好的 SPI 总线上。 -```C +```c rt_err_t rt_spi_bus_attach_device(struct rt_spi_device *device, const char *name, const char *bus_name, diff --git a/rt-thread-version/rt-thread-standard/programming-manual/posix/posix.md b/rt-thread-version/rt-thread-standard/programming-manual/posix/posix.md index 768767e789f35e3c65131edd9d08986011e50a30..fbbe56c7b8c24e95c9f74808703426999d541679 100644 --- a/rt-thread-version/rt-thread-standard/programming-manual/posix/posix.md +++ b/rt-thread-version/rt-thread-standard/programming-manual/posix/posix.md @@ -51,7 +51,7 @@ Std1003.1c-1995)标准里,该标准定义了一套 C 程序语言的类型、 在 RT-Thread 中使用 POSIX API 接口包括几个部分:libc(例如 newlib),filesystem,pthread 等。需要在 rtconfig.h 中打开相关的选项: -``` c +```c #define RT_USING_LIBC #define RT_USING_DFS #define RT_USING_DFS_DEVFS @@ -64,7 +64,7 @@ RT-Thread 实现了 Pthreads 的大部分函数和常量,按照 POSIX 标准 ### 线程句柄 -``` c +```c typedef rt_thread_t pthread_t; ``` @@ -72,7 +72,7 @@ pthread_t 是 rt_thread_t 类型的重定义,定义在 pthread.h 头文件里 ### 创建线程 -``` c +```c int pthread_create (pthread_t *tid, const pthread_attr_t *attr, void *(*start) (void *), void *arg); @@ -100,7 +100,7 @@ int pthread_create (pthread_t *tid, 以下程序会初始化 2 个线程,它们拥有共同的入口函数,但是它们的入口参数不相同。其他的,它们具备相同的优先级,并以时间片进行轮转调度。 -``` c +```c #include #include #include @@ -156,7 +156,7 @@ int rt_application_init() ### 脱离线程 -``` c +```c int pthread_detach (pthread_t thread); ``` @@ -177,7 +177,7 @@ int pthread_detach (pthread_t thread); 以下程序会初始化 2 个线程,它们拥有相同的优先级,并按照时间片轮转调度。2 个线程都会被设置为脱离状态,2 个线程循环打印 3 次信息后自动退出,退出后系统将会自动回收其资源。 -``` c +```c #include #include #include @@ -254,7 +254,7 @@ int rt_application_init() ### 等待线程结束 -``` c +```c int pthread_join (pthread_t thread, void**value_ptr); ``` @@ -276,7 +276,7 @@ pthread_join() 和 pthread_detach() 函数功能类似,都是在线程结束 以下程序代码会初始化 2 个线程,它们拥有相同的优先级,相同优先级的线程是按照时间片轮转调度。2 个线程属性的分离状态为默认值 joinable,线程 1 先开始运行,循环打印 3 次信息后结束。线程 2 调用 pthread_join() 阻塞等待线程 1 结束,并回收线程 1 占用的资源,然后线程 2 每隔 2 秒钟会打印一次信息。 -``` c +```c #include #include #include @@ -353,7 +353,7 @@ int rt_application_init() ### 退出线程 -``` c +```c void pthread_exit(void *value_ptr); ``` @@ -370,7 +370,7 @@ pthread 线程调用此函数会终止执行,如同进程调用 exit() 函数 这个程序会初始化 2 个线程,它们拥有相同的优先级,相同优先级的线程是按照时间片轮转调度。2 个线程属性的分离状态为默认值 joinable,线程 1 先开始运行,打印一次信息后休眠 2 秒,之后打印退出信息然后结束运行。线程 2 调用 pthread_join() 阻塞等待线程 1 结束,并回收线程 1 占用的资源,然后线程 2 每隔 2 秒钟会打印一次信息。 -``` c +```c #include #include #include @@ -458,7 +458,7 @@ int rt_application_init() 每个互斥锁对应一个互斥锁控制块,包含对互斥锁进行的控制的一些信息。创建互斥锁前必须先定义一个 pthread_mutex_t 类型的变量,pthread_mutex_t 是 pthread_mutex 的重定义,pthread_mutex 数据结构定义在 pthread.h 头文件里,数据结构如下: -``` c +```c struct pthread_mutex { pthread_mutexattr_t attr; /* 互斥锁属性 */ @@ -481,7 +481,7 @@ typedef struct rt_mutex* rt_mutex_t; /* rt_mutext_t 为指向互斥锁结 ### 初始化互斥锁 -``` c +```c int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *attr); ``` @@ -501,7 +501,7 @@ int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *attr); ### 销毁互斥锁 -``` c +```c int pthread_mutex_destroy(pthread_mutex_t *mutex); ``` @@ -519,7 +519,7 @@ int pthread_mutex_destroy(pthread_mutex_t *mutex); ### 阻塞方式对互斥锁上锁 -``` c +```c int pthread_mutex_lock(pthread_mutex_t *mutex); ``` @@ -535,7 +535,7 @@ int pthread_mutex_lock(pthread_mutex_t *mutex); ### 非阻塞方式对互斥锁上锁 -``` c +```c int pthread_mutex_trylock(pthread_mutex_t *mutex); ``` @@ -552,7 +552,7 @@ int pthread_mutex_trylock(pthread_mutex_t *mutex); ### 解锁互斥锁 -``` c +```c int pthread_mutex_unlock(pthread_mutex_t *mutex); ``` @@ -571,7 +571,7 @@ int pthread_mutex_unlock(pthread_mutex_t *mutex); 这个程序会初始化 2 个线程,它们拥有相同的优先级,2 个线程都会调用同一个 printer() 函数输出自己的字符串,printer() 函数每次只输出一个字符,之后休眠 1 秒,调用 printer() 函数的线程同样也休眠。如果不使用互斥锁,线程 1 打印了一个字符,休眠后执行线程 2,线程 2 打印一个字符,这样就不能完整的打印线程 1 和线程 2 的字符串,打印出的字符串是混乱的。如果使用了互斥锁保护 2 个线程共享的打印函数 printer(),线程 1 拿到互斥锁后执行 printer() 打印函数打印一个字符,之后休眠 1 秒,这是切换到线程 2,因为互斥锁已经被线程 1 上锁,线程 2 将阻塞,直到线程 1 的字符串打印完整后主动释放互斥锁后线程 2 才会被唤醒。 -``` c +```c #include #include #include @@ -665,7 +665,7 @@ pthread_cond_destroy() 销毁一个条件变量,调用 pthread_cond_wait() 等 每个条件变量对应一个条件变量控制块,包括对条件变量进行操作的一些信息。初始化一个条件变量前需要先定义一个 pthread_cond_t 条件变量控制块。pthread_cond_t 是 pthread_cond 结构体类型的重定义,定义在 pthread.h 头文件里。 -``` c +```c struct pthread_cond { pthread_condattr_t attr; /* 条件变量属性 */ @@ -685,7 +685,7 @@ struct rt_semaphore ### 初始化条件变量 -``` c +```c int pthread_cond_init(pthread_cond_t *cond, const pthread_condattr_t *attr); ``` @@ -707,7 +707,7 @@ attr 一般设置 NULL 使用默认值即可,具体会在线程高级编程一 ### 销毁条件变量 -``` c +```c int pthread_cond_destroy(pthread_cond_t *cond); ``` @@ -726,7 +726,7 @@ int pthread_cond_destroy(pthread_cond_t *cond); ### 阻塞方式获取条件变量 -``` c +```c int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex); ``` @@ -742,7 +742,7 @@ int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex); ### 指定阻塞时间获取条件变量 -``` c +```c int pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex, const struct timespec *abstime); @@ -763,7 +763,7 @@ int pthread_cond_timedwait(pthread_cond_t *cond, ### 发送满足条件信号量 -``` c +```c int pthread_cond_signal(pthread_cond_t *cond); ``` @@ -777,7 +777,7 @@ int pthread_cond_signal(pthread_cond_t *cond); ### 广播 -``` c +```c int pthread_cond_broadcast(pthread_cond_t *cond); ``` @@ -794,7 +794,7 @@ int pthread_cond_broadcast(pthread_cond_t *cond); 这个程序是一个生产者消费者模型,有一个生产者线程,一个消费者线程,它们拥有相同的优先级。生产者每隔 2 秒会生产一个数字,放到 head 指向的链表里面,之后调用 pthread_cond_signal() 给消费者线程发信号,通知消费者线程链表里面有数据。消费者线程会调用 pthread_cond_wait() 等待生产者线程发送信号。 -``` c +```c #include #include #include @@ -921,7 +921,7 @@ int rt_application_init() 每个读写锁对应一个读写锁控制块,包括对读写锁进行操作的一些信息。pthread_rwlock_t 是 pthread_rwlock 数据结构的重定义,定义在 pthread.h 头文件里。在创建一个读写锁之前需要先定义一个 pthread_rwlock_t 类型的数据结构。 -``` c +```c struct pthread_rwlock { pthread_rwlockattr_t attr; /* 读写锁属性 */ @@ -938,7 +938,7 @@ typedef struct pthread_rwlock pthread_rwlock_t; /* 类型重定义 */ ### 初始化读写锁初始化 -``` c +```c int pthread_rwlock_init (pthread_rwlock_t *rwlock, const pthread_rwlockattr_t *attr); ``` @@ -960,7 +960,7 @@ attr 一般设置 NULL 使用默认值即可,具体会在线程高级编程一 ### 销毁读写锁 -``` c +```c int pthread_rwlock_destroy (pthread_rwlock_t *rwlock); ``` @@ -979,7 +979,7 @@ int pthread_rwlock_destroy (pthread_rwlock_t *rwlock); #### 阻塞方式对读写锁读锁定 -``` c +```c int pthread_rwlock_rdlock (pthread_rwlock_t *rwlock); ``` @@ -995,7 +995,7 @@ int pthread_rwlock_rdlock (pthread_rwlock_t *rwlock); #### 非阻塞方式对读写锁读锁定 -``` c +```c int pthread_rwlock_tryrdlock (pthread_rwlock_t *rwlock); ``` @@ -1012,7 +1012,7 @@ int pthread_rwlock_tryrdlock (pthread_rwlock_t *rwlock); #### 指定阻塞时间对读写锁读锁定 -``` c +```c int pthread_rwlock_timedrdlock (pthread_rwlock_t *rwlock, const struct timespec *abstime); ``` @@ -1033,7 +1033,7 @@ int pthread_rwlock_timedrdlock (pthread_rwlock_t *rwlock, #### 阻塞方式对读写锁写锁定 -``` c +```c int pthread_rwlock_wrlock (pthread_rwlock_t *rwlock); ``` @@ -1049,7 +1049,7 @@ int pthread_rwlock_wrlock (pthread_rwlock_t *rwlock); #### 非阻塞方式写锁定读写锁 -``` c +```c int pthread_rwlock_trywrlock (pthread_rwlock_t *rwlock); ``` @@ -1066,7 +1066,7 @@ int pthread_rwlock_trywrlock (pthread_rwlock_t *rwlock); #### 指定阻塞时长写锁定读写锁 -``` c +```c int pthread_rwlock_timedwrlock (pthread_rwlock_t *rwlock, const struct timespec *abstime); ``` @@ -1084,7 +1084,7 @@ int pthread_rwlock_timedwrlock (pthread_rwlock_t *rwlock, ### 读写锁解锁 -``` c +```c int pthread_rwlock_unlock (pthread_rwlock_t *rwlock); ``` @@ -1102,7 +1102,7 @@ int pthread_rwlock_unlock (pthread_rwlock_t *rwlock); 这个程序有 2 个读者线程,一个写着线程。2 个读者线程先对读写锁读锁定,之后休眠 2 秒,这是其他的读者线程还是可以对该读写锁读锁定,然后读取共享数据。 -``` c +```c #include #include #include @@ -1200,7 +1200,7 @@ int rt_application_init() 创建一个屏障前需要先定义一个 pthread_barrier_t 屏障控制块。pthread_barrier_t 是 pthread_barrier 结构体类型的重定义,定义在 pthread.h 头文件里。 -``` c +```c struct pthread_barrier { int count; /* 指定的等待线程个数 */ @@ -1212,7 +1212,7 @@ typedef struct pthread_barrier pthread_barrier_t; ### 创建屏障 -``` c +```c int pthread_barrier_init(pthread_barrier_t *barrier, const pthread_barrierattr_t *attr, unsigned count); @@ -1233,7 +1233,7 @@ attr 一般设置 NULL 使用默认值即可,具体会在线程高级编程一 ### 销毁屏障 -``` c +```c int pthread_barrier_destroy(pthread_barrier_t *barrier); ``` @@ -1248,7 +1248,7 @@ int pthread_barrier_destroy(pthread_barrier_t *barrier); ### 等待屏障 -``` c +```c int pthread_barrier_wait(pthread_barrier_t *barrier); ``` @@ -1265,7 +1265,7 @@ int pthread_barrier_wait(pthread_barrier_t *barrier); 此程序会创建 3 个线程,初始化一个屏障,屏障等待线程数初始化为 3。3 个线程都会调用 pthread_barrier_wait() 等待在屏障前,当 3 个线程都到齐后,3 个线程进入就绪态,之后会每隔 2 秒打印输出计数信息。 -``` c +```c #include #include #include @@ -1382,7 +1382,7 @@ RT-Thread 操作系统的 POSIX 信号量主要是基于 RT-Thread 内核信号 每个信号量对应一个信号量控制块,创建一个信号量前需要先定义一个 sem_t 信号量控制块。sem_t 是 posix_sem 结构体类型的重定义,定义在 semaphore.h 头文件里。 -``` c +```c struct posix_sem { rt_uint16_t refcount; @@ -1411,7 +1411,7 @@ typedef struct rt_semaphore* rt_sem_t; #### 初始化无名信号量 -``` c +```c int sem_init(sem_t *sem, int pshared, unsigned int value); ``` @@ -1428,7 +1428,7 @@ int sem_init(sem_t *sem, int pshared, unsigned int value); #### 销毁无名信号量 -``` c +```c int sem_destroy(sem_t *sem); ``` @@ -1447,7 +1447,7 @@ int sem_destroy(sem_t *sem); #### 创建或打开有名信号量 -``` c +```c sem_t *sem_open(const char *name, int oflag, ...); ``` @@ -1463,7 +1463,7 @@ sem_t *sem_open(const char *name, int oflag, ...); #### 分离有名信号量 -``` c +```c int sem_unlink(const char *name); ``` @@ -1478,7 +1478,7 @@ int sem_unlink(const char *name); #### 关闭有名信号量 -``` c +```c int sem_close(sem_t *sem); ``` @@ -1493,7 +1493,7 @@ int sem_close(sem_t *sem); ### 获取信号量值 -``` c +```c int sem_getvalue(sem_t *sem, int *sval); ``` @@ -1509,7 +1509,7 @@ int sem_getvalue(sem_t *sem, int *sval); ### 阻塞方式等待信号量 -``` c +```c int sem_wait(sem_t *sem); ``` @@ -1524,7 +1524,7 @@ int sem_wait(sem_t *sem); ### 非阻塞方式获取信号量 -``` c +```c int sem_trywait(sem_t *sem); ``` @@ -1539,7 +1539,7 @@ int sem_trywait(sem_t *sem); ### 指定阻塞时间等待信号量 -``` c +```c int sem_timedwait(sem_t *sem, const struct timespec *abs_timeout); ``` @@ -1555,7 +1555,7 @@ int sem_timedwait(sem_t *sem, const struct timespec *abs_timeout); ### 发送信号量 -``` c +```c int sem_post(sem_t *sem); ``` @@ -1574,7 +1574,7 @@ int sem_post(sem_t *sem); 此程序会创建 2 个线程,2 个信号量,一个信号量表示共享数据为空状态,一个信号量表示共享数据不为空状态,一个互斥锁用于保护共享资源。生产者线程生产好数据后会给消费者发送一个 full_sem 信号量,通知消费者线程有数据可用,休眠 2 秒后会等待消费者线程发送的 empty_sem 信号量。消费者线程等到生产者发送的 full_sem 后会处理共享数据,处理完后会给生产者线程发送 empty_sem 信号量。程序会这样一直循环。 -``` c +```c #include #include #include @@ -1699,7 +1699,7 @@ POSIX 消息队列主要用于进程间通信,RT-Thread 操作系统的 POSIX 每个消息队列对应一个消息队列控制块,创建消息队列前需要先定义一个消息队列控制块。消息队列控制块定义在 mqueue.h 头文件里。 -``` c +```c struct mqdes { rt_uint16_t refcount; /* 引用计数 */ @@ -1712,7 +1712,7 @@ typedef struct mqdes* mqd_t; /* 消息队列控制块指针类型重定义 */ ### 创建或打开消息队列 -``` c +```c mqd_t mq_open(const char *name, int oflag, ...); ``` @@ -1728,7 +1728,7 @@ mqd_t mq_open(const char *name, int oflag, ...); ### 分离消息队列 -``` c +```c int mq_unlink(const char *name); ``` @@ -1743,7 +1743,7 @@ int mq_unlink(const char *name); ### 关闭消息队列 -``` c +```c int mq_close(mqd_t mqdes); ``` @@ -1758,7 +1758,7 @@ int mq_close(mqd_t mqdes); ### 阻塞方式发送消息 -``` c +```c int mq_send(mqd_t mqdes, const char *msg_ptr, size_t msg_len, @@ -1781,7 +1781,7 @@ int mq_send(mqd_t mqdes, ### 指定阻塞时间发送消息 -``` c +```c int mq_timedsend(mqd_t mqdes, const char *msg_ptr, size_t msg_len, @@ -1804,7 +1804,7 @@ int mq_timedsend(mqd_t mqdes, ### 阻塞方式接受消息 -``` c +```c ssize_t mq_receive(mqd_t mqdes, char *msg_ptr, size_t msg_len, @@ -1825,7 +1825,7 @@ ssize_t mq_receive(mqd_t mqdes, ### 指定阻塞时间接受消息 -``` c +```c ssize_t mq_timedreceive(mqd_t mqdes, char *msg_ptr, size_t msg_len, @@ -1850,7 +1850,7 @@ ssize_t mq_timedreceive(mqd_t mqdes, 这个程序会创建 3 个线程,线程 2 从消息队列接受消息,线程 2 和线程 3 往消息队列发送消息。 -``` c +```c #include #include @@ -1986,7 +1986,7 @@ RT-Thread 实现的线程属性包括线程栈大小、线程优先级、线程 线程属性结构 pthread_attr_t 定义在 pthread.h 头文件里。线程属性结构如下: -``` c +```c /* pthread_attr_t 类型重定义 */ typedef struct pthread_attr pthread_attr_t; /* 线程属性结构体 */ @@ -2005,7 +2005,7 @@ struct pthread_attr 线程属性初始化及去初始化函数如下所示: -``` c +```c int pthread_attr_init(pthread_attr_t *attr); int pthread_attr_destroy(pthread_attr_t *attr); ``` @@ -2024,7 +2024,7 @@ pthread_attr_destroy() 函数对 attr 指向的属性去初始化,之后可以 设置线程的分离状态 / 获取线程的分离状态如下所示,默认情况下线程是非分离状态。 -``` c +```c int pthread_attr_setdetachstate(pthread_attr_t *attr, int state); int pthread_attr_getdetachstate(pthread_attr_t const *attr, int *state); ``` @@ -2045,7 +2045,7 @@ PTHREAD_CREATE_DETACHED(分离)。 设置 \ 获取线程调度策略函数如下所示: -``` c +```c int pthread_attr_setschedpolicy(pthread_attr_t *attr, int policy); int pthread_attr_getschedpolicy(pthread_attr_t const *attr, int *policy); ``` @@ -2056,7 +2056,7 @@ int pthread_attr_getschedpolicy(pthread_attr_t const *attr, int *policy); 设置线程的优先级 / 获取线程的优先级函数如下所示: -``` c +```c int pthread_attr_setschedparam(pthread_attr_t *attr, struct sched_param const *param); int pthread_attr_getschedparam(pthread_attr_t const *attr, @@ -2074,7 +2074,7 @@ pthread_attr_setschedparam() 函数设置线程的优先级。使用 param 对 **参数** struct sched_param 定义在 sched.h 里,结构如下: -``` c +```c struct sched_param { int sched_priority; /* 线程优先级 */ @@ -2087,7 +2087,7 @@ struct sched_param 设置 / 获取 线程的堆栈大小的函数如下所示: -``` c +```c int pthread_attr_setstacksize(pthread_attr_t *attr, size_t stack_size); int pthread_attr_getstacksize(pthread_attr_t const *attr, size_t *stack_size); ``` @@ -2105,7 +2105,7 @@ pthread_attr_setstacksize() 函数可以设置堆栈大小,单位是字节。 设置 / 获取 线程的堆栈地址和堆栈大小的函数如下所示: -``` c +```c int pthread_attr_setstack(pthread_attr_t *attr, void *stack_base, size_t stack_size); @@ -2126,7 +2126,7 @@ int pthread_attr_getstack(pthread_attr_t const *attr, 设置 / 获取线程的作用域的函数如下所示: -``` c +```c int pthread_attr_setscope(pthread_attr_t *attr, int scope); int pthread_attr_getscope(pthread_attr_t const *attr); ``` @@ -2144,7 +2144,7 @@ int pthread_attr_getscope(pthread_attr_t const *attr); 这个程序会初始化 2 个线程,它们拥有共同的入口函数,但是它们的入口参数不相同。最先创建的线程会使用提供的 attr 线程属性,另外一个线程使用系统默认的属性。线程的优先级是很重要的一个参数,因此这个程序会修改第一个创建的线程的优先级为 8,而系统默认的优先级为 24。 -``` c +```c #include #include #include @@ -2212,7 +2212,7 @@ int rt_application_init() 可使用如下函数发送取消请求: -``` c +```c int pthread_cancel(pthread_t thread); ``` @@ -2228,7 +2228,7 @@ int pthread_cancel(pthread_t thread); 可使用如下函数设置取消请求: -``` c +```c int pthread_setcancelstate(int state, int *oldstate); ``` @@ -2246,7 +2246,7 @@ int pthread_setcancelstate(int state, int *oldstate); 可使用如下函数设置取消类型,由线程自己调用: -``` c +```c int pthread_setcanceltype(int type, int *oldtype); ``` @@ -2262,7 +2262,7 @@ int pthread_setcanceltype(int type, int *oldtype); 可使用如下函数设置取消点: -``` c +```c void pthread_testcancel(void); ``` @@ -2312,7 +2312,7 @@ RT-Thread 包含的所有取消点如下: 此程序会创建 2 个线程,线程 2 开始运行后马上休眠 8 秒,线程 1 设置了自己的取消状态和类型,之后在一个无限循环里打印运行计数信息。线程 2 唤醒后向线程 1 发送取消请求,线程 1 收到取消请求后马上结束运行。 -``` c +```c #include #include #include @@ -2388,7 +2388,7 @@ int rt_application_init() 可使用如下函数一次性初始化: -``` c +```c int pthread_once(pthread_once_t * once_control, void (*init_routine) (void)); ``` @@ -2405,7 +2405,7 @@ int pthread_once(pthread_once_t * once_control, void (*init_routine) (void)); 线程清理函数接口如下所示: -``` c +```c void pthread_cleanup_pop(int execute); void pthread_cleanup_push(void (*routine)(void*), void *arg); ``` @@ -2422,7 +2422,7 @@ pthread_cleanup_push() 把指定的清理函数 routine 放到线程的清理函 #### 判断 2 个线程是否相等 -``` c +```c int pthread_equal (pthread_t t1, pthread_t t2); ``` @@ -2435,14 +2435,14 @@ int pthread_equal (pthread_t t1, pthread_t t2); #### 获取线程句柄 -``` c +```c pthread_t pthread_self (void); ``` pthread_self() 返回调用线程的句柄。 #### 获取最大最小优先级 -``` c +```c int sched_get_priority_min(int policy); int sched_get_priority_max(int policy); ``` @@ -2459,7 +2459,7 @@ RT-Thread 实现的互斥锁属性包括互斥锁类型和互斥锁作用域。 #### 互斥锁属性初始化及去初始化 -``` c +```c int pthread_mutexattr_init(pthread_mutexattr_t *attr); int pthread_mutexattr_destroy(pthread_mutexattr_t *attr); ``` @@ -2477,7 +2477,7 @@ pthread_mutexattr_destroy() 函数将会对 attr 指向的属性对象去初始 #### 互斥锁作用域 -``` c +```c int pthread_mutexattr_setpshared(pthread_mutexattr_t *attr, int pshared); int pthread_mutexattr_getpshared(pthread_mutexattr_t *attr, int *pshared); ``` @@ -2492,7 +2492,7 @@ int pthread_mutexattr_getpshared(pthread_mutexattr_t *attr, int *pshared); #### 互斥锁类型 -``` c +```c int pthread_mutexattr_settype(pthread_mutexattr_t *attr, int type); int pthread_mutexattr_gettype(const pthread_mutexattr_t *attr, int *type); ``` @@ -2517,7 +2517,7 @@ int pthread_mutexattr_gettype(const pthread_mutexattr_t *attr, int *type); 使用默认值 PTHREAD_PROCESS_PRIVATE 初始化条件变量属性 attr 可使用如下函数: -``` c +```c int pthread_condattr_init(pthread_condattr_t *attr); ``` @@ -2530,7 +2530,7 @@ int pthread_condattr_init(pthread_condattr_t *attr); #### 获取条件变量作用域 -``` c +```c int pthread_mutexattr_getpshared(pthread_mutexattr_t *attr, int *pshared); ``` @@ -2545,7 +2545,7 @@ int pthread_mutexattr_getpshared(pthread_mutexattr_t *attr, int *pshared); #### 初始化属性 -``` c +```c int pthread_rwlockattr_init (pthread_rwlockattr_t *attr); ``` @@ -2560,7 +2560,7 @@ int pthread_rwlockattr_init (pthread_rwlockattr_t *attr); #### 获取作用域 -``` c +```c int pthread_rwlockattr_getpshared (const pthread_rwlockattr_t *attr, int *pshared); ``` @@ -2578,7 +2578,7 @@ pshared 指向的内存保存的值为 PTHREAD_PROCESS_PRIVATE。 #### 初始化属性 -``` c +```c int pthread_barrierattr_init(pthread_barrierattr_t *attr); ``` @@ -2593,7 +2593,7 @@ int pthread_barrierattr_init(pthread_barrierattr_t *attr); #### 获取作用域 -``` c +```c int pthread_barrierattr_getpshared(const pthread_barrierattr_t *attr, int *pshared); ``` @@ -2609,7 +2609,7 @@ int pthread_barrierattr_getpshared(const pthread_barrierattr_t *attr, int *pshar 消息队列属性控制块如下: -``` c +```c struct mq_attr { long mq_flags; /* 消息队列的标志,用来表示是否阻塞 */ @@ -2619,7 +2619,7 @@ struct mq_attr }; ``` #### 获取属性 -``` c +```c int mq_getattr(mqd_t mqdes, struct mq_attr *mqstat); ``` diff --git a/rt-thread-version/rt-thread-standard/programming-manual/sal/sal.md b/rt-thread-version/rt-thread-standard/programming-manual/sal/sal.md index 518981d4f9afe8db3f6c3a674e12e3338729cb80..1e0730ff773318e5cde67d58748835536dea900b 100644 --- a/rt-thread-version/rt-thread-standard/programming-manual/sal/sal.md +++ b/rt-thread-version/rt-thread-standard/programming-manual/sal/sal.md @@ -265,7 +265,7 @@ SAL 组件抽象出标准 BSD Socket API 接口,如下是对常用网络接口 ### 创建套接字(socket) -``` c +```c int socket(int domain, int type, int protocol); ``` diff --git a/rt-thread-version/rt-thread-standard/tutorial/experimental-manual/msgq_sample/msgq_sample.md b/rt-thread-version/rt-thread-standard/tutorial/experimental-manual/msgq_sample/msgq_sample.md index 0f010e02e0d2102742c3311e4fdcf3825cef272f..b4fcac84cf839c3ce0bd666da2b254d6baa8186a 100644 --- a/rt-thread-version/rt-thread-standard/tutorial/experimental-manual/msgq_sample/msgq_sample.md +++ b/rt-thread-version/rt-thread-standard/tutorial/experimental-manual/msgq_sample/msgq_sample.md @@ -56,7 +56,7 @@ RT-Thread 示例代码都通过 MSH_CMD_EXPORT 将示例初始函数导出到 ms 以下定义了待创建线程需要用到的优先级、时间片的宏,消息队列控制块以及存放消息用到的内存池。 -```C +```c #include #define THREAD_PRIORITY 25 diff --git a/rt-thread-version/rt-thread-standard/tutorial/quick-start/Nordic-nrf52840-pac10056/images/NRFX_BSP.png b/rt-thread-version/rt-thread-standard/tutorial/quick-start/nordic-nrf5x/images/NRFX_BSP.png similarity index 100% rename from rt-thread-version/rt-thread-standard/tutorial/quick-start/Nordic-nrf52840-pac10056/images/NRFX_BSP.png rename to rt-thread-version/rt-thread-standard/tutorial/quick-start/nordic-nrf5x/images/NRFX_BSP.png diff --git a/rt-thread-version/rt-thread-standard/tutorial/quick-start/Nordic-nrf52840-pac10056/images/NRFX_BSP_2.png b/rt-thread-version/rt-thread-standard/tutorial/quick-start/nordic-nrf5x/images/NRFX_BSP_2.png similarity index 100% rename from rt-thread-version/rt-thread-standard/tutorial/quick-start/Nordic-nrf52840-pac10056/images/NRFX_BSP_2.png rename to rt-thread-version/rt-thread-standard/tutorial/quick-start/nordic-nrf5x/images/NRFX_BSP_2.png diff --git a/rt-thread-version/rt-thread-standard/tutorial/quick-start/Nordic-nrf52840-pac10056/images/console.png b/rt-thread-version/rt-thread-standard/tutorial/quick-start/nordic-nrf5x/images/console.png similarity index 100% rename from rt-thread-version/rt-thread-standard/tutorial/quick-start/Nordic-nrf52840-pac10056/images/console.png rename to rt-thread-version/rt-thread-standard/tutorial/quick-start/nordic-nrf5x/images/console.png diff --git a/rt-thread-version/rt-thread-standard/tutorial/quick-start/Nordic-nrf52840-pac10056/images/faq1.png b/rt-thread-version/rt-thread-standard/tutorial/quick-start/nordic-nrf5x/images/faq1.png similarity index 100% rename from rt-thread-version/rt-thread-standard/tutorial/quick-start/Nordic-nrf52840-pac10056/images/faq1.png rename to rt-thread-version/rt-thread-standard/tutorial/quick-start/nordic-nrf5x/images/faq1.png diff --git a/rt-thread-version/rt-thread-standard/tutorial/quick-start/Nordic-nrf52840-pac10056/images/nimble.png b/rt-thread-version/rt-thread-standard/tutorial/quick-start/nordic-nrf5x/images/nimble.png similarity index 100% rename from rt-thread-version/rt-thread-standard/tutorial/quick-start/Nordic-nrf52840-pac10056/images/nimble.png rename to rt-thread-version/rt-thread-standard/tutorial/quick-start/nordic-nrf5x/images/nimble.png diff --git a/rt-thread-version/rt-thread-standard/tutorial/quick-start/Nordic-nrf52840-pac10056/images/nimble_gnu.jpg b/rt-thread-version/rt-thread-standard/tutorial/quick-start/nordic-nrf5x/images/nimble_gnu.jpg similarity index 100% rename from rt-thread-version/rt-thread-standard/tutorial/quick-start/Nordic-nrf52840-pac10056/images/nimble_gnu.jpg rename to rt-thread-version/rt-thread-standard/tutorial/quick-start/nordic-nrf5x/images/nimble_gnu.jpg diff --git a/rt-thread-version/rt-thread-standard/tutorial/quick-start/Nordic-nrf52840-pac10056/images/nrf_connect.jpg b/rt-thread-version/rt-thread-standard/tutorial/quick-start/nordic-nrf5x/images/nrf_connect.jpg similarity index 100% rename from rt-thread-version/rt-thread-standard/tutorial/quick-start/Nordic-nrf52840-pac10056/images/nrf_connect.jpg rename to rt-thread-version/rt-thread-standard/tutorial/quick-start/nordic-nrf5x/images/nrf_connect.jpg diff --git a/rt-thread-version/rt-thread-standard/tutorial/quick-start/Nordic-nrf52840-pac10056/images/sample.png b/rt-thread-version/rt-thread-standard/tutorial/quick-start/nordic-nrf5x/images/sample.png similarity index 100% rename from rt-thread-version/rt-thread-standard/tutorial/quick-start/Nordic-nrf52840-pac10056/images/sample.png rename to rt-thread-version/rt-thread-standard/tutorial/quick-start/nordic-nrf5x/images/sample.png diff --git a/rt-thread-version/rt-thread-standard/tutorial/quick-start/Nordic-nrf52840-pac10056/images/softdevice_2.png b/rt-thread-version/rt-thread-standard/tutorial/quick-start/nordic-nrf5x/images/softdevice_2.png similarity index 100% rename from rt-thread-version/rt-thread-standard/tutorial/quick-start/Nordic-nrf52840-pac10056/images/softdevice_2.png rename to rt-thread-version/rt-thread-standard/tutorial/quick-start/nordic-nrf5x/images/softdevice_2.png diff --git a/rt-thread-version/rt-thread-standard/tutorial/quick-start/Nordic-nrf52840-pac10056/images/softdevice_erase.png b/rt-thread-version/rt-thread-standard/tutorial/quick-start/nordic-nrf5x/images/softdevice_erase.png similarity index 100% rename from rt-thread-version/rt-thread-standard/tutorial/quick-start/Nordic-nrf52840-pac10056/images/softdevice_erase.png rename to rt-thread-version/rt-thread-standard/tutorial/quick-start/nordic-nrf5x/images/softdevice_erase.png diff --git a/rt-thread-version/rt-thread-standard/tutorial/quick-start/Nordic-nrf52840-pac10056/images/softdevice_menuconfig.png b/rt-thread-version/rt-thread-standard/tutorial/quick-start/nordic-nrf5x/images/softdevice_menuconfig.png similarity index 100% rename from rt-thread-version/rt-thread-standard/tutorial/quick-start/Nordic-nrf52840-pac10056/images/softdevice_menuconfig.png rename to rt-thread-version/rt-thread-standard/tutorial/quick-start/nordic-nrf5x/images/softdevice_menuconfig.png diff --git a/rt-thread-version/rt-thread-standard/tutorial/quick-start/Nordic-nrf52840-pac10056/images/update.png b/rt-thread-version/rt-thread-standard/tutorial/quick-start/nordic-nrf5x/images/update.png similarity index 100% rename from rt-thread-version/rt-thread-standard/tutorial/quick-start/Nordic-nrf52840-pac10056/images/update.png rename to rt-thread-version/rt-thread-standard/tutorial/quick-start/nordic-nrf5x/images/update.png diff --git a/rt-thread-version/rt-thread-standard/tutorial/quick-start/Nordic-nrf52840-pac10056/README.md b/rt-thread-version/rt-thread-standard/tutorial/quick-start/nordic-nrf5x/quick-start.md similarity index 99% rename from rt-thread-version/rt-thread-standard/tutorial/quick-start/Nordic-nrf52840-pac10056/README.md rename to rt-thread-version/rt-thread-standard/tutorial/quick-start/nordic-nrf5x/quick-start.md index abc8695919550089455e04fb554ed26716cc8da0..9322fcaf8dfd3b59400014cf53006c1e65a4b79d 100644 --- a/rt-thread-version/rt-thread-standard/tutorial/quick-start/Nordic-nrf52840-pac10056/README.md +++ b/rt-thread-version/rt-thread-standard/tutorial/quick-start/nordic-nrf5x/quick-start.md @@ -25,7 +25,6 @@ Nordic nRF5x 系列 BSP 目前支持情况如下: - 支持 nimble 的软件包及对应的 sample - 支持 RT-THREAD 下面的外设驱动。 - ### Nrf5x BSP 目录结构 该 bsp 位于 RT-THREAD master 目录下面的 bsp/nrf5x 目录下面