UCOS-III 系统启动接口OSStart详解

uc/os中OSStart()函数分析 <br />OSStart()函数分析<br />多任务的的启动是通过调用OSStart()实现的,而在启动uc/os之前至少需要建立一个应用任务。<br />OSStart()函数源码<br />void  OSStart (void)<br />{<br />    INT8U y;<br />    INT8U x;<br />    if (OSRunning == FALSE) {//参数检验,多任务尚未启动<br />        y             = OSUnMapTbl[OSRd 阅读详情

        在实时操作系统 uC/OS-III 中,OSStart 函数是启动多任务处理的关键步骤。它让 uC/OS-III 管理已经创建的任务。在调用 OSStart 之前,必须先调用 OSInit 并至少创建一个应用任务。本文将详细解析 OSStart 函数的工作原理。

1. OSStart 函数概述

OSStart 函数主要完成以下任务:

  1. 检查操作系统是否已初始化
  2. 计算内核任务的数量
  3. 检查是否有应用任务已创建
  4. 设置最高优先级任务
  5. 启动最高优先级任务
  6. 错误处理

2. OSStart 函数流程图

345fce7de16c4375b61f40673d3de61a.png

3. OSStart 函数详细解析

3.1 检查操作系统是否已初始化

在 OSStart 函数中,首先检查操作系统是否已初始化。如果操作系统未初始化,则返回错误。

if (OSInitialized != OS_TRUE) {
    *p_err = OS_ERR_OS_NOT_INIT;
    return;
}

3.2  计算内核任务的数量并检查是否有应用任务已创建

计算内核任务(如统计任务、定时器任务和空闲任务)的数量,并检查是否有应用任务创建

kernel_task_cnt = 0u;
#if (OS_CFG_STAT_TASK_EN > 0u)
    kernel_task_cnt++;
#endif
#if (OS_CFG_TMR_EN > 0u)
    kernel_task_cnt++;
#endif
#if (OS_CFG_TASK_IDLE_EN > 0u)
    kernel_task_cnt++;
#endif
if (OSTaskQty <= kernel_task_cnt) {
    *p_err = OS_ERR_OS_NO_APP_TASK;
    return;
}

3.3. 设置最高优先级任务

设置当前最高优先级任务

if (OSRunning == OS_STATE_OS_STOPPED) {
    OSPrioHighRdy   = OS_PrioGetHighest();
    OSPrioCur       = OSPrioHighRdy;
    OSTCBHighRdyPtr = OSRdyList[OSPrioHighRdy].HeadPtr;
    OSTCBCurPtr     = OSTCBHighRdyPtr;
    OSRunning       = OS_STATE_OS_RUNNING;
}


3.4  调用OSStartHighRdy启动就绪任务

OSStartHighRdy();  /* Execute target specific code to start task */
*p_err = OS_ERR_FATAL_RETURN;

4. 如何启动第一个就绪任务

 调用OSStartHighRdy 启动第一个就绪任务。该函数的主要作用是触发一个 PendSV 异常,从而引发上下文切换,开始执行第一个任务。函数的主要步骤包括设置 PendSV 异常优先级、初始化堆栈指针、获取当前高优先级任务、恢复任务上下文等

4.1 OSStartHighRdy 流程图

20503da15aee40a790996c53a21ddff4.png

4.2 详细解析

4.2.1 禁止中断

通过禁止中断(CPSID I 指令),防止在上下文切换期间发生中断

CPSID   I

4.2.2 设置 PendSV 异常优先级

设置 PendSV 异常优先级为最低优先级,确保任务切换不会中断其他更高优先级的中断服务程序

MOV32   R0, NVIC_SYSPRI14
MOV32   R1, NVIC_PENDSV_PRI
STRB    R1, [R0]

4.2.3  初始化 PSP 

将 PSP(进程堆栈指针)设置为 0,用于初始上下文切换调用

MOVS    R0, #0
MSR     PSP, R0

4.2.4  初始化 MSP

将 MSP(主堆栈指针/中断堆栈指针)初始化为 OS_CPU_ExceptStkBase

MOV32   R0, OS_CPU_ExceptStkBase
LDR     R1, [R0]
MSR     MSP, R1

4.2.5 调用 OSTaskSwHook

调用 OSTaskSwHook 函数,用于执行其他操作

BL      OSTaskSwHook

4.2.6 设置当前优先级

设置当前优先级(OSPrioCur)为最高优先级(OSPrioHighRdy)

MOV32   R0, OSPrioCur
MOV32   R1, OSPrioHighRdy
LDRB    R2, [R1]
STRB    R2, [R0]

4.2.7 设置当前任务控制块指针

设置当前任务控制块指针(OSTCBCurPtr)为最高优先级任务控制块指针(OSTCBHighRdyPtr)

MOV32   R0, OSTCBCurPtr
MOV32   R1, OSTCBHighRdyPtr
LDR     R2, [R1]
STR     R2, [R0]

4.2.8 加载 PSP

从最高优先级任务控制块指针(OSTCBHighRdyPtr)中加载新的进程堆栈指针(PSP)

LDR     R0, [R2]
MSR     PSP, R0

4.2.9 更新 CONTROL 寄存器

更新 CONTROL 寄存器,确保使用 PSP 作为堆栈指针并禁用浮点协处理器。

MRS     R0, CONTROL
ORR     R0, R0, #2
BIC     R0, R0, #4
MSR     CONTROL, R0
ISB

4.2.10 恢复任务上下文

从堆栈中恢复任务的寄存器上下文,使能中断,并跳转到任务的程序计数器

LDMFD    SP!, {R4-R11, LR}
LDMFD    SP!, {R0-R3}
LDMFD    SP!, {R12, LR}
LDMFD    SP!, {R1, R2}
CPSIE    I
BX       R1

5. 为什么设置PendSV异常优先级为最低优先级

       PendSV通常用于实现上下文切换,即从一个任务切换到另一个任务。以下是设置 PendSV 异常优先级为最低优先级的几个原因:

5.1. 确保任务切换在所有其他中断处理之后进行

        PendSV 的主要用途是触发任务切换。通过将 PendSV 的优先级设置为最低,可以确保它在所有其他中断处理完成之后才被执行。以确保系统中更高优先级的中断能够及时处理,不会被任务切换延迟。

5.2. 避免中断嵌套

        如果 PendSV 异常的优先级高于某些中断,那么在这些中断处理过程中可能会发生任务切换,从而导致中断嵌套和处理复杂性增加。将 PendSV 的优先级设置为最低,可以避免这种情况,确保任务切换在所有中断处理完成后进行,简化了中断处理逻辑。

5.3. 优化系统实时性

        系统的实时性要求某些关键中断必须尽快得到响应。通过将 PendSV 的优先级设置为最低,可以确保这些关键中断优先得到处理,从而提高系统的实时性。

5.4. 避免中断响应时间过长

        在嵌入式系统中,某些中断(如定时器中断、外部事件中断等)的响应时间非常关键。如果 PendSV 的优先级高于这些中断,那么在处理任务切换时可能会延迟这些中断的响应,导致系统性能下降或数据丢失。将 PendSV 的优先级设置为最低,可以避免这种情况,确保关键中断得到及时响应。

 

[uC/OS-III] 18. uC/OS-III 的启动流程 在目前的 RTOS 中,主要有两种比较流行的启动方式:1. 万事俱备,只欠东风 在 main 函数中将硬件初始化,RTOS 系统初始化,所有任务的创建这些都弄好,这个我称之为万事都已经准备好。最后只欠一道东风,即启动 RTOS 的调度器,开始多任务的调度。 2. 小心翼翼,十分谨慎 在 main 函数中将硬件和 RTOS 系统先初始化好,然后创建一个启动任务后就启动调度器,然后在启动任务里面创建各种应用任务,当所有任务都创建成功后,启动任务把自己删除。 3. 系统的启动 在系统上电的时候第一个执. 阅读详情

相关推荐

UCOSII实时操作系统启动原理和理解

1,ucos系统的任务表示: 需要在里面添加中断的代码的,以便于它能跳转到其他的任务中执行,切换任务的时候,判断优先级进行任务之间的切换的工作。 void task1(void * param) 当调用 OSStart()时,OSStart()从任务就绪表中找出那个用户建立的优先级最高任务的任务控制块。Start()调用高优先级就绪任务启动函数 OSStartHighRdy()[(2)],这个文件与选择的微处理器有关。函数 OSStartHighRdy()是将任务栈中保存的值弹回到CPU 寄存器中,然后执行

wangjie36的博客 2457

OSStartHighRdy()

µC/OS-II 的移植需要用户改写OS_CPU_A.ASM中的四个函数: OSStartHighRdy() OSCtxSw() OSIntCtxSw() OSTickISR()该函数由SStart()函数调用,功能是运行优先级最高的就绪任务,在调用OSStart()之前,用户必须先调用OSInit(),并且已经至少创建了一个任务(请参考OSTaskCreate()和OSTaskCreateExt

FunkyFrog821951259的博客 6777

uC/OS-Il的初始化函数---OSStart()

【代码】uC/OS-Il的初始化函数---OSStart()。

weixin_45880844的博客 209

OSStart()函数简介

多任务的的启动是通过调用OSStart()实现的,而在启动uc/os之前至少需要建立一个应用任务。 OSStart()函数源码 void  OSStart (void) {     INT8U y;     INT8U x;     if (OSRunning ==

圈圈教你玩叉叉 3383

UCOSIII 3.04源码深度解析:从任务调度到移植实战

实时操作系统(RTOS)是嵌入式开发的核心组件,它通过任务调度、同步与通信机制,为多任务应用提供确定性的响应能力。其原理基于优先级抢占式调度算法,确保高优先级任务能及时获得CPU控制权,这对于工业控制、汽车电子等对实时性要求高的场景至关重要。UCOSIII作为一款经典RTOS,其源码是理解这些机制的最佳范本。本文聚焦任务控制块(TCB)、上下文切换等热词,深入剖析其就绪列表、位图算法及PendSV异常处理等核心实现,并详解如何移植到Cortex-M内核,为开发者裁剪优化、构建稳定高效的嵌入式系统提供实践指导

weixin_34067102的博客 398

GD32F303C移植UCOSIII实时操作系统实战指南

实时操作系统(RTOS)是现代嵌入式开发的核心技术,通过任务调度、同步与通信机制,有效解决多任务并发下的实时性与资源管理难题。Cortex-M4内核的GD32F303C微控制器凭借120MHz主频与FPU浮点运算能力,成为运行RTOS的高性价比选择。µC/OS-III作为抢占式实时内核,支持多任务、信号量、互斥量与消息队列,广泛应用于工业控制、仪器仪表等需要确定性响应的场景。本文从RTOS基础概念与调度原理出发,梳理将µC/OS-III移植至GD32F303C的关键流程,涵盖SysTick与PendSV配置

weixin_34232744的博客 342

UCOS-III学习(一)——创建任务

创建任务 1、定义任务栈 在UCOS中,每个任务都是独立的,它们的运行环境都单独的保存在各个栈空间,任务使用的栈和任务控制块都使用的是静态变量,也就是全局变量。 #define APP_STK_SIZE 128 static CPU_STK APPTaskStartStk[APP_STK_SIZE]; 2、定义任务控制块 任务控制块就是一个结构体,其中的成员共同描述了任务的全部信息。 static OS_TCB APPTaskTCB; 3、定义任务主体函数 任务实际上就是一个无限循环且不带返回值的C

weixin_43795667的博客 1377

TCGA之GDC-client工具下载安装与使用

文章主要是对GDC-client工具下载TCGA数据库数据整个过程的一个记录 1.下载GDC-client工具 GDC-client工具网址:GDC Data Transfer Tool | NCI Genomic Data Commons (cancer.gov) 我这里下的是上图中红圈中的版本, 2.解压安装 从网上了解的是不能解压到带中文的路径里,解压后是一个.exe文件,为了能直接在cmd命令行下使用,将其加入系统环境: 点击新建之后,输入将文件解压到的路径,然后...

better_strong的博客 1万+

STM32平台UCOS-III移植实战:从工程搭建到问题排查

实时操作系统(RTOS)是嵌入式开发中的重要基石,它通过任务调度、中断管理和时间管理机制,让复杂系统高效稳定运行。其中,UCOS-III作为一款经典内核,以其源码清晰、可裁剪性强而广泛用于物联网设备、工业控制器等领域。但将UCOS-III从官方代码适配到具体芯片(如STM32)并非仅仅编译通过那么简单,需要理解上下文切换、临界区保护、SysTick时基、PendSV异常等底层原理。只有把握这些核心概念,才能从裸机思维平滑过渡到多任务开发,并应对启动即HardFault、任务不调度等实际陷阱。本文以STM32

weixin_33907511的博客 399

中科蓝讯AB536X/AB892X芯片开发避坑指南:Downloader配置中那些容易忽略的细节

本文详细解析中科蓝讯AB536X/AB892X芯片开发中Downloader配置的关键细节,包括软开关机实现、触摸灵敏度调试、量产校频等常见问题。特别针对无PR口芯片的替代方案、触摸参数优化、校频流程等易忽略环节提供实用解决方案,帮助开发者规避量产风险,提升开发效率。

weixin_30687051的博客 476

《阵列信号处理及MATLAB实现》阵列响应矩阵(均匀线阵、均匀圆阵、L型阵列、平面阵列和任意阵列)

《阵列信号处理及MATLAB实现》内容总结,如需阅读更详细内容请购买正版书籍。

APPLECHARLOTTE的博客 1万+

UCOS-III学习(二)——ucos-iii的启动流程

1、系统的启动 系统上电第一个运行的是启动文件中的复位函数Reset_Handler()函数,函数最后调用main()函数,程序正式启动。 2、系统初始化 调用创建任务函数前需对系统进行一次初始化,如空闲任务,时钟节拍任务的初始化可通过配置宏定义进行。 3、CPU初始化 CPU初始化很重要就是初始化时间戳,其精度为1ns。 4、SysTick初始化 时钟节拍的频率为1s产生多少个Tick,tick为操作系统节拍数的时钟周期。需在“os_cfg_app.h”中设定节拍频率,一般采用1000HZ,也就是时钟节拍

weixin_43795667的博客 909

从网格剖分到结果外推:一文拆解HFSS快速扫频(Fast Sweep)的底层逻辑与性能调优

本文深入解析了HFSS快速扫频(Fast Sweep)技术的底层逻辑与性能调优方法。通过ALPS算法实现频带外推,快速扫频相比离散扫频和插值扫频能提升3-5倍计算效率,特别适用于天线阵列、微波滤波器等宽频带分析场景。文章详细介绍了算法架构、参数优化策略及工程实践中的精度保障机制,帮助工程师高效完成电磁仿真。

weixin_28693447的博客 93

(学习日记)2024.03.25:UCOSIII第二十二节:系统启动流程详解

三十六、UCOSIII:系统启动流程详解 1、运行启动文件 2、主流程 main 3、系统初始化函数OSInit() 1. 空闲任务的初始化 2. 空闲任务的定义 3. 时钟节拍任务的初始化 4、启动任务AppTaskStart() 1. 时间戳初始化 2. SysTick初始化 3. 内存初始化 5、任务调度器启动函数OSStart()

一个放笔记的小书架 1420

STM32F103循迹小车PID调参实战:手把手教你整定舵机PD与电机PI参数

本文详细介绍了基于STM32F103的循迹小车PID调参实战,重点讲解舵机PD控制与电机PI参数的整定技巧。通过硬件选型、基础测试、四步调参法和分段控制策略,帮助开发者解决小车蛇形走位等问题,提升循迹性能。文章还分享了高级调试技巧和典型问题排查方法,适用于智能车竞赛和机器人开发。

weixin_42524226的博客 361

深度学习基于Resnet18的图像多分类--训练自己的数据集(超详细 含源码)

深度学习基于Resnet18的图像多分类--训练自己的数据集(超详细 含源码)

她是不会无条件的!! 2万+

[uC/OS-III] 17.创建任务

上章基于STM32板子创建好了uC/OS-III工程模板,这章开始真正进入如何使用uCOS的征程。 1.硬件初始化 要将 LED 相关的函数初始化好,为了方便以后统一管理板级外设的初始化,我们在 bsp.c 文件中创建一个 BSP_Init()函数,专门用于存放板级外设初始化函数。其中运行顺序如下——首先运行BSP_Init ()函数, 接下来才慢慢启动操作系统uC/OS-III, 最后运行创建好的任务。 2.创建单任务 定义任务栈: 在 uCOS 系统中,每一个任务都是独立的,他们的运行环境都单独

weixin_44386138的博客 548

Ribo-seq数据解析:从翻译效率计算到动态可视化分析

本文系统介绍了Ribo-seq(核糖体印迹测序)数据分析全流程,从核心的P-site定位、翻译效率计算,到差异翻译分析和动态可视化。重点阐述了如何利用Ribo-seq高分辨率数据揭示基因表达在翻译层面的精细调控,并提供了从数据处理到生物学解读的实用工具与避坑指南。

weixin_28559803的博客 422

uCOS-III启动与初始化

使用UCOSIII的步骤: 第一步:使用OSInit()初始化UCOSIII; 第二步:创建一个Start_task()任务; 第三步:调用oSStart()函数开启UCOSIII。 注意:我们在调用OSStart()开启UCOSIII之前一定要至少创建一个任务,其实我们在调用OSInit()函数初始化UCOSI的时候已经创建了一个空闲任务。

u014139867的博客 606

基于本机知识库 + 豆包(火山引擎)+ MCP的落地方案

最小 MVP:本地知识库 + Doubao Embedding + 简单检索。工具化:把检索/写入/系统功能通过 MCP 封装。Agent 编排:RAG 流程 + 自检 + 引用输出。这样你就可以快速落地一个基于豆包 + 本机知识库的 MCP Agent。

lpfasd123的博客 1096

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

【17】从0到1教你写uC/OS-III————>支持多优先级

简述: 本章之前OS还没有用到优先级,只支持两个任务相互切换; 本章之后加入优先级功能,在uC/OS-III中,数字优先级越小,逻辑优先级越高; 修改之前如下几个函数: OSInit(); 任务控制块TCB; 任务创建OSTaskCreate(); 空闲函数OS_Idle_TaskInit(); 系统启动函数OSStart(); 任务切换PendSV_H...

Dream Catcher 414

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

RTOS学习之旅(二)(ucosIII OS初始化 任务切换)

之前学习了任务的创建和TCB模块,在这之前还有就是系统是初始化。 1.OS系统初始化 OS 系统初始化一般是在硬件初始化完成之后来做的,主要做的工作就是初始化uC/OS-III 中定义的全局变量。OSInit()函数在文件 os_core.c。 void OSInit(OS_ERR *p_err) { /*系统用一个全局变量 OSRunning 来指示系统的运行状态,刚开 始默认STOPPED...

weixin_36101480的博客 583

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

UCOS-II代码OSStart()函数分析

第一次开始多任务调度,最高优先级任务运行,即当前优先级和最高优先级一样。第一次启动,最高优先级任务运行,即当前TCB和最高优先级TCB一样。通过上面两行代码将当前最高优先级的任务的优先级存放在。然后通过此变量从存放任务控制块指针的数组。中获得该任务的任务控制块指针,并存放在指针变量。参数检验,多任务尚未启动。8位无符号整数x,y。

weixin_51659166的博客 362

stm32 ucos/ii移植,程序执行到OSStart()内部的OSStartHighRdy()语句时跑飞问题解决方法之一

@[TOC](stm32 ucos/ii移植,程序执行到OSStart()内部的OSStartHighRdy()语句时跑飞问题解决办法之一) 网络上的一些解决办法: stm32程序遇到OSStartHang的问题解决方法总结 但并不适合我遇到的情况。 我的情况是已经能够正确的运行程序切换,然后增加一了个任务,并在任务中实现信号量的请求。同时在原有任务中增加信号量的发布,用来验证信号量功能。 增加信号量请求功能后,程序就不再正常,用调试方式单步运行时,程序总是崩溃在OSStartHighRdy汇编语言处,

gsm197851的博客 2335

Small RTOS OSStart 函数解析 以及 内存堆栈 变化 (一)

Small RTOS 是在 Keil C51 上面 编译的。 看如下代码: #include &amp;amp;amp;amp;quot;config.h&amp;amp;amp;amp;quot; void main(void) { TMOD = (TMOD &amp;amp;amp;amp;amp;amp; 0XF0) | 0X01; TL0 = 0x0; TH0 = 0x0; TR0 = 1; ET0 = 1; OSStart();

abc 1031

STM32 进入HardFault_Handler调试定位问题方法 + 定位到ucos的 OSStartHighRdy()的处理方法

调试STM32+ucosII的程序,程序老是进入HardFault_Handler。定位问题方法如下: 进入调试界面,在HardFault_Handler中断处理的while(1)处打断点,等待程序出错。 然后打开register窗口 注意红框中的数值,将MSP中的数值在Memory窗口中搜索。在栈中找到程序在进入HardFault_Handler中断处理函数前的入栈地址。 红框内就是出错程序...

难波儿万的博客 3310
上一篇: UCOS-III 任务调度接口(OSSched)详解
下一篇: UCOSIII 时间片轮调度接口OS_SchedRoundRobin详解
TechIot@tpzw
博客等级 码龄14年 1123粉丝 48原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

TechIot@tpzw

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值