uCOS任务信号量相关函数代码理解

2023-05-16

强调任务信号量思想:① 任务信号量只是一个标志,获取成功就是指把信号量计数值减1;释放就是指把信号量计数值加1(溢出则计数值不变)。② 获取信号量需要判断信号量是否可用(大于0),如果可用,表明一定会获取成功(大于0的数可以进行减1还是>=0),那么就可以获取当前时间戳与之前最新一次释放时间戳作差,作为此次等待信号量的时间(保存在TCB中的元素SemPendTime中)。③ 在释放函数中,因为释放不用考虑任务信号量是否可用,释放就是增加信号量可用数的操作,所以如果在一系列安全、参数检查检查正常后,就表示可以释放了,此时就可以获取当前时间戳作为此次释放任务信号量的时间戳(保存在TCB中的TS元素中)。

TCB中与任务信号量相关的元素

{

CPU_TS  SemPendTime; 任务等待自身任务信号量的等待时间。

CPU_TS  SemPendTimeMax; 任务多次等待任务信号量的最久一次的等待时间。

OS_SEM_CTR  SemCtr; 任务信号量计数值。

CPU_TS  TS; 任务信号量发布/释放时的时间戳。

CPU_INT08U  SemID; 第三方调试器和跟踪程序的唯一ID。

}

OSTaskSemPend:任务信号量获取函数

{

函数思想:任务信号量获取,是获取任务自身的信号量。如果自身信号量个数大于0(可用),就获取成功;否则,需要判断是否阻塞,从而判断是否等待任务信号量。

4个入口参数:超时时间;选项;返回的时间戳(任务信号量最新释放时的时间戳);返回的错误类型。

返回:任务信号量计数值

函数过程:① 首先进行安全、参数、选项等检查,不允许在中断中被调用;选项包括OS_OPT_PEND_BLOCKING和OS_OPT_PEND_NON_BLOCKING。② 如果任务自身信号量计数值(OSTCBCurPtr->SemCtr)大于0,表明任务信号量可用,可以获取信号量,任务信号量个数减1;获取任务信号量最新一次释放时的时间戳(OSTCBCurPtr->TS),和当前时间戳作差,就是最近一次等待任务信号量的时间;并与OSTCBCurPtr->SemPendTimeMax做比较,更新SemPendTimeMax的值。③ 如果任务信号量不可用,需要进入阻塞以等待信号量释放。如果用户选择OS_OPT_PEND_NON_BLOCKING,不等待阻塞,那么就返回需要等待阻塞的错误类型,把那个返回信号量计数值为0。④ 如果信号量不可用,但选择了进入阻塞。那么首先判断调度器是否被锁,因为调度器被锁,任务得不到调度,自然不能改变任务的状态。如果没有锁调度器,那么调用OS_CRITICAL_ENTER_CPU_EXIT()锁住调度器,因为接下来是对该任务进行阻塞操作,操作的是TCB,是全局变量,作为临界段资源,需要被保护。调用OS_Pend()对该任务进行阻塞。注意:这里任务信号量并不是内核对象,所以函数入口参数为(OS_PEND_DATA *)0和(OS_PEND_OBJ  *)0。因为任务信号量没有等待列表,所以阻塞仅仅是调用OS_TaskBlock()将任务移出就绪列表和插入时基列表(如果超时时间不为0)。然后调用OSSched()进行任务切换。⑤ 进行到这一步,意味着超时结束、被中止,或者有任务释放了该任务信号量,任务信号量可用,任务等到了该任务信号量。这么多种情况都是跟任务状态有关,所以根据任务状态switch-case。如果是OS_STATUS_PEND_OK表示正常等到了任务信号量,进行步骤②的操作,更新TCB中等待任务信号量的与时间相关的元素SemPendTime和SemPendTimeMax。如果是OS_STATUS_PEND_ABORT,表示等待被中止,返回任务信号量最近一次释放时的时间戳和相应的错误类型。如果是在超时时间中没等到信号量OS_STATUS_PEND_TIMEOUT,也是返回任务信号量最近一次释放时的时间戳和相应的错误类型。⑥ 最后返回任务信号量当前计数值。

}

OSTaskSemPost:任务信号量释放函数

{

虽然任务只能等待任务自身的任务信号量,但是其他所有的任务或者中断都可以向该任务释放信号量。

参数不同:任务信号量释放函数的入口参数个数同内核信号量的一样,也是3个。只不过任务信号量针对任务,所以第一个参数是指向目标任务的TCB指针,而内核信号量时指向创建的信号量的指针。

返回:返回任务信号量个数。如果从ISR调用,则为0;如果溢出,也返回0;另外参数非法之类的也返回0。所以如果当真在实现功能时,进行了复杂操作,出现返回0的情况;或者操作不当返回0,需要通过返回的错误类型(p_err)判断是哪种情况。

过程:除参数有些不同,过程与内核信号量都差不多。① 首先获取当前时间戳作为最新一次释放任务信号量的时间戳,该时间戳会在后面p_tcb->TS = ts; 赋值给任务TCB中用来记录释放任务信号量时间戳元素TS。(因为任务信号量只是一个计数标志,只要调用任务信号量释放函数,在一系列安全、参数检查都正常的情况,该任务信号量必然被释放,任务信号量计数值要么正常加1,要么就不变,因为加1就溢出了。所以在检查正常之后即是获取当前时间戳的代码,并把它作为该任务信号量最新一次释放的时间戳)。② 如果使能了中断延迟发布,且在中断中调用该函数,则调用OS_IntQPost()将任务信号量发布到中断消息队列。③ 如果是在任务中发送,调用函数OS_TaskSemPost()。

--调用OS_TaskSemPost()

{

过程:因为任务信号量是针对的任务,每个任务中只定义了一个32位变量对任务信号量进行计数,并不存在内核信号量结构体中的等待列表。任务阻塞并不进入等待列表。我们释放任务信号量,是通过任务信号量指向的目标任务的状态判断任务是否在等待该任务信号量。释放任务信号量后,任务信号量可用,其他操作都相似:如果任务在阻塞,就将任务解除阻塞,任务得到该信号量。如果没有任务在等待,就将任务信号量计数值加1。

① 如果参数目标TCB指针为空,就让目标TCB指向当前TCB,释放当前任务的任务信号量。② 如果任务状态没有等待态(pend),说明目标任务暂时不需要获取任务信号量,或者可用任务信号量足够,目标任务已经获取了,无须等待;没有等待该任务信号量的任务,那么就通过sizeof(OS_SEM_CTR),判断任务信号量是否会溢出,溢出就返回错误类型“OS_ERR_SEM_OVF”,并返回任务信号量计数值为0;否则任务信号量计数值加1。③ 如果任务状态有等待状态,并且任务是在等待任务信号量,调用OS_Post()将该任务信号量发送给等待的任务,该函数会把任务插入就绪列表,既然就绪列表中任务个数有改变,那么紧接着就调用判断是否opt选择了OS_OPT_POST_NO_SCHED,从而判断是否调用OSSched()。④ 如果任务处于等待状态,但是不是等待任务信号量,那么进行步骤②的操作。⑤ 最后返回当前任务信号量计数值。

}

}

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

uCOS任务信号量相关函数代码理解 的相关文章

  • 我发现ucos里面也是任务,任务控制块,消息队列,信号量,事件 。这些概念感觉和freertos一模一样啊

    我发现ucos里面也是任务 xff0c 任务控制块 xff0c 消息队列 xff0c 信号量 xff0c 事件 这些概念感觉和freertos一模一样啊 xff0c 感觉大家就是抄来抄去 xff1f 应该这些操作系统原理都差不多 xff0c
  • UCOS的事件有:信号量,消息邮箱,消息队列,信号量集

  • UCOS-III

    一 UCOSIII 简介 UCOSIII 是一个可裁剪 可固化 可剥夺 的多任务系统 xff0c 没有任务数目的限制 xff0c 是 UCOS 的第三代内核 xff0c UCOSIII 有以下几个重要的特性 xff1a 可剥夺多任务管理 x
  • UCOSⅢ简介

    UCOS 简介 简述一 裸机系统与多任务系统二 UCOS 的重要特性三 UCOS 的组成 简述 UCOS xff08 UCOS的第三代内核 xff09 是一个可裁剪 可固化 可剥夺的多任务系统 xff0c 具有高度可移植性 xff0c 没有
  • uCOS上下文切换,PendSV中断函数

    摘自 xff1a http www stmcu org module forum thread 384142 1 1 html 介绍一 xff1a 移植详解1和2中主要讲了移植需要用到的基础知识 xff0c 本文则对具体的移植过程进行介绍
  • 白话----之UCOS 信号量和邮箱

    总体理解 xff1a 两个任务需要共同访问一个共同的资源 xff0c 来切换或跳到不同的动作执行 这就产生信号量 两个任务 需要根据不同的按键选择 xff0c 来执行不同的动作 xff0c 产生邮箱 信号量和邮箱 我通过一个例子来学习的 希
  • 推荐ucos-II 3本参考书 经典

    在这里给大家推荐三本学习ucos的必看书籍 1 xff08 比较难买 xff09 嵌入式实时操作系统uc os II教程 西安电子科技大学出版 这本书对UCOS的源代码分析的非常清楚 比作者原著 在某种程度上要好 xff0c 这本书对关键的
  • uCOS-II任务间通信之信号量 [转载]

    uCOS II任务间通信之信号量 信号量是什么 xff1f 信号量有什么用 xff1f 信号量是可以用来表示一个或多个事件的发生 xff0c 还可以用来对共享资源的访问 uCOS II提供了5个对信号量进行操作的函数 如下所示 xff1a
  • STM32之RTOS:uCOS和FreeRTOS

    RTOS全称是 Real Time Operating System xff0c 中文就是实时操作系统 RTOS是指一类系统 xff0c 如 uC OS xff0c FreeRTOS xff0c RTX xff0c RT Thread 等
  • uCOS消息队列相关函数的理解

    OSQCreate xff1a 创建消息队列函数 有四个入口参数 xff1a 消息队列指针 xff1b 消息队列名称 xff1b 消息队列大小 xff08 不能为0 xff09 xff1b 返回错误类型 函数过程 xff1a 首先进行安全检
  • Huawei LiteOS与freeRTOS、Ucos主流嵌入式操作内核的区别

    LiteOS与freeRTOS Ucos主流嵌入式操作内核的区别 云社区 华为云
  • ucos iii 任务栈使用率统计方法

    第一步 使能任务统计功能 修改文件 os cfg h中的 OS CFG STAT TASK STK CHK EN宏 span class token comment TASK MANAGEMENT span span class token
  • UCOS-II时间管理

    uC OS II时间管理 xff1a 任务延时函数 xff0c OSTimeDly INT16U ticks 申请该服务的任务可以延时一段时间 xff0c 这段时间的长短是用时钟节拍的数目来确定的 实现这个系统服务的函数叫做 OSTimeD
  • ucos源码阅读3——信号量,互斥信号量(未完待续)

    ucos源码阅读3 信号量 xff0c 互斥信号量 事件控制块ECBInitEventList xff08 xff09 EventWaitListInit xff08 xff09 EventTaskRdy xff08 xff09 Event
  • UCOS消息队列的使用【转】

    UCOS消息队列的使用 转 收藏 消息队列的使用 1 需在以下文件中配置如下内容 OS CFG H OS MAX QS N 你需要的值 根据需要自己配置 define OS Q EN 1 Enable 1 or Disable 0 code
  • 【STM32】入门(十一):初识uCOS-III

    STM32 STM32单片机总目录 1 轮询 中断 多任务对比 2 什么是任务 如果您学过linux xff0c 那么任务可以理解为线程 在代码中的体现就是线程函数 xff0c 一个函数中有个无限循环函数 xff0c 并且永不返回 例如 x
  • UCOS II两个任务的模板

    芯片lm3s9b92 include lt includes h gt include 34 utils uartstdio h 34 Application tasks 优先级 define TASK2 PRIO 11 define ta
  • ucos OSTimeDly

    来源 xff1a http blog sina com cn s blog 5f9b3de40100e182 html OSTimeDly 在Task中 xff0c 一般执行一段时间之后调用OSTimeDly推迟一段时间再继续运行 xff0
  • cpu.h-栈的宏定义-满减栈

    常常两两相对的东西 整一起后有点记不住 就写下来 cpu h中有宏定义使用哪种栈 define OS STK GROWTH 1 Stack grows from HIGH to LOW memory on ARM 栈的四种 满栈 满 字表示
  • STM32滴答定时器与UCOS时钟系统,以及心跳和延时函数的实现.

    Systick就是一个定时器而已 只是它放在了NVIC中 主要的目的是为了给操作系统提供一个硬件上的中断 号称滴答中断 滴答中断 这里来简单地解释一下 操作系统进行运转的时候 也会有 心跳 它会根据 心跳 的节拍来工作 把整个时间段分成很多

随机推荐