- Java锁的逻辑(结合对象头和ObjectMonitor)
- 还在用饼状图?来瞧瞧这些炫酷的百分比可视化新图形(附代码实现)⛵
- 自动注册实体类到EntityFrameworkCore上下文,并适配ABP及ABPVNext
- 基于Sklearn机器学习代码实战
本节以沁恒的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 环境的配置 。
USE_FREERTOS
选项, 设置为 USE_FREERTOS ?= y
, 打开这个选项, 在编译时会包含 FreeRTOS 库相关文件 AFILES := Libraries/Startup/startup_ch32v20x_D8W.S
, 将其替换为 AFILES := Libraries/Startup/startup_ch32v20x_D8W_RTOS.S
后者禁用了硬件堆栈, 禁用了机器模式下的中断, 如果不禁用, FreeRTOS 无法正常工作 make
编译项目 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 文件中需要禁用硬件堆栈, 并在机器模式下禁用中断.
在无系统场景时的 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
CSR 0x804地址对应的是 INTSYSCR, 中断系统控制寄存器. 青稞V4手册第13页. 。
位 | 名称 | 读写 | 描述 | 复位值 |
---|---|---|---|---|
1 | INESTEN | RW | 中断嵌套使能, 0:关闭, 1:开启 | 0 |
0 | HWSTKEN | RW | 硬件压栈使能, 0:关闭, 1:开启 | 0 |
运行 FreeRTOS 时, 需要关闭硬件压栈使能, 因此上面对 0x804 写入了 0x2. 。
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] | -- |
运行FreeRTOS时, 需要将 mstatus 设为 0x1800
需要增加 __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 调用了 。
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();
最后此篇关于沁恒CH32V208(五):CH32V208运行FreeRTOS示例的说明的文章就讲到这里了,如果你想了解更多关于沁恒CH32V208(五):CH32V208运行FreeRTOS示例的说明的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
package practicejava; public class Query { public static void main(String[] args) { char
因为我很困惑其中会存储什么。它是 ascii 值还是“z”,因为有些网站说它存储 ascii,有些网站说它存储“z”。链接说答案是“z”:http://cprogrammingworld4u.blog
这个问题在这里已经有了答案: mysql_fetch_array()/mysql_fetch_assoc()/mysql_fetch_row()/mysql_num_rows etc... expec
我无法将字符指针数组 s 的字符存储到字符数组 ch 中: int main() { char *s; s = malloc(1024 * sizeof(char));
我有这个代码: int main() { char ch[15]; cout<
在看《C++ Primer Plus 5th edition》时,看到了这样一段代码: cin.get(ch); ++ch; cout void print_type(cha
这行代码做了什么? char_to_ix = { ch:i for i,ch in enumerate(sorted(chars)) } ch:i 是什么意思? 最佳答案 这是@han solo 中提
这行代码做了什么? char_to_ix = { ch:i for i,ch in enumerate(sorted(chars)) } ch:i 是什么意思? 最佳答案 这是@han solo 中提
我在关注《C Primer Plus》这本书,遇到这样一段代码: // echo_eof.c -- repeats input to end of file. #include int main(v
这个问题在这里已经有了答案: Difference between int* a and int *a [duplicate] (2 个答案) Why is the asterisk before
我正在运行单个 goroutine 来处理与某些用户相关的消息 channel 。处理消息后,用户状态由 goroutine 更新并存储在数据库中。当对数据库的请求正在进行时,可以将许多消息发送到 c
这是完整的代码: s = 'life is short, stunt it!!?' from string import punctuation tbl = str.maketrans({ord(ch
在 C++ 中,(int) ch 是否等同于 int(ch)。 如果不是,有什么区别? 最佳答案 它们是同一个东西,也和(int)(ch)一样.在 C++ 中,通常首选使用命名转换来阐明您的意图: 使
我在 php 中使用 cURL。注意到每次启动 curl 案例时,人们总是把: $ch=curl_init(); “$ch”是什么意思? curl -F template_invoke_name='s
我正在编写与对齐相关的代码,如果给定的指针正确对齐,却没有标准的功能测试,这让我感到非常惊讶。 似乎互联网上的大多数代码都使用(long)ptr或 reinterpret_cast(ptr)测试对齐,
这个问题已经有答案了: C skipping one command of a function? [duplicate] (2 个回答) 已关闭 5 年前。 scanf("%c", &ch ) sc
然后我遇到了系统调用“write”,我尝试将“putchar”与“write”进行比较。现在,我对上面的代码行感到困惑。 最佳答案 putchar 是一个库函数。它调用 write 系统调用将字符写入
在 codechef 上用于更快输入输出的许多解决方案中,我遇到过这个表达式,但我无法理解它,因为我没有很多经验。 inline int scan( ) { int n=0; int ch=getch
这个问题在这里已经有了答案: What does space in scanf mean? [duplicate] (6 个答案) 关闭 7 年前。 像这样在scanf中加一个空格的目的是什么 sc
我的 spring-boot 应用程序中有以下 logback.xml: ... ...
我是一名优秀的程序员,十分优秀!