From d222d12ec0fc5907be597eb7c7ffec85c09a1ddb Mon Sep 17 00:00:00 2001 From: 18092575223 <15717808+M0k1se@user.noreply.gitee.com> Date: Tue, 22 Jul 2025 01:14:43 +0800 Subject: [PATCH 1/4] first --- .../\344\275\234\344\270\232.md" | 0 .../\347\254\224\350\256\260.md" | 82 +++++++++++++++++++ 2 files changed, 82 insertions(+) create mode 100644 "2025/\347\254\2541\347\273\204(STM32H750-ART-PI)/\345\274\240\344\270\200\346\231\250/\344\275\234\344\270\232/\344\275\234\344\270\232.md" create mode 100644 "2025/\347\254\2541\347\273\204(STM32H750-ART-PI)/\345\274\240\344\270\200\346\231\250/\347\254\224\350\256\260/\347\254\224\350\256\260.md" diff --git "a/2025/\347\254\2541\347\273\204(STM32H750-ART-PI)/\345\274\240\344\270\200\346\231\250/\344\275\234\344\270\232/\344\275\234\344\270\232.md" "b/2025/\347\254\2541\347\273\204(STM32H750-ART-PI)/\345\274\240\344\270\200\346\231\250/\344\275\234\344\270\232/\344\275\234\344\270\232.md" new file mode 100644 index 0000000..e69de29 diff --git "a/2025/\347\254\2541\347\273\204(STM32H750-ART-PI)/\345\274\240\344\270\200\346\231\250/\347\254\224\350\256\260/\347\254\224\350\256\260.md" "b/2025/\347\254\2541\347\273\204(STM32H750-ART-PI)/\345\274\240\344\270\200\346\231\250/\347\254\224\350\256\260/\347\254\224\350\256\260.md" new file mode 100644 index 0000000..26ec3e1 --- /dev/null +++ "b/2025/\347\254\2541\347\273\204(STM32H750-ART-PI)/\345\274\240\344\270\200\346\231\250/\347\254\224\350\256\260/\347\254\224\350\256\260.md" @@ -0,0 +1,82 @@ +# 2025RT-Thread夏令营第一天笔记 +## 上午 +### 一、开发环境配置及示例工程的运行 +1.利用git抓取RT-Thread源代码和安装ENV环境,具体步骤如下:   +1.1先在电脑上下载git,然后通过命令行输入以下代码抓取源代码和evn环境:     +`git clone https://gitee.com/mirrors_RT-Thread/rt-thread.git `     +`git clone --recursive --depth 1 https://gitee.com/mirrors_RT-Thread/env-windows.git`   + +1.2然后打开*env-windows*文件夹,运行*env.bat*,之后利用快捷键*Win+Alt+P*打开*Setting*,然后在界面左侧点击*Intergration*,然后再点击*Register*完成对ENV环境的配置和注册,此时,便可以在任一一个文件夹内单击鼠标右键后就可以*Conemu Here*。   + +1.3然后利用刚才配置好的ENV环境,通过以下路径: +`\rt-thread\bsp\qemu-vexpress-a9`,右键*Conemu Here*,然后输入*menuconfig*,回车,然后再保存退出,此时就生成了*Config*文件。然后*pkgs --upgrade*,将ENV环境更新到最新的版本,再输入*scons -j4*,回车,进行编译(~~等待编译ing~~)编译完成之后,输入*qemu-nographic.bat*,回车,运行编译好的文件。最后再次进入*menuconfig*界面,配置并下载*lvgl*软件包,然后编译,输入*qemu*便能成功运行*lvgl*的示例工程。 + +1.4下载并安装*Visual Stduio Code*软件。然后用其打开*qemu-vexpress-a9*文件夹,找到*application*(应用层),然后就可以在主函数*main.c*里~~愉快的~~敲代码了,然后重复1.3编译,运行的步骤,就可以在命令行里看到结果了。 +## 下午 +### 二、git的学习和使用 +2.1在命令行中通过`git clone`的指令抓取*gitee*仓库的代码。 + +2.2在VSCode上下载*Git Graph*的拓展,可以避免使用命令行,简化操作,方便使用,提高效率。然后在*gitee*上*fork RSOC-RTT*到自己的仓库,然后通过SHH的方式拉取到本地,然后创建自己的分支,建立自己的笔记和作业,再*PR*到远端。 + +### 三、常用的git指令 + +#### 初始化仓库 +- `git init`   +  初始化一个新的 Git 仓库。 + +#### 克隆仓库 +- `git clone [url]`   +  从远程仓库克隆一个项目到本地。 + +#### 查看状态 +- `git status`   +  显示工作目录和暂存区的状态。 + +#### 添加文件到暂存区 +- `git add [file]`   +  将指定文件添加到暂存区。 +- `git add .`   +  将所有改动添加到暂存区。 + +#### 提交更改 +- `git commit -m "[message]"`   +  提交暂存区的更改,并附带提交信息。 + +#### 查看提交历史 +- `git log`   +  显示项目的提交日志。 +- `git log --oneline`   +  以简洁的一行格式显示提交日志。 + +#### 分支操作 +- `git branch`   +  列出所有的本地分支。 +- `git branch [branch-name]`   +  创建新分支。 +- `git checkout [branch-name]`   +  切换到指定分支。 +- `git checkout -b [branch-name]`   +  创建并切换到新的分支。 + +#### 合并分支 +- `git merge [branch]`   +  将指定分支合并到当前分支。 + +#### 远程操作 +- `git remote add [remote-name] [url]`   +  添加一个新的远程仓库。 +- `git fetch [remote-name]`   +  从远程仓库获取最新更新而不自动合并。 +- `git pull [remote-name] [branch]`   +  获取并合并远程仓库的更改到当前分支。 +- `git push [remote-name] [branch]`   +  推送本地分支的更新到远程仓库。 + +#### 查看差异 +- `git diff`   +  显示工作目录与暂存区之间的差异。 +- `git diff --staged`   +  显示暂存区与最近一次提交之间的差异。 + +#### 删除操作 +- `git rese \ No newline at end of file -- Gitee From c6feaa372a8dec63217860d97d03580e8d10c90b Mon Sep 17 00:00:00 2001 From: 18092575223 <15717808+M0k1se@user.noreply.gitee.com> Date: Wed, 23 Jul 2025 02:09:59 +0800 Subject: [PATCH 2/4] sec --- .vscode/tasks.json | 28 +++ .../\344\275\234\344\270\232/main..c" | 71 +++++++ .../\347\254\224\350\256\260.md" | 82 -------- ...00\345\244\251\347\254\224\350\256\260.md" | 180 ++++++++++++++++++ ...14\345\244\251\347\254\224\350\256\260.md" | 60 ++++++ 5 files changed, 339 insertions(+), 82 deletions(-) create mode 100644 .vscode/tasks.json create mode 100644 "2025/\347\254\2541\347\273\204(STM32H750-ART-PI)/\345\274\240\344\270\200\346\231\250/\344\275\234\344\270\232/main..c" delete mode 100644 "2025/\347\254\2541\347\273\204(STM32H750-ART-PI)/\345\274\240\344\270\200\346\231\250/\347\254\224\350\256\260/\347\254\224\350\256\260.md" create mode 100644 "2025/\347\254\2541\347\273\204(STM32H750-ART-PI)/\345\274\240\344\270\200\346\231\250/\347\254\224\350\256\260/\347\254\254\344\270\200\345\244\251\347\254\224\350\256\260.md" create mode 100644 "2025/\347\254\2541\347\273\204(STM32H750-ART-PI)/\345\274\240\344\270\200\346\231\250/\347\254\224\350\256\260/\347\254\254\344\272\214\345\244\251\347\254\224\350\256\260.md" diff --git a/.vscode/tasks.json b/.vscode/tasks.json new file mode 100644 index 0000000..38dfcd7 --- /dev/null +++ b/.vscode/tasks.json @@ -0,0 +1,28 @@ +{ + "tasks": [ + { + "type": "cppbuild", + "label": "C/C++: gcc.exe 生成活动文件", + "command": "C:\\mingw\\mingw64\\bin\\gcc.exe", + "args": [ + "-fdiagnostics-color=always", + "-g", + "${file}", + "-o", + "${fileDirname}\\${fileBasenameNoExtension}.exe" + ], + "options": { + "cwd": "${fileDirname}" + }, + "problemMatcher": [ + "$gcc" + ], + "group": { + "kind": "build", + "isDefault": true + }, + "detail": "调试器生成的任务。" + } + ], + "version": "2.0.0" +} \ No newline at end of file diff --git "a/2025/\347\254\2541\347\273\204(STM32H750-ART-PI)/\345\274\240\344\270\200\346\231\250/\344\275\234\344\270\232/main..c" "b/2025/\347\254\2541\347\273\204(STM32H750-ART-PI)/\345\274\240\344\270\200\346\231\250/\344\275\234\344\270\232/main..c" new file mode 100644 index 0000000..4f17332 --- /dev/null +++ "b/2025/\347\254\2541\347\273\204(STM32H750-ART-PI)/\345\274\240\344\270\200\346\231\250/\344\275\234\344\270\232/main..c" @@ -0,0 +1,71 @@ +#include +#include +#include + +#define THREAD_PRIORITY 25 +#define THREAD_STACK_SIZE 1024 +#define THREAD_TIMESLICE 10 + +static rt_thread_t tid1 = RT_NULL; +static rt_thread_t tid2 = RT_NULL; +static rt_thread_t tid3 = RT_NULL; + +static void thread1_entry(void *parameter) +{ + rt_uint32_t count = 0; + + while (1) + { + rt_kprintf("thread1 count: %d\n", count++); + rt_thread_mdelay(500); + } +} + +static void thread2_entry(void *parameter) +{ + rt_uint32_t count = 0; + + while (1) + { + rt_kprintf("thread2 count: %d\n", count++); + for (int i = 0; i < 1000000; i++); + } +} + +static void thread3_entry(void *parameter) +{ + rt_uint32_t count = 0; + + while (1) + { + rt_kprintf("THREAD3 COUNT: %d\n", count++); + rt_thread_mdelay(200); + } +} + +int main(void) +{ + tid1 = rt_thread_create("thread1",thread1_entry, RT_NULL,THREAD_STACK_SIZE,THREAD_PRIORITY + 2, THREAD_TIMESLICE); + if (tid1 != RT_NULL) + { + rt_thread_startup(tid1); + } + tid2 = rt_thread_create("thread2",thread2_entry, RT_NULL,THREAD_STACK_SIZE,THREAD_PRIORITY + 1, THREAD_TIMESLICE); + if (tid2 != RT_NULL) + { + rt_thread_startup(tid2); + } + tid3 = rt_thread_create("thread3",thread3_entry, RT_NULL,THREAD_STACK_SIZE,THREAD_PRIORITY, THREAD_TIMESLICE); + if (tid3 != RT_NULL) + { + rt_thread_startup(tid3); + } + + while (1) + { + rt_kprintf("main thread running\n"); + rt_thread_mdelay(1000); + } + + return RT_EOK; +} \ No newline at end of file diff --git "a/2025/\347\254\2541\347\273\204(STM32H750-ART-PI)/\345\274\240\344\270\200\346\231\250/\347\254\224\350\256\260/\347\254\224\350\256\260.md" "b/2025/\347\254\2541\347\273\204(STM32H750-ART-PI)/\345\274\240\344\270\200\346\231\250/\347\254\224\350\256\260/\347\254\224\350\256\260.md" deleted file mode 100644 index 26ec3e1..0000000 --- "a/2025/\347\254\2541\347\273\204(STM32H750-ART-PI)/\345\274\240\344\270\200\346\231\250/\347\254\224\350\256\260/\347\254\224\350\256\260.md" +++ /dev/null @@ -1,82 +0,0 @@ -# 2025RT-Thread夏令营第一天笔记 -## 上午 -### 一、开发环境配置及示例工程的运行 -1.利用git抓取RT-Thread源代码和安装ENV环境,具体步骤如下:   -1.1先在电脑上下载git,然后通过命令行输入以下代码抓取源代码和evn环境:     -`git clone https://gitee.com/mirrors_RT-Thread/rt-thread.git `     -`git clone --recursive --depth 1 https://gitee.com/mirrors_RT-Thread/env-windows.git`   - -1.2然后打开*env-windows*文件夹,运行*env.bat*,之后利用快捷键*Win+Alt+P*打开*Setting*,然后在界面左侧点击*Intergration*,然后再点击*Register*完成对ENV环境的配置和注册,此时,便可以在任一一个文件夹内单击鼠标右键后就可以*Conemu Here*。   - -1.3然后利用刚才配置好的ENV环境,通过以下路径: -`\rt-thread\bsp\qemu-vexpress-a9`,右键*Conemu Here*,然后输入*menuconfig*,回车,然后再保存退出,此时就生成了*Config*文件。然后*pkgs --upgrade*,将ENV环境更新到最新的版本,再输入*scons -j4*,回车,进行编译(~~等待编译ing~~)编译完成之后,输入*qemu-nographic.bat*,回车,运行编译好的文件。最后再次进入*menuconfig*界面,配置并下载*lvgl*软件包,然后编译,输入*qemu*便能成功运行*lvgl*的示例工程。 - -1.4下载并安装*Visual Stduio Code*软件。然后用其打开*qemu-vexpress-a9*文件夹,找到*application*(应用层),然后就可以在主函数*main.c*里~~愉快的~~敲代码了,然后重复1.3编译,运行的步骤,就可以在命令行里看到结果了。 -## 下午 -### 二、git的学习和使用 -2.1在命令行中通过`git clone`的指令抓取*gitee*仓库的代码。 - -2.2在VSCode上下载*Git Graph*的拓展,可以避免使用命令行,简化操作,方便使用,提高效率。然后在*gitee*上*fork RSOC-RTT*到自己的仓库,然后通过SHH的方式拉取到本地,然后创建自己的分支,建立自己的笔记和作业,再*PR*到远端。 - -### 三、常用的git指令 - -#### 初始化仓库 -- `git init`   -  初始化一个新的 Git 仓库。 - -#### 克隆仓库 -- `git clone [url]`   -  从远程仓库克隆一个项目到本地。 - -#### 查看状态 -- `git status`   -  显示工作目录和暂存区的状态。 - -#### 添加文件到暂存区 -- `git add [file]`   -  将指定文件添加到暂存区。 -- `git add .`   -  将所有改动添加到暂存区。 - -#### 提交更改 -- `git commit -m "[message]"`   -  提交暂存区的更改,并附带提交信息。 - -#### 查看提交历史 -- `git log`   -  显示项目的提交日志。 -- `git log --oneline`   -  以简洁的一行格式显示提交日志。 - -#### 分支操作 -- `git branch`   -  列出所有的本地分支。 -- `git branch [branch-name]`   -  创建新分支。 -- `git checkout [branch-name]`   -  切换到指定分支。 -- `git checkout -b [branch-name]`   -  创建并切换到新的分支。 - -#### 合并分支 -- `git merge [branch]`   -  将指定分支合并到当前分支。 - -#### 远程操作 -- `git remote add [remote-name] [url]`   -  添加一个新的远程仓库。 -- `git fetch [remote-name]`   -  从远程仓库获取最新更新而不自动合并。 -- `git pull [remote-name] [branch]`   -  获取并合并远程仓库的更改到当前分支。 -- `git push [remote-name] [branch]`   -  推送本地分支的更新到远程仓库。 - -#### 查看差异 -- `git diff`   -  显示工作目录与暂存区之间的差异。 -- `git diff --staged`   -  显示暂存区与最近一次提交之间的差异。 - -#### 删除操作 -- `git rese \ No newline at end of file diff --git "a/2025/\347\254\2541\347\273\204(STM32H750-ART-PI)/\345\274\240\344\270\200\346\231\250/\347\254\224\350\256\260/\347\254\254\344\270\200\345\244\251\347\254\224\350\256\260.md" "b/2025/\347\254\2541\347\273\204(STM32H750-ART-PI)/\345\274\240\344\270\200\346\231\250/\347\254\224\350\256\260/\347\254\254\344\270\200\345\244\251\347\254\224\350\256\260.md" new file mode 100644 index 0000000..f2ddf28 --- /dev/null +++ "b/2025/\347\254\2541\347\273\204(STM32H750-ART-PI)/\345\274\240\344\270\200\346\231\250/\347\254\224\350\256\260/\347\254\254\344\270\200\345\244\251\347\254\224\350\256\260.md" @@ -0,0 +1,180 @@ +# 2025 RT-Thread 夏令营第一天笔记 + +## 上午 + +### 一、开发环境配置及示例工程的运行 + +#### 1.1 安装 Git 并抓取源码 +首先在电脑上安装 Git。然后打开命令行,输入以下命令来抓取 RT-Thread 源码和 ENV 环境: +```bash +git clone https://gitee.com/mirrors_RT-Thread/rt-thread.git +git clone --recursive --depth 1 https://gitee.com/mirrors_RT-Thread/env-windows.git +``` + +#### 1.2 配置 ENV 环境 +1. 打开 env-windows 文件夹,并运行 env.bat +2. 使用快捷键 Win + Alt + P 打开设置界面 +3. 在左侧点击 Integration,然后点击 Register 完成对 ENV 环境的配置与注册 +4. 注册完成后,在任意文件夹中右键菜单会出现 ConEmu Here 选项 + +#### 1.3 编译并运行 RT-Thread 示例工程 +1. 进入路径 `\rt-thread\bsp\qemu-vexpress-a9`,右键选择 ConEmu Here 打开终端 +2. 输入以下命令: +```bash +menuconfig +``` +回车后保存并退出,生成 Config 文件 +3. 更新 ENV 环境: +```bash +pkgs --upgrade +``` +4. 编译工程: +```bash +scons -j4 +``` +5. 编译完成后运行: +```bash +qemu-nographic.bat +``` +6. 再次进入 menuconfig,配置并下载 lvgl 软件包 +7. 重新编译后输入: +```bash +qemu +``` +即可成功运行 lvgl 示例工程 + +#### 1.4 安装 VS Code 并进行开发 +1. 下载并安装 Visual Studio Code +2. 使用 VS Code 打开 qemu-vexpress-a9 文件夹 +3. 找到 application 文件夹,编辑主函数 main.c +4. 修改完成后重复 1.3 中的编译和运行步骤,即可在终端看到运行结果 + +## 下午 + +### 二、Git 的学习和使用 + +#### 2.1 使用 Git 抓取代码 +在命令行中使用以下命令从 Gitee 抓取仓库代码: +```bash +git clone [仓库地址] +``` + +#### 2.2 使用 VS Code 和 Git Graph 插件 +1. 在 VS Code 中安装 Git Graph 插件 +2. 该插件可以避免使用命令行,简化 Git 操作,提高效率 +3. 在 Gitee 上 Fork RSOC-RTT 到自己的仓库 +4. 使用 SSH 方式将代码拉取到本地 +5. 创建自己的分支,编写笔记和作业 +6. 最后通过 Pull Request(PR)提交到远端仓库 + +### 三、常用的 Git 指令 + +#### 初始化仓库 +```bash +git init +``` +初始化一个新的 Git 仓库 + +#### 克隆仓库 +```bash +git clone [url] +``` +从远程仓库克隆一个项目到本地 + +#### 查看状态 +```bash +git status +``` +显示工作目录和暂存区的状态 + +#### 添加文件到暂存区 +```bash +git add [file] +``` +将指定文件添加到暂存区 +```bash +git add . +``` +将所有改动添加到暂存区 + +#### 提交更改 +```bash +git commit -m "[message]" +``` +提交暂存区的更改,并附带提交信息 + +#### 查看提交历史 +```bash +git log +``` +显示项目的提交日志 +```bash +git log --oneline +``` +以简洁的一行格式显示提交日志 + +#### 分支操作 +```bash +git branch +``` +列出所有的本地分支 +```bash +git branch [branch-name] +``` +创建新分支 +```bash +git checkout [branch-name] +``` +切换到指定分支 +```bash +git checkout -b [branch-name] +``` +创建并切换到新的分支 + +#### 合并分支 +```bash +git merge [branch] +``` +将指定分支合并到当前分支 + +#### 远程操作 +```bash +git remote add [remote-name] [url] +``` +添加一个新的远程仓库 +```bash +git fetch [remote-name] +``` +从远程仓库获取最新更新而不自动合并 +```bash +git pull [remote-name] [branch] +``` +获取并合并远程仓库的更改到当前分支 +```bash +git push [remote-name] [branch] +``` +推送本地分支的更新到远程仓库 + +#### 查看差异 +```bash +git diff +``` +显示工作目录与暂存区之间的差异 +```bash +git diff --staged +``` +显示暂存区与最近一次提交之间的差异 + +#### 删除操作 +```bash +git reset [file] +``` +将指定文件从暂存区移除,但保留工作目录中的内容 +```bash +git reset [commit] +``` +回滚到特定的提交(请谨慎使用,可能会丢失未提交的更改) +```bash +git rm [file] +``` +从工作目录和暂存区中删除文件 \ No newline at end of file diff --git "a/2025/\347\254\2541\347\273\204(STM32H750-ART-PI)/\345\274\240\344\270\200\346\231\250/\347\254\224\350\256\260/\347\254\254\344\272\214\345\244\251\347\254\224\350\256\260.md" "b/2025/\347\254\2541\347\273\204(STM32H750-ART-PI)/\345\274\240\344\270\200\346\231\250/\347\254\224\350\256\260/\347\254\254\344\272\214\345\244\251\347\254\224\350\256\260.md" new file mode 100644 index 0000000..621377b --- /dev/null +++ "b/2025/\347\254\2541\347\273\204(STM32H750-ART-PI)/\345\274\240\344\270\200\346\231\250/\347\254\224\350\256\260/\347\254\254\344\272\214\345\244\251\347\254\224\350\256\260.md" @@ -0,0 +1,60 @@ +# 2025 RT-Thread 夏令营第二天笔记 +## 一、RT-Thread STtudio安装与配置 +### 1.1 RT Studio和SDK资源包下载 + 到*RT-Thread*官网*https://www.rt-thread.org/download.html#download-rt-thread-studio*下载*RT Studio*,下载完成后正常安装即可。然后打开*RT Studio*,然后打开SDK资源管理器,然后选择*STM32F407*,选择最新版本后安装。之后再安装最新版本的*QEMU* 。 + ### 1.2新建工程并模拟运行QEMU + 选择基于开发板创建新工程,开发板选择*STM32F407-ATK-EXPLORER*,然后调制器选择*QEMU*,待创建完成之后build工程即可。然后在工具栏选择下载,并选择与之对应的模拟器,然后系统控制台就会自动运行,然后输入*PC*即可查看当前任务状态。 +## 二、裸机和RTOS的区别 +### 2.1裸机的优势 +裸机适用于系统功能单一的情况下使用,并可以提高其运行效率;还可以使用较少的储存实现嵌入式系统的功能。 +### 2.2裸机的劣势 +裸机的代码耦合度较高,复用性较差;而且不适合复杂的嵌入式系统;同时在编写的代码不合理时容易造成系统阻塞。 +### 2.3ROTS的优势 +相较于裸机代码耦合度低,复用性较好;而且可以使用任务划分的方式降低实现复杂嵌入式系统的代码逻辑;RTOS下的延时不会一直占用CPU,延时期间处理其他任务;使用RTOS提供的线程同步与信息传递会提高系统的实时性。 +### 2.3ROTS的劣势 +在小容量的嵌入式系统中,其本身会占据部分内存;而且在单一系统中,系统调度会增加额外的开销。 + ## 三、初识RT-Thread内核 +### 3.1临界区 +定义:访问共享资源的代码段,同一时间仅允许一个线程访问。一但被占用,其他线程就不能够再使用,只能等待。 +### 3.2阻塞式线程和非阻塞式线程 +阻塞式线程对于临界区只能等,期间不能执行其他任务;非阻塞式线程对于临界区,等待期间可以执行其他任务。 +### 3.3RT-Thread系统启动流程 +3.3.1 **启动文件初始化**: + ```assembly + Reset_Handler: + BL SystemInit ; 时钟配置 + BL entry ; 进入RT-Thread + ``` + +3.3.2. **软件初始化**: + ```c + rt_hw_interrupt_disable(); // 关中断 + rt_hw_board_init(); // 板级外设 + rt_show_version(); // 打印版本 + rt_system_timer_init(); // 硬件定时器 + rt_system_scheduler_init(); // 调度器 + ``` +3.3.3. **线程创建**: + ```c + rt_application_init(); // 主线程 + rt_thread_idle_init(); // 空闲线程(优先级最低) + ``` +3.3.4 **启动调度**: + ```c + rt_system_scheduler_start(); // 开始线程调度 + ``` +### 3.4 空闲线程 +- 优先级最低(通常31) +- 永不挂起 +- 功能: + - CPU使用率统计 + - 低功耗模式管理 + - 僵尸线程资源回收 +### 3.5 线程调度机制 +1. **优先级抢占**: + - 高优先级线程可抢占低优先级线程 + - 示例:中断服务程序唤醒高优先级线程 + +2. **时间片轮转**: + - 相同优先级线程轮流执行 + - 时间片用完触发切换 \ No newline at end of file -- Gitee From 57b6034411f16c5255f8350af90c6474333fedff Mon Sep 17 00:00:00 2001 From: 18092575223 <15717808+M0k1se@user.noreply.gitee.com> Date: Wed, 23 Jul 2025 17:04:49 +0800 Subject: [PATCH 3/4] day2 --- .../\344\275\234\344\270\232/main.c" | 67 +++++++++++ .../Day1\347\254\224\350\256\260.md" | 30 +++++ .../Day2\347\254\224\350\256\260.md" | 111 ++++++++++++++++++ 3 files changed, 208 insertions(+) create mode 100644 "2025/\347\254\2544\347\273\204(FRDM-MCXA156)/\350\202\226\346\231\257\345\263\260/\344\275\234\344\270\232/main.c" create mode 100644 "2025/\347\254\2544\347\273\204(FRDM-MCXA156)/\350\202\226\346\231\257\345\263\260/\347\254\224\350\256\260/Day1\347\254\224\350\256\260.md" create mode 100644 "2025/\347\254\2544\347\273\204(FRDM-MCXA156)/\350\202\226\346\231\257\345\263\260/\347\254\224\350\256\260/Day2\347\254\224\350\256\260.md" diff --git "a/2025/\347\254\2544\347\273\204(FRDM-MCXA156)/\350\202\226\346\231\257\345\263\260/\344\275\234\344\270\232/main.c" "b/2025/\347\254\2544\347\273\204(FRDM-MCXA156)/\350\202\226\346\231\257\345\263\260/\344\275\234\344\270\232/main.c" new file mode 100644 index 0000000..9393360 --- /dev/null +++ "b/2025/\347\254\2544\347\273\204(FRDM-MCXA156)/\350\202\226\346\231\257\345\263\260/\344\275\234\344\270\232/main.c" @@ -0,0 +1,67 @@ +#include +#include +#include + +#define thread_size 512 +#define thread_pri 15 +#define thread_tick 5 + + +#define THREAD1_TICK 10 +#define THREAD2_TICK 20 +#define THREAD3_TICK 30 + +uint16_t sum1, sum2; + + +void thread1_entry() +{ + while(1) + { + rt_kprintf("sum1=%d\n", sum1++); + rt_thread_mdelay(500); + } +} + +void thread2_entry() +{ + while(1) + { + rt_kprintf("sum2=%d\n", sum2++); + rt_thread_mdelay(500); + } +} + +void thread3_entry() +{ + while(1) + { + rt_kprintf("ing......\n"); + rt_thread_mdelay(300); + } +} + + +int main(void) +{ + rt_thread_t thread1 = RT_NULL; + rt_thread_t thread2 = RT_NULL; + rt_thread_t thread3 = RT_NULL; + + thread3 = rt_thread_create("thread3", thread3_entry, RT_NULL, + thread_size, thread_pri, THREAD3_TICK); + thread1 = rt_thread_create("thread1", thread1_entry, RT_NULL, + thread_size, thread_pri, THREAD1_TICK); + + thread2 = rt_thread_create("thread2", thread2_entry, RT_NULL, + thread_size, thread_pri, THREAD2_TICK); + + if(thread3) + rt_thread_startup(thread3); + if(thread1) + rt_thread_startup(thread1); + if(thread2) + rt_thread_startup(thread2); + + return RT_EOK; +} diff --git "a/2025/\347\254\2544\347\273\204(FRDM-MCXA156)/\350\202\226\346\231\257\345\263\260/\347\254\224\350\256\260/Day1\347\254\224\350\256\260.md" "b/2025/\347\254\2544\347\273\204(FRDM-MCXA156)/\350\202\226\346\231\257\345\263\260/\347\254\224\350\256\260/Day1\347\254\224\350\256\260.md" new file mode 100644 index 0000000..49c7f29 --- /dev/null +++ "b/2025/\347\254\2544\347\273\204(FRDM-MCXA156)/\350\202\226\346\231\257\345\263\260/\347\254\224\350\256\260/Day1\347\254\224\350\256\260.md" @@ -0,0 +1,30 @@ +# ENV工具使用 +```c +scons -4j//对文件进行编译 +pkgs --upgrade//升级软件包 +menuconfig//打开图形化配置界面 +``` +其中使用pkgs --upgrade时可能会报错如下 +![screenshot_image.png](https://oss-club.rt-thread.org/uploads/20250722/e7d05ce56c526fcc60c8346d89eff8d0.png.webp) +此时需要进入ENV的这个目录:E:\env\tools\scripts\cmds,注意ENV安装的目录 +在这个目录下打开ENV工具,运行menuconfig,保存 + +vsc进行代码编写,在env工具进行编译后使用qemu-nographic.bat 运行编译好的文件 +![screenshot_image.png](https://oss-club.rt-thread.org/uploads/20250722/6a1eb985c8edab33fe71d2828a403a0a.png.webp) + +![screenshot_image.png](https://oss-club.rt-thread.org/uploads/20250722/63fc6d6d9f8b2a94616f28f942f7caae.png.webp) +使用qemu.bat运行lvgl的demo + +![screenshot_image.png](https://oss-club.rt-thread.org/uploads/20250722/e8553b927d181517f5217ea3022c0554.png.webp) +#git使用 + +```c +git add 暂存 +git commit 提交 +git log 查看历史 +git checkout/git reset 回退 +git branch 创建分支 +git merge 合并分支 +git push/pull 推送/拉取 +git status 查看文件状态 +``` \ No newline at end of file diff --git "a/2025/\347\254\2544\347\273\204(FRDM-MCXA156)/\350\202\226\346\231\257\345\263\260/\347\254\224\350\256\260/Day2\347\254\224\350\256\260.md" "b/2025/\347\254\2544\347\273\204(FRDM-MCXA156)/\350\202\226\346\231\257\345\263\260/\347\254\224\350\256\260/Day2\347\254\224\350\256\260.md" new file mode 100644 index 0000000..0cd1925 --- /dev/null +++ "b/2025/\347\254\2544\347\273\204(FRDM-MCXA156)/\350\202\226\346\231\257\345\263\260/\347\254\224\350\256\260/Day2\347\254\224\350\256\260.md" @@ -0,0 +1,111 @@ +# RTT Studio使用 +**1.资源包下载** + 安装STM32F407探索者和qemu的资源包 +**2.新建RTT项目** +**3.打开RT-Thread Settings下载示例** +# 基本知识 +**临界区**:每个进程中访问临界资源的那段程序称之为临界区 +**信号量**:表示可用资源的数量,即线程可访问 +**阻塞**:当程序执行某个操作时,若条件未满足,则主动挂起等待,直到条件满足后才继续执行。 +**非阻塞**:执行操作时无论是否满足条件都立即返回。 +# 创建线程以及应用 +**动态**: + +```c +rt_thread_create(1.线程名字 + 2.入口函数 + 3.入口函数参数 + 4.栈大小 + 5.线程优先级 + 6.线程时间片大小) +``` +**静态**: + +```c +rt_thread_init(1.线程控制块的地址 + 2.线程名字 + 3.入口函数 + 4.入口函数参数 + 5.线程栈起始地址 + 6.栈大小 + 7.线程优先级 + 8.线程时间片大小) +``` +两者区别在于静态的需要提前分配内存,在某些需要保证安全的情况下更合适使用 +**初始化线程**: + +```c +rt_thread_startup(线程名) +``` +**作业**: + +```c +#include +#include +#include + +#define thread_size 512 +#define thread_pri 15 +#define thread_tick 5 + + +#define THREAD1_TICK 10 +#define THREAD2_TICK 20 +#define THREAD3_TICK 30 + +uint16_t sum1, sum2; + + +void thread1_entry() +{ + while(1) + { + rt_kprintf("sum1=%d\n", sum1++); + rt_thread_mdelay(500); + } +} + +void thread2_entry() +{ + while(1) + { + rt_kprintf("sum2=%d\n", sum2++); + rt_thread_mdelay(500); + } +} + +void thread3_entry() +{ + while(1) + { + rt_kprintf("ing......\n"); + rt_thread_mdelay(300); + } +} + + +int main(void) +{ + rt_thread_t thread1 = RT_NULL; + rt_thread_t thread2 = RT_NULL; + rt_thread_t thread3 = RT_NULL; + + thread3 = rt_thread_create("thread3", thread3_entry, RT_NULL, + thread_size, thread_pri, THREAD3_TICK); + thread1 = rt_thread_create("thread1", thread1_entry, RT_NULL, + thread_size, thread_pri, THREAD1_TICK); + + thread2 = rt_thread_create("thread2", thread2_entry, RT_NULL, + thread_size, thread_pri, THREAD2_TICK); + + if(thread3) + rt_thread_startup(thread3); + if(thread1) + rt_thread_startup(thread1); + if(thread2) + rt_thread_startup(thread2); + + return RT_EOK; +} + +``` \ No newline at end of file -- Gitee From 889d247f6c6b869e09ce19a1a675c4a0f311e87d Mon Sep 17 00:00:00 2001 From: 18092575223 <15717808+M0k1se@user.noreply.gitee.com> Date: Fri, 25 Jul 2025 00:51:40 +0800 Subject: [PATCH 4/4] thir --- .../event_demo.c" | 53 ++++++++++ .../mailbox_demo.c" | 52 ++++++++++ .../message_queue_demo.c" | 63 ++++++++++++ .../mutex_demo.c" | 50 ++++++++++ .../semaphore_demo.c" | 51 ++++++++++ .../signal_demo.c" | 49 ++++++++++ ...11\345\244\251\347\254\224\350\256\260.md" | 98 +++++++++++++++++++ 7 files changed, 416 insertions(+) create mode 100644 "2025/\347\254\2541\347\273\204(STM32H750-ART-PI)/\345\274\240\344\270\200\346\231\250/\344\275\234\344\270\232/\347\254\254\344\270\211\345\244\251\344\275\234\344\270\232/event_demo.c" create mode 100644 "2025/\347\254\2541\347\273\204(STM32H750-ART-PI)/\345\274\240\344\270\200\346\231\250/\344\275\234\344\270\232/\347\254\254\344\270\211\345\244\251\344\275\234\344\270\232/mailbox_demo.c" create mode 100644 "2025/\347\254\2541\347\273\204(STM32H750-ART-PI)/\345\274\240\344\270\200\346\231\250/\344\275\234\344\270\232/\347\254\254\344\270\211\345\244\251\344\275\234\344\270\232/message_queue_demo.c" create mode 100644 "2025/\347\254\2541\347\273\204(STM32H750-ART-PI)/\345\274\240\344\270\200\346\231\250/\344\275\234\344\270\232/\347\254\254\344\270\211\345\244\251\344\275\234\344\270\232/mutex_demo.c" create mode 100644 "2025/\347\254\2541\347\273\204(STM32H750-ART-PI)/\345\274\240\344\270\200\346\231\250/\344\275\234\344\270\232/\347\254\254\344\270\211\345\244\251\344\275\234\344\270\232/semaphore_demo.c" create mode 100644 "2025/\347\254\2541\347\273\204(STM32H750-ART-PI)/\345\274\240\344\270\200\346\231\250/\344\275\234\344\270\232/\347\254\254\344\270\211\345\244\251\344\275\234\344\270\232/signal_demo.c" create mode 100644 "2025/\347\254\2541\347\273\204(STM32H750-ART-PI)/\345\274\240\344\270\200\346\231\250/\347\254\224\350\256\260/\347\254\254\344\270\211\345\244\251\347\254\224\350\256\260.md" diff --git "a/2025/\347\254\2541\347\273\204(STM32H750-ART-PI)/\345\274\240\344\270\200\346\231\250/\344\275\234\344\270\232/\347\254\254\344\270\211\345\244\251\344\275\234\344\270\232/event_demo.c" "b/2025/\347\254\2541\347\273\204(STM32H750-ART-PI)/\345\274\240\344\270\200\346\231\250/\344\275\234\344\270\232/\347\254\254\344\270\211\345\244\251\344\275\234\344\270\232/event_demo.c" new file mode 100644 index 0000000..e7fc8d4 --- /dev/null +++ "b/2025/\347\254\2541\347\273\204(STM32H750-ART-PI)/\345\274\240\344\270\200\346\231\250/\344\275\234\344\270\232/\347\254\254\344\270\211\345\244\251\344\275\234\344\270\232/event_demo.c" @@ -0,0 +1,53 @@ +#include + +#define EVENT_FLAG3 (1 << 3) +#define EVENT_FLAG5 (1 << 5) + +static struct rt_event event; + +static void event_thread1(void *parameter) +{ + rt_uint32_t e; + while (1) + { + if (rt_event_recv(&event, (EVENT_FLAG3 | EVENT_FLAG5), + RT_EVENT_FLAG_OR | RT_EVENT_FLAG_CLEAR, + RT_WAITING_FOREVER, &e) == RT_EOK) + { + rt_kprintf("thread1: OR event received 0x%x\n", e); + } + } +} + +static void event_thread2(void *parameter) +{ + while (1) + { + rt_event_send(&event, EVENT_FLAG3); + rt_kprintf("thread2 send event 0x%x\n", EVENT_FLAG3); + rt_thread_mdelay(200); + + rt_event_send(&event, EVENT_FLAG5); + rt_kprintf("thread2 send event 0x%x\n", EVENT_FLAG5); + rt_thread_mdelay(500); + } +} + +int event_demo(void) +{ + rt_event_init(&event, "event", RT_IPC_FLAG_FIFO); + + rt_thread_t thread1 = rt_thread_create("thread1", + event_thread1, RT_NULL, + 512, 25, 5); + rt_thread_t thread2 = rt_thread_create("thread2", + event_thread2, RT_NULL, + 512, 26, 5); + + if (thread1 != RT_NULL) rt_thread_startup(thread1); + if (thread2 != RT_NULL) rt_thread_startup(thread2); + + return 0; +} + +MSH_CMD_EXPORT(event_demo, event demo); \ No newline at end of file diff --git "a/2025/\347\254\2541\347\273\204(STM32H750-ART-PI)/\345\274\240\344\270\200\346\231\250/\344\275\234\344\270\232/\347\254\254\344\270\211\345\244\251\344\275\234\344\270\232/mailbox_demo.c" "b/2025/\347\254\2541\347\273\204(STM32H750-ART-PI)/\345\274\240\344\270\200\346\231\250/\344\275\234\344\270\232/\347\254\254\344\270\211\345\244\251\344\275\234\344\270\232/mailbox_demo.c" new file mode 100644 index 0000000..f9b1120 --- /dev/null +++ "b/2025/\347\254\2541\347\273\204(STM32H750-ART-PI)/\345\274\240\344\270\200\346\231\250/\344\275\234\344\270\232/\347\254\254\344\270\211\345\244\251\344\275\234\344\270\232/mailbox_demo.c" @@ -0,0 +1,52 @@ +#include + +#define THREAD_PRIORITY 25 +#define MB_ENTRY_SIZE sizeof(rt_uint32_t) +#define MB_SIZE 4 + +static struct rt_mailbox mb; + +static void mailbox_send_thread(void *parameter) +{ + rt_uint32_t value = 0; + while (1) + { + value++; + if (rt_mb_send(&mb, (rt_uint32_t)value) == RT_EOK) + { + rt_kprintf("thread1 send mailbox: %d\n", value); + } + rt_thread_mdelay(500); + } +} + +static void mailbox_recv_thread(void *parameter) +{ + rt_uint32_t value; + while (1) + { + if (rt_mb_recv(&mb, (rt_ubase_t *)&value, RT_WAITING_FOREVER) == RT_EOK) + { + rt_kprintf("thread2 recv mailbox: %d\n", value); + } + } +} + +int mailbox_demo(void) +{ + rt_mb_init(&mb, "mbt", &mb[0], MB_SIZE, RT_IPC_FLAG_FIFO); + + rt_thread_t thread1 = rt_thread_create("thread1", + mailbox_send_thread, RT_NULL, + 512, THREAD_PRIORITY, 5); + rt_thread_t thread2 = rt_thread_create("thread2", + mailbox_recv_thread, RT_NULL, + 512, THREAD_PRIORITY, 5); + + if (thread1 != RT_NULL) rt_thread_startup(thread1); + if (thread2 != RT_NULL) rt_thread_startup(thread2); + + return 0; +} + +MSH_CMD_EXPORT(mailbox_demo, mailbox demo); \ No newline at end of file diff --git "a/2025/\347\254\2541\347\273\204(STM32H750-ART-PI)/\345\274\240\344\270\200\346\231\250/\344\275\234\344\270\232/\347\254\254\344\270\211\345\244\251\344\275\234\344\270\232/message_queue_demo.c" "b/2025/\347\254\2541\347\273\204(STM32H750-ART-PI)/\345\274\240\344\270\200\346\231\250/\344\275\234\344\270\232/\347\254\254\344\270\211\345\244\251\344\275\234\344\270\232/message_queue_demo.c" new file mode 100644 index 0000000..d27a096 --- /dev/null +++ "b/2025/\347\254\2541\347\273\204(STM32H750-ART-PI)/\345\274\240\344\270\200\346\231\250/\344\275\234\344\270\232/\347\254\254\344\270\211\345\244\251\344\275\234\344\270\232/message_queue_demo.c" @@ -0,0 +1,63 @@ +#include + +#define THREAD_PRIORITY 25 +#define QUEUE_SIZE 5 +#define MSG_SIZE sizeof(struct msg) + +struct msg { + rt_uint8_t type; + rt_uint8_t data[20]; +}; + +static struct rt_messagequeue mq; + +static void mq_send_thread(void *parameter) +{ + struct msg buf; + buf.type = 0x01; + rt_memcpy(buf.data, "hello", 6); + + while (1) + { + if (rt_mq_send(&mq, &buf, MSG_SIZE) == RT_EOK) + { + rt_kprintf("thread1 send message: %s\n", buf.data); + } + rt_thread_mdelay(800); + } +} + +static void mq_recv_thread(void *parameter) +{ + struct msg buf; + while (1) + { + if (rt_mq_recv(&mq, &buf, MSG_SIZE, RT_WAITING_FOREVER) == RT_EOK) + { + rt_kprintf("thread2 recv message: type=%d data=%s\n", buf.type, buf.data); + } + } +} + +int message_queue_demo(void) +{ + rt_uint8_t msg_pool[QUEUE_SIZE * (MSG_SIZE + 4)]; + + rt_mq_init(&mq, "mqt", msg_pool, + MSG_SIZE, sizeof(msg_pool), + RT_IPC_FLAG_FIFO); + + rt_thread_t thread1 = rt_thread_create("thread1", + mq_send_thread, RT_NULL, + 512, THREAD_PRIORITY, 5); + rt_thread_t thread2 = rt_thread_create("thread2", + mq_recv_thread, RT_NULL, + 512, THREAD_PRIORITY, 5); + + if (thread1 != RT_NULL) rt_thread_startup(thread1); + if (thread2 != RT_NULL) rt_thread_startup(thread2); + + return 0; +} + +MSH_CMD_EXPORT(message_queue_demo, message queue demo); \ No newline at end of file diff --git "a/2025/\347\254\2541\347\273\204(STM32H750-ART-PI)/\345\274\240\344\270\200\346\231\250/\344\275\234\344\270\232/\347\254\254\344\270\211\345\244\251\344\275\234\344\270\232/mutex_demo.c" "b/2025/\347\254\2541\347\273\204(STM32H750-ART-PI)/\345\274\240\344\270\200\346\231\250/\344\275\234\344\270\232/\347\254\254\344\270\211\345\244\251\344\275\234\344\270\232/mutex_demo.c" new file mode 100644 index 0000000..9e9b69f --- /dev/null +++ "b/2025/\347\254\2541\347\273\204(STM32H750-ART-PI)/\345\274\240\344\270\200\346\231\250/\344\275\234\344\270\232/\347\254\254\344\270\211\345\244\251\344\275\234\344\270\232/mutex_demo.c" @@ -0,0 +1,50 @@ +#include + +static rt_mutex_t mutex; +static rt_uint32_t counter; + +static void mutex_thread1(void *parameter) +{ + while (1) + { + rt_mutex_take(mutex, RT_WAITING_FOREVER); + rt_kprintf("thread1: counter = %d\n", ++counter); + rt_mutex_release(mutex); + rt_thread_mdelay(10); + } +} + +static void mutex_thread2(void *parameter) +{ + while (1) + { + rt_mutex_take(mutex, RT_WAITING_FOREVER); + rt_kprintf("thread2: counter = %d\n", ++counter); + rt_mutex_release(mutex); + rt_thread_mdelay(10); + } +} + +int mutex_demo(void) +{ + mutex = rt_mutex_create("mtx", RT_IPC_FLAG_FIFO); + if (mutex == RT_NULL) + { + rt_kprintf("create mutex failed.\n"); + return -1; + } + + rt_thread_t thread1 = rt_thread_create("thread1", + mutex_thread1, RT_NULL, + 512, 25, 5); + rt_thread_t thread2 = rt_thread_create("thread2", + mutex_thread2, RT_NULL, + 512, 25, 5); + + if (thread1 != RT_NULL) rt_thread_startup(thread1); + if (thread2 != RT_NULL) rt_thread_startup(thread2); + + return 0; +} + +MSH_CMD_EXPORT(mutex_demo, mutex demo); \ No newline at end of file diff --git "a/2025/\347\254\2541\347\273\204(STM32H750-ART-PI)/\345\274\240\344\270\200\346\231\250/\344\275\234\344\270\232/\347\254\254\344\270\211\345\244\251\344\275\234\344\270\232/semaphore_demo.c" "b/2025/\347\254\2541\347\273\204(STM32H750-ART-PI)/\345\274\240\344\270\200\346\231\250/\344\275\234\344\270\232/\347\254\254\344\270\211\345\244\251\344\275\234\344\270\232/semaphore_demo.c" new file mode 100644 index 0000000..ea7adc0 --- /dev/null +++ "b/2025/\347\254\2541\347\273\204(STM32H750-ART-PI)/\345\274\240\344\270\200\346\231\250/\344\275\234\344\270\232/\347\254\254\344\270\211\345\244\251\344\275\234\344\270\232/semaphore_demo.c" @@ -0,0 +1,51 @@ +#include + +#define THREAD_PRIORITY 25 +#define THREAD_TIMESLICE 5 + +static rt_sem_t dynamic_sem; + +static void semaphore_thread1(void *parameter) +{ + while (1) + { + rt_kprintf("thread1 try to take semaphore...\n"); + rt_sem_take(dynamic_sem, RT_WAITING_FOREVER); + rt_kprintf("thread1 take semaphore!\n"); + rt_thread_mdelay(500); + } +} + +static void semaphore_thread2(void *parameter) +{ + while (1) + { + rt_kprintf("thread2 release semaphore!\n"); + rt_sem_release(dynamic_sem); + rt_thread_mdelay(1000); + } +} + +int semaphore_demo(void) +{ + dynamic_sem = rt_sem_create("dsem", 0, RT_IPC_FLAG_FIFO); + if (dynamic_sem == RT_NULL) + { + rt_kprintf("create semaphore failed.\n"); + return -1; + } + + rt_thread_t thread1 = rt_thread_create("thread1", + semaphore_thread1, RT_NULL, + 512, THREAD_PRIORITY, THREAD_TIMESLICE); + rt_thread_t thread2 = rt_thread_create("thread2", + semaphore_thread2, RT_NULL, + 512, THREAD_PRIORITY, THREAD_TIMESLICE); + + if (thread1 != RT_NULL) rt_thread_startup(thread1); + if (thread2 != RT_NULL) rt_thread_startup(thread2); + + return 0; +} + +MSH_CMD_EXPORT(semaphore_demo, semaphore demo); \ No newline at end of file diff --git "a/2025/\347\254\2541\347\273\204(STM32H750-ART-PI)/\345\274\240\344\270\200\346\231\250/\344\275\234\344\270\232/\347\254\254\344\270\211\345\244\251\344\275\234\344\270\232/signal_demo.c" "b/2025/\347\254\2541\347\273\204(STM32H750-ART-PI)/\345\274\240\344\270\200\346\231\250/\344\275\234\344\270\232/\347\254\254\344\270\211\345\244\251\344\275\234\344\270\232/signal_demo.c" new file mode 100644 index 0000000..5c61739 --- /dev/null +++ "b/2025/\347\254\2541\347\273\204(STM32H750-ART-PI)/\345\274\240\344\270\200\346\231\250/\344\275\234\344\270\232/\347\254\254\344\270\211\345\244\251\344\275\234\344\270\232/signal_demo.c" @@ -0,0 +1,49 @@ +#include + +static void signal_handler(int sig) +{ + rt_kprintf("Received signal %d\n", sig); +} + +static void signal_thread(void *parameter) +{ + rt_thread_t tid = rt_thread_self(); + rt_signal_install(SIGUSR1, signal_handler); + rt_signal_unmask(SIGUSR1); + + while (1) + { + rt_kprintf("thread1 wait signal...\n"); + rt_thread_mdelay(1000); + } +} + +static void trigger_thread(void *parameter) +{ + rt_thread_t tid = rt_thread_find("thread1"); + if (tid == RT_NULL) return; + + while (1) + { + rt_thread_mdelay(2000); + rt_kprintf("thread2 send signal\n"); + rt_thread_kill(tid, SIGUSR1); + } +} + +int signal_demo(void) +{ + rt_thread_t thread1 = rt_thread_create("thread1", + signal_thread, RT_NULL, + 512, 25, 5); + rt_thread_t thread2 = rt_thread_create("thread2", + trigger_thread, RT_NULL, + 512, 26, 5); + + if (thread1 != RT_NULL) rt_thread_startup(thread1); + if (thread2 != RT_NULL) rt_thread_startup(thread2); + + return 0; +} + +MSH_CMD_EXPORT(signal_demo, signal demo); \ No newline at end of file diff --git "a/2025/\347\254\2541\347\273\204(STM32H750-ART-PI)/\345\274\240\344\270\200\346\231\250/\347\254\224\350\256\260/\347\254\254\344\270\211\345\244\251\347\254\224\350\256\260.md" "b/2025/\347\254\2541\347\273\204(STM32H750-ART-PI)/\345\274\240\344\270\200\346\231\250/\347\254\224\350\256\260/\347\254\254\344\270\211\345\244\251\347\254\224\350\256\260.md" new file mode 100644 index 0000000..fc3b31b --- /dev/null +++ "b/2025/\347\254\2541\347\273\204(STM32H750-ART-PI)/\345\274\240\344\270\200\346\231\250/\347\254\224\350\256\260/\347\254\254\344\270\211\345\244\251\347\254\224\350\256\260.md" @@ -0,0 +1,98 @@ +# 2025 RT-Thread 夏令营第三天笔记 +## 一、线程间的同步 +### 1.1 信号量(Semaphore) +**概念**: +信号量是一种用于控制多个线程对共享资源访问的同步机制。它通常代表可用资源的数量,可以用于线程间的同步或资源管理。信号量有两种类型:二值信号量(只能取0或1)和计数信号量(非负整数)。 +**工作机制**: +- **创建**:初始化一个信号量时,会指定一个初始值(例如,初始资源数量)。 +- **获取(take)**:当一个线程需要访问共享资源时,它会尝试获取信号量。如果信号量的值大于0,则信号量减1,线程继续执行;如果信号量的值为0,则线程会被阻塞,直到信号量的值大于0(表示有资源可用)。 +- **释放(release)**:当线程使用完共享资源后,会释放信号量,信号量的值加1。如果有其他线程正在等待该信号量,则其中一个线程会被唤醒(取决于等待策略,如FIFO或优先级)。 +信号量常用于: +- 限制同时访问共享资源的线程数量(例如,限制同时访问一个硬件的线程数)。 +- 线程同步(例如,一个线程完成任务后通知另一个线程)。 + +**示例代码**:先打开*RT-Studio*,然后创建新的工程,然后在界面左侧栏选择*RT-Thread Settings*,然后在软件包的杂项软件包里选择*samples*然后打开*rt-thread*软件包内核实例,然后依次打开*semaphore*、*mutex*和*event*,然后还可以将注释更改为中文,然后*Ctrl+s*保存文件,然后编译,运行即可看到信号量是如何使用的了。 +### 1.2 互斥量(Mutex) +**概念**: +互斥量是一种特殊的二值信号量,用于实现互斥访问共享资源。与信号量不同,互斥量具有所有权概念,即只有获取互斥量的线程才能释放它。互斥量还支持优先级继承,以防止优先级反转问题。 +**工作机制**: +- **创建**:互斥量初始为可用状态(解锁状态)。 +- **获取(lock)**:线程尝试获取互斥量。如果互斥量当前未被占用,则线程成功获取互斥量(互斥量变为锁定状态),并成为互斥量的所有者。如果互斥量已被其他线程占用,则当前线程被阻塞,直到互斥量被释放。 +- **释放(unlock)**:只有拥有互斥量的线程才能释放它。释放后,互斥量变为解锁状态。如果有其他线程在等待该互斥量,则其中一个线程会被唤醒并获取互斥量。 +互斥量的特点: +- **所有权**:只有持有互斥量的线程才能释放它。 +- **优先级继承**:如果一个高优先级线程等待一个被低优先级线程占有的互斥量,则低优先级线程会暂时提升到高优先级,以防止中优先级线程抢占导致的高优先级线程被阻塞过久(即优先级反转问题)。 +互斥量用于保护共享资源,确保同一时间只有一个线程访问该资源。 + +**示例代码**:与信号量的相同。 +### 1.3 事件集(Event) +**概念**: +事件集是一种用于线程间同步的机制,允许一个线程等待多个事件的发生,并且可以等待多个事件的任意组合(如任意一个事件发生或所有事件发生)。每个事件由一个位表示(通常32位系统支持32个事件)。 +**工作机制**: +- **创建**:事件集被初始化为0(没有任何事件发生)。 +- **发送(send)**:线程可以设置事件集中的某些位(表示事件发生)。发送事件会唤醒正在等待这些事件的线程。 +- **接收(recv)**:线程可以等待事件集中的事件。在等待时,可以指定: + - 等待哪些事件(通过事件掩码)。 + - 等待条件:是等待所有指定事件(逻辑与)还是任意一个事件(逻辑或)。 + - 是否清除事件:在成功接收到事件后,是否清除事件标志(自动清零)。 + **示例代码**:与信号量的相同。 + ## 二、线程间的通信 + ### 2.1邮箱(Mailbox) +**概念**: +邮箱是一种用于线程间通信的机制,它允许线程发送一个固定大小的消息(通常是4字节,在32位系统上为一个指针或一个整数值)给另一个线程。邮箱中每个消息槽只能存放一条消息,当邮箱满时,发送线程可以选择等待或立即返回。 +**工作机制**: +1. **初始化**:创建一个邮箱,并指定邮箱容量(消息数量)和消息大小(RT-Thread中固定为4字节)。 +2. **发送消息**: + - 如果邮箱未满,消息被复制到邮箱的一个槽中,并唤醒等待接收的线程(如果有)。 + - 如果邮箱已满,发送线程可以选择挂起等待(阻塞)直到有空位,或者立即返回错误。 +3. **接收消息**: + - 如果邮箱中有消息,接收线程取出消息(复制到提供的缓冲区),并唤醒等待发送的线程(如果有)。 + - 如果邮箱为空,接收线程可以选择挂起等待(阻塞)直到有消息,或者立即返回错误。 +**关键特性**: +- 消息大小固定(通常为4字节,适合传递指针或整数)。 +- 可以传递一个指向更大数据块的指针,但需要确保数据在接收线程访问时仍然有效(通常需要动态分配内存,并约定释放责任)。 +- 支持超时机制。 +**典型应用**: +- 传递简单的整数值或状态标志。 +- 传递指针,指向动态分配的数据结构(需注意内存管理)。 +- 轻量级的事件通知。 +### 2.2消息队列(Message Queue) +**概念**: +消息队列是邮箱的扩展,允许发送不定长的消息(但每条消息有最大长度限制)。消息队列在内部维护一个消息缓冲区,每个消息由消息头和消息内容组成。发送时消息被复制到队列缓冲区,接收时再从缓冲区复制出来。 +**工作机制**: +1. **初始化**:创建消息队列时,需要指定队列中消息的最大数量、每条消息的最大长度,并分配相应的存储空间(通常是一个连续的内存块)。 +2. **发送消息**: + - 如果队列中有足够的空间存放新消息,则消息被复制到队列的缓冲区中,并唤醒等待接收的线程。 + - 如果队列空间不足,发送线程可以选择挂起等待(阻塞)直到有空间,或者立即返回错误。 +3. **接收消息**: + - 如果队列中有消息,接收线程将消息从队列缓冲区复制到用户提供的缓冲区(需要足够大),并唤醒等待发送的线程(如果有空间释放)。 + - 如果队列为空,接收线程可以选择挂起等待(阻塞)直到有消息,或者立即返回错误。 +**关键特性**: +- 支持可变长度消息(每条消息长度在初始化时设定的最大值内)。 +- 消息在传递过程中被复制,发送方和接收方操作的是不同的内存副本(避免了共享内存的同步问题)。 +- 支持超时机制。 +- 比邮箱更灵活,但开销也更大。 +**典型应用**: +- 传递长度可变的数据(如字符串、结构体等)。 +- 需要传递较大数据块的场景(通过传递指针,但需要注意内存管理)。 +- 多线程之间传递复杂消息。 +### 2.3信号(Signal) +**概念**: +信号是一种异步通信机制,类似于操作系统中的软中断。一个线程可以给另一个线程(或自身)发送信号,接收线程在收到信号后,将中断当前执行流程,转而去执行预先注册的信号处理函数。处理完成后,线程再返回到被中断的地方继续执行。 +**工作机制**: +1. **安装信号处理函数**:线程通过`rt_signal_install()`为特定信号注册处理函数。 +2. **阻塞/解除阻塞信号**:线程可以屏蔽某些信号(`rt_signal_mask()`)或解除屏蔽(`rt_signal_unmask()`)。 +3. **发送信号**:线程通过`rt_thread_kill()`(注意:函数名类似Unix的kill,但只是发送信号)向目标线程发送信号。 +4. **信号处理**: + - 当目标线程被调度运行时,如果收到信号且该信号未被屏蔽,则调用相应的处理函数。 + - 信号处理函数在目标线程的上下文中执行(类似于中断,但属于线程上下文)。 + - 信号处理函数应尽量简短,避免调用可能引起阻塞的函数。 +**关键特性**: +- 异步通知:信号可以在任何时候发送给目标线程。 +- 处理函数执行在目标线程的上下文:因此会中断目标线程的正常执行流程。 +- 支持标准信号(如SIGINT, SIGUSR1等),也可以自定义信号。 +- 线程可以屏蔽信号(暂时不处理)或解除屏蔽。 +**典型应用**: +- 中断线程的正常流程以处理异常情况。 +- 自定义事件通知(如超时提醒、外部事件等)。 +- 实现类似Unix风格的信号处理(如Ctrl+C中断)。 \ No newline at end of file -- Gitee