沁恒 CH32V208(五): CH32V208 运行FreeRTOS示例的说明
目录
- 沁恒 CH32V208(一): CH32V208WBU6 评估板上手报告和Win10环境配置
- 沁恒 CH32V208(二): CH32V208的储存结构, 启动模式和时钟
- 沁恒 CH32V208(三): CH32V208 Ubuntu22.04 Makefile VSCode环境配置
- 沁恒 CH32V208(四): CH32V208 网络DHCP示例代码分析
- 沁恒 CH32V208(五): CH32V208 运行FreeRTOS示例的说明
硬件部分
- CH32V208WBU6 评估板
- WCH-LinkE 或 WCH-Link
软件部分
本节以沁恒的FreeRTOS示例项目为例进行说明.
示例代码位于 CH32V20xEVT 压缩包的 EVT/EXAM/FreeRTOS 目录.
对应 GCC 环境的项目代码位于 https://github.com/IOsetting/ch32v208-template/tree/main/Examples/FreeRTOS/Task/Blink
青稞V4的手册下载地址 https://www.wch.cn/downloads/QingKeV4_Processor_Manual_PDF.html
编译和烧录
这里只介绍 GCC & Makefile 环境的编译和烧录. 参考上一节进行 GCC 环境的配置
- 修改 Makefile 中的
USE_FREERTOS选项, 设置为USE_FREERTOS ?= y, 打开这个选项, 在编译时会包含 FreeRTOS 库相关文件 - 修改 Makefile 中的
AFILES := Libraries/Startup/startup_ch32v20x_D8W.S, 将其替换为AFILES := Libraries/Startup/startup_ch32v20x_D8W_RTOS.S后者禁用了硬件堆栈, 禁用了机器模式下的中断, 如果不禁用, FreeRTOS 无法正常工作 - 清空 User 目录, 将 FreeRTOS/Task/Blink 目录下的文件复制到 User 目录, 运行
make编译项目 - 连接好 WCH-Link 和 CH32V208 评估板, 运行
make flash烧录
运行示例
将 PA0, PA1 分别连接到 LED1 和 LED2, 观察两个GPIO任务的输出.
将评估板的串口输出连接到 WCH-Link, 在PC端使用串口工具, 波特率115200打开 /dev/ttyACM0 观察两个GPIO任务的printf输出
运行时, 除了 LED1 间隔半秒 和 LED2 间隔一秒闪烁外, 串口会打印以下内容(忽略其中的时间戳部分)
SystemClk:96000000
FreeRTOS Kernel Version:V10.4.6
task2 entry
task1 entry
32:33.611 task1 entry
32:34.611 task2 entry
task1 entry
32:35.611 task1 entry
32:36.610 task2 entry
task1 entry
32:37.611 task1 entry
32:38.611 task2 entry
task1 entry
32:39.611 task1 entry
涉及的代码改动
中断处理变动
CH32V20x 运行 FreeRTOS 时不支持硬件压栈, 中断只能使用软件压栈
在无系统场景时的中断处理
void NMI_Handler(void) __attribute__((interrupt("WCH-Interrupt-fast")));
void HardFault_Handler(void) __attribute__((interrupt("WCH-Interrupt-fast")));
就要换成不带WCH-Interrupt-fast的中断处理
void NMI_Handler(void) __attribute__((interrupt()));
void HardFault_Handler(void) __attribute__((interrupt()));
Startup 文件变动
在 startup 文件中需要禁用硬件堆栈, 并在机器模式下禁用中断,
在无系统场景时的 0x804 和 mstatus 设置
/* Enable nested and hardware stack */
li t0, 0x3
csrw 0x804, t0
/* Enable interrupt */
li t0, 0x88
csrs mstatus, t0
就要替换为下面的设置
/* Enable nested stack, no hardware stack */
li t0, 0x2
csrw 0x804, t0
/* Machine mode, no interrupt */
li t0, 0x1800
csrs mstatus, t0
804寄存器
CSR 0x804地址对应的是 INTSYSCR, 中断系统控制寄存器. 青稞V4手册第13页.
| 位 | 名称 | 读写 | 描述 | 复位值 |
|---|---|---|---|---|
| 1 | INESTEN | RW | 中断嵌套使能, 0:关闭, 1:开启 | 0 |
| 0 | HWSTKEN | RW | 硬件压栈使能, 0:关闭, 1:开启 | 0 |
运行 FreeRTOS 时, 需要关闭硬件压栈使能, 因此上面对 0x804 写入了 0x2.
mstatus寄存器
mstatus 是 机器模式状态寄存器, 青稞V4手册第30页, 每一位的定义为
| 位 | 名称 | 读写 | 描述 | 复位值 |
|---|---|---|---|---|
| [31:15] | -- | |||
| [14:13] | FS | RW | 浮点单元状态, 00:OFF, 01:Initial, 10:Clean, 11:Dirty | 00 |
| [12:11] | MPP | RW | 进中断前特权模式 | 00 |
| [10:8] | -- | |||
| [7] | MPIE | RW | 进中断之前中断使能状态 | 00 |
| [6:4] | -- | |||
| [3] | MIE | RW | 机器模式中断使能 | 00 |
| [2:0] | -- |
- FS
用于描述和维护浮点单元状态, 所以该域只有在含有硬件浮点功能的青稞 V4F 微处理器上才有意义. 当其值为 0 时, 表示浮点单元为关闭状态, 且如果此时使用浮点指令, 将触发异常;若其值为 1 或 2, 当执行了浮点指令后, 该域会被更新为 3. 若用户在使用 V4F 微处理器时, 不期望使用硬件浮点功能, 可在机器模式下, 手动清除该两位, 以关闭硬件浮点并降低功耗. - MPP
用于保存进入异常或中断前的特权模式, 用于退出异常或中断后的特权模式恢复 - MPIE
用于保存进入异常或中断前的中断使能状态(MIE的值), 用于退出异常或中断后中断使能状态恢复 - MIE
全局中断使能位, 当进入异常或中断时, MPIE 的值被更新为 MIE 值, 需要注意的是青稞 V4 在最后一级嵌套中断前 MIE 不会被更新为 0, 以保证机器模式下的中断嵌套继续执行.
当退出异常或中断后, 处理器恢复为 MPP 保存的机器模式, MIE 恢复为 MPIE 保存的使能状态.
运行FreeRTOS时, 需要将 mstatus 设为 0x1800:
- 仅工作在机器模式, 把 MPP 设置为 0x11 (对应[12,11]), 使其返回后始终保持在机器模式.
- 在机器模式禁用中断使能, MIE (对应[3]) 设为 0
LD 脚本
需要增加 __freertos_irq_stack_top 锚定栈顶地址
.stack ORIGIN(RAM) + LENGTH(RAM) - __stack_size :
{
PROVIDE( _heap_end = . );
. = ALIGN(4);
PROVIDE(_susrstack = . );
. = . + __stack_size;
PROVIDE( _eusrstack = .);
__freertos_irq_stack_top = .;
} >RAM
运行 FreeRTOS 任务
这部分就是正常的 FreeRTOS 调用了
xTaskCreate((TaskFunction_t )task2_task,
(const char* )"task2",
(uint16_t )TASK2_STK_SIZE,
(void* )NULL,
(UBaseType_t )TASK2_TASK_PRIO,
(TaskHandle_t* )&Task2Task_Handler);
xTaskCreate((TaskFunction_t )task1_task,
(const char* )"task1",
(uint16_t )TASK1_STK_SIZE,
(void* )NULL,
(UBaseType_t )TASK1_TASK_PRIO,
(TaskHandle_t* )&Task1Task_Handler);
vTaskStartScheduler();
参考
- https://www.cnblogs.com/wchmcu/p/17390935.html
- https://www.eevblog.com/forum/microcontrollers/wch-0-10-risc-v-mcu/100/
沁恒 CH32V208(五): CH32V208 运行FreeRTOS示例的说明的更多相关文章
- 沁恒CH32F103C8T6(二): Linux PlatformIO环境配置, 示例运行和烧录
目录 沁恒CH32F103C8T6(一): Keil5环境配置,示例运行和烧录 沁恒CH32F103C8T6(二): Linux PlatformIO环境配置, 示例运行和烧录 StdPeriphLi ...
- 沁恒CH32F103C8T6(三): PlatformIO DAPLink和WCHLink下载配置
目录 沁恒CH32F103C8T6(一): Keil5环境配置,示例运行和烧录 沁恒CH32F103C8T6(二): Linux PlatformIO环境配置, 示例运行和烧录 沁恒CH32F103C ...
- 蓝牙mesh组网实践(mesh组网的评估与沁恒蓝牙芯片选型)
目录 沁恒的组网方式主要有2.4G私有协议组网和BLE mesh组网两大类.2.4G私有协议组网灵活性相对较高,对开发者的要求也相对较高.mesh组网本身有一系列规范,考虑到了可靠性.安全性.功能性等 ...
- 沁恒CH32V103C8T6(二): Linux RISC-V编译和烧录环境配置
目录 沁恒CH32V103C8T6(一): 核心板焊接和Windows开发环境配置 沁恒CH32V103C8T6(二): Linux RISC-V编译和烧录环境配置 硬件准备 CH32V103 开发板 ...
- 沁恒CH32V003F4P6 开发板上手报告和Win10环境配置
CH32V003 沁恒最近推出的低价CH32V003系列, 基于青稞RISC-V2A内核, 48MHz主频, 2KB SRAM, 16KB Flash, 工作电压兼容3.3V和5V. 主要参数如下 S ...
- 沁恒CH32F103C8T6的开发和烧录配置说明
概述 CH32F1系列是沁恒生产的32位Cortex-M3 MCU, 片上集成了时钟安全机制.多级电源管理. 通用DMA控制器等. 此系列具有 2 路 USB2.0接口.多通道 TouchKey. 1 ...
- 沁恒CH32V003(二): Ubuntu20.04 MRS和Makefile开发环境配置
目录 沁恒CH32V003(一): CH32V003F4P6开发板上手报告和Win10环境配置 沁恒CH32V003(二): Ubuntu20.04 MRS和Makefile开发环境配置 硬件准备 沁 ...
- 转:Windows下的PHP开发环境搭建——PHP线程安全与非线程安全、Apache版本选择,及详解五种运行模式。
原文来自于:http://www.ituring.com.cn/article/128439 Windows下的PHP开发环境搭建——PHP线程安全与非线程安全.Apache版本选择,及详解五种运行模 ...
- JavaEE Tutorials (9) - 运行持久化示例
9.1order应用118 9.1.1order应用中的实体关系119 9.1.2order应用中的主键121 9.1.3实体映射到多个数据库表125 9.1.4order应用中的层叠操作125 9. ...
- JHipster生成微服务架构的应用栈(五)- 容器编排示例
本系列文章演示如何用JHipster生成一个微服务架构风格的应用栈. 环境需求:安装好JHipster开发环境的CentOS 7.4(参考这里) 应用栈名称:appstack 认证微服务: uaa 业 ...
随机推荐
- 后台运行&和nohup使用
这里首先先介绍一下 ctrl+z bg fg jobs 命令 下面为了观察效果,test1.sh脚本不停的输出hello ctrl + z ,会使一个正在运行的进程挂起(暂停)到后台,而且执行jobs ...
- python-if、while、for语句的练习
简单练习 1. 根据百分制成绩打印及格和不及格,60分一下不及格 source = float(input('请输入您的成绩:')) if 0 <= source < 60: print( ...
- 关于如何在IDEA里面配置好Git和Github的相关步骤详解
配置Git 1.File->settings 然后选择其中的Version Control: 接着选择其中的Git选项: 2.将文本框内容定位到本地下载git路径下面 然后点击右边的Test测试 ...
- odoo 开发入门教程系列-模型和基本字段
模型和基本字段 在上一章的末尾,我们创建一个odoo模块.然而,此时它仍然是一个空壳,不允许我们存储任何数据.在我们的房地产模块中,我们希望将与房地产相关的信息(名称(name).描述(descrip ...
- 浅谈Vue 2.x当中组件之间传值方式
一.父子之间传值 1. 父传子 :props <!DOCTYPE html> <html lang="en"> <head> <meta ...
- 必知必会的 WebSocket 协议
文章介绍 WebSocket 是一种在单个 TCP 连接上进行全双工通信的协议,它的出现使客户端和服务器之间的数据交换变得更加简单.WebSocket 通常被应用在实时性要求较高的场景,例如赛事数据. ...
- 打工人都在用的AI工具(第二期)
更多精彩内容,欢迎关注公众号:数量技术宅,也可添加技术宅个人微信号:sljsz01,与我交流. 上周更新的打工人都在用的AI工具(第一期)收到了小伙伴们的高度好评,于是很多小伙伴们急急忙忙的催更,技术 ...
- VUE插值语法
目录 基本使用 基本使用 在body中创建一个标签,一般使用div,定义好id后,在script中进行定义,在前台使用{{变量}}的形式进行调用,语法如下: <!DOCTYPE html> ...
- IDEAL部署外部tomcat及其乱码解决
控制台tomca乱码问题: 本人使用tomcat9为例 1.启动信息有中文乱码: 原因:tomcat采用的是utf-8,而windows默认是GBK 修改java.util.logging.Conso ...
- 你知道Vue响应式数据原理吗
1. Vue2的响应式式原理主要是通过Object.defineProperty的方法里面的setter和getter方法的观察者模式来实现.也就是在组件的初始话阶段给每一个data属性都注册一个se ...