移植UCOSII系统到STM32上
移植UCOSII系统到STM32上
This commit is contained in:
91
BUGLIST/UCOS移植到stm32,相关文件配置.txt
Normal file
91
BUGLIST/UCOS移植到stm32,相关文件配置.txt
Normal file
@@ -0,0 +1,91 @@
|
||||
// 学习ucosII操作系统
|
||||
|
||||
// 1. 了解ucosII的系统架构与ASCII源码
|
||||
|
||||
// 2. 学习ucosII在STM32上的移植
|
||||
|
||||
// 提供的 SYSTEM 文件夹里面的系统函数直接支持 ucosII,只需要在 sys.h 文件里面将:SYSTEM_SUPPORT_UCOS 宏定义改为 1, 即可通过 delay_init 函数初始化 ucosII 的系统时钟节拍,为 ucosII 提供时钟节拍。
|
||||
|
||||
|
||||
// 3. 理解ucosII操作系统下实现多任务并发工作的编程原理
|
||||
|
||||
// 4. 理解 任务 :
|
||||
|
||||
// 任务其实就是一个死循环函数
|
||||
|
||||
void MyTask(void *pdata)
|
||||
{
|
||||
// 准备
|
||||
while(1)
|
||||
{
|
||||
// 任务实体代码
|
||||
OSTimeDlyHMSM(x,x,x,x);//调用任务延时函数,释放cpu控制权
|
||||
// 例如,该任务延时1s后释放cpu控制权
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// 5. 理解 任务优先级 :
|
||||
|
||||
// ucos中,每个任务都有唯一的一个优先级,ucos不支持多个任务优先级相同。
|
||||
|
||||
// 任务就绪表中总是优先级最高的任务获得cpu使用权
|
||||
|
||||
// ucos中,任务优先级 就是 任务 的唯一标识
|
||||
|
||||
// 6. 理解 任务堆栈 :
|
||||
|
||||
// 就是存储器中分配了一块连续的存储空间,作为 任务堆栈 使用
|
||||
|
||||
// 满足任务切换和响应中断时保存cpu寄存器中的内容以及任务调用其它函数时的需要
|
||||
|
||||
// 每个任务都有自己的一个任务堆栈,它是任务创建的一个重要入口参数
|
||||
|
||||
// 7. 理解 任务控制块 :
|
||||
|
||||
// 用来记录任务堆栈指针,任务当前状态以及任务优先等级等任务的相关属性
|
||||
|
||||
// 包含三个重要参数:任务函数指针、任务堆栈指针、任务优先级
|
||||
|
||||
// 8. 理解 任务就绪表 :
|
||||
|
||||
// 记录系统中所有处于就绪状态的任务
|
||||
|
||||
// 它是一个位图,任务相应位置0或置1表示是否处于就绪状态
|
||||
|
||||
// 9. 理解 任务调度 :
|
||||
|
||||
// 在任务就绪表中查找优先级最高的就绪任务
|
||||
|
||||
// 实现任务的切换
|
||||
|
||||
// 10. 理解ucos中任务的5个状态及其转换关系
|
||||
|
||||
// 就绪,运行,等待,睡眠,中断
|
||||
|
||||
//********************************************************************************************************************************
|
||||
|
||||
// STM32上运行uscoII来进行硬件开发
|
||||
|
||||
// 1. 移植 ucosII 到stm32
|
||||
|
||||
// 2. 编写任务函数并设置其堆栈大小和优先级等参数
|
||||
|
||||
// 3. 初始化ucosII,并在ucosII中创建任务
|
||||
|
||||
// 4. 启动 ucosII
|
||||
|
||||
//********************************************************************************************************************************
|
||||
|
||||
// 工程中要添加的文件夹以及文件:
|
||||
|
||||
// 1. UCOSII-CORE
|
||||
---- 添加 ucosII源码 Source 文件夹中除 os_cfg_r.h 和 os_dbg_r.c 文件外的所有文件
|
||||
|
||||
// 2. UCOSII-CONFIG
|
||||
---- 添加 includes.h 和 os_cfg.h 文件
|
||||
|
||||
// 3. UCOSII-PORT
|
||||
---- 添加 os_cpu.h、os_cpu_a.asm、os_cpu_c.c、os_dbg.c、os_dbg_r.c 文件
|
||||
|
||||
// 注意:不要添加 ucosii.c 文件到 UCOSII-CORE 分组中,防止出现编译时重复定义的错误。
|
||||
37
BUGLIST/为什么要学习ucos(用操作系统的编程思维来解决硬件开发).txt
Normal file
37
BUGLIST/为什么要学习ucos(用操作系统的编程思维来解决硬件开发).txt
Normal file
@@ -0,0 +1,37 @@
|
||||
// 这是在网上看到的一篇文章,觉得写得还行
|
||||
// 当然这篇文章也是国内最大的盗版网站CSDN上某人转载的一篇文章
|
||||
// https://blog.csdn.net/eagle11235/article/details/54620131
|
||||
// 转载自:微信公众号 嵌入式ARM
|
||||
|
||||
// 毕业后,做的项目用到过RTX51, uCos, linux ,当做linux下的项目时,研究过一阵子linux的源码,后来又一天,闲来无事再去看uCos的源码时,突然发现uCos里的一些原理,对于理解和构建一个操作系统这这么的经典和透彻!
|
||||
|
||||
// 于是我觉得是时候再好好理解和整理下uCos里的一些原理了。 我觉得第一个要解决的问题是,为什么我需要uCos?
|
||||
|
||||
// 就像最开始学C编程时,老师告诉我,指针很重要,我那时就有一个大的疑问,指针到底有什么好?
|
||||
|
||||
// 还一边在心里嘀咕着:我不用指针不一样把程序编出来了?现在想想c语言没了指针,将寸步难行!
|
||||
|
||||
// 回到正题,我们到底为什么需要uCos?
|
||||
|
||||
// 一般的简单的嵌入式设备的编程思路是下面这样的:main{{处理事务1};{处理事务2};{处理事务3}; .......{处理事务N};}isr_server{{处理中断};}
|
||||
|
||||
// 这是最一般的思路,对于简单的系统当然是够用了,但这样的系统实时性是很差的,比如“事务1”如果是一个用户输入的检测,当用户输入时,如果程序正在处理事务1下面的那些事务,那么这次用户输入将失效,用户的体验是“这个按键不灵敏,这个机器很慢”。
|
||||
|
||||
// 而我们如果把事务放到中断里去处理,虽然改善了实时性但会导致另外一个问题,有可能会引发中断丢失,这个后果有时候比“慢一点”更加严重和恶劣!
|
||||
|
||||
// 又比如事务2是一个只需要1s钟处理一次的任务,那么显然事务2会白白浪费CPU的时间。
|
||||
|
||||
// 这时,我们可能需要改进我们的编程思路,一般我们会尝试采用“时间片”的方式。这时候编程会变成下面的方式:main{{事务1的时间片到了则处理事务1};{事务2的时间片到了则处理事务2}; .......{事务N的时间片到了则处理事务N};}time_isr_server{{判断每个事务的时间片是否到来,并进行标记};}isr_server{{处理中断};}
|
||||
|
||||
// 我们可以看到,这种改进后的思路,使得事务的执行时间得到控制,事务只在自己的时间片到来后,才会去执行,但我们发现,这种方式仍然不能彻底解决“实时性”的问题,因为某个事务的时间片到来后,也不能立即就执行,她必须等到当前事务的时间片用完,并且后面的事务时间片没到来,她才有机会获得“执行时间”。
|
||||
|
||||
// 这时候我们需要继续改进思路, 为了使得某个事务的时间片到来后能立即执行,我们需要在时钟中断里判断完时间片后,改变程序的返回位置,让程序不返回到刚刚被打断的位置,而从最新获得了时间片的事务处开始执行,这样就彻底解决了事务的实时问题。
|
||||
|
||||
// 我们在这个思路上,进行改进,我们需要在每次进入时钟中断前,保存CPU的当前状态和当前事务用到的一些数据,然后我们进入时钟中断进行时间片处理,若发现有新的更紧急的事务的时间片到来了,则我们改变中断的返回的地址,并在CPU中恢复这个更紧急的事务的现场,然后返回中断开始执行这个更紧急的事务。
|
||||
|
||||
// 上面的这段话有些不好读,事实上,这是因为要实现这个过程是有些复杂和麻烦的,这时候我们就需要找一个操作系统(OS)帮我们做这些事了,如果你能自己用代码实现这个过程,事实上你就在自己写操作系统了,其实从这里也可也看出,操作系统的原理其实并不那么神秘,只是一些细节你很难做好。
|
||||
// uCos就是这样一个操作系统,她能帮你完成这些事情,而且是很优雅的帮你完成!
|
||||
|
||||
// uCos的用处远不止帮你完成这个“事务时间片的处理”,她还能帮你处理各种超时,进行内存管理,完成任务间的通信等,有了她,程序的层次也更加清晰,给系统添加功能也更方便,这一切在大型项目中越发的明显!
|
||||
|
||||
// 我们知道了uCos能给我们提供这么多的便利,那么我们就开始使用uCos吧!
|
||||
@@ -157,6 +157,10 @@ void append(unsigned char dat, BUFFER *b)
|
||||
}
|
||||
}
|
||||
|
||||
/ **********************************************************************************************************************************
|
||||
|
||||
// 函数原型(函数声明)就是告诉编译器这个函数是存在的,让编译器知道这个函数的相关信息。函数原型不要求提供形参名,有类型列表就可以了。
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -147,6 +147,10 @@ TIM_SetAutoreload(TIMx,fpwm_arr)
|
||||
> 按下K7,计时加长;
|
||||
>
|
||||
> 按下K8,计时减少;
|
||||
|
||||
### 5. UC/OSII系统使用说明:
|
||||
> sys.h 文件中 SYSTEM_SUPPORT_UCOS 置1
|
||||
> stm32f10x_it.c 文件中 USE_UCOSII 置1(实际 stm32f10x_it.c 这个文件没有在我的项目中用到)
|
||||
|
||||
|
||||
\* @Version: Beta2.0
|
||||
|
||||
55
UCOSII/CONFIG/includes.h
Normal file
55
UCOSII/CONFIG/includes.h
Normal file
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
************************************************************************************************
|
||||
<EFBFBD><EFBFBD>Ҫ<EFBFBD>İ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD>
|
||||
|
||||
<EFBFBD><EFBFBD> <20><>: INCLUDES.C ucos<6F><73><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD>
|
||||
<EFBFBD><EFBFBD> <20><>: Jean J. Labrosse
|
||||
************************************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef __INCLUDES_H__
|
||||
#define __INCLUDES_H__
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "ucos_ii.h"
|
||||
#include "os_cpu.h"
|
||||
#include "os_cfg.h"
|
||||
|
||||
#include <stm32f10x.h>
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
144
UCOSII/CONFIG/os_cfg.h
Normal file
144
UCOSII/CONFIG/os_cfg.h
Normal file
@@ -0,0 +1,144 @@
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* uC/OS-II
|
||||
* The Real-Time Kernel
|
||||
* uC/OS-II Configuration File for V2.8x
|
||||
*
|
||||
* (c) Copyright 2005-2009, Micrium, Weston, FL
|
||||
* All Rights Reserved
|
||||
*
|
||||
*
|
||||
* File : OS_CFG.H
|
||||
* By : Jean J. Labrosse
|
||||
* Version : V2.91
|
||||
*
|
||||
* LICENSING TERMS:
|
||||
* ---------------
|
||||
* uC/OS-II is provided in source form for FREE evaluation, for educational use or for peaceful research.
|
||||
* If you plan on using uC/OS-II in a commercial product you need to contact Micri<72>m to properly license
|
||||
* its use in your product. We provide ALL the source code for your convenience and to help you experience
|
||||
* uC/OS-II. The fact that the source is provided does NOT mean that you can use it without paying a
|
||||
* licensing fee.
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef OS_CFG_H
|
||||
#define OS_CFG_H
|
||||
|
||||
|
||||
/* ---------------------- MISCELLANEOUS ----------------------- */
|
||||
#define OS_APP_HOOKS_EN 0u /* Application-defined hooks are called from the uC/OS-II hooks */
|
||||
#define OS_ARG_CHK_EN 0u /* Enable (1) or Disable (0) argument checking */
|
||||
#define OS_CPU_HOOKS_EN 1u /* uC/OS-II hooks are found in the processor port files */
|
||||
|
||||
#define OS_DEBUG_EN 0u /* Enable(1) debug variables */
|
||||
|
||||
#define OS_EVENT_MULTI_EN 0u /* Include code for OSEventPendMulti() */
|
||||
#define OS_EVENT_NAME_EN 0u /* Enable names for Sem, Mutex, Mbox and Q */
|
||||
|
||||
#define OS_LOWEST_PRIO 63u /* Defines the lowest priority that can be assigned ... */
|
||||
/* ... MUST NEVER be higher than 254! */
|
||||
|
||||
#define OS_MAX_EVENTS 10u /* Max. number of event control blocks in your application */
|
||||
#define OS_MAX_FLAGS 5u /* Max. number of Event Flag Groups in your application */
|
||||
#define OS_MAX_MEM_PART 0u /* Max. number of memory partitions */
|
||||
#define OS_MAX_QS 5u /* Max. number of queue control blocks in your application */
|
||||
#define OS_MAX_TASKS 10u /* Max. number of tasks in your application, MUST be >= 2 */
|
||||
|
||||
#define OS_SCHED_LOCK_EN 1u /* Include code for OSSchedLock() and OSSchedUnlock() */
|
||||
|
||||
#define OS_TICK_STEP_EN 1u /* Enable tick stepping feature for uC/OS-View */
|
||||
#define OS_TICKS_PER_SEC 200u /* Set the number of ticks in one second */
|
||||
|
||||
|
||||
/* --------------------- TASK STACK SIZE ---------------------- */
|
||||
#define OS_TASK_TMR_STK_SIZE 128u /* Timer task stack size (# of OS_STK wide entries) */
|
||||
#define OS_TASK_STAT_STK_SIZE 128u /* Statistics task stack size (# of OS_STK wide entries) */
|
||||
#define OS_TASK_IDLE_STK_SIZE 128u /* Idle task stack size (# of OS_STK wide entries) */
|
||||
|
||||
|
||||
/* --------------------- TASK MANAGEMENT ---------------------- */
|
||||
#define OS_TASK_CHANGE_PRIO_EN 1u /* Include code for OSTaskChangePrio() */
|
||||
#define OS_TASK_CREATE_EN 1u /* Include code for OSTaskCreate() */
|
||||
#define OS_TASK_CREATE_EXT_EN 1u /* Include code for OSTaskCreateExt() */
|
||||
#define OS_TASK_DEL_EN 1u /* Include code for OSTaskDel() */
|
||||
#define OS_TASK_NAME_EN 1u /* Enable task names */
|
||||
#define OS_TASK_PROFILE_EN 1u /* Include variables in OS_TCB for profiling */
|
||||
#define OS_TASK_QUERY_EN 1u /* Include code for OSTaskQuery() */
|
||||
#define OS_TASK_REG_TBL_SIZE 1u /* Size of task variables array (#of INT32U entries) */
|
||||
#define OS_TASK_STAT_EN 1u /* Enable (1) or Disable(0) the statistics task */
|
||||
#define OS_TASK_STAT_STK_CHK_EN 1u /* Check task stacks from statistic task */
|
||||
#define OS_TASK_SUSPEND_EN 1u /* Include code for OSTaskSuspend() and OSTaskResume() */
|
||||
#define OS_TASK_SW_HOOK_EN 1u /* Include code for OSTaskSwHook() */
|
||||
|
||||
|
||||
/* ----------------------- EVENT FLAGS ------------------------ */
|
||||
#define OS_FLAG_EN 1u /* Enable (1) or Disable (0) code generation for EVENT FLAGS */
|
||||
#define OS_FLAG_ACCEPT_EN 1u /* Include code for OSFlagAccept() */
|
||||
#define OS_FLAG_DEL_EN 1u /* Include code for OSFlagDel() */
|
||||
#define OS_FLAG_NAME_EN 1u /* Enable names for event flag group */
|
||||
#define OS_FLAG_QUERY_EN 1u /* Include code for OSFlagQuery() */
|
||||
#define OS_FLAG_WAIT_CLR_EN 1u /* Include code for Wait on Clear EVENT FLAGS */
|
||||
#define OS_FLAGS_NBITS 16u /* Size in #bits of OS_FLAGS data type (8, 16 or 32) */
|
||||
|
||||
|
||||
/* -------------------- MESSAGE MAILBOXES --------------------- */
|
||||
#define OS_MBOX_EN 1u /* Enable (1) or Disable (0) code generation for MAILBOXES */
|
||||
#define OS_MBOX_ACCEPT_EN 1u /* Include code for OSMboxAccept() */
|
||||
#define OS_MBOX_DEL_EN 1u /* Include code for OSMboxDel() */
|
||||
#define OS_MBOX_PEND_ABORT_EN 1u /* Include code for OSMboxPendAbort() */
|
||||
#define OS_MBOX_POST_EN 1u /* Include code for OSMboxPost() */
|
||||
#define OS_MBOX_POST_OPT_EN 1u /* Include code for OSMboxPostOpt() */
|
||||
#define OS_MBOX_QUERY_EN 1u /* Include code for OSMboxQuery() */
|
||||
|
||||
|
||||
/* --------------------- MEMORY MANAGEMENT -------------------- */
|
||||
#define OS_MEM_EN 1u /* Enable (1) or Disable (0) code generation for MEMORY MANAGER */
|
||||
#define OS_MEM_NAME_EN 1u /* Enable memory partition names */
|
||||
#define OS_MEM_QUERY_EN 1u /* Include code for OSMemQuery() */
|
||||
|
||||
|
||||
/* ---------------- MUTUAL EXCLUSION SEMAPHORES --------------- */
|
||||
#define OS_MUTEX_EN 1u /* Enable (1) or Disable (0) code generation for MUTEX */
|
||||
#define OS_MUTEX_ACCEPT_EN 1u /* Include code for OSMutexAccept() */
|
||||
#define OS_MUTEX_DEL_EN 1u /* Include code for OSMutexDel() */
|
||||
#define OS_MUTEX_QUERY_EN 1u /* Include code for OSMutexQuery() */
|
||||
|
||||
|
||||
/* ---------------------- MESSAGE QUEUES ---------------------- */
|
||||
#define OS_Q_EN 1u /* Enable (1) or Disable (0) code generation for QUEUES */
|
||||
#define OS_Q_ACCEPT_EN 1u /* Include code for OSQAccept() */
|
||||
#define OS_Q_DEL_EN 1u /* Include code for OSQDel() */
|
||||
#define OS_Q_FLUSH_EN 1u /* Include code for OSQFlush() */
|
||||
#define OS_Q_PEND_ABORT_EN 1u /* Include code for OSQPendAbort() */
|
||||
#define OS_Q_POST_EN 1u /* Include code for OSQPost() */
|
||||
#define OS_Q_POST_FRONT_EN 1u /* Include code for OSQPostFront() */
|
||||
#define OS_Q_POST_OPT_EN 1u /* Include code for OSQPostOpt() */
|
||||
#define OS_Q_QUERY_EN 1u /* Include code for OSQQuery() */
|
||||
|
||||
|
||||
/* ------------------------ SEMAPHORES ------------------------ */
|
||||
#define OS_SEM_EN 1u /* Enable (1) or Disable (0) code generation for SEMAPHORES */
|
||||
#define OS_SEM_ACCEPT_EN 1u /* Include code for OSSemAccept() */
|
||||
#define OS_SEM_DEL_EN 1u /* Include code for OSSemDel() */
|
||||
#define OS_SEM_PEND_ABORT_EN 1u /* Include code for OSSemPendAbort() */
|
||||
#define OS_SEM_QUERY_EN 1u /* Include code for OSSemQuery() */
|
||||
#define OS_SEM_SET_EN 1u /* Include code for OSSemSet() */
|
||||
|
||||
|
||||
/* --------------------- TIME MANAGEMENT ---------------------- */
|
||||
#define OS_TIME_DLY_HMSM_EN 1u /* Include code for OSTimeDlyHMSM() */
|
||||
#define OS_TIME_DLY_RESUME_EN 1u /* Include code for OSTimeDlyResume() */
|
||||
#define OS_TIME_GET_SET_EN 1u /* Include code for OSTimeGet() and OSTimeSet() */
|
||||
#define OS_TIME_TICK_HOOK_EN 1u /* Include code for OSTimeTickHook() */
|
||||
|
||||
|
||||
/* --------------------- TIMER MANAGEMENT --------------------- */
|
||||
#define OS_TMR_EN 0u /* Enable (1) or Disable (0) code generation for TIMERS */
|
||||
#define OS_TMR_CFG_MAX 16u /* Maximum number of timers */
|
||||
#define OS_TMR_CFG_NAME_EN 1u /* Determine timer names */
|
||||
#define OS_TMR_CFG_WHEEL_SIZE 8u /* Size of timer wheel (#Spokes) */
|
||||
#define OS_TMR_CFG_TICKS_PER_SEC 10u /* Rate at which timer management task runs (Hz) */
|
||||
|
||||
#endif
|
||||
|
||||
2029
UCOSII/CORE/os_core.c
Normal file
2029
UCOSII/CORE/os_core.c
Normal file
File diff suppressed because it is too large
Load Diff
1215
UCOSII/CORE/os_flag.c
Normal file
1215
UCOSII/CORE/os_flag.c
Normal file
File diff suppressed because it is too large
Load Diff
647
UCOSII/CORE/os_mbox.c
Normal file
647
UCOSII/CORE/os_mbox.c
Normal file
@@ -0,0 +1,647 @@
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* uC/OS-II
|
||||
* The Real-Time Kernel
|
||||
* MESSAGE MAILBOX MANAGEMENT
|
||||
*
|
||||
* (c) Copyright 1992-2009, Micrium, Weston, FL
|
||||
* All Rights Reserved
|
||||
*
|
||||
* File : OS_MBOX.C
|
||||
* By : Jean J. Labrosse
|
||||
* Version : V2.91
|
||||
*
|
||||
* LICENSING TERMS:
|
||||
* ---------------
|
||||
* uC/OS-II is provided in source form for FREE evaluation, for educational use or for peaceful research.
|
||||
* If you plan on using uC/OS-II in a commercial product you need to contact Micri<72>m to properly license
|
||||
* its use in your product. We provide ALL the source code for your convenience and to help you experience
|
||||
* uC/OS-II. The fact that the source is provided does NOT mean that you can use it without paying a
|
||||
* licensing fee.
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef OS_MASTER_FILE
|
||||
#include <ucos_ii.h>
|
||||
#endif
|
||||
|
||||
#if OS_MBOX_EN > 0u
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* ACCEPT MESSAGE FROM MAILBOX
|
||||
*
|
||||
* Description: This function checks the mailbox to see if a message is available. Unlike OSMboxPend(),
|
||||
* OSMboxAccept() does not suspend the calling task if a message is not available.
|
||||
*
|
||||
* Arguments : pevent is a pointer to the event control block
|
||||
*
|
||||
* Returns : != (void *)0 is the message in the mailbox if one is available. The mailbox is cleared
|
||||
* so the next time OSMboxAccept() is called, the mailbox will be empty.
|
||||
* == (void *)0 if the mailbox is empty or,
|
||||
* if 'pevent' is a NULL pointer or,
|
||||
* if you didn't pass the proper event pointer.
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
#if OS_MBOX_ACCEPT_EN > 0u
|
||||
void *OSMboxAccept (OS_EVENT *pevent)
|
||||
{
|
||||
void *pmsg;
|
||||
#if OS_CRITICAL_METHOD == 3u /* Allocate storage for CPU status register */
|
||||
OS_CPU_SR cpu_sr = 0u;
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#if OS_ARG_CHK_EN > 0u
|
||||
if (pevent == (OS_EVENT *)0) { /* Validate 'pevent' */
|
||||
return ((void *)0);
|
||||
}
|
||||
#endif
|
||||
if (pevent->OSEventType != OS_EVENT_TYPE_MBOX) { /* Validate event block type */
|
||||
return ((void *)0);
|
||||
}
|
||||
OS_ENTER_CRITICAL();
|
||||
pmsg = pevent->OSEventPtr;
|
||||
pevent->OSEventPtr = (void *)0; /* Clear the mailbox */
|
||||
OS_EXIT_CRITICAL();
|
||||
return (pmsg); /* Return the message received (or NULL) */
|
||||
}
|
||||
#endif
|
||||
/*$PAGE*/
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* CREATE A MESSAGE MAILBOX
|
||||
*
|
||||
* Description: This function creates a message mailbox if free event control blocks are available.
|
||||
*
|
||||
* Arguments : pmsg is a pointer to a message that you wish to deposit in the mailbox. If
|
||||
* you set this value to the NULL pointer (i.e. (void *)0) then the mailbox
|
||||
* will be considered empty.
|
||||
*
|
||||
* Returns : != (OS_EVENT *)0 is a pointer to the event control clock (OS_EVENT) associated with the
|
||||
* created mailbox
|
||||
* == (OS_EVENT *)0 if no event control blocks were available
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
OS_EVENT *OSMboxCreate (void *pmsg)
|
||||
{
|
||||
OS_EVENT *pevent;
|
||||
#if OS_CRITICAL_METHOD == 3u /* Allocate storage for CPU status register */
|
||||
OS_CPU_SR cpu_sr = 0u;
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#ifdef OS_SAFETY_CRITICAL_IEC61508
|
||||
if (OSSafetyCriticalStartFlag == OS_TRUE) {
|
||||
OS_SAFETY_CRITICAL_EXCEPTION();
|
||||
}
|
||||
#endif
|
||||
|
||||
if (OSIntNesting > 0u) { /* See if called from ISR ... */
|
||||
return ((OS_EVENT *)0); /* ... can't CREATE from an ISR */
|
||||
}
|
||||
OS_ENTER_CRITICAL();
|
||||
pevent = OSEventFreeList; /* Get next free event control block */
|
||||
if (OSEventFreeList != (OS_EVENT *)0) { /* See if pool of free ECB pool was empty */
|
||||
OSEventFreeList = (OS_EVENT *)OSEventFreeList->OSEventPtr;
|
||||
}
|
||||
OS_EXIT_CRITICAL();
|
||||
if (pevent != (OS_EVENT *)0) {
|
||||
pevent->OSEventType = OS_EVENT_TYPE_MBOX;
|
||||
pevent->OSEventCnt = 0u;
|
||||
pevent->OSEventPtr = pmsg; /* Deposit message in event control block */
|
||||
#if OS_EVENT_NAME_EN > 0u
|
||||
pevent->OSEventName = (INT8U *)(void *)"?";
|
||||
#endif
|
||||
OS_EventWaitListInit(pevent);
|
||||
}
|
||||
return (pevent); /* Return pointer to event control block */
|
||||
}
|
||||
/*$PAGE*/
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* DELETE A MAIBOX
|
||||
*
|
||||
* Description: This function deletes a mailbox and readies all tasks pending on the mailbox.
|
||||
*
|
||||
* Arguments : pevent is a pointer to the event control block associated with the desired
|
||||
* mailbox.
|
||||
*
|
||||
* opt determines delete options as follows:
|
||||
* opt == OS_DEL_NO_PEND Delete the mailbox ONLY if no task pending
|
||||
* opt == OS_DEL_ALWAYS Deletes the mailbox even if tasks are waiting.
|
||||
* In this case, all the tasks pending will be readied.
|
||||
*
|
||||
* perr is a pointer to an error code that can contain one of the following values:
|
||||
* OS_ERR_NONE The call was successful and the mailbox was deleted
|
||||
* OS_ERR_DEL_ISR If you attempted to delete the mailbox from an ISR
|
||||
* OS_ERR_INVALID_OPT An invalid option was specified
|
||||
* OS_ERR_TASK_WAITING One or more tasks were waiting on the mailbox
|
||||
* OS_ERR_EVENT_TYPE If you didn't pass a pointer to a mailbox
|
||||
* OS_ERR_PEVENT_NULL If 'pevent' is a NULL pointer.
|
||||
*
|
||||
* Returns : pevent upon error
|
||||
* (OS_EVENT *)0 if the mailbox was successfully deleted.
|
||||
*
|
||||
* Note(s) : 1) This function must be used with care. Tasks that would normally expect the presence of
|
||||
* the mailbox MUST check the return code of OSMboxPend().
|
||||
* 2) OSMboxAccept() callers will not know that the intended mailbox has been deleted!
|
||||
* 3) This call can potentially disable interrupts for a long time. The interrupt disable
|
||||
* time is directly proportional to the number of tasks waiting on the mailbox.
|
||||
* 4) Because ALL tasks pending on the mailbox will be readied, you MUST be careful in
|
||||
* applications where the mailbox is used for mutual exclusion because the resource(s)
|
||||
* will no longer be guarded by the mailbox.
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
#if OS_MBOX_DEL_EN > 0u
|
||||
OS_EVENT *OSMboxDel (OS_EVENT *pevent,
|
||||
INT8U opt,
|
||||
INT8U *perr)
|
||||
{
|
||||
BOOLEAN tasks_waiting;
|
||||
OS_EVENT *pevent_return;
|
||||
#if OS_CRITICAL_METHOD == 3u /* Allocate storage for CPU status register */
|
||||
OS_CPU_SR cpu_sr = 0u;
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#ifdef OS_SAFETY_CRITICAL
|
||||
if (perr == (INT8U *)0) {
|
||||
OS_SAFETY_CRITICAL_EXCEPTION();
|
||||
}
|
||||
#endif
|
||||
|
||||
#if OS_ARG_CHK_EN > 0u
|
||||
if (pevent == (OS_EVENT *)0) { /* Validate 'pevent' */
|
||||
*perr = OS_ERR_PEVENT_NULL;
|
||||
return (pevent);
|
||||
}
|
||||
#endif
|
||||
if (pevent->OSEventType != OS_EVENT_TYPE_MBOX) { /* Validate event block type */
|
||||
*perr = OS_ERR_EVENT_TYPE;
|
||||
return (pevent);
|
||||
}
|
||||
if (OSIntNesting > 0u) { /* See if called from ISR ... */
|
||||
*perr = OS_ERR_DEL_ISR; /* ... can't DELETE from an ISR */
|
||||
return (pevent);
|
||||
}
|
||||
OS_ENTER_CRITICAL();
|
||||
if (pevent->OSEventGrp != 0u) { /* See if any tasks waiting on mailbox */
|
||||
tasks_waiting = OS_TRUE; /* Yes */
|
||||
} else {
|
||||
tasks_waiting = OS_FALSE; /* No */
|
||||
}
|
||||
switch (opt) {
|
||||
case OS_DEL_NO_PEND: /* Delete mailbox only if no task waiting */
|
||||
if (tasks_waiting == OS_FALSE) {
|
||||
#if OS_EVENT_NAME_EN > 0u
|
||||
pevent->OSEventName = (INT8U *)(void *)"?";
|
||||
#endif
|
||||
pevent->OSEventType = OS_EVENT_TYPE_UNUSED;
|
||||
pevent->OSEventPtr = OSEventFreeList; /* Return Event Control Block to free list */
|
||||
pevent->OSEventCnt = 0u;
|
||||
OSEventFreeList = pevent; /* Get next free event control block */
|
||||
OS_EXIT_CRITICAL();
|
||||
*perr = OS_ERR_NONE;
|
||||
pevent_return = (OS_EVENT *)0; /* Mailbox has been deleted */
|
||||
} else {
|
||||
OS_EXIT_CRITICAL();
|
||||
*perr = OS_ERR_TASK_WAITING;
|
||||
pevent_return = pevent;
|
||||
}
|
||||
break;
|
||||
|
||||
case OS_DEL_ALWAYS: /* Always delete the mailbox */
|
||||
while (pevent->OSEventGrp != 0u) { /* Ready ALL tasks waiting for mailbox */
|
||||
(void)OS_EventTaskRdy(pevent, (void *)0, OS_STAT_MBOX, OS_STAT_PEND_OK);
|
||||
}
|
||||
#if OS_EVENT_NAME_EN > 0u
|
||||
pevent->OSEventName = (INT8U *)(void *)"?";
|
||||
#endif
|
||||
pevent->OSEventType = OS_EVENT_TYPE_UNUSED;
|
||||
pevent->OSEventPtr = OSEventFreeList; /* Return Event Control Block to free list */
|
||||
pevent->OSEventCnt = 0u;
|
||||
OSEventFreeList = pevent; /* Get next free event control block */
|
||||
OS_EXIT_CRITICAL();
|
||||
if (tasks_waiting == OS_TRUE) { /* Reschedule only if task(s) were waiting */
|
||||
OS_Sched(); /* Find highest priority task ready to run */
|
||||
}
|
||||
*perr = OS_ERR_NONE;
|
||||
pevent_return = (OS_EVENT *)0; /* Mailbox has been deleted */
|
||||
break;
|
||||
|
||||
default:
|
||||
OS_EXIT_CRITICAL();
|
||||
*perr = OS_ERR_INVALID_OPT;
|
||||
pevent_return = pevent;
|
||||
break;
|
||||
}
|
||||
return (pevent_return);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*$PAGE*/
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* PEND ON MAILBOX FOR A MESSAGE
|
||||
*
|
||||
* Description: This function waits for a message to be sent to a mailbox
|
||||
*
|
||||
* Arguments : pevent is a pointer to the event control block associated with the desired mailbox
|
||||
*
|
||||
* timeout is an optional timeout period (in clock ticks). If non-zero, your task will
|
||||
* wait for a message to arrive at the mailbox up to the amount of time
|
||||
* specified by this argument. If you specify 0, however, your task will wait
|
||||
* forever at the specified mailbox or, until a message arrives.
|
||||
*
|
||||
* perr is a pointer to where an error message will be deposited. Possible error
|
||||
* messages are:
|
||||
*
|
||||
* OS_ERR_NONE The call was successful and your task received a
|
||||
* message.
|
||||
* OS_ERR_TIMEOUT A message was not received within the specified 'timeout'.
|
||||
* OS_ERR_PEND_ABORT The wait on the mailbox was aborted.
|
||||
* OS_ERR_EVENT_TYPE Invalid event type
|
||||
* OS_ERR_PEND_ISR If you called this function from an ISR and the result
|
||||
* would lead to a suspension.
|
||||
* OS_ERR_PEVENT_NULL If 'pevent' is a NULL pointer
|
||||
* OS_ERR_PEND_LOCKED If you called this function when the scheduler is locked
|
||||
*
|
||||
* Returns : != (void *)0 is a pointer to the message received
|
||||
* == (void *)0 if no message was received or,
|
||||
* if 'pevent' is a NULL pointer or,
|
||||
* if you didn't pass the proper pointer to the event control block.
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
/*$PAGE*/
|
||||
void *OSMboxPend (OS_EVENT *pevent,
|
||||
INT32U timeout,
|
||||
INT8U *perr)
|
||||
{
|
||||
void *pmsg;
|
||||
#if OS_CRITICAL_METHOD == 3u /* Allocate storage for CPU status register */
|
||||
OS_CPU_SR cpu_sr = 0u;
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#ifdef OS_SAFETY_CRITICAL
|
||||
if (perr == (INT8U *)0) {
|
||||
OS_SAFETY_CRITICAL_EXCEPTION();
|
||||
}
|
||||
#endif
|
||||
|
||||
#if OS_ARG_CHK_EN > 0u
|
||||
if (pevent == (OS_EVENT *)0) { /* Validate 'pevent' */
|
||||
*perr = OS_ERR_PEVENT_NULL;
|
||||
return ((void *)0);
|
||||
}
|
||||
#endif
|
||||
if (pevent->OSEventType != OS_EVENT_TYPE_MBOX) { /* Validate event block type */
|
||||
*perr = OS_ERR_EVENT_TYPE;
|
||||
return ((void *)0);
|
||||
}
|
||||
if (OSIntNesting > 0u) { /* See if called from ISR ... */
|
||||
*perr = OS_ERR_PEND_ISR; /* ... can't PEND from an ISR */
|
||||
return ((void *)0);
|
||||
}
|
||||
if (OSLockNesting > 0u) { /* See if called with scheduler locked ... */
|
||||
*perr = OS_ERR_PEND_LOCKED; /* ... can't PEND when locked */
|
||||
return ((void *)0);
|
||||
}
|
||||
OS_ENTER_CRITICAL();
|
||||
pmsg = pevent->OSEventPtr;
|
||||
if (pmsg != (void *)0) { /* See if there is already a message */
|
||||
pevent->OSEventPtr = (void *)0; /* Clear the mailbox */
|
||||
OS_EXIT_CRITICAL();
|
||||
*perr = OS_ERR_NONE;
|
||||
return (pmsg); /* Return the message received (or NULL) */
|
||||
}
|
||||
OSTCBCur->OSTCBStat |= OS_STAT_MBOX; /* Message not available, task will pend */
|
||||
OSTCBCur->OSTCBStatPend = OS_STAT_PEND_OK;
|
||||
OSTCBCur->OSTCBDly = timeout; /* Load timeout in TCB */
|
||||
OS_EventTaskWait(pevent); /* Suspend task until event or timeout occurs */
|
||||
OS_EXIT_CRITICAL();
|
||||
OS_Sched(); /* Find next highest priority task ready to run */
|
||||
OS_ENTER_CRITICAL();
|
||||
switch (OSTCBCur->OSTCBStatPend) { /* See if we timed-out or aborted */
|
||||
case OS_STAT_PEND_OK:
|
||||
pmsg = OSTCBCur->OSTCBMsg;
|
||||
*perr = OS_ERR_NONE;
|
||||
break;
|
||||
|
||||
case OS_STAT_PEND_ABORT:
|
||||
pmsg = (void *)0;
|
||||
*perr = OS_ERR_PEND_ABORT; /* Indicate that we aborted */
|
||||
break;
|
||||
|
||||
case OS_STAT_PEND_TO:
|
||||
default:
|
||||
OS_EventTaskRemove(OSTCBCur, pevent);
|
||||
pmsg = (void *)0;
|
||||
*perr = OS_ERR_TIMEOUT; /* Indicate that we didn't get event within TO */
|
||||
break;
|
||||
}
|
||||
OSTCBCur->OSTCBStat = OS_STAT_RDY; /* Set task status to ready */
|
||||
OSTCBCur->OSTCBStatPend = OS_STAT_PEND_OK; /* Clear pend status */
|
||||
OSTCBCur->OSTCBEventPtr = (OS_EVENT *)0; /* Clear event pointers */
|
||||
#if (OS_EVENT_MULTI_EN > 0u)
|
||||
OSTCBCur->OSTCBEventMultiPtr = (OS_EVENT **)0;
|
||||
#endif
|
||||
OSTCBCur->OSTCBMsg = (void *)0; /* Clear received message */
|
||||
OS_EXIT_CRITICAL();
|
||||
return (pmsg); /* Return received message */
|
||||
}
|
||||
/*$PAGE*/
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* ABORT WAITING ON A MESSAGE MAILBOX
|
||||
*
|
||||
* Description: This function aborts & readies any tasks currently waiting on a mailbox. This function
|
||||
* should be used to fault-abort the wait on the mailbox, rather than to normally signal
|
||||
* the mailbox via OSMboxPost() or OSMboxPostOpt().
|
||||
*
|
||||
* Arguments : pevent is a pointer to the event control block associated with the desired mailbox.
|
||||
*
|
||||
* opt determines the type of ABORT performed:
|
||||
* OS_PEND_OPT_NONE ABORT wait for a single task (HPT) waiting on the
|
||||
* mailbox
|
||||
* OS_PEND_OPT_BROADCAST ABORT wait for ALL tasks that are waiting on the
|
||||
* mailbox
|
||||
*
|
||||
* perr is a pointer to where an error message will be deposited. Possible error
|
||||
* messages are:
|
||||
*
|
||||
* OS_ERR_NONE No tasks were waiting on the mailbox.
|
||||
* OS_ERR_PEND_ABORT At least one task waiting on the mailbox was readied
|
||||
* and informed of the aborted wait; check return value
|
||||
* for the number of tasks whose wait on the mailbox
|
||||
* was aborted.
|
||||
* OS_ERR_EVENT_TYPE If you didn't pass a pointer to a mailbox.
|
||||
* OS_ERR_PEVENT_NULL If 'pevent' is a NULL pointer.
|
||||
*
|
||||
* Returns : == 0 if no tasks were waiting on the mailbox, or upon error.
|
||||
* > 0 if one or more tasks waiting on the mailbox are now readied and informed.
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
#if OS_MBOX_PEND_ABORT_EN > 0u
|
||||
INT8U OSMboxPendAbort (OS_EVENT *pevent,
|
||||
INT8U opt,
|
||||
INT8U *perr)
|
||||
{
|
||||
INT8U nbr_tasks;
|
||||
#if OS_CRITICAL_METHOD == 3u /* Allocate storage for CPU status register */
|
||||
OS_CPU_SR cpu_sr = 0u;
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#ifdef OS_SAFETY_CRITICAL
|
||||
if (perr == (INT8U *)0) {
|
||||
OS_SAFETY_CRITICAL_EXCEPTION();
|
||||
}
|
||||
#endif
|
||||
|
||||
#if OS_ARG_CHK_EN > 0u
|
||||
if (pevent == (OS_EVENT *)0) { /* Validate 'pevent' */
|
||||
*perr = OS_ERR_PEVENT_NULL;
|
||||
return (0u);
|
||||
}
|
||||
#endif
|
||||
if (pevent->OSEventType != OS_EVENT_TYPE_MBOX) { /* Validate event block type */
|
||||
*perr = OS_ERR_EVENT_TYPE;
|
||||
return (0u);
|
||||
}
|
||||
OS_ENTER_CRITICAL();
|
||||
if (pevent->OSEventGrp != 0u) { /* See if any task waiting on mailbox? */
|
||||
nbr_tasks = 0u;
|
||||
switch (opt) {
|
||||
case OS_PEND_OPT_BROADCAST: /* Do we need to abort ALL waiting tasks? */
|
||||
while (pevent->OSEventGrp != 0u) { /* Yes, ready ALL tasks waiting on mailbox */
|
||||
(void)OS_EventTaskRdy(pevent, (void *)0, OS_STAT_MBOX, OS_STAT_PEND_ABORT);
|
||||
nbr_tasks++;
|
||||
}
|
||||
break;
|
||||
|
||||
case OS_PEND_OPT_NONE:
|
||||
default: /* No, ready HPT waiting on mailbox */
|
||||
(void)OS_EventTaskRdy(pevent, (void *)0, OS_STAT_MBOX, OS_STAT_PEND_ABORT);
|
||||
nbr_tasks++;
|
||||
break;
|
||||
}
|
||||
OS_EXIT_CRITICAL();
|
||||
OS_Sched(); /* Find HPT ready to run */
|
||||
*perr = OS_ERR_PEND_ABORT;
|
||||
return (nbr_tasks);
|
||||
}
|
||||
OS_EXIT_CRITICAL();
|
||||
*perr = OS_ERR_NONE;
|
||||
return (0u); /* No tasks waiting on mailbox */
|
||||
}
|
||||
#endif
|
||||
|
||||
/*$PAGE*/
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* POST MESSAGE TO A MAILBOX
|
||||
*
|
||||
* Description: This function sends a message to a mailbox
|
||||
*
|
||||
* Arguments : pevent is a pointer to the event control block associated with the desired mailbox
|
||||
*
|
||||
* pmsg is a pointer to the message to send. You MUST NOT send a NULL pointer.
|
||||
*
|
||||
* Returns : OS_ERR_NONE The call was successful and the message was sent
|
||||
* OS_ERR_MBOX_FULL If the mailbox already contains a message. You can can only send one
|
||||
* message at a time and thus, the message MUST be consumed before you
|
||||
* are allowed to send another one.
|
||||
* OS_ERR_EVENT_TYPE If you are attempting to post to a non mailbox.
|
||||
* OS_ERR_PEVENT_NULL If 'pevent' is a NULL pointer
|
||||
* OS_ERR_POST_NULL_PTR If you are attempting to post a NULL pointer
|
||||
*
|
||||
* Note(s) : 1) HPT means Highest Priority Task
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
#if OS_MBOX_POST_EN > 0u
|
||||
INT8U OSMboxPost (OS_EVENT *pevent,
|
||||
void *pmsg)
|
||||
{
|
||||
#if OS_CRITICAL_METHOD == 3u /* Allocate storage for CPU status register */
|
||||
OS_CPU_SR cpu_sr = 0u;
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#if OS_ARG_CHK_EN > 0u
|
||||
if (pevent == (OS_EVENT *)0) { /* Validate 'pevent' */
|
||||
return (OS_ERR_PEVENT_NULL);
|
||||
}
|
||||
if (pmsg == (void *)0) { /* Make sure we are not posting a NULL pointer */
|
||||
return (OS_ERR_POST_NULL_PTR);
|
||||
}
|
||||
#endif
|
||||
if (pevent->OSEventType != OS_EVENT_TYPE_MBOX) { /* Validate event block type */
|
||||
return (OS_ERR_EVENT_TYPE);
|
||||
}
|
||||
OS_ENTER_CRITICAL();
|
||||
if (pevent->OSEventGrp != 0u) { /* See if any task pending on mailbox */
|
||||
/* Ready HPT waiting on event */
|
||||
(void)OS_EventTaskRdy(pevent, pmsg, OS_STAT_MBOX, OS_STAT_PEND_OK);
|
||||
OS_EXIT_CRITICAL();
|
||||
OS_Sched(); /* Find highest priority task ready to run */
|
||||
return (OS_ERR_NONE);
|
||||
}
|
||||
if (pevent->OSEventPtr != (void *)0) { /* Make sure mailbox doesn't already have a msg */
|
||||
OS_EXIT_CRITICAL();
|
||||
return (OS_ERR_MBOX_FULL);
|
||||
}
|
||||
pevent->OSEventPtr = pmsg; /* Place message in mailbox */
|
||||
OS_EXIT_CRITICAL();
|
||||
return (OS_ERR_NONE);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*$PAGE*/
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* POST MESSAGE TO A MAILBOX
|
||||
*
|
||||
* Description: This function sends a message to a mailbox
|
||||
*
|
||||
* Arguments : pevent is a pointer to the event control block associated with the desired mailbox
|
||||
*
|
||||
* pmsg is a pointer to the message to send. You MUST NOT send a NULL pointer.
|
||||
*
|
||||
* opt determines the type of POST performed:
|
||||
* OS_POST_OPT_NONE POST to a single waiting task
|
||||
* (Identical to OSMboxPost())
|
||||
* OS_POST_OPT_BROADCAST POST to ALL tasks that are waiting on the mailbox
|
||||
*
|
||||
* OS_POST_OPT_NO_SCHED Indicates that the scheduler will NOT be invoked
|
||||
*
|
||||
* Returns : OS_ERR_NONE The call was successful and the message was sent
|
||||
* OS_ERR_MBOX_FULL If the mailbox already contains a message. You can can only send one
|
||||
* message at a time and thus, the message MUST be consumed before you
|
||||
* are allowed to send another one.
|
||||
* OS_ERR_EVENT_TYPE If you are attempting to post to a non mailbox.
|
||||
* OS_ERR_PEVENT_NULL If 'pevent' is a NULL pointer
|
||||
* OS_ERR_POST_NULL_PTR If you are attempting to post a NULL pointer
|
||||
*
|
||||
* Note(s) : 1) HPT means Highest Priority Task
|
||||
*
|
||||
* Warning : Interrupts can be disabled for a long time if you do a 'broadcast'. In fact, the
|
||||
* interrupt disable time is proportional to the number of tasks waiting on the mailbox.
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
#if OS_MBOX_POST_OPT_EN > 0u
|
||||
INT8U OSMboxPostOpt (OS_EVENT *pevent,
|
||||
void *pmsg,
|
||||
INT8U opt)
|
||||
{
|
||||
#if OS_CRITICAL_METHOD == 3u /* Allocate storage for CPU status register */
|
||||
OS_CPU_SR cpu_sr = 0u;
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#if OS_ARG_CHK_EN > 0u
|
||||
if (pevent == (OS_EVENT *)0) { /* Validate 'pevent' */
|
||||
return (OS_ERR_PEVENT_NULL);
|
||||
}
|
||||
if (pmsg == (void *)0) { /* Make sure we are not posting a NULL pointer */
|
||||
return (OS_ERR_POST_NULL_PTR);
|
||||
}
|
||||
#endif
|
||||
if (pevent->OSEventType != OS_EVENT_TYPE_MBOX) { /* Validate event block type */
|
||||
return (OS_ERR_EVENT_TYPE);
|
||||
}
|
||||
OS_ENTER_CRITICAL();
|
||||
if (pevent->OSEventGrp != 0u) { /* See if any task pending on mailbox */
|
||||
if ((opt & OS_POST_OPT_BROADCAST) != 0x00u) { /* Do we need to post msg to ALL waiting tasks ? */
|
||||
while (pevent->OSEventGrp != 0u) { /* Yes, Post to ALL tasks waiting on mailbox */
|
||||
(void)OS_EventTaskRdy(pevent, pmsg, OS_STAT_MBOX, OS_STAT_PEND_OK);
|
||||
}
|
||||
} else { /* No, Post to HPT waiting on mbox */
|
||||
(void)OS_EventTaskRdy(pevent, pmsg, OS_STAT_MBOX, OS_STAT_PEND_OK);
|
||||
}
|
||||
OS_EXIT_CRITICAL();
|
||||
if ((opt & OS_POST_OPT_NO_SCHED) == 0u) { /* See if scheduler needs to be invoked */
|
||||
OS_Sched(); /* Find HPT ready to run */
|
||||
}
|
||||
return (OS_ERR_NONE);
|
||||
}
|
||||
if (pevent->OSEventPtr != (void *)0) { /* Make sure mailbox doesn't already have a msg */
|
||||
OS_EXIT_CRITICAL();
|
||||
return (OS_ERR_MBOX_FULL);
|
||||
}
|
||||
pevent->OSEventPtr = pmsg; /* Place message in mailbox */
|
||||
OS_EXIT_CRITICAL();
|
||||
return (OS_ERR_NONE);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*$PAGE*/
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* QUERY A MESSAGE MAILBOX
|
||||
*
|
||||
* Description: This function obtains information about a message mailbox.
|
||||
*
|
||||
* Arguments : pevent is a pointer to the event control block associated with the desired mailbox
|
||||
*
|
||||
* p_mbox_data is a pointer to a structure that will contain information about the message
|
||||
* mailbox.
|
||||
*
|
||||
* Returns : OS_ERR_NONE The call was successful and the message was sent
|
||||
* OS_ERR_EVENT_TYPE If you are attempting to obtain data from a non mailbox.
|
||||
* OS_ERR_PEVENT_NULL If 'pevent' is a NULL pointer
|
||||
* OS_ERR_PDATA_NULL If 'p_mbox_data' is a NULL pointer
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
#if OS_MBOX_QUERY_EN > 0u
|
||||
INT8U OSMboxQuery (OS_EVENT *pevent,
|
||||
OS_MBOX_DATA *p_mbox_data)
|
||||
{
|
||||
INT8U i;
|
||||
OS_PRIO *psrc;
|
||||
OS_PRIO *pdest;
|
||||
#if OS_CRITICAL_METHOD == 3u /* Allocate storage for CPU status register */
|
||||
OS_CPU_SR cpu_sr = 0u;
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#if OS_ARG_CHK_EN > 0u
|
||||
if (pevent == (OS_EVENT *)0) { /* Validate 'pevent' */
|
||||
return (OS_ERR_PEVENT_NULL);
|
||||
}
|
||||
if (p_mbox_data == (OS_MBOX_DATA *)0) { /* Validate 'p_mbox_data' */
|
||||
return (OS_ERR_PDATA_NULL);
|
||||
}
|
||||
#endif
|
||||
if (pevent->OSEventType != OS_EVENT_TYPE_MBOX) { /* Validate event block type */
|
||||
return (OS_ERR_EVENT_TYPE);
|
||||
}
|
||||
OS_ENTER_CRITICAL();
|
||||
p_mbox_data->OSEventGrp = pevent->OSEventGrp; /* Copy message mailbox wait list */
|
||||
psrc = &pevent->OSEventTbl[0];
|
||||
pdest = &p_mbox_data->OSEventTbl[0];
|
||||
for (i = 0u; i < OS_EVENT_TBL_SIZE; i++) {
|
||||
*pdest++ = *psrc++;
|
||||
}
|
||||
p_mbox_data->OSMsg = pevent->OSEventPtr; /* Get message from mailbox */
|
||||
OS_EXIT_CRITICAL();
|
||||
return (OS_ERR_NONE);
|
||||
}
|
||||
#endif /* OS_MBOX_QUERY_EN */
|
||||
#endif /* OS_MBOX_EN */
|
||||
|
||||
456
UCOSII/CORE/os_mem.c
Normal file
456
UCOSII/CORE/os_mem.c
Normal file
@@ -0,0 +1,456 @@
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* uC/OS-II
|
||||
* The Real-Time Kernel
|
||||
* MEMORY MANAGEMENT
|
||||
*
|
||||
* (c) Copyright 1992-2009, Micrium, Weston, FL
|
||||
* All Rights Reserved
|
||||
*
|
||||
* File : OS_MEM.C
|
||||
* By : Jean J. Labrosse
|
||||
* Version : V2.91
|
||||
*
|
||||
* LICENSING TERMS:
|
||||
* ---------------
|
||||
* uC/OS-II is provided in source form for FREE evaluation, for educational use or for peaceful research.
|
||||
* If you plan on using uC/OS-II in a commercial product you need to contact Micri<72>m to properly license
|
||||
* its use in your product. We provide ALL the source code for your convenience and to help you experience
|
||||
* uC/OS-II. The fact that the source is provided does NOT mean that you can use it without paying a
|
||||
* licensing fee.
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef OS_MASTER_FILE
|
||||
#include <ucos_ii.h>
|
||||
#endif
|
||||
|
||||
#if (OS_MEM_EN > 0u) && (OS_MAX_MEM_PART > 0u)
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* CREATE A MEMORY PARTITION
|
||||
*
|
||||
* Description : Create a fixed-sized memory partition that will be managed by uC/OS-II.
|
||||
*
|
||||
* Arguments : addr is the starting address of the memory partition
|
||||
*
|
||||
* nblks is the number of memory blocks to create from the partition.
|
||||
*
|
||||
* blksize is the size (in bytes) of each block in the memory partition.
|
||||
*
|
||||
* perr is a pointer to a variable containing an error message which will be set by
|
||||
* this function to either:
|
||||
*
|
||||
* OS_ERR_NONE if the memory partition has been created correctly.
|
||||
* OS_ERR_MEM_INVALID_ADDR if you are specifying an invalid address for the memory
|
||||
* storage of the partition or, the block does not align
|
||||
* on a pointer boundary
|
||||
* OS_ERR_MEM_INVALID_PART no free partitions available
|
||||
* OS_ERR_MEM_INVALID_BLKS user specified an invalid number of blocks (must be >= 2)
|
||||
* OS_ERR_MEM_INVALID_SIZE user specified an invalid block size
|
||||
* - must be greater than the size of a pointer
|
||||
* - must be able to hold an integral number of pointers
|
||||
* Returns : != (OS_MEM *)0 is the partition was created
|
||||
* == (OS_MEM *)0 if the partition was not created because of invalid arguments or, no
|
||||
* free partition is available.
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
OS_MEM *OSMemCreate (void *addr,
|
||||
INT32U nblks,
|
||||
INT32U blksize,
|
||||
INT8U *perr)
|
||||
{
|
||||
OS_MEM *pmem;
|
||||
INT8U *pblk;
|
||||
void **plink;
|
||||
INT32U loops;
|
||||
INT32U i;
|
||||
#if OS_CRITICAL_METHOD == 3u /* Allocate storage for CPU status register */
|
||||
OS_CPU_SR cpu_sr = 0u;
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#ifdef OS_SAFETY_CRITICAL
|
||||
if (perr == (INT8U *)0) {
|
||||
OS_SAFETY_CRITICAL_EXCEPTION();
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef OS_SAFETY_CRITICAL_IEC61508
|
||||
if (OSSafetyCriticalStartFlag == OS_TRUE) {
|
||||
OS_SAFETY_CRITICAL_EXCEPTION();
|
||||
}
|
||||
#endif
|
||||
|
||||
#if OS_ARG_CHK_EN > 0u
|
||||
if (addr == (void *)0) { /* Must pass a valid address for the memory part.*/
|
||||
*perr = OS_ERR_MEM_INVALID_ADDR;
|
||||
return ((OS_MEM *)0);
|
||||
}
|
||||
if (((INT32U)addr & (sizeof(void *) - 1u)) != 0u){ /* Must be pointer size aligned */
|
||||
*perr = OS_ERR_MEM_INVALID_ADDR;
|
||||
return ((OS_MEM *)0);
|
||||
}
|
||||
if (nblks < 2u) { /* Must have at least 2 blocks per partition */
|
||||
*perr = OS_ERR_MEM_INVALID_BLKS;
|
||||
return ((OS_MEM *)0);
|
||||
}
|
||||
if (blksize < sizeof(void *)) { /* Must contain space for at least a pointer */
|
||||
*perr = OS_ERR_MEM_INVALID_SIZE;
|
||||
return ((OS_MEM *)0);
|
||||
}
|
||||
#endif
|
||||
OS_ENTER_CRITICAL();
|
||||
pmem = OSMemFreeList; /* Get next free memory partition */
|
||||
if (OSMemFreeList != (OS_MEM *)0) { /* See if pool of free partitions was empty */
|
||||
OSMemFreeList = (OS_MEM *)OSMemFreeList->OSMemFreeList;
|
||||
}
|
||||
OS_EXIT_CRITICAL();
|
||||
if (pmem == (OS_MEM *)0) { /* See if we have a memory partition */
|
||||
*perr = OS_ERR_MEM_INVALID_PART;
|
||||
return ((OS_MEM *)0);
|
||||
}
|
||||
plink = (void **)addr; /* Create linked list of free memory blocks */
|
||||
pblk = (INT8U *)addr;
|
||||
loops = nblks - 1u;
|
||||
for (i = 0u; i < loops; i++) {
|
||||
pblk += blksize; /* Point to the FOLLOWING block */
|
||||
*plink = (void *)pblk; /* Save pointer to NEXT block in CURRENT block */
|
||||
plink = (void **)pblk; /* Position to NEXT block */
|
||||
}
|
||||
*plink = (void *)0; /* Last memory block points to NULL */
|
||||
pmem->OSMemAddr = addr; /* Store start address of memory partition */
|
||||
pmem->OSMemFreeList = addr; /* Initialize pointer to pool of free blocks */
|
||||
pmem->OSMemNFree = nblks; /* Store number of free blocks in MCB */
|
||||
pmem->OSMemNBlks = nblks;
|
||||
pmem->OSMemBlkSize = blksize; /* Store block size of each memory blocks */
|
||||
*perr = OS_ERR_NONE;
|
||||
return (pmem);
|
||||
}
|
||||
/*$PAGE*/
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* GET A MEMORY BLOCK
|
||||
*
|
||||
* Description : Get a memory block from a partition
|
||||
*
|
||||
* Arguments : pmem is a pointer to the memory partition control block
|
||||
*
|
||||
* perr is a pointer to a variable containing an error message which will be set by this
|
||||
* function to either:
|
||||
*
|
||||
* OS_ERR_NONE if the memory partition has been created correctly.
|
||||
* OS_ERR_MEM_NO_FREE_BLKS if there are no more free memory blocks to allocate to caller
|
||||
* OS_ERR_MEM_INVALID_PMEM if you passed a NULL pointer for 'pmem'
|
||||
*
|
||||
* Returns : A pointer to a memory block if no error is detected
|
||||
* A pointer to NULL if an error is detected
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
void *OSMemGet (OS_MEM *pmem,
|
||||
INT8U *perr)
|
||||
{
|
||||
void *pblk;
|
||||
#if OS_CRITICAL_METHOD == 3u /* Allocate storage for CPU status register */
|
||||
OS_CPU_SR cpu_sr = 0u;
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#ifdef OS_SAFETY_CRITICAL
|
||||
if (perr == (INT8U *)0) {
|
||||
OS_SAFETY_CRITICAL_EXCEPTION();
|
||||
}
|
||||
#endif
|
||||
|
||||
#if OS_ARG_CHK_EN > 0u
|
||||
if (pmem == (OS_MEM *)0) { /* Must point to a valid memory partition */
|
||||
*perr = OS_ERR_MEM_INVALID_PMEM;
|
||||
return ((void *)0);
|
||||
}
|
||||
#endif
|
||||
OS_ENTER_CRITICAL();
|
||||
if (pmem->OSMemNFree > 0u) { /* See if there are any free memory blocks */
|
||||
pblk = pmem->OSMemFreeList; /* Yes, point to next free memory block */
|
||||
pmem->OSMemFreeList = *(void **)pblk; /* Adjust pointer to new free list */
|
||||
pmem->OSMemNFree--; /* One less memory block in this partition */
|
||||
OS_EXIT_CRITICAL();
|
||||
*perr = OS_ERR_NONE; /* No error */
|
||||
return (pblk); /* Return memory block to caller */
|
||||
}
|
||||
OS_EXIT_CRITICAL();
|
||||
*perr = OS_ERR_MEM_NO_FREE_BLKS; /* No, Notify caller of empty memory partition */
|
||||
return ((void *)0); /* Return NULL pointer to caller */
|
||||
}
|
||||
/*$PAGE*/
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* GET THE NAME OF A MEMORY PARTITION
|
||||
*
|
||||
* Description: This function is used to obtain the name assigned to a memory partition.
|
||||
*
|
||||
* Arguments : pmem is a pointer to the memory partition
|
||||
*
|
||||
* pname is a pointer to a pointer to an ASCII string that will receive the name of the memory partition.
|
||||
*
|
||||
* perr is a pointer to an error code that can contain one of the following values:
|
||||
*
|
||||
* OS_ERR_NONE if the name was copied to 'pname'
|
||||
* OS_ERR_MEM_INVALID_PMEM if you passed a NULL pointer for 'pmem'
|
||||
* OS_ERR_PNAME_NULL You passed a NULL pointer for 'pname'
|
||||
* OS_ERR_NAME_GET_ISR You called this function from an ISR
|
||||
*
|
||||
* Returns : The length of the string or 0 if 'pmem' is a NULL pointer.
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
#if OS_MEM_NAME_EN > 0u
|
||||
INT8U OSMemNameGet (OS_MEM *pmem,
|
||||
INT8U **pname,
|
||||
INT8U *perr)
|
||||
{
|
||||
INT8U len;
|
||||
#if OS_CRITICAL_METHOD == 3u /* Allocate storage for CPU status register */
|
||||
OS_CPU_SR cpu_sr = 0u;
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#ifdef OS_SAFETY_CRITICAL
|
||||
if (perr == (INT8U *)0) {
|
||||
OS_SAFETY_CRITICAL_EXCEPTION();
|
||||
}
|
||||
#endif
|
||||
|
||||
#if OS_ARG_CHK_EN > 0u
|
||||
if (pmem == (OS_MEM *)0) { /* Is 'pmem' a NULL pointer? */
|
||||
*perr = OS_ERR_MEM_INVALID_PMEM;
|
||||
return (0u);
|
||||
}
|
||||
if (pname == (INT8U **)0) { /* Is 'pname' a NULL pointer? */
|
||||
*perr = OS_ERR_PNAME_NULL;
|
||||
return (0u);
|
||||
}
|
||||
#endif
|
||||
if (OSIntNesting > 0u) { /* See if trying to call from an ISR */
|
||||
*perr = OS_ERR_NAME_GET_ISR;
|
||||
return (0u);
|
||||
}
|
||||
OS_ENTER_CRITICAL();
|
||||
*pname = pmem->OSMemName;
|
||||
len = OS_StrLen(*pname);
|
||||
OS_EXIT_CRITICAL();
|
||||
*perr = OS_ERR_NONE;
|
||||
return (len);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*$PAGE*/
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* ASSIGN A NAME TO A MEMORY PARTITION
|
||||
*
|
||||
* Description: This function assigns a name to a memory partition.
|
||||
*
|
||||
* Arguments : pmem is a pointer to the memory partition
|
||||
*
|
||||
* pname is a pointer to an ASCII string that contains the name of the memory partition.
|
||||
*
|
||||
* perr is a pointer to an error code that can contain one of the following values:
|
||||
*
|
||||
* OS_ERR_NONE if the name was copied to 'pname'
|
||||
* OS_ERR_MEM_INVALID_PMEM if you passed a NULL pointer for 'pmem'
|
||||
* OS_ERR_PNAME_NULL You passed a NULL pointer for 'pname'
|
||||
* OS_ERR_MEM_NAME_TOO_LONG if the name doesn't fit in the storage area
|
||||
* OS_ERR_NAME_SET_ISR if you called this function from an ISR
|
||||
*
|
||||
* Returns : None
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
#if OS_MEM_NAME_EN > 0u
|
||||
void OSMemNameSet (OS_MEM *pmem,
|
||||
INT8U *pname,
|
||||
INT8U *perr)
|
||||
{
|
||||
#if OS_CRITICAL_METHOD == 3u /* Allocate storage for CPU status register */
|
||||
OS_CPU_SR cpu_sr = 0u;
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#ifdef OS_SAFETY_CRITICAL
|
||||
if (perr == (INT8U *)0) {
|
||||
OS_SAFETY_CRITICAL_EXCEPTION();
|
||||
}
|
||||
#endif
|
||||
|
||||
#if OS_ARG_CHK_EN > 0u
|
||||
if (pmem == (OS_MEM *)0) { /* Is 'pmem' a NULL pointer? */
|
||||
*perr = OS_ERR_MEM_INVALID_PMEM;
|
||||
return;
|
||||
}
|
||||
if (pname == (INT8U *)0) { /* Is 'pname' a NULL pointer? */
|
||||
*perr = OS_ERR_PNAME_NULL;
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
if (OSIntNesting > 0u) { /* See if trying to call from an ISR */
|
||||
*perr = OS_ERR_NAME_SET_ISR;
|
||||
return;
|
||||
}
|
||||
OS_ENTER_CRITICAL();
|
||||
pmem->OSMemName = pname;
|
||||
OS_EXIT_CRITICAL();
|
||||
*perr = OS_ERR_NONE;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*$PAGE*/
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* RELEASE A MEMORY BLOCK
|
||||
*
|
||||
* Description : Returns a memory block to a partition
|
||||
*
|
||||
* Arguments : pmem is a pointer to the memory partition control block
|
||||
*
|
||||
* pblk is a pointer to the memory block being released.
|
||||
*
|
||||
* Returns : OS_ERR_NONE if the memory block was inserted into the partition
|
||||
* OS_ERR_MEM_FULL if you are returning a memory block to an already FULL memory
|
||||
* partition (You freed more blocks than you allocated!)
|
||||
* OS_ERR_MEM_INVALID_PMEM if you passed a NULL pointer for 'pmem'
|
||||
* OS_ERR_MEM_INVALID_PBLK if you passed a NULL pointer for the block to release.
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
INT8U OSMemPut (OS_MEM *pmem,
|
||||
void *pblk)
|
||||
{
|
||||
#if OS_CRITICAL_METHOD == 3u /* Allocate storage for CPU status register */
|
||||
OS_CPU_SR cpu_sr = 0u;
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#if OS_ARG_CHK_EN > 0u
|
||||
if (pmem == (OS_MEM *)0) { /* Must point to a valid memory partition */
|
||||
return (OS_ERR_MEM_INVALID_PMEM);
|
||||
}
|
||||
if (pblk == (void *)0) { /* Must release a valid block */
|
||||
return (OS_ERR_MEM_INVALID_PBLK);
|
||||
}
|
||||
#endif
|
||||
OS_ENTER_CRITICAL();
|
||||
if (pmem->OSMemNFree >= pmem->OSMemNBlks) { /* Make sure all blocks not already returned */
|
||||
OS_EXIT_CRITICAL();
|
||||
return (OS_ERR_MEM_FULL);
|
||||
}
|
||||
*(void **)pblk = pmem->OSMemFreeList; /* Insert released block into free block list */
|
||||
pmem->OSMemFreeList = pblk;
|
||||
pmem->OSMemNFree++; /* One more memory block in this partition */
|
||||
OS_EXIT_CRITICAL();
|
||||
return (OS_ERR_NONE); /* Notify caller that memory block was released */
|
||||
}
|
||||
/*$PAGE*/
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* QUERY MEMORY PARTITION
|
||||
*
|
||||
* Description : This function is used to determine the number of free memory blocks and the number of
|
||||
* used memory blocks from a memory partition.
|
||||
*
|
||||
* Arguments : pmem is a pointer to the memory partition control block
|
||||
*
|
||||
* p_mem_data is a pointer to a structure that will contain information about the memory
|
||||
* partition.
|
||||
*
|
||||
* Returns : OS_ERR_NONE if no errors were found.
|
||||
* OS_ERR_MEM_INVALID_PMEM if you passed a NULL pointer for 'pmem'
|
||||
* OS_ERR_MEM_INVALID_PDATA if you passed a NULL pointer to the data recipient.
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
#if OS_MEM_QUERY_EN > 0u
|
||||
INT8U OSMemQuery (OS_MEM *pmem,
|
||||
OS_MEM_DATA *p_mem_data)
|
||||
{
|
||||
#if OS_CRITICAL_METHOD == 3u /* Allocate storage for CPU status register */
|
||||
OS_CPU_SR cpu_sr = 0u;
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#if OS_ARG_CHK_EN > 0u
|
||||
if (pmem == (OS_MEM *)0) { /* Must point to a valid memory partition */
|
||||
return (OS_ERR_MEM_INVALID_PMEM);
|
||||
}
|
||||
if (p_mem_data == (OS_MEM_DATA *)0) { /* Must release a valid storage area for the data */
|
||||
return (OS_ERR_MEM_INVALID_PDATA);
|
||||
}
|
||||
#endif
|
||||
OS_ENTER_CRITICAL();
|
||||
p_mem_data->OSAddr = pmem->OSMemAddr;
|
||||
p_mem_data->OSFreeList = pmem->OSMemFreeList;
|
||||
p_mem_data->OSBlkSize = pmem->OSMemBlkSize;
|
||||
p_mem_data->OSNBlks = pmem->OSMemNBlks;
|
||||
p_mem_data->OSNFree = pmem->OSMemNFree;
|
||||
OS_EXIT_CRITICAL();
|
||||
p_mem_data->OSNUsed = p_mem_data->OSNBlks - p_mem_data->OSNFree;
|
||||
return (OS_ERR_NONE);
|
||||
}
|
||||
#endif /* OS_MEM_QUERY_EN */
|
||||
/*$PAGE*/
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* INITIALIZE MEMORY PARTITION MANAGER
|
||||
*
|
||||
* Description : This function is called by uC/OS-II to initialize the memory partition manager. Your
|
||||
* application MUST NOT call this function.
|
||||
*
|
||||
* Arguments : none
|
||||
*
|
||||
* Returns : none
|
||||
*
|
||||
* Note(s) : This function is INTERNAL to uC/OS-II and your application should not call it.
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
void OS_MemInit (void)
|
||||
{
|
||||
#if OS_MAX_MEM_PART == 1u
|
||||
OS_MemClr((INT8U *)&OSMemTbl[0], sizeof(OSMemTbl)); /* Clear the memory partition table */
|
||||
OSMemFreeList = (OS_MEM *)&OSMemTbl[0]; /* Point to beginning of free list */
|
||||
#if OS_MEM_NAME_EN > 0u
|
||||
OSMemFreeList->OSMemName = (INT8U *)"?"; /* Unknown name */
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if OS_MAX_MEM_PART >= 2u
|
||||
OS_MEM *pmem;
|
||||
INT16U i;
|
||||
|
||||
|
||||
OS_MemClr((INT8U *)&OSMemTbl[0], sizeof(OSMemTbl)); /* Clear the memory partition table */
|
||||
for (i = 0u; i < (OS_MAX_MEM_PART - 1u); i++) { /* Init. list of free memory partitions */
|
||||
pmem = &OSMemTbl[i]; /* Point to memory control block (MCB) */
|
||||
pmem->OSMemFreeList = (void *)&OSMemTbl[i + 1u]; /* Chain list of free partitions */
|
||||
#if OS_MEM_NAME_EN > 0u
|
||||
pmem->OSMemName = (INT8U *)(void *)"?";
|
||||
#endif
|
||||
}
|
||||
pmem = &OSMemTbl[i];
|
||||
pmem->OSMemFreeList = (void *)0; /* Initialize last node */
|
||||
#if OS_MEM_NAME_EN > 0u
|
||||
pmem->OSMemName = (INT8U *)(void *)"?";
|
||||
#endif
|
||||
|
||||
OSMemFreeList = &OSMemTbl[0]; /* Point to beginning of free list */
|
||||
#endif
|
||||
}
|
||||
#endif /* OS_MEM_EN */
|
||||
|
||||
735
UCOSII/CORE/os_mutex.c
Normal file
735
UCOSII/CORE/os_mutex.c
Normal file
@@ -0,0 +1,735 @@
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* uC/OS-II
|
||||
* The Real-Time Kernel
|
||||
* MUTUAL EXCLUSION SEMAPHORE MANAGEMENT
|
||||
*
|
||||
* (c) Copyright 1992-2009, Micrium, Weston, FL
|
||||
* All Rights Reserved
|
||||
*
|
||||
* File : OS_MUTEX.C
|
||||
* By : Jean J. Labrosse
|
||||
* Version : V2.91
|
||||
*
|
||||
* LICENSING TERMS:
|
||||
* ---------------
|
||||
* uC/OS-II is provided in source form for FREE evaluation, for educational use or for peaceful research.
|
||||
* If you plan on using uC/OS-II in a commercial product you need to contact Micri<72>m to properly license
|
||||
* its use in your product. We provide ALL the source code for your convenience and to help you experience
|
||||
* uC/OS-II. The fact that the source is provided does NOT mean that you can use it without paying a
|
||||
* licensing fee.
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef OS_MASTER_FILE
|
||||
#include <ucos_ii.h>
|
||||
#endif
|
||||
|
||||
|
||||
#if OS_MUTEX_EN > 0u
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* LOCAL CONSTANTS
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
#define OS_MUTEX_KEEP_LOWER_8 ((INT16U)0x00FFu)
|
||||
#define OS_MUTEX_KEEP_UPPER_8 ((INT16U)0xFF00u)
|
||||
|
||||
#define OS_MUTEX_AVAILABLE ((INT16U)0x00FFu)
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* LOCAL CONSTANTS
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
static void OSMutex_RdyAtPrio(OS_TCB *ptcb, INT8U prio);
|
||||
|
||||
/*$PAGE*/
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* ACCEPT MUTUAL EXCLUSION SEMAPHORE
|
||||
*
|
||||
* Description: This function checks the mutual exclusion semaphore to see if a resource is available.
|
||||
* Unlike OSMutexPend(), OSMutexAccept() does not suspend the calling task if the resource is
|
||||
* not available or the event did not occur.
|
||||
*
|
||||
* Arguments : pevent is a pointer to the event control block
|
||||
*
|
||||
* perr is a pointer to an error code which will be returned to your application:
|
||||
* OS_ERR_NONE if the call was successful.
|
||||
* OS_ERR_EVENT_TYPE if 'pevent' is not a pointer to a mutex
|
||||
* OS_ERR_PEVENT_NULL 'pevent' is a NULL pointer
|
||||
* OS_ERR_PEND_ISR if you called this function from an ISR
|
||||
* OS_ERR_PIP_LOWER If the priority of the task that owns the Mutex is
|
||||
* HIGHER (i.e. a lower number) than the PIP. This error
|
||||
* indicates that you did not set the PIP higher (lower
|
||||
* number) than ALL the tasks that compete for the Mutex.
|
||||
* Unfortunately, this is something that could not be
|
||||
* detected when the Mutex is created because we don't know
|
||||
* what tasks will be using the Mutex.
|
||||
*
|
||||
* Returns : == OS_TRUE if the resource is available, the mutual exclusion semaphore is acquired
|
||||
* == OS_FALSE a) if the resource is not available
|
||||
* b) you didn't pass a pointer to a mutual exclusion semaphore
|
||||
* c) you called this function from an ISR
|
||||
*
|
||||
* Warning(s) : This function CANNOT be called from an ISR because mutual exclusion semaphores are
|
||||
* intended to be used by tasks only.
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
#if OS_MUTEX_ACCEPT_EN > 0u
|
||||
BOOLEAN OSMutexAccept (OS_EVENT *pevent,
|
||||
INT8U *perr)
|
||||
{
|
||||
INT8U pip; /* Priority Inheritance Priority (PIP) */
|
||||
#if OS_CRITICAL_METHOD == 3u /* Allocate storage for CPU status register */
|
||||
OS_CPU_SR cpu_sr = 0u;
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#ifdef OS_SAFETY_CRITICAL
|
||||
if (perr == (INT8U *)0) {
|
||||
OS_SAFETY_CRITICAL_EXCEPTION();
|
||||
}
|
||||
#endif
|
||||
|
||||
#if OS_ARG_CHK_EN > 0u
|
||||
if (pevent == (OS_EVENT *)0) { /* Validate 'pevent' */
|
||||
*perr = OS_ERR_PEVENT_NULL;
|
||||
return (OS_FALSE);
|
||||
}
|
||||
#endif
|
||||
if (pevent->OSEventType != OS_EVENT_TYPE_MUTEX) { /* Validate event block type */
|
||||
*perr = OS_ERR_EVENT_TYPE;
|
||||
return (OS_FALSE);
|
||||
}
|
||||
if (OSIntNesting > 0u) { /* Make sure it's not called from an ISR */
|
||||
*perr = OS_ERR_PEND_ISR;
|
||||
return (OS_FALSE);
|
||||
}
|
||||
OS_ENTER_CRITICAL(); /* Get value (0 or 1) of Mutex */
|
||||
pip = (INT8U)(pevent->OSEventCnt >> 8u); /* Get PIP from mutex */
|
||||
if ((pevent->OSEventCnt & OS_MUTEX_KEEP_LOWER_8) == OS_MUTEX_AVAILABLE) {
|
||||
pevent->OSEventCnt &= OS_MUTEX_KEEP_UPPER_8; /* Mask off LSByte (Acquire Mutex) */
|
||||
pevent->OSEventCnt |= OSTCBCur->OSTCBPrio; /* Save current task priority in LSByte */
|
||||
pevent->OSEventPtr = (void *)OSTCBCur; /* Link TCB of task owning Mutex */
|
||||
if (OSTCBCur->OSTCBPrio <= pip) { /* PIP 'must' have a SMALLER prio ... */
|
||||
OS_EXIT_CRITICAL(); /* ... than current task! */
|
||||
*perr = OS_ERR_PIP_LOWER;
|
||||
} else {
|
||||
OS_EXIT_CRITICAL();
|
||||
*perr = OS_ERR_NONE;
|
||||
}
|
||||
return (OS_TRUE);
|
||||
}
|
||||
OS_EXIT_CRITICAL();
|
||||
*perr = OS_ERR_NONE;
|
||||
return (OS_FALSE);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*$PAGE*/
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* CREATE A MUTUAL EXCLUSION SEMAPHORE
|
||||
*
|
||||
* Description: This function creates a mutual exclusion semaphore.
|
||||
*
|
||||
* Arguments : prio is the priority to use when accessing the mutual exclusion semaphore. In
|
||||
* other words, when the semaphore is acquired and a higher priority task
|
||||
* attempts to obtain the semaphore then the priority of the task owning the
|
||||
* semaphore is raised to this priority. It is assumed that you will specify
|
||||
* a priority that is LOWER in value than ANY of the tasks competing for the
|
||||
* mutex.
|
||||
*
|
||||
* perr is a pointer to an error code which will be returned to your application:
|
||||
* OS_ERR_NONE if the call was successful.
|
||||
* OS_ERR_CREATE_ISR if you attempted to create a MUTEX from an ISR
|
||||
* OS_ERR_PRIO_EXIST if a task at the priority inheritance priority
|
||||
* already exist.
|
||||
* OS_ERR_PEVENT_NULL No more event control blocks available.
|
||||
* OS_ERR_PRIO_INVALID if the priority you specify is higher that the
|
||||
* maximum allowed (i.e. > OS_LOWEST_PRIO)
|
||||
*
|
||||
* Returns : != (void *)0 is a pointer to the event control clock (OS_EVENT) associated with the
|
||||
* created mutex.
|
||||
* == (void *)0 if an error is detected.
|
||||
*
|
||||
* Note(s) : 1) The LEAST significant 8 bits of '.OSEventCnt' are used to hold the priority number
|
||||
* of the task owning the mutex or 0xFF if no task owns the mutex.
|
||||
*
|
||||
* 2) The MOST significant 8 bits of '.OSEventCnt' are used to hold the priority number
|
||||
* to use to reduce priority inversion.
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
OS_EVENT *OSMutexCreate (INT8U prio,
|
||||
INT8U *perr)
|
||||
{
|
||||
OS_EVENT *pevent;
|
||||
#if OS_CRITICAL_METHOD == 3u /* Allocate storage for CPU status register */
|
||||
OS_CPU_SR cpu_sr = 0u;
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#ifdef OS_SAFETY_CRITICAL
|
||||
if (perr == (INT8U *)0) {
|
||||
OS_SAFETY_CRITICAL_EXCEPTION();
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef OS_SAFETY_CRITICAL_IEC61508
|
||||
if (OSSafetyCriticalStartFlag == OS_TRUE) {
|
||||
OS_SAFETY_CRITICAL_EXCEPTION();
|
||||
}
|
||||
#endif
|
||||
|
||||
#if OS_ARG_CHK_EN > 0u
|
||||
if (prio >= OS_LOWEST_PRIO) { /* Validate PIP */
|
||||
*perr = OS_ERR_PRIO_INVALID;
|
||||
return ((OS_EVENT *)0);
|
||||
}
|
||||
#endif
|
||||
if (OSIntNesting > 0u) { /* See if called from ISR ... */
|
||||
*perr = OS_ERR_CREATE_ISR; /* ... can't CREATE mutex from an ISR */
|
||||
return ((OS_EVENT *)0);
|
||||
}
|
||||
OS_ENTER_CRITICAL();
|
||||
if (OSTCBPrioTbl[prio] != (OS_TCB *)0) { /* Mutex priority must not already exist */
|
||||
OS_EXIT_CRITICAL(); /* Task already exist at priority ... */
|
||||
*perr = OS_ERR_PRIO_EXIST; /* ... inheritance priority */
|
||||
return ((OS_EVENT *)0);
|
||||
}
|
||||
OSTCBPrioTbl[prio] = OS_TCB_RESERVED; /* Reserve the table entry */
|
||||
pevent = OSEventFreeList; /* Get next free event control block */
|
||||
if (pevent == (OS_EVENT *)0) { /* See if an ECB was available */
|
||||
OSTCBPrioTbl[prio] = (OS_TCB *)0; /* No, Release the table entry */
|
||||
OS_EXIT_CRITICAL();
|
||||
*perr = OS_ERR_PEVENT_NULL; /* No more event control blocks */
|
||||
return (pevent);
|
||||
}
|
||||
OSEventFreeList = (OS_EVENT *)OSEventFreeList->OSEventPtr; /* Adjust the free list */
|
||||
OS_EXIT_CRITICAL();
|
||||
pevent->OSEventType = OS_EVENT_TYPE_MUTEX;
|
||||
pevent->OSEventCnt = (INT16U)((INT16U)prio << 8u) | OS_MUTEX_AVAILABLE; /* Resource is avail. */
|
||||
pevent->OSEventPtr = (void *)0; /* No task owning the mutex */
|
||||
#if OS_EVENT_NAME_EN > 0u
|
||||
pevent->OSEventName = (INT8U *)(void *)"?";
|
||||
#endif
|
||||
OS_EventWaitListInit(pevent);
|
||||
*perr = OS_ERR_NONE;
|
||||
return (pevent);
|
||||
}
|
||||
|
||||
/*$PAGE*/
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* DELETE A MUTEX
|
||||
*
|
||||
* Description: This function deletes a mutual exclusion semaphore and readies all tasks pending on the it.
|
||||
*
|
||||
* Arguments : pevent is a pointer to the event control block associated with the desired mutex.
|
||||
*
|
||||
* opt determines delete options as follows:
|
||||
* opt == OS_DEL_NO_PEND Delete mutex ONLY if no task pending
|
||||
* opt == OS_DEL_ALWAYS Deletes the mutex even if tasks are waiting.
|
||||
* In this case, all the tasks pending will be readied.
|
||||
*
|
||||
* perr is a pointer to an error code that can contain one of the following values:
|
||||
* OS_ERR_NONE The call was successful and the mutex was deleted
|
||||
* OS_ERR_DEL_ISR If you attempted to delete the MUTEX from an ISR
|
||||
* OS_ERR_INVALID_OPT An invalid option was specified
|
||||
* OS_ERR_TASK_WAITING One or more tasks were waiting on the mutex
|
||||
* OS_ERR_EVENT_TYPE If you didn't pass a pointer to a mutex
|
||||
* OS_ERR_PEVENT_NULL If 'pevent' is a NULL pointer.
|
||||
*
|
||||
* Returns : pevent upon error
|
||||
* (OS_EVENT *)0 if the mutex was successfully deleted.
|
||||
*
|
||||
* Note(s) : 1) This function must be used with care. Tasks that would normally expect the presence of
|
||||
* the mutex MUST check the return code of OSMutexPend().
|
||||
*
|
||||
* 2) This call can potentially disable interrupts for a long time. The interrupt disable
|
||||
* time is directly proportional to the number of tasks waiting on the mutex.
|
||||
*
|
||||
* 3) Because ALL tasks pending on the mutex will be readied, you MUST be careful because the
|
||||
* resource(s) will no longer be guarded by the mutex.
|
||||
*
|
||||
* 4) IMPORTANT: In the 'OS_DEL_ALWAYS' case, we assume that the owner of the Mutex (if there
|
||||
* is one) is ready-to-run and is thus NOT pending on another kernel object or
|
||||
* has delayed itself. In other words, if a task owns the mutex being deleted,
|
||||
* that task will be made ready-to-run at its original priority.
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
#if OS_MUTEX_DEL_EN > 0u
|
||||
OS_EVENT *OSMutexDel (OS_EVENT *pevent,
|
||||
INT8U opt,
|
||||
INT8U *perr)
|
||||
{
|
||||
BOOLEAN tasks_waiting;
|
||||
OS_EVENT *pevent_return;
|
||||
INT8U pip; /* Priority inheritance priority */
|
||||
INT8U prio;
|
||||
OS_TCB *ptcb;
|
||||
#if OS_CRITICAL_METHOD == 3u /* Allocate storage for CPU status register */
|
||||
OS_CPU_SR cpu_sr = 0u;
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#ifdef OS_SAFETY_CRITICAL
|
||||
if (perr == (INT8U *)0) {
|
||||
OS_SAFETY_CRITICAL_EXCEPTION();
|
||||
}
|
||||
#endif
|
||||
|
||||
#if OS_ARG_CHK_EN > 0u
|
||||
if (pevent == (OS_EVENT *)0) { /* Validate 'pevent' */
|
||||
*perr = OS_ERR_PEVENT_NULL;
|
||||
return (pevent);
|
||||
}
|
||||
#endif
|
||||
if (pevent->OSEventType != OS_EVENT_TYPE_MUTEX) { /* Validate event block type */
|
||||
*perr = OS_ERR_EVENT_TYPE;
|
||||
return (pevent);
|
||||
}
|
||||
if (OSIntNesting > 0u) { /* See if called from ISR ... */
|
||||
*perr = OS_ERR_DEL_ISR; /* ... can't DELETE from an ISR */
|
||||
return (pevent);
|
||||
}
|
||||
OS_ENTER_CRITICAL();
|
||||
if (pevent->OSEventGrp != 0u) { /* See if any tasks waiting on mutex */
|
||||
tasks_waiting = OS_TRUE; /* Yes */
|
||||
} else {
|
||||
tasks_waiting = OS_FALSE; /* No */
|
||||
}
|
||||
switch (opt) {
|
||||
case OS_DEL_NO_PEND: /* DELETE MUTEX ONLY IF NO TASK WAITING --- */
|
||||
if (tasks_waiting == OS_FALSE) {
|
||||
#if OS_EVENT_NAME_EN > 0u
|
||||
pevent->OSEventName = (INT8U *)(void *)"?";
|
||||
#endif
|
||||
pip = (INT8U)(pevent->OSEventCnt >> 8u);
|
||||
OSTCBPrioTbl[pip] = (OS_TCB *)0; /* Free up the PIP */
|
||||
pevent->OSEventType = OS_EVENT_TYPE_UNUSED;
|
||||
pevent->OSEventPtr = OSEventFreeList; /* Return Event Control Block to free list */
|
||||
pevent->OSEventCnt = 0u;
|
||||
OSEventFreeList = pevent;
|
||||
OS_EXIT_CRITICAL();
|
||||
*perr = OS_ERR_NONE;
|
||||
pevent_return = (OS_EVENT *)0; /* Mutex has been deleted */
|
||||
} else {
|
||||
OS_EXIT_CRITICAL();
|
||||
*perr = OS_ERR_TASK_WAITING;
|
||||
pevent_return = pevent;
|
||||
}
|
||||
break;
|
||||
|
||||
case OS_DEL_ALWAYS: /* ALWAYS DELETE THE MUTEX ---------------- */
|
||||
pip = (INT8U)(pevent->OSEventCnt >> 8u); /* Get PIP of mutex */
|
||||
prio = (INT8U)(pevent->OSEventCnt & OS_MUTEX_KEEP_LOWER_8); /* Get owner's original prio */
|
||||
ptcb = (OS_TCB *)pevent->OSEventPtr;
|
||||
if (ptcb != (OS_TCB *)0) { /* See if any task owns the mutex */
|
||||
if (ptcb->OSTCBPrio == pip) { /* See if original prio was changed */
|
||||
OSMutex_RdyAtPrio(ptcb, prio); /* Yes, Restore the task's original prio */
|
||||
}
|
||||
}
|
||||
while (pevent->OSEventGrp != 0u) { /* Ready ALL tasks waiting for mutex */
|
||||
(void)OS_EventTaskRdy(pevent, (void *)0, OS_STAT_MUTEX, OS_STAT_PEND_OK);
|
||||
}
|
||||
#if OS_EVENT_NAME_EN > 0u
|
||||
pevent->OSEventName = (INT8U *)(void *)"?";
|
||||
#endif
|
||||
pip = (INT8U)(pevent->OSEventCnt >> 8u);
|
||||
OSTCBPrioTbl[pip] = (OS_TCB *)0; /* Free up the PIP */
|
||||
pevent->OSEventType = OS_EVENT_TYPE_UNUSED;
|
||||
pevent->OSEventPtr = OSEventFreeList; /* Return Event Control Block to free list */
|
||||
pevent->OSEventCnt = 0u;
|
||||
OSEventFreeList = pevent; /* Get next free event control block */
|
||||
OS_EXIT_CRITICAL();
|
||||
if (tasks_waiting == OS_TRUE) { /* Reschedule only if task(s) were waiting */
|
||||
OS_Sched(); /* Find highest priority task ready to run */
|
||||
}
|
||||
*perr = OS_ERR_NONE;
|
||||
pevent_return = (OS_EVENT *)0; /* Mutex has been deleted */
|
||||
break;
|
||||
|
||||
default:
|
||||
OS_EXIT_CRITICAL();
|
||||
*perr = OS_ERR_INVALID_OPT;
|
||||
pevent_return = pevent;
|
||||
break;
|
||||
}
|
||||
return (pevent_return);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*$PAGE*/
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* PEND ON MUTUAL EXCLUSION SEMAPHORE
|
||||
*
|
||||
* Description: This function waits for a mutual exclusion semaphore.
|
||||
*
|
||||
* Arguments : pevent is a pointer to the event control block associated with the desired
|
||||
* mutex.
|
||||
*
|
||||
* timeout is an optional timeout period (in clock ticks). If non-zero, your task will
|
||||
* wait for the resource up to the amount of time specified by this argument.
|
||||
* If you specify 0, however, your task will wait forever at the specified
|
||||
* mutex or, until the resource becomes available.
|
||||
*
|
||||
* perr is a pointer to where an error message will be deposited. Possible error
|
||||
* messages are:
|
||||
* OS_ERR_NONE The call was successful and your task owns the mutex
|
||||
* OS_ERR_TIMEOUT The mutex was not available within the specified 'timeout'.
|
||||
* OS_ERR_PEND_ABORT The wait on the mutex was aborted.
|
||||
* OS_ERR_EVENT_TYPE If you didn't pass a pointer to a mutex
|
||||
* OS_ERR_PEVENT_NULL 'pevent' is a NULL pointer
|
||||
* OS_ERR_PEND_ISR If you called this function from an ISR and the result
|
||||
* would lead to a suspension.
|
||||
* OS_ERR_PIP_LOWER If the priority of the task that owns the Mutex is
|
||||
* HIGHER (i.e. a lower number) than the PIP. This error
|
||||
* indicates that you did not set the PIP higher (lower
|
||||
* number) than ALL the tasks that compete for the Mutex.
|
||||
* Unfortunately, this is something that could not be
|
||||
* detected when the Mutex is created because we don't know
|
||||
* what tasks will be using the Mutex.
|
||||
* OS_ERR_PEND_LOCKED If you called this function when the scheduler is locked
|
||||
*
|
||||
* Returns : none
|
||||
*
|
||||
* Note(s) : 1) The task that owns the Mutex MUST NOT pend on any other event while it owns the mutex.
|
||||
*
|
||||
* 2) You MUST NOT change the priority of the task that owns the mutex
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
void OSMutexPend (OS_EVENT *pevent,
|
||||
INT32U timeout,
|
||||
INT8U *perr)
|
||||
{
|
||||
INT8U pip; /* Priority Inheritance Priority (PIP) */
|
||||
INT8U mprio; /* Mutex owner priority */
|
||||
BOOLEAN rdy; /* Flag indicating task was ready */
|
||||
OS_TCB *ptcb;
|
||||
OS_EVENT *pevent2;
|
||||
INT8U y;
|
||||
#if OS_CRITICAL_METHOD == 3u /* Allocate storage for CPU status register */
|
||||
OS_CPU_SR cpu_sr = 0u;
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#ifdef OS_SAFETY_CRITICAL
|
||||
if (perr == (INT8U *)0) {
|
||||
OS_SAFETY_CRITICAL_EXCEPTION();
|
||||
}
|
||||
#endif
|
||||
|
||||
#if OS_ARG_CHK_EN > 0u
|
||||
if (pevent == (OS_EVENT *)0) { /* Validate 'pevent' */
|
||||
*perr = OS_ERR_PEVENT_NULL;
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
if (pevent->OSEventType != OS_EVENT_TYPE_MUTEX) { /* Validate event block type */
|
||||
*perr = OS_ERR_EVENT_TYPE;
|
||||
return;
|
||||
}
|
||||
if (OSIntNesting > 0u) { /* See if called from ISR ... */
|
||||
*perr = OS_ERR_PEND_ISR; /* ... can't PEND from an ISR */
|
||||
return;
|
||||
}
|
||||
if (OSLockNesting > 0u) { /* See if called with scheduler locked ... */
|
||||
*perr = OS_ERR_PEND_LOCKED; /* ... can't PEND when locked */
|
||||
return;
|
||||
}
|
||||
/*$PAGE*/
|
||||
OS_ENTER_CRITICAL();
|
||||
pip = (INT8U)(pevent->OSEventCnt >> 8u); /* Get PIP from mutex */
|
||||
/* Is Mutex available? */
|
||||
if ((INT8U)(pevent->OSEventCnt & OS_MUTEX_KEEP_LOWER_8) == OS_MUTEX_AVAILABLE) {
|
||||
pevent->OSEventCnt &= OS_MUTEX_KEEP_UPPER_8; /* Yes, Acquire the resource */
|
||||
pevent->OSEventCnt |= OSTCBCur->OSTCBPrio; /* Save priority of owning task */
|
||||
pevent->OSEventPtr = (void *)OSTCBCur; /* Point to owning task's OS_TCB */
|
||||
if (OSTCBCur->OSTCBPrio <= pip) { /* PIP 'must' have a SMALLER prio ... */
|
||||
OS_EXIT_CRITICAL(); /* ... than current task! */
|
||||
*perr = OS_ERR_PIP_LOWER;
|
||||
} else {
|
||||
OS_EXIT_CRITICAL();
|
||||
*perr = OS_ERR_NONE;
|
||||
}
|
||||
return;
|
||||
}
|
||||
mprio = (INT8U)(pevent->OSEventCnt & OS_MUTEX_KEEP_LOWER_8); /* No, Get priority of mutex owner */
|
||||
ptcb = (OS_TCB *)(pevent->OSEventPtr); /* Point to TCB of mutex owner */
|
||||
if (ptcb->OSTCBPrio > pip) { /* Need to promote prio of owner?*/
|
||||
if (mprio > OSTCBCur->OSTCBPrio) {
|
||||
y = ptcb->OSTCBY;
|
||||
if ((OSRdyTbl[y] & ptcb->OSTCBBitX) != 0u) { /* See if mutex owner is ready */
|
||||
OSRdyTbl[y] &= (OS_PRIO)~ptcb->OSTCBBitX; /* Yes, Remove owner from Rdy ...*/
|
||||
if (OSRdyTbl[y] == 0u) { /* ... list at current prio */
|
||||
OSRdyGrp &= (OS_PRIO)~ptcb->OSTCBBitY;
|
||||
}
|
||||
rdy = OS_TRUE;
|
||||
} else {
|
||||
pevent2 = ptcb->OSTCBEventPtr;
|
||||
if (pevent2 != (OS_EVENT *)0) { /* Remove from event wait list */
|
||||
y = ptcb->OSTCBY;
|
||||
pevent2->OSEventTbl[y] &= (OS_PRIO)~ptcb->OSTCBBitX;
|
||||
if (pevent2->OSEventTbl[y] == 0u) {
|
||||
pevent2->OSEventGrp &= (OS_PRIO)~ptcb->OSTCBBitY;
|
||||
}
|
||||
}
|
||||
rdy = OS_FALSE; /* No */
|
||||
}
|
||||
ptcb->OSTCBPrio = pip; /* Change owner task prio to PIP */
|
||||
#if OS_LOWEST_PRIO <= 63u
|
||||
ptcb->OSTCBY = (INT8U)( ptcb->OSTCBPrio >> 3u);
|
||||
ptcb->OSTCBX = (INT8U)( ptcb->OSTCBPrio & 0x07u);
|
||||
#else
|
||||
ptcb->OSTCBY = (INT8U)((INT8U)(ptcb->OSTCBPrio >> 4u) & 0xFFu);
|
||||
ptcb->OSTCBX = (INT8U)( ptcb->OSTCBPrio & 0x0Fu);
|
||||
#endif
|
||||
ptcb->OSTCBBitY = (OS_PRIO)(1uL << ptcb->OSTCBY);
|
||||
ptcb->OSTCBBitX = (OS_PRIO)(1uL << ptcb->OSTCBX);
|
||||
|
||||
if (rdy == OS_TRUE) { /* If task was ready at owner's priority ...*/
|
||||
OSRdyGrp |= ptcb->OSTCBBitY; /* ... make it ready at new priority. */
|
||||
OSRdyTbl[ptcb->OSTCBY] |= ptcb->OSTCBBitX;
|
||||
} else {
|
||||
pevent2 = ptcb->OSTCBEventPtr;
|
||||
if (pevent2 != (OS_EVENT *)0) { /* Add to event wait list */
|
||||
pevent2->OSEventGrp |= ptcb->OSTCBBitY;
|
||||
pevent2->OSEventTbl[ptcb->OSTCBY] |= ptcb->OSTCBBitX;
|
||||
}
|
||||
}
|
||||
OSTCBPrioTbl[pip] = ptcb;
|
||||
}
|
||||
}
|
||||
OSTCBCur->OSTCBStat |= OS_STAT_MUTEX; /* Mutex not available, pend current task */
|
||||
OSTCBCur->OSTCBStatPend = OS_STAT_PEND_OK;
|
||||
OSTCBCur->OSTCBDly = timeout; /* Store timeout in current task's TCB */
|
||||
OS_EventTaskWait(pevent); /* Suspend task until event or timeout occurs */
|
||||
OS_EXIT_CRITICAL();
|
||||
OS_Sched(); /* Find next highest priority task ready */
|
||||
OS_ENTER_CRITICAL();
|
||||
switch (OSTCBCur->OSTCBStatPend) { /* See if we timed-out or aborted */
|
||||
case OS_STAT_PEND_OK:
|
||||
*perr = OS_ERR_NONE;
|
||||
break;
|
||||
|
||||
case OS_STAT_PEND_ABORT:
|
||||
*perr = OS_ERR_PEND_ABORT; /* Indicate that we aborted getting mutex */
|
||||
break;
|
||||
|
||||
case OS_STAT_PEND_TO:
|
||||
default:
|
||||
OS_EventTaskRemove(OSTCBCur, pevent);
|
||||
*perr = OS_ERR_TIMEOUT; /* Indicate that we didn't get mutex within TO */
|
||||
break;
|
||||
}
|
||||
OSTCBCur->OSTCBStat = OS_STAT_RDY; /* Set task status to ready */
|
||||
OSTCBCur->OSTCBStatPend = OS_STAT_PEND_OK; /* Clear pend status */
|
||||
OSTCBCur->OSTCBEventPtr = (OS_EVENT *)0; /* Clear event pointers */
|
||||
#if (OS_EVENT_MULTI_EN > 0u)
|
||||
OSTCBCur->OSTCBEventMultiPtr = (OS_EVENT **)0;
|
||||
#endif
|
||||
OS_EXIT_CRITICAL();
|
||||
}
|
||||
/*$PAGE*/
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* POST TO A MUTUAL EXCLUSION SEMAPHORE
|
||||
*
|
||||
* Description: This function signals a mutual exclusion semaphore
|
||||
*
|
||||
* Arguments : pevent is a pointer to the event control block associated with the desired
|
||||
* mutex.
|
||||
*
|
||||
* Returns : OS_ERR_NONE The call was successful and the mutex was signaled.
|
||||
* OS_ERR_EVENT_TYPE If you didn't pass a pointer to a mutex
|
||||
* OS_ERR_PEVENT_NULL 'pevent' is a NULL pointer
|
||||
* OS_ERR_POST_ISR Attempted to post from an ISR (not valid for MUTEXes)
|
||||
* OS_ERR_NOT_MUTEX_OWNER The task that did the post is NOT the owner of the MUTEX.
|
||||
* OS_ERR_PIP_LOWER If the priority of the new task that owns the Mutex is
|
||||
* HIGHER (i.e. a lower number) than the PIP. This error
|
||||
* indicates that you did not set the PIP higher (lower
|
||||
* number) than ALL the tasks that compete for the Mutex.
|
||||
* Unfortunately, this is something that could not be
|
||||
* detected when the Mutex is created because we don't know
|
||||
* what tasks will be using the Mutex.
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
INT8U OSMutexPost (OS_EVENT *pevent)
|
||||
{
|
||||
INT8U pip; /* Priority inheritance priority */
|
||||
INT8U prio;
|
||||
#if OS_CRITICAL_METHOD == 3u /* Allocate storage for CPU status register */
|
||||
OS_CPU_SR cpu_sr = 0u;
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
if (OSIntNesting > 0u) { /* See if called from ISR ... */
|
||||
return (OS_ERR_POST_ISR); /* ... can't POST mutex from an ISR */
|
||||
}
|
||||
#if OS_ARG_CHK_EN > 0u
|
||||
if (pevent == (OS_EVENT *)0) { /* Validate 'pevent' */
|
||||
return (OS_ERR_PEVENT_NULL);
|
||||
}
|
||||
#endif
|
||||
if (pevent->OSEventType != OS_EVENT_TYPE_MUTEX) { /* Validate event block type */
|
||||
return (OS_ERR_EVENT_TYPE);
|
||||
}
|
||||
OS_ENTER_CRITICAL();
|
||||
pip = (INT8U)(pevent->OSEventCnt >> 8u); /* Get priority inheritance priority of mutex */
|
||||
prio = (INT8U)(pevent->OSEventCnt & OS_MUTEX_KEEP_LOWER_8); /* Get owner's original priority */
|
||||
if (OSTCBCur != (OS_TCB *)pevent->OSEventPtr) { /* See if posting task owns the MUTEX */
|
||||
OS_EXIT_CRITICAL();
|
||||
return (OS_ERR_NOT_MUTEX_OWNER);
|
||||
}
|
||||
if (OSTCBCur->OSTCBPrio == pip) { /* Did we have to raise current task's priority? */
|
||||
OSMutex_RdyAtPrio(OSTCBCur, prio); /* Restore the task's original priority */
|
||||
}
|
||||
OSTCBPrioTbl[pip] = OS_TCB_RESERVED; /* Reserve table entry */
|
||||
if (pevent->OSEventGrp != 0u) { /* Any task waiting for the mutex? */
|
||||
/* Yes, Make HPT waiting for mutex ready */
|
||||
prio = OS_EventTaskRdy(pevent, (void *)0, OS_STAT_MUTEX, OS_STAT_PEND_OK);
|
||||
pevent->OSEventCnt &= OS_MUTEX_KEEP_UPPER_8; /* Save priority of mutex's new owner */
|
||||
pevent->OSEventCnt |= prio;
|
||||
pevent->OSEventPtr = OSTCBPrioTbl[prio]; /* Link to new mutex owner's OS_TCB */
|
||||
if (prio <= pip) { /* PIP 'must' have a SMALLER prio ... */
|
||||
OS_EXIT_CRITICAL(); /* ... than current task! */
|
||||
OS_Sched(); /* Find highest priority task ready to run */
|
||||
return (OS_ERR_PIP_LOWER);
|
||||
} else {
|
||||
OS_EXIT_CRITICAL();
|
||||
OS_Sched(); /* Find highest priority task ready to run */
|
||||
return (OS_ERR_NONE);
|
||||
}
|
||||
}
|
||||
pevent->OSEventCnt |= OS_MUTEX_AVAILABLE; /* No, Mutex is now available */
|
||||
pevent->OSEventPtr = (void *)0;
|
||||
OS_EXIT_CRITICAL();
|
||||
return (OS_ERR_NONE);
|
||||
}
|
||||
/*$PAGE*/
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* QUERY A MUTUAL EXCLUSION SEMAPHORE
|
||||
*
|
||||
* Description: This function obtains information about a mutex
|
||||
*
|
||||
* Arguments : pevent is a pointer to the event control block associated with the desired mutex
|
||||
*
|
||||
* p_mutex_data is a pointer to a structure that will contain information about the mutex
|
||||
*
|
||||
* Returns : OS_ERR_NONE The call was successful and the message was sent
|
||||
* OS_ERR_QUERY_ISR If you called this function from an ISR
|
||||
* OS_ERR_PEVENT_NULL If 'pevent' is a NULL pointer
|
||||
* OS_ERR_PDATA_NULL If 'p_mutex_data' is a NULL pointer
|
||||
* OS_ERR_EVENT_TYPE If you are attempting to obtain data from a non mutex.
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
#if OS_MUTEX_QUERY_EN > 0u
|
||||
INT8U OSMutexQuery (OS_EVENT *pevent,
|
||||
OS_MUTEX_DATA *p_mutex_data)
|
||||
{
|
||||
INT8U i;
|
||||
OS_PRIO *psrc;
|
||||
OS_PRIO *pdest;
|
||||
#if OS_CRITICAL_METHOD == 3u /* Allocate storage for CPU status register */
|
||||
OS_CPU_SR cpu_sr = 0u;
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
if (OSIntNesting > 0u) { /* See if called from ISR ... */
|
||||
return (OS_ERR_QUERY_ISR); /* ... can't QUERY mutex from an ISR */
|
||||
}
|
||||
#if OS_ARG_CHK_EN > 0u
|
||||
if (pevent == (OS_EVENT *)0) { /* Validate 'pevent' */
|
||||
return (OS_ERR_PEVENT_NULL);
|
||||
}
|
||||
if (p_mutex_data == (OS_MUTEX_DATA *)0) { /* Validate 'p_mutex_data' */
|
||||
return (OS_ERR_PDATA_NULL);
|
||||
}
|
||||
#endif
|
||||
if (pevent->OSEventType != OS_EVENT_TYPE_MUTEX) { /* Validate event block type */
|
||||
return (OS_ERR_EVENT_TYPE);
|
||||
}
|
||||
OS_ENTER_CRITICAL();
|
||||
p_mutex_data->OSMutexPIP = (INT8U)(pevent->OSEventCnt >> 8u);
|
||||
p_mutex_data->OSOwnerPrio = (INT8U)(pevent->OSEventCnt & OS_MUTEX_KEEP_LOWER_8);
|
||||
if (p_mutex_data->OSOwnerPrio == 0xFFu) {
|
||||
p_mutex_data->OSValue = OS_TRUE;
|
||||
} else {
|
||||
p_mutex_data->OSValue = OS_FALSE;
|
||||
}
|
||||
p_mutex_data->OSEventGrp = pevent->OSEventGrp; /* Copy wait list */
|
||||
psrc = &pevent->OSEventTbl[0];
|
||||
pdest = &p_mutex_data->OSEventTbl[0];
|
||||
for (i = 0u; i < OS_EVENT_TBL_SIZE; i++) {
|
||||
*pdest++ = *psrc++;
|
||||
}
|
||||
OS_EXIT_CRITICAL();
|
||||
return (OS_ERR_NONE);
|
||||
}
|
||||
#endif /* OS_MUTEX_QUERY_EN */
|
||||
|
||||
/*$PAGE*/
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* RESTORE A TASK BACK TO ITS ORIGINAL PRIORITY
|
||||
*
|
||||
* Description: This function makes a task ready at the specified priority
|
||||
*
|
||||
* Arguments : ptcb is a pointer to OS_TCB of the task to make ready
|
||||
*
|
||||
* prio is the desired priority
|
||||
*
|
||||
* Returns : none
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
static void OSMutex_RdyAtPrio (OS_TCB *ptcb,
|
||||
INT8U prio)
|
||||
{
|
||||
INT8U y;
|
||||
|
||||
|
||||
y = ptcb->OSTCBY; /* Remove owner from ready list at 'pip' */
|
||||
OSRdyTbl[y] &= (OS_PRIO)~ptcb->OSTCBBitX;
|
||||
if (OSRdyTbl[y] == 0u) {
|
||||
OSRdyGrp &= (OS_PRIO)~ptcb->OSTCBBitY;
|
||||
}
|
||||
ptcb->OSTCBPrio = prio;
|
||||
OSPrioCur = prio; /* The current task is now at this priority */
|
||||
#if OS_LOWEST_PRIO <= 63u
|
||||
ptcb->OSTCBY = (INT8U)((INT8U)(prio >> 3u) & 0x07u);
|
||||
ptcb->OSTCBX = (INT8U)(prio & 0x07u);
|
||||
#else
|
||||
ptcb->OSTCBY = (INT8U)((INT8U)(prio >> 4u) & 0x0Fu);
|
||||
ptcb->OSTCBX = (INT8U) (prio & 0x0Fu);
|
||||
#endif
|
||||
ptcb->OSTCBBitY = (OS_PRIO)(1uL << ptcb->OSTCBY);
|
||||
ptcb->OSTCBBitX = (OS_PRIO)(1uL << ptcb->OSTCBX);
|
||||
OSRdyGrp |= ptcb->OSTCBBitY; /* Make task ready at original priority */
|
||||
OSRdyTbl[ptcb->OSTCBY] |= ptcb->OSTCBBitX;
|
||||
OSTCBPrioTbl[prio] = ptcb;
|
||||
|
||||
}
|
||||
|
||||
|
||||
#endif /* OS_MUTEX_EN */
|
||||
|
||||
893
UCOSII/CORE/os_q.c
Normal file
893
UCOSII/CORE/os_q.c
Normal file
@@ -0,0 +1,893 @@
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* uC/OS-II
|
||||
* The Real-Time Kernel
|
||||
* MESSAGE QUEUE MANAGEMENT
|
||||
*
|
||||
* (c) Copyright 1992-2009, Micrium, Weston, FL
|
||||
* All Rights Reserved
|
||||
*
|
||||
* File : OS_Q.C
|
||||
* By : Jean J. Labrosse
|
||||
* Version : V2.91
|
||||
*
|
||||
* LICENSING TERMS:
|
||||
* ---------------
|
||||
* uC/OS-II is provided in source form for FREE evaluation, for educational use or for peaceful research.
|
||||
* If you plan on using uC/OS-II in a commercial product you need to contact Micri<72>m to properly license
|
||||
* its use in your product. We provide ALL the source code for your convenience and to help you experience
|
||||
* uC/OS-II. The fact that the source is provided does NOT mean that you can use it without paying a
|
||||
* licensing fee.
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef OS_MASTER_FILE
|
||||
#include <ucos_ii.h>
|
||||
#endif
|
||||
|
||||
#if (OS_Q_EN > 0u) && (OS_MAX_QS > 0u)
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* ACCEPT MESSAGE FROM QUEUE
|
||||
*
|
||||
* Description: This function checks the queue to see if a message is available. Unlike OSQPend(),
|
||||
* OSQAccept() does not suspend the calling task if a message is not available.
|
||||
*
|
||||
* Arguments : pevent is a pointer to the event control block
|
||||
*
|
||||
* perr is a pointer to where an error message will be deposited. Possible error
|
||||
* messages are:
|
||||
*
|
||||
* OS_ERR_NONE The call was successful and your task received a
|
||||
* message.
|
||||
* OS_ERR_EVENT_TYPE You didn't pass a pointer to a queue
|
||||
* OS_ERR_PEVENT_NULL If 'pevent' is a NULL pointer
|
||||
* OS_ERR_Q_EMPTY The queue did not contain any messages
|
||||
*
|
||||
* Returns : != (void *)0 is the message in the queue if one is available. The message is removed
|
||||
* from the so the next time OSQAccept() is called, the queue will contain
|
||||
* one less entry.
|
||||
* == (void *)0 if you received a NULL pointer message
|
||||
* if the queue is empty or,
|
||||
* if 'pevent' is a NULL pointer or,
|
||||
* if you passed an invalid event type
|
||||
*
|
||||
* Note(s) : As of V2.60, you can now pass NULL pointers through queues. Because of this, the argument
|
||||
* 'perr' has been added to the API to tell you about the outcome of the call.
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
#if OS_Q_ACCEPT_EN > 0u
|
||||
void *OSQAccept (OS_EVENT *pevent,
|
||||
INT8U *perr)
|
||||
{
|
||||
void *pmsg;
|
||||
OS_Q *pq;
|
||||
#if OS_CRITICAL_METHOD == 3u /* Allocate storage for CPU status register */
|
||||
OS_CPU_SR cpu_sr = 0u;
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#ifdef OS_SAFETY_CRITICAL
|
||||
if (perr == (INT8U *)0) {
|
||||
OS_SAFETY_CRITICAL_EXCEPTION();
|
||||
}
|
||||
#endif
|
||||
|
||||
#if OS_ARG_CHK_EN > 0u
|
||||
if (pevent == (OS_EVENT *)0) { /* Validate 'pevent' */
|
||||
*perr = OS_ERR_PEVENT_NULL;
|
||||
return ((void *)0);
|
||||
}
|
||||
#endif
|
||||
if (pevent->OSEventType != OS_EVENT_TYPE_Q) {/* Validate event block type */
|
||||
*perr = OS_ERR_EVENT_TYPE;
|
||||
return ((void *)0);
|
||||
}
|
||||
OS_ENTER_CRITICAL();
|
||||
pq = (OS_Q *)pevent->OSEventPtr; /* Point at queue control block */
|
||||
if (pq->OSQEntries > 0u) { /* See if any messages in the queue */
|
||||
pmsg = *pq->OSQOut++; /* Yes, extract oldest message from the queue */
|
||||
pq->OSQEntries--; /* Update the number of entries in the queue */
|
||||
if (pq->OSQOut == pq->OSQEnd) { /* Wrap OUT pointer if we are at the end of the queue */
|
||||
pq->OSQOut = pq->OSQStart;
|
||||
}
|
||||
*perr = OS_ERR_NONE;
|
||||
} else {
|
||||
*perr = OS_ERR_Q_EMPTY;
|
||||
pmsg = (void *)0; /* Queue is empty */
|
||||
}
|
||||
OS_EXIT_CRITICAL();
|
||||
return (pmsg); /* Return message received (or NULL) */
|
||||
}
|
||||
#endif
|
||||
/*$PAGE*/
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* CREATE A MESSAGE QUEUE
|
||||
*
|
||||
* Description: This function creates a message queue if free event control blocks are available.
|
||||
*
|
||||
* Arguments : start is a pointer to the base address of the message queue storage area. The
|
||||
* storage area MUST be declared as an array of pointers to 'void' as follows
|
||||
*
|
||||
* void *MessageStorage[size]
|
||||
*
|
||||
* size is the number of elements in the storage area
|
||||
*
|
||||
* Returns : != (OS_EVENT *)0 is a pointer to the event control clock (OS_EVENT) associated with the
|
||||
* created queue
|
||||
* == (OS_EVENT *)0 if no event control blocks were available or an error was detected
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
OS_EVENT *OSQCreate (void **start,
|
||||
INT16U size)
|
||||
{
|
||||
OS_EVENT *pevent;
|
||||
OS_Q *pq;
|
||||
#if OS_CRITICAL_METHOD == 3u /* Allocate storage for CPU status register */
|
||||
OS_CPU_SR cpu_sr = 0u;
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#ifdef OS_SAFETY_CRITICAL_IEC61508
|
||||
if (OSSafetyCriticalStartFlag == OS_TRUE) {
|
||||
OS_SAFETY_CRITICAL_EXCEPTION();
|
||||
}
|
||||
#endif
|
||||
|
||||
if (OSIntNesting > 0u) { /* See if called from ISR ... */
|
||||
return ((OS_EVENT *)0); /* ... can't CREATE from an ISR */
|
||||
}
|
||||
OS_ENTER_CRITICAL();
|
||||
pevent = OSEventFreeList; /* Get next free event control block */
|
||||
if (OSEventFreeList != (OS_EVENT *)0) { /* See if pool of free ECB pool was empty */
|
||||
OSEventFreeList = (OS_EVENT *)OSEventFreeList->OSEventPtr;
|
||||
}
|
||||
OS_EXIT_CRITICAL();
|
||||
if (pevent != (OS_EVENT *)0) { /* See if we have an event control block */
|
||||
OS_ENTER_CRITICAL();
|
||||
pq = OSQFreeList; /* Get a free queue control block */
|
||||
if (pq != (OS_Q *)0) { /* Were we able to get a queue control block ? */
|
||||
OSQFreeList = OSQFreeList->OSQPtr; /* Yes, Adjust free list pointer to next free*/
|
||||
OS_EXIT_CRITICAL();
|
||||
pq->OSQStart = start; /* Initialize the queue */
|
||||
pq->OSQEnd = &start[size];
|
||||
pq->OSQIn = start;
|
||||
pq->OSQOut = start;
|
||||
pq->OSQSize = size;
|
||||
pq->OSQEntries = 0u;
|
||||
pevent->OSEventType = OS_EVENT_TYPE_Q;
|
||||
pevent->OSEventCnt = 0u;
|
||||
pevent->OSEventPtr = pq;
|
||||
#if OS_EVENT_NAME_EN > 0u
|
||||
pevent->OSEventName = (INT8U *)(void *)"?";
|
||||
#endif
|
||||
OS_EventWaitListInit(pevent); /* Initalize the wait list */
|
||||
} else {
|
||||
pevent->OSEventPtr = (void *)OSEventFreeList; /* No, Return event control block on error */
|
||||
OSEventFreeList = pevent;
|
||||
OS_EXIT_CRITICAL();
|
||||
pevent = (OS_EVENT *)0;
|
||||
}
|
||||
}
|
||||
return (pevent);
|
||||
}
|
||||
/*$PAGE*/
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* DELETE A MESSAGE QUEUE
|
||||
*
|
||||
* Description: This function deletes a message queue and readies all tasks pending on the queue.
|
||||
*
|
||||
* Arguments : pevent is a pointer to the event control block associated with the desired
|
||||
* queue.
|
||||
*
|
||||
* opt determines delete options as follows:
|
||||
* opt == OS_DEL_NO_PEND Delete the queue ONLY if no task pending
|
||||
* opt == OS_DEL_ALWAYS Deletes the queue even if tasks are waiting.
|
||||
* In this case, all the tasks pending will be readied.
|
||||
*
|
||||
* perr is a pointer to an error code that can contain one of the following values:
|
||||
* OS_ERR_NONE The call was successful and the queue was deleted
|
||||
* OS_ERR_DEL_ISR If you tried to delete the queue from an ISR
|
||||
* OS_ERR_INVALID_OPT An invalid option was specified
|
||||
* OS_ERR_TASK_WAITING One or more tasks were waiting on the queue
|
||||
* OS_ERR_EVENT_TYPE If you didn't pass a pointer to a queue
|
||||
* OS_ERR_PEVENT_NULL If 'pevent' is a NULL pointer.
|
||||
*
|
||||
* Returns : pevent upon error
|
||||
* (OS_EVENT *)0 if the queue was successfully deleted.
|
||||
*
|
||||
* Note(s) : 1) This function must be used with care. Tasks that would normally expect the presence of
|
||||
* the queue MUST check the return code of OSQPend().
|
||||
* 2) OSQAccept() callers will not know that the intended queue has been deleted unless
|
||||
* they check 'pevent' to see that it's a NULL pointer.
|
||||
* 3) This call can potentially disable interrupts for a long time. The interrupt disable
|
||||
* time is directly proportional to the number of tasks waiting on the queue.
|
||||
* 4) Because ALL tasks pending on the queue will be readied, you MUST be careful in
|
||||
* applications where the queue is used for mutual exclusion because the resource(s)
|
||||
* will no longer be guarded by the queue.
|
||||
* 5) If the storage for the message queue was allocated dynamically (i.e. using a malloc()
|
||||
* type call) then your application MUST release the memory storage by call the counterpart
|
||||
* call of the dynamic allocation scheme used. If the queue storage was created statically
|
||||
* then, the storage can be reused.
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
#if OS_Q_DEL_EN > 0u
|
||||
OS_EVENT *OSQDel (OS_EVENT *pevent,
|
||||
INT8U opt,
|
||||
INT8U *perr)
|
||||
{
|
||||
BOOLEAN tasks_waiting;
|
||||
OS_EVENT *pevent_return;
|
||||
OS_Q *pq;
|
||||
#if OS_CRITICAL_METHOD == 3u /* Allocate storage for CPU status register */
|
||||
OS_CPU_SR cpu_sr = 0u;
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#ifdef OS_SAFETY_CRITICAL
|
||||
if (perr == (INT8U *)0) {
|
||||
OS_SAFETY_CRITICAL_EXCEPTION();
|
||||
}
|
||||
#endif
|
||||
|
||||
#if OS_ARG_CHK_EN > 0u
|
||||
if (pevent == (OS_EVENT *)0) { /* Validate 'pevent' */
|
||||
*perr = OS_ERR_PEVENT_NULL;
|
||||
return (pevent);
|
||||
}
|
||||
#endif
|
||||
if (pevent->OSEventType != OS_EVENT_TYPE_Q) { /* Validate event block type */
|
||||
*perr = OS_ERR_EVENT_TYPE;
|
||||
return (pevent);
|
||||
}
|
||||
if (OSIntNesting > 0u) { /* See if called from ISR ... */
|
||||
*perr = OS_ERR_DEL_ISR; /* ... can't DELETE from an ISR */
|
||||
return (pevent);
|
||||
}
|
||||
OS_ENTER_CRITICAL();
|
||||
if (pevent->OSEventGrp != 0u) { /* See if any tasks waiting on queue */
|
||||
tasks_waiting = OS_TRUE; /* Yes */
|
||||
} else {
|
||||
tasks_waiting = OS_FALSE; /* No */
|
||||
}
|
||||
switch (opt) {
|
||||
case OS_DEL_NO_PEND: /* Delete queue only if no task waiting */
|
||||
if (tasks_waiting == OS_FALSE) {
|
||||
#if OS_EVENT_NAME_EN > 0u
|
||||
pevent->OSEventName = (INT8U *)(void *)"?";
|
||||
#endif
|
||||
pq = (OS_Q *)pevent->OSEventPtr; /* Return OS_Q to free list */
|
||||
pq->OSQPtr = OSQFreeList;
|
||||
OSQFreeList = pq;
|
||||
pevent->OSEventType = OS_EVENT_TYPE_UNUSED;
|
||||
pevent->OSEventPtr = OSEventFreeList; /* Return Event Control Block to free list */
|
||||
pevent->OSEventCnt = 0u;
|
||||
OSEventFreeList = pevent; /* Get next free event control block */
|
||||
OS_EXIT_CRITICAL();
|
||||
*perr = OS_ERR_NONE;
|
||||
pevent_return = (OS_EVENT *)0; /* Queue has been deleted */
|
||||
} else {
|
||||
OS_EXIT_CRITICAL();
|
||||
*perr = OS_ERR_TASK_WAITING;
|
||||
pevent_return = pevent;
|
||||
}
|
||||
break;
|
||||
|
||||
case OS_DEL_ALWAYS: /* Always delete the queue */
|
||||
while (pevent->OSEventGrp != 0u) { /* Ready ALL tasks waiting for queue */
|
||||
(void)OS_EventTaskRdy(pevent, (void *)0, OS_STAT_Q, OS_STAT_PEND_OK);
|
||||
}
|
||||
#if OS_EVENT_NAME_EN > 0u
|
||||
pevent->OSEventName = (INT8U *)(void *)"?";
|
||||
#endif
|
||||
pq = (OS_Q *)pevent->OSEventPtr; /* Return OS_Q to free list */
|
||||
pq->OSQPtr = OSQFreeList;
|
||||
OSQFreeList = pq;
|
||||
pevent->OSEventType = OS_EVENT_TYPE_UNUSED;
|
||||
pevent->OSEventPtr = OSEventFreeList; /* Return Event Control Block to free list */
|
||||
pevent->OSEventCnt = 0u;
|
||||
OSEventFreeList = pevent; /* Get next free event control block */
|
||||
OS_EXIT_CRITICAL();
|
||||
if (tasks_waiting == OS_TRUE) { /* Reschedule only if task(s) were waiting */
|
||||
OS_Sched(); /* Find highest priority task ready to run */
|
||||
}
|
||||
*perr = OS_ERR_NONE;
|
||||
pevent_return = (OS_EVENT *)0; /* Queue has been deleted */
|
||||
break;
|
||||
|
||||
default:
|
||||
OS_EXIT_CRITICAL();
|
||||
*perr = OS_ERR_INVALID_OPT;
|
||||
pevent_return = pevent;
|
||||
break;
|
||||
}
|
||||
return (pevent_return);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*$PAGE*/
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* FLUSH QUEUE
|
||||
*
|
||||
* Description : This function is used to flush the contents of the message queue.
|
||||
*
|
||||
* Arguments : none
|
||||
*
|
||||
* Returns : OS_ERR_NONE upon success
|
||||
* OS_ERR_EVENT_TYPE If you didn't pass a pointer to a queue
|
||||
* OS_ERR_PEVENT_NULL If 'pevent' is a NULL pointer
|
||||
*
|
||||
* WARNING : You should use this function with great care because, when to flush the queue, you LOOSE
|
||||
* the references to what the queue entries are pointing to and thus, you could cause
|
||||
* 'memory leaks'. In other words, the data you are pointing to that's being referenced
|
||||
* by the queue entries should, most likely, need to be de-allocated (i.e. freed).
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
#if OS_Q_FLUSH_EN > 0u
|
||||
INT8U OSQFlush (OS_EVENT *pevent)
|
||||
{
|
||||
OS_Q *pq;
|
||||
#if OS_CRITICAL_METHOD == 3u /* Allocate storage for CPU status register */
|
||||
OS_CPU_SR cpu_sr = 0u;
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#if OS_ARG_CHK_EN > 0u
|
||||
if (pevent == (OS_EVENT *)0) { /* Validate 'pevent' */
|
||||
return (OS_ERR_PEVENT_NULL);
|
||||
}
|
||||
if (pevent->OSEventType != OS_EVENT_TYPE_Q) { /* Validate event block type */
|
||||
return (OS_ERR_EVENT_TYPE);
|
||||
}
|
||||
#endif
|
||||
OS_ENTER_CRITICAL();
|
||||
pq = (OS_Q *)pevent->OSEventPtr; /* Point to queue storage structure */
|
||||
pq->OSQIn = pq->OSQStart;
|
||||
pq->OSQOut = pq->OSQStart;
|
||||
pq->OSQEntries = 0u;
|
||||
OS_EXIT_CRITICAL();
|
||||
return (OS_ERR_NONE);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*$PAGE*/
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* PEND ON A QUEUE FOR A MESSAGE
|
||||
*
|
||||
* Description: This function waits for a message to be sent to a queue
|
||||
*
|
||||
* Arguments : pevent is a pointer to the event control block associated with the desired queue
|
||||
*
|
||||
* timeout is an optional timeout period (in clock ticks). If non-zero, your task will
|
||||
* wait for a message to arrive at the queue up to the amount of time
|
||||
* specified by this argument. If you specify 0, however, your task will wait
|
||||
* forever at the specified queue or, until a message arrives.
|
||||
*
|
||||
* perr is a pointer to where an error message will be deposited. Possible error
|
||||
* messages are:
|
||||
*
|
||||
* OS_ERR_NONE The call was successful and your task received a
|
||||
* message.
|
||||
* OS_ERR_TIMEOUT A message was not received within the specified 'timeout'.
|
||||
* OS_ERR_PEND_ABORT The wait on the queue was aborted.
|
||||
* OS_ERR_EVENT_TYPE You didn't pass a pointer to a queue
|
||||
* OS_ERR_PEVENT_NULL If 'pevent' is a NULL pointer
|
||||
* OS_ERR_PEND_ISR If you called this function from an ISR and the result
|
||||
* would lead to a suspension.
|
||||
* OS_ERR_PEND_LOCKED If you called this function with the scheduler is locked
|
||||
*
|
||||
* Returns : != (void *)0 is a pointer to the message received
|
||||
* == (void *)0 if you received a NULL pointer message or,
|
||||
* if no message was received or,
|
||||
* if 'pevent' is a NULL pointer or,
|
||||
* if you didn't pass a pointer to a queue.
|
||||
*
|
||||
* Note(s) : As of V2.60, this function allows you to receive NULL pointer messages.
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
void *OSQPend (OS_EVENT *pevent,
|
||||
INT32U timeout,
|
||||
INT8U *perr)
|
||||
{
|
||||
void *pmsg;
|
||||
OS_Q *pq;
|
||||
#if OS_CRITICAL_METHOD == 3u /* Allocate storage for CPU status register */
|
||||
OS_CPU_SR cpu_sr = 0u;
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#ifdef OS_SAFETY_CRITICAL
|
||||
if (perr == (INT8U *)0) {
|
||||
OS_SAFETY_CRITICAL_EXCEPTION();
|
||||
}
|
||||
#endif
|
||||
|
||||
#if OS_ARG_CHK_EN > 0u
|
||||
if (pevent == (OS_EVENT *)0) { /* Validate 'pevent' */
|
||||
*perr = OS_ERR_PEVENT_NULL;
|
||||
return ((void *)0);
|
||||
}
|
||||
#endif
|
||||
if (pevent->OSEventType != OS_EVENT_TYPE_Q) {/* Validate event block type */
|
||||
*perr = OS_ERR_EVENT_TYPE;
|
||||
return ((void *)0);
|
||||
}
|
||||
if (OSIntNesting > 0u) { /* See if called from ISR ... */
|
||||
*perr = OS_ERR_PEND_ISR; /* ... can't PEND from an ISR */
|
||||
return ((void *)0);
|
||||
}
|
||||
if (OSLockNesting > 0u) { /* See if called with scheduler locked ... */
|
||||
*perr = OS_ERR_PEND_LOCKED; /* ... can't PEND when locked */
|
||||
return ((void *)0);
|
||||
}
|
||||
OS_ENTER_CRITICAL();
|
||||
pq = (OS_Q *)pevent->OSEventPtr; /* Point at queue control block */
|
||||
if (pq->OSQEntries > 0u) { /* See if any messages in the queue */
|
||||
pmsg = *pq->OSQOut++; /* Yes, extract oldest message from the queue */
|
||||
pq->OSQEntries--; /* Update the number of entries in the queue */
|
||||
if (pq->OSQOut == pq->OSQEnd) { /* Wrap OUT pointer if we are at the end of the queue */
|
||||
pq->OSQOut = pq->OSQStart;
|
||||
}
|
||||
OS_EXIT_CRITICAL();
|
||||
*perr = OS_ERR_NONE;
|
||||
return (pmsg); /* Return message received */
|
||||
}
|
||||
OSTCBCur->OSTCBStat |= OS_STAT_Q; /* Task will have to pend for a message to be posted */
|
||||
OSTCBCur->OSTCBStatPend = OS_STAT_PEND_OK;
|
||||
OSTCBCur->OSTCBDly = timeout; /* Load timeout into TCB */
|
||||
OS_EventTaskWait(pevent); /* Suspend task until event or timeout occurs */
|
||||
OS_EXIT_CRITICAL();
|
||||
OS_Sched(); /* Find next highest priority task ready to run */
|
||||
OS_ENTER_CRITICAL();
|
||||
switch (OSTCBCur->OSTCBStatPend) { /* See if we timed-out or aborted */
|
||||
case OS_STAT_PEND_OK: /* Extract message from TCB (Put there by QPost) */
|
||||
pmsg = OSTCBCur->OSTCBMsg;
|
||||
*perr = OS_ERR_NONE;
|
||||
break;
|
||||
|
||||
case OS_STAT_PEND_ABORT:
|
||||
pmsg = (void *)0;
|
||||
*perr = OS_ERR_PEND_ABORT; /* Indicate that we aborted */
|
||||
break;
|
||||
|
||||
case OS_STAT_PEND_TO:
|
||||
default:
|
||||
OS_EventTaskRemove(OSTCBCur, pevent);
|
||||
pmsg = (void *)0;
|
||||
*perr = OS_ERR_TIMEOUT; /* Indicate that we didn't get event within TO */
|
||||
break;
|
||||
}
|
||||
OSTCBCur->OSTCBStat = OS_STAT_RDY; /* Set task status to ready */
|
||||
OSTCBCur->OSTCBStatPend = OS_STAT_PEND_OK; /* Clear pend status */
|
||||
OSTCBCur->OSTCBEventPtr = (OS_EVENT *)0; /* Clear event pointers */
|
||||
#if (OS_EVENT_MULTI_EN > 0u)
|
||||
OSTCBCur->OSTCBEventMultiPtr = (OS_EVENT **)0;
|
||||
#endif
|
||||
OSTCBCur->OSTCBMsg = (void *)0; /* Clear received message */
|
||||
OS_EXIT_CRITICAL();
|
||||
return (pmsg); /* Return received message */
|
||||
}
|
||||
/*$PAGE*/
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* ABORT WAITING ON A MESSAGE QUEUE
|
||||
*
|
||||
* Description: This function aborts & readies any tasks currently waiting on a queue. This function
|
||||
* should be used to fault-abort the wait on the queue, rather than to normally signal
|
||||
* the queue via OSQPost(), OSQPostFront() or OSQPostOpt().
|
||||
*
|
||||
* Arguments : pevent is a pointer to the event control block associated with the desired queue.
|
||||
*
|
||||
* opt determines the type of ABORT performed:
|
||||
* OS_PEND_OPT_NONE ABORT wait for a single task (HPT) waiting on the
|
||||
* queue
|
||||
* OS_PEND_OPT_BROADCAST ABORT wait for ALL tasks that are waiting on the
|
||||
* queue
|
||||
*
|
||||
* perr is a pointer to where an error message will be deposited. Possible error
|
||||
* messages are:
|
||||
*
|
||||
* OS_ERR_NONE No tasks were waiting on the queue.
|
||||
* OS_ERR_PEND_ABORT At least one task waiting on the queue was readied
|
||||
* and informed of the aborted wait; check return value
|
||||
* for the number of tasks whose wait on the queue
|
||||
* was aborted.
|
||||
* OS_ERR_EVENT_TYPE If you didn't pass a pointer to a queue.
|
||||
* OS_ERR_PEVENT_NULL If 'pevent' is a NULL pointer.
|
||||
*
|
||||
* Returns : == 0 if no tasks were waiting on the queue, or upon error.
|
||||
* > 0 if one or more tasks waiting on the queue are now readied and informed.
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
#if OS_Q_PEND_ABORT_EN > 0u
|
||||
INT8U OSQPendAbort (OS_EVENT *pevent,
|
||||
INT8U opt,
|
||||
INT8U *perr)
|
||||
{
|
||||
INT8U nbr_tasks;
|
||||
#if OS_CRITICAL_METHOD == 3u /* Allocate storage for CPU status register */
|
||||
OS_CPU_SR cpu_sr = 0u;
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#ifdef OS_SAFETY_CRITICAL
|
||||
if (perr == (INT8U *)0) {
|
||||
OS_SAFETY_CRITICAL_EXCEPTION();
|
||||
}
|
||||
#endif
|
||||
|
||||
#if OS_ARG_CHK_EN > 0u
|
||||
if (pevent == (OS_EVENT *)0) { /* Validate 'pevent' */
|
||||
*perr = OS_ERR_PEVENT_NULL;
|
||||
return (0u);
|
||||
}
|
||||
#endif
|
||||
if (pevent->OSEventType != OS_EVENT_TYPE_Q) { /* Validate event block type */
|
||||
*perr = OS_ERR_EVENT_TYPE;
|
||||
return (0u);
|
||||
}
|
||||
OS_ENTER_CRITICAL();
|
||||
if (pevent->OSEventGrp != 0u) { /* See if any task waiting on queue? */
|
||||
nbr_tasks = 0u;
|
||||
switch (opt) {
|
||||
case OS_PEND_OPT_BROADCAST: /* Do we need to abort ALL waiting tasks? */
|
||||
while (pevent->OSEventGrp != 0u) { /* Yes, ready ALL tasks waiting on queue */
|
||||
(void)OS_EventTaskRdy(pevent, (void *)0, OS_STAT_Q, OS_STAT_PEND_ABORT);
|
||||
nbr_tasks++;
|
||||
}
|
||||
break;
|
||||
|
||||
case OS_PEND_OPT_NONE:
|
||||
default: /* No, ready HPT waiting on queue */
|
||||
(void)OS_EventTaskRdy(pevent, (void *)0, OS_STAT_Q, OS_STAT_PEND_ABORT);
|
||||
nbr_tasks++;
|
||||
break;
|
||||
}
|
||||
OS_EXIT_CRITICAL();
|
||||
OS_Sched(); /* Find HPT ready to run */
|
||||
*perr = OS_ERR_PEND_ABORT;
|
||||
return (nbr_tasks);
|
||||
}
|
||||
OS_EXIT_CRITICAL();
|
||||
*perr = OS_ERR_NONE;
|
||||
return (0u); /* No tasks waiting on queue */
|
||||
}
|
||||
#endif
|
||||
|
||||
/*$PAGE*/
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* POST MESSAGE TO A QUEUE
|
||||
*
|
||||
* Description: This function sends a message to a queue
|
||||
*
|
||||
* Arguments : pevent is a pointer to the event control block associated with the desired queue
|
||||
*
|
||||
* pmsg is a pointer to the message to send.
|
||||
*
|
||||
* Returns : OS_ERR_NONE The call was successful and the message was sent
|
||||
* OS_ERR_Q_FULL If the queue cannot accept any more messages because it is full.
|
||||
* OS_ERR_EVENT_TYPE If you didn't pass a pointer to a queue.
|
||||
* OS_ERR_PEVENT_NULL If 'pevent' is a NULL pointer
|
||||
*
|
||||
* Note(s) : As of V2.60, this function allows you to send NULL pointer messages.
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
#if OS_Q_POST_EN > 0u
|
||||
INT8U OSQPost (OS_EVENT *pevent,
|
||||
void *pmsg)
|
||||
{
|
||||
OS_Q *pq;
|
||||
#if OS_CRITICAL_METHOD == 3u /* Allocate storage for CPU status register */
|
||||
OS_CPU_SR cpu_sr = 0u;
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#if OS_ARG_CHK_EN > 0u
|
||||
if (pevent == (OS_EVENT *)0) { /* Validate 'pevent' */
|
||||
return (OS_ERR_PEVENT_NULL);
|
||||
}
|
||||
#endif
|
||||
if (pevent->OSEventType != OS_EVENT_TYPE_Q) { /* Validate event block type */
|
||||
return (OS_ERR_EVENT_TYPE);
|
||||
}
|
||||
OS_ENTER_CRITICAL();
|
||||
if (pevent->OSEventGrp != 0u) { /* See if any task pending on queue */
|
||||
/* Ready highest priority task waiting on event */
|
||||
(void)OS_EventTaskRdy(pevent, pmsg, OS_STAT_Q, OS_STAT_PEND_OK);
|
||||
OS_EXIT_CRITICAL();
|
||||
OS_Sched(); /* Find highest priority task ready to run */
|
||||
return (OS_ERR_NONE);
|
||||
}
|
||||
pq = (OS_Q *)pevent->OSEventPtr; /* Point to queue control block */
|
||||
if (pq->OSQEntries >= pq->OSQSize) { /* Make sure queue is not full */
|
||||
OS_EXIT_CRITICAL();
|
||||
return (OS_ERR_Q_FULL);
|
||||
}
|
||||
*pq->OSQIn++ = pmsg; /* Insert message into queue */
|
||||
pq->OSQEntries++; /* Update the nbr of entries in the queue */
|
||||
if (pq->OSQIn == pq->OSQEnd) { /* Wrap IN ptr if we are at end of queue */
|
||||
pq->OSQIn = pq->OSQStart;
|
||||
}
|
||||
OS_EXIT_CRITICAL();
|
||||
return (OS_ERR_NONE);
|
||||
}
|
||||
#endif
|
||||
/*$PAGE*/
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* POST MESSAGE TO THE FRONT OF A QUEUE
|
||||
*
|
||||
* Description: This function sends a message to a queue but unlike OSQPost(), the message is posted at
|
||||
* the front instead of the end of the queue. Using OSQPostFront() allows you to send
|
||||
* 'priority' messages.
|
||||
*
|
||||
* Arguments : pevent is a pointer to the event control block associated with the desired queue
|
||||
*
|
||||
* pmsg is a pointer to the message to send.
|
||||
*
|
||||
* Returns : OS_ERR_NONE The call was successful and the message was sent
|
||||
* OS_ERR_Q_FULL If the queue cannot accept any more messages because it is full.
|
||||
* OS_ERR_EVENT_TYPE If you didn't pass a pointer to a queue.
|
||||
* OS_ERR_PEVENT_NULL If 'pevent' is a NULL pointer
|
||||
*
|
||||
* Note(s) : As of V2.60, this function allows you to send NULL pointer messages.
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
#if OS_Q_POST_FRONT_EN > 0u
|
||||
INT8U OSQPostFront (OS_EVENT *pevent,
|
||||
void *pmsg)
|
||||
{
|
||||
OS_Q *pq;
|
||||
#if OS_CRITICAL_METHOD == 3u /* Allocate storage for CPU status register */
|
||||
OS_CPU_SR cpu_sr = 0u;
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#if OS_ARG_CHK_EN > 0u
|
||||
if (pevent == (OS_EVENT *)0) { /* Validate 'pevent' */
|
||||
return (OS_ERR_PEVENT_NULL);
|
||||
}
|
||||
#endif
|
||||
if (pevent->OSEventType != OS_EVENT_TYPE_Q) { /* Validate event block type */
|
||||
return (OS_ERR_EVENT_TYPE);
|
||||
}
|
||||
OS_ENTER_CRITICAL();
|
||||
if (pevent->OSEventGrp != 0u) { /* See if any task pending on queue */
|
||||
/* Ready highest priority task waiting on event */
|
||||
(void)OS_EventTaskRdy(pevent, pmsg, OS_STAT_Q, OS_STAT_PEND_OK);
|
||||
OS_EXIT_CRITICAL();
|
||||
OS_Sched(); /* Find highest priority task ready to run */
|
||||
return (OS_ERR_NONE);
|
||||
}
|
||||
pq = (OS_Q *)pevent->OSEventPtr; /* Point to queue control block */
|
||||
if (pq->OSQEntries >= pq->OSQSize) { /* Make sure queue is not full */
|
||||
OS_EXIT_CRITICAL();
|
||||
return (OS_ERR_Q_FULL);
|
||||
}
|
||||
if (pq->OSQOut == pq->OSQStart) { /* Wrap OUT ptr if we are at the 1st queue entry */
|
||||
pq->OSQOut = pq->OSQEnd;
|
||||
}
|
||||
pq->OSQOut--;
|
||||
*pq->OSQOut = pmsg; /* Insert message into queue */
|
||||
pq->OSQEntries++; /* Update the nbr of entries in the queue */
|
||||
OS_EXIT_CRITICAL();
|
||||
return (OS_ERR_NONE);
|
||||
}
|
||||
#endif
|
||||
/*$PAGE*/
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* POST MESSAGE TO A QUEUE
|
||||
*
|
||||
* Description: This function sends a message to a queue. This call has been added to reduce code size
|
||||
* since it can replace both OSQPost() and OSQPostFront(). Also, this function adds the
|
||||
* capability to broadcast a message to ALL tasks waiting on the message queue.
|
||||
*
|
||||
* Arguments : pevent is a pointer to the event control block associated with the desired queue
|
||||
*
|
||||
* pmsg is a pointer to the message to send.
|
||||
*
|
||||
* opt determines the type of POST performed:
|
||||
* OS_POST_OPT_NONE POST to a single waiting task
|
||||
* (Identical to OSQPost())
|
||||
* OS_POST_OPT_BROADCAST POST to ALL tasks that are waiting on the queue
|
||||
* OS_POST_OPT_FRONT POST as LIFO (Simulates OSQPostFront())
|
||||
* OS_POST_OPT_NO_SCHED Indicates that the scheduler will NOT be invoked
|
||||
*
|
||||
* Returns : OS_ERR_NONE The call was successful and the message was sent
|
||||
* OS_ERR_Q_FULL If the queue cannot accept any more messages because it is full.
|
||||
* OS_ERR_EVENT_TYPE If you didn't pass a pointer to a queue.
|
||||
* OS_ERR_PEVENT_NULL If 'pevent' is a NULL pointer
|
||||
*
|
||||
* Warning : Interrupts can be disabled for a long time if you do a 'broadcast'. In fact, the
|
||||
* interrupt disable time is proportional to the number of tasks waiting on the queue.
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
#if OS_Q_POST_OPT_EN > 0u
|
||||
INT8U OSQPostOpt (OS_EVENT *pevent,
|
||||
void *pmsg,
|
||||
INT8U opt)
|
||||
{
|
||||
OS_Q *pq;
|
||||
#if OS_CRITICAL_METHOD == 3u /* Allocate storage for CPU status register */
|
||||
OS_CPU_SR cpu_sr = 0u;
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#if OS_ARG_CHK_EN > 0u
|
||||
if (pevent == (OS_EVENT *)0) { /* Validate 'pevent' */
|
||||
return (OS_ERR_PEVENT_NULL);
|
||||
}
|
||||
#endif
|
||||
if (pevent->OSEventType != OS_EVENT_TYPE_Q) { /* Validate event block type */
|
||||
return (OS_ERR_EVENT_TYPE);
|
||||
}
|
||||
OS_ENTER_CRITICAL();
|
||||
if (pevent->OSEventGrp != 0x00u) { /* See if any task pending on queue */
|
||||
if ((opt & OS_POST_OPT_BROADCAST) != 0x00u) { /* Do we need to post msg to ALL waiting tasks ? */
|
||||
while (pevent->OSEventGrp != 0u) { /* Yes, Post to ALL tasks waiting on queue */
|
||||
(void)OS_EventTaskRdy(pevent, pmsg, OS_STAT_Q, OS_STAT_PEND_OK);
|
||||
}
|
||||
} else { /* No, Post to HPT waiting on queue */
|
||||
(void)OS_EventTaskRdy(pevent, pmsg, OS_STAT_Q, OS_STAT_PEND_OK);
|
||||
}
|
||||
OS_EXIT_CRITICAL();
|
||||
if ((opt & OS_POST_OPT_NO_SCHED) == 0u) { /* See if scheduler needs to be invoked */
|
||||
OS_Sched(); /* Find highest priority task ready to run */
|
||||
}
|
||||
return (OS_ERR_NONE);
|
||||
}
|
||||
pq = (OS_Q *)pevent->OSEventPtr; /* Point to queue control block */
|
||||
if (pq->OSQEntries >= pq->OSQSize) { /* Make sure queue is not full */
|
||||
OS_EXIT_CRITICAL();
|
||||
return (OS_ERR_Q_FULL);
|
||||
}
|
||||
if ((opt & OS_POST_OPT_FRONT) != 0x00u) { /* Do we post to the FRONT of the queue? */
|
||||
if (pq->OSQOut == pq->OSQStart) { /* Yes, Post as LIFO, Wrap OUT pointer if we ... */
|
||||
pq->OSQOut = pq->OSQEnd; /* ... are at the 1st queue entry */
|
||||
}
|
||||
pq->OSQOut--;
|
||||
*pq->OSQOut = pmsg; /* Insert message into queue */
|
||||
} else { /* No, Post as FIFO */
|
||||
*pq->OSQIn++ = pmsg; /* Insert message into queue */
|
||||
if (pq->OSQIn == pq->OSQEnd) { /* Wrap IN ptr if we are at end of queue */
|
||||
pq->OSQIn = pq->OSQStart;
|
||||
}
|
||||
}
|
||||
pq->OSQEntries++; /* Update the nbr of entries in the queue */
|
||||
OS_EXIT_CRITICAL();
|
||||
return (OS_ERR_NONE);
|
||||
}
|
||||
#endif
|
||||
/*$PAGE*/
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* QUERY A MESSAGE QUEUE
|
||||
*
|
||||
* Description: This function obtains information about a message queue.
|
||||
*
|
||||
* Arguments : pevent is a pointer to the event control block associated with the desired queue
|
||||
*
|
||||
* p_q_data is a pointer to a structure that will contain information about the message
|
||||
* queue.
|
||||
*
|
||||
* Returns : OS_ERR_NONE The call was successful and the message was sent
|
||||
* OS_ERR_EVENT_TYPE If you are attempting to obtain data from a non queue.
|
||||
* OS_ERR_PEVENT_NULL If 'pevent' is a NULL pointer
|
||||
* OS_ERR_PDATA_NULL If 'p_q_data' is a NULL pointer
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
#if OS_Q_QUERY_EN > 0u
|
||||
INT8U OSQQuery (OS_EVENT *pevent,
|
||||
OS_Q_DATA *p_q_data)
|
||||
{
|
||||
OS_Q *pq;
|
||||
INT8U i;
|
||||
OS_PRIO *psrc;
|
||||
OS_PRIO *pdest;
|
||||
#if OS_CRITICAL_METHOD == 3u /* Allocate storage for CPU status register */
|
||||
OS_CPU_SR cpu_sr = 0u;
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#if OS_ARG_CHK_EN > 0u
|
||||
if (pevent == (OS_EVENT *)0) { /* Validate 'pevent' */
|
||||
return (OS_ERR_PEVENT_NULL);
|
||||
}
|
||||
if (p_q_data == (OS_Q_DATA *)0) { /* Validate 'p_q_data' */
|
||||
return (OS_ERR_PDATA_NULL);
|
||||
}
|
||||
#endif
|
||||
if (pevent->OSEventType != OS_EVENT_TYPE_Q) { /* Validate event block type */
|
||||
return (OS_ERR_EVENT_TYPE);
|
||||
}
|
||||
OS_ENTER_CRITICAL();
|
||||
p_q_data->OSEventGrp = pevent->OSEventGrp; /* Copy message queue wait list */
|
||||
psrc = &pevent->OSEventTbl[0];
|
||||
pdest = &p_q_data->OSEventTbl[0];
|
||||
for (i = 0u; i < OS_EVENT_TBL_SIZE; i++) {
|
||||
*pdest++ = *psrc++;
|
||||
}
|
||||
pq = (OS_Q *)pevent->OSEventPtr;
|
||||
if (pq->OSQEntries > 0u) {
|
||||
p_q_data->OSMsg = *pq->OSQOut; /* Get next message to return if available */
|
||||
} else {
|
||||
p_q_data->OSMsg = (void *)0;
|
||||
}
|
||||
p_q_data->OSNMsgs = pq->OSQEntries;
|
||||
p_q_data->OSQSize = pq->OSQSize;
|
||||
OS_EXIT_CRITICAL();
|
||||
return (OS_ERR_NONE);
|
||||
}
|
||||
#endif /* OS_Q_QUERY_EN */
|
||||
|
||||
/*$PAGE*/
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* QUEUE MODULE INITIALIZATION
|
||||
*
|
||||
* Description : This function is called by uC/OS-II to initialize the message queue module. Your
|
||||
* application MUST NOT call this function.
|
||||
*
|
||||
* Arguments : none
|
||||
*
|
||||
* Returns : none
|
||||
*
|
||||
* Note(s) : This function is INTERNAL to uC/OS-II and your application should not call it.
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
void OS_QInit (void)
|
||||
{
|
||||
#if OS_MAX_QS == 1u
|
||||
OSQFreeList = &OSQTbl[0]; /* Only ONE queue! */
|
||||
OSQFreeList->OSQPtr = (OS_Q *)0;
|
||||
#endif
|
||||
|
||||
#if OS_MAX_QS >= 2u
|
||||
INT16U ix;
|
||||
INT16U ix_next;
|
||||
OS_Q *pq1;
|
||||
OS_Q *pq2;
|
||||
|
||||
|
||||
|
||||
OS_MemClr((INT8U *)&OSQTbl[0], sizeof(OSQTbl)); /* Clear the queue table */
|
||||
for (ix = 0u; ix < (OS_MAX_QS - 1u); ix++) { /* Init. list of free QUEUE control blocks */
|
||||
ix_next = ix + 1u;
|
||||
pq1 = &OSQTbl[ix];
|
||||
pq2 = &OSQTbl[ix_next];
|
||||
pq1->OSQPtr = pq2;
|
||||
}
|
||||
pq1 = &OSQTbl[ix];
|
||||
pq1->OSQPtr = (OS_Q *)0;
|
||||
OSQFreeList = &OSQTbl[0];
|
||||
#endif
|
||||
}
|
||||
#endif /* OS_Q_EN */
|
||||
|
||||
629
UCOSII/CORE/os_sem.c
Normal file
629
UCOSII/CORE/os_sem.c
Normal file
@@ -0,0 +1,629 @@
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* uC/OS-II
|
||||
* The Real-Time Kernel
|
||||
* SEMAPHORE MANAGEMENT
|
||||
*
|
||||
* (c) Copyright 1992-2009, Micrium, Weston, FL
|
||||
* All Rights Reserved
|
||||
*
|
||||
* File : OS_SEM.C
|
||||
* By : Jean J. Labrosse
|
||||
* Version : V2.91
|
||||
*
|
||||
* LICENSING TERMS:
|
||||
* ---------------
|
||||
* uC/OS-II is provided in source form for FREE evaluation, for educational use or for peaceful research.
|
||||
* If you plan on using uC/OS-II in a commercial product you need to contact Micri<72>m to properly license
|
||||
* its use in your product. We provide ALL the source code for your convenience and to help you experience
|
||||
* uC/OS-II. The fact that the source is provided does NOT mean that you can use it without paying a
|
||||
* licensing fee.
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef OS_MASTER_FILE
|
||||
#include <ucos_ii.h>
|
||||
#endif
|
||||
|
||||
#if OS_SEM_EN > 0u
|
||||
/*$PAGE*/
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* ACCEPT SEMAPHORE
|
||||
*
|
||||
* Description: This function checks the semaphore to see if a resource is available or, if an event
|
||||
* occurred. Unlike OSSemPend(), OSSemAccept() does not suspend the calling task if the
|
||||
* resource is not available or the event did not occur.
|
||||
*
|
||||
* Arguments : pevent is a pointer to the event control block
|
||||
*
|
||||
* Returns : > 0 if the resource is available or the event did not occur the semaphore is
|
||||
* decremented to obtain the resource.
|
||||
* == 0 if the resource is not available or the event did not occur or,
|
||||
* if 'pevent' is a NULL pointer or,
|
||||
* if you didn't pass a pointer to a semaphore
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
#if OS_SEM_ACCEPT_EN > 0u
|
||||
INT16U OSSemAccept (OS_EVENT *pevent)
|
||||
{
|
||||
INT16U cnt;
|
||||
#if OS_CRITICAL_METHOD == 3u /* Allocate storage for CPU status register */
|
||||
OS_CPU_SR cpu_sr = 0u;
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#if OS_ARG_CHK_EN > 0u
|
||||
if (pevent == (OS_EVENT *)0) { /* Validate 'pevent' */
|
||||
return (0u);
|
||||
}
|
||||
#endif
|
||||
if (pevent->OSEventType != OS_EVENT_TYPE_SEM) { /* Validate event block type */
|
||||
return (0u);
|
||||
}
|
||||
OS_ENTER_CRITICAL();
|
||||
cnt = pevent->OSEventCnt;
|
||||
if (cnt > 0u) { /* See if resource is available */
|
||||
pevent->OSEventCnt--; /* Yes, decrement semaphore and notify caller */
|
||||
}
|
||||
OS_EXIT_CRITICAL();
|
||||
return (cnt); /* Return semaphore count */
|
||||
}
|
||||
#endif
|
||||
|
||||
/*$PAGE*/
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* CREATE A SEMAPHORE
|
||||
*
|
||||
* Description: This function creates a semaphore.
|
||||
*
|
||||
* Arguments : cnt is the initial value for the semaphore. If the value is 0, no resource is
|
||||
* available (or no event has occurred). You initialize the semaphore to a
|
||||
* non-zero value to specify how many resources are available (e.g. if you have
|
||||
* 10 resources, you would initialize the semaphore to 10).
|
||||
*
|
||||
* Returns : != (void *)0 is a pointer to the event control block (OS_EVENT) associated with the
|
||||
* created semaphore
|
||||
* == (void *)0 if no event control blocks were available
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
OS_EVENT *OSSemCreate (INT16U cnt)
|
||||
{
|
||||
OS_EVENT *pevent;
|
||||
#if OS_CRITICAL_METHOD == 3u /* Allocate storage for CPU status register */
|
||||
OS_CPU_SR cpu_sr = 0u;
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#ifdef OS_SAFETY_CRITICAL_IEC61508
|
||||
if (OSSafetyCriticalStartFlag == OS_TRUE) {
|
||||
OS_SAFETY_CRITICAL_EXCEPTION();
|
||||
}
|
||||
#endif
|
||||
|
||||
if (OSIntNesting > 0u) { /* See if called from ISR ... */
|
||||
return ((OS_EVENT *)0); /* ... can't CREATE from an ISR */
|
||||
}
|
||||
OS_ENTER_CRITICAL();
|
||||
pevent = OSEventFreeList; /* Get next free event control block */
|
||||
if (OSEventFreeList != (OS_EVENT *)0) { /* See if pool of free ECB pool was empty */
|
||||
OSEventFreeList = (OS_EVENT *)OSEventFreeList->OSEventPtr;
|
||||
}
|
||||
OS_EXIT_CRITICAL();
|
||||
if (pevent != (OS_EVENT *)0) { /* Get an event control block */
|
||||
pevent->OSEventType = OS_EVENT_TYPE_SEM;
|
||||
pevent->OSEventCnt = cnt; /* Set semaphore value */
|
||||
pevent->OSEventPtr = (void *)0; /* Unlink from ECB free list */
|
||||
#if OS_EVENT_NAME_EN > 0u
|
||||
pevent->OSEventName = (INT8U *)(void *)"?";
|
||||
#endif
|
||||
OS_EventWaitListInit(pevent); /* Initialize to 'nobody waiting' on sem. */
|
||||
}
|
||||
return (pevent);
|
||||
}
|
||||
|
||||
/*$PAGE*/
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* DELETE A SEMAPHORE
|
||||
*
|
||||
* Description: This function deletes a semaphore and readies all tasks pending on the semaphore.
|
||||
*
|
||||
* Arguments : pevent is a pointer to the event control block associated with the desired
|
||||
* semaphore.
|
||||
*
|
||||
* opt determines delete options as follows:
|
||||
* opt == OS_DEL_NO_PEND Delete semaphore ONLY if no task pending
|
||||
* opt == OS_DEL_ALWAYS Deletes the semaphore even if tasks are waiting.
|
||||
* In this case, all the tasks pending will be readied.
|
||||
*
|
||||
* perr is a pointer to an error code that can contain one of the following values:
|
||||
* OS_ERR_NONE The call was successful and the semaphore was deleted
|
||||
* OS_ERR_DEL_ISR If you attempted to delete the semaphore from an ISR
|
||||
* OS_ERR_INVALID_OPT An invalid option was specified
|
||||
* OS_ERR_TASK_WAITING One or more tasks were waiting on the semaphore
|
||||
* OS_ERR_EVENT_TYPE If you didn't pass a pointer to a semaphore
|
||||
* OS_ERR_PEVENT_NULL If 'pevent' is a NULL pointer.
|
||||
*
|
||||
* Returns : pevent upon error
|
||||
* (OS_EVENT *)0 if the semaphore was successfully deleted.
|
||||
*
|
||||
* Note(s) : 1) This function must be used with care. Tasks that would normally expect the presence of
|
||||
* the semaphore MUST check the return code of OSSemPend().
|
||||
* 2) OSSemAccept() callers will not know that the intended semaphore has been deleted unless
|
||||
* they check 'pevent' to see that it's a NULL pointer.
|
||||
* 3) This call can potentially disable interrupts for a long time. The interrupt disable
|
||||
* time is directly proportional to the number of tasks waiting on the semaphore.
|
||||
* 4) Because ALL tasks pending on the semaphore will be readied, you MUST be careful in
|
||||
* applications where the semaphore is used for mutual exclusion because the resource(s)
|
||||
* will no longer be guarded by the semaphore.
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
#if OS_SEM_DEL_EN > 0u
|
||||
OS_EVENT *OSSemDel (OS_EVENT *pevent,
|
||||
INT8U opt,
|
||||
INT8U *perr)
|
||||
{
|
||||
BOOLEAN tasks_waiting;
|
||||
OS_EVENT *pevent_return;
|
||||
#if OS_CRITICAL_METHOD == 3u /* Allocate storage for CPU status register */
|
||||
OS_CPU_SR cpu_sr = 0u;
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#ifdef OS_SAFETY_CRITICAL
|
||||
if (perr == (INT8U *)0) {
|
||||
OS_SAFETY_CRITICAL_EXCEPTION();
|
||||
}
|
||||
#endif
|
||||
|
||||
#if OS_ARG_CHK_EN > 0u
|
||||
if (pevent == (OS_EVENT *)0) { /* Validate 'pevent' */
|
||||
*perr = OS_ERR_PEVENT_NULL;
|
||||
return (pevent);
|
||||
}
|
||||
#endif
|
||||
if (pevent->OSEventType != OS_EVENT_TYPE_SEM) { /* Validate event block type */
|
||||
*perr = OS_ERR_EVENT_TYPE;
|
||||
return (pevent);
|
||||
}
|
||||
if (OSIntNesting > 0u) { /* See if called from ISR ... */
|
||||
*perr = OS_ERR_DEL_ISR; /* ... can't DELETE from an ISR */
|
||||
return (pevent);
|
||||
}
|
||||
OS_ENTER_CRITICAL();
|
||||
if (pevent->OSEventGrp != 0u) { /* See if any tasks waiting on semaphore */
|
||||
tasks_waiting = OS_TRUE; /* Yes */
|
||||
} else {
|
||||
tasks_waiting = OS_FALSE; /* No */
|
||||
}
|
||||
switch (opt) {
|
||||
case OS_DEL_NO_PEND: /* Delete semaphore only if no task waiting */
|
||||
if (tasks_waiting == OS_FALSE) {
|
||||
#if OS_EVENT_NAME_EN > 0u
|
||||
pevent->OSEventName = (INT8U *)(void *)"?";
|
||||
#endif
|
||||
pevent->OSEventType = OS_EVENT_TYPE_UNUSED;
|
||||
pevent->OSEventPtr = OSEventFreeList; /* Return Event Control Block to free list */
|
||||
pevent->OSEventCnt = 0u;
|
||||
OSEventFreeList = pevent; /* Get next free event control block */
|
||||
OS_EXIT_CRITICAL();
|
||||
*perr = OS_ERR_NONE;
|
||||
pevent_return = (OS_EVENT *)0; /* Semaphore has been deleted */
|
||||
} else {
|
||||
OS_EXIT_CRITICAL();
|
||||
*perr = OS_ERR_TASK_WAITING;
|
||||
pevent_return = pevent;
|
||||
}
|
||||
break;
|
||||
|
||||
case OS_DEL_ALWAYS: /* Always delete the semaphore */
|
||||
while (pevent->OSEventGrp != 0u) { /* Ready ALL tasks waiting for semaphore */
|
||||
(void)OS_EventTaskRdy(pevent, (void *)0, OS_STAT_SEM, OS_STAT_PEND_OK);
|
||||
}
|
||||
#if OS_EVENT_NAME_EN > 0u
|
||||
pevent->OSEventName = (INT8U *)(void *)"?";
|
||||
#endif
|
||||
pevent->OSEventType = OS_EVENT_TYPE_UNUSED;
|
||||
pevent->OSEventPtr = OSEventFreeList; /* Return Event Control Block to free list */
|
||||
pevent->OSEventCnt = 0u;
|
||||
OSEventFreeList = pevent; /* Get next free event control block */
|
||||
OS_EXIT_CRITICAL();
|
||||
if (tasks_waiting == OS_TRUE) { /* Reschedule only if task(s) were waiting */
|
||||
OS_Sched(); /* Find highest priority task ready to run */
|
||||
}
|
||||
*perr = OS_ERR_NONE;
|
||||
pevent_return = (OS_EVENT *)0; /* Semaphore has been deleted */
|
||||
break;
|
||||
|
||||
default:
|
||||
OS_EXIT_CRITICAL();
|
||||
*perr = OS_ERR_INVALID_OPT;
|
||||
pevent_return = pevent;
|
||||
break;
|
||||
}
|
||||
return (pevent_return);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*$PAGE*/
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* PEND ON SEMAPHORE
|
||||
*
|
||||
* Description: This function waits for a semaphore.
|
||||
*
|
||||
* Arguments : pevent is a pointer to the event control block associated with the desired
|
||||
* semaphore.
|
||||
*
|
||||
* timeout is an optional timeout period (in clock ticks). If non-zero, your task will
|
||||
* wait for the resource up to the amount of time specified by this argument.
|
||||
* If you specify 0, however, your task will wait forever at the specified
|
||||
* semaphore or, until the resource becomes available (or the event occurs).
|
||||
*
|
||||
* perr is a pointer to where an error message will be deposited. Possible error
|
||||
* messages are:
|
||||
*
|
||||
* OS_ERR_NONE The call was successful and your task owns the resource
|
||||
* or, the event you are waiting for occurred.
|
||||
* OS_ERR_TIMEOUT The semaphore was not received within the specified
|
||||
* 'timeout'.
|
||||
* OS_ERR_PEND_ABORT The wait on the semaphore was aborted.
|
||||
* OS_ERR_EVENT_TYPE If you didn't pass a pointer to a semaphore.
|
||||
* OS_ERR_PEND_ISR If you called this function from an ISR and the result
|
||||
* would lead to a suspension.
|
||||
* OS_ERR_PEVENT_NULL If 'pevent' is a NULL pointer.
|
||||
* OS_ERR_PEND_LOCKED If you called this function when the scheduler is locked
|
||||
*
|
||||
* Returns : none
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
/*$PAGE*/
|
||||
void OSSemPend (OS_EVENT *pevent,
|
||||
INT32U timeout,
|
||||
INT8U *perr)
|
||||
{
|
||||
#if OS_CRITICAL_METHOD == 3u /* Allocate storage for CPU status register */
|
||||
OS_CPU_SR cpu_sr = 0u;
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#ifdef OS_SAFETY_CRITICAL
|
||||
if (perr == (INT8U *)0) {
|
||||
OS_SAFETY_CRITICAL_EXCEPTION();
|
||||
}
|
||||
#endif
|
||||
|
||||
#if OS_ARG_CHK_EN > 0u
|
||||
if (pevent == (OS_EVENT *)0) { /* Validate 'pevent' */
|
||||
*perr = OS_ERR_PEVENT_NULL;
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
if (pevent->OSEventType != OS_EVENT_TYPE_SEM) { /* Validate event block type */
|
||||
*perr = OS_ERR_EVENT_TYPE;
|
||||
return;
|
||||
}
|
||||
if (OSIntNesting > 0u) { /* See if called from ISR ... */
|
||||
*perr = OS_ERR_PEND_ISR; /* ... can't PEND from an ISR */
|
||||
return;
|
||||
}
|
||||
if (OSLockNesting > 0u) { /* See if called with scheduler locked ... */
|
||||
*perr = OS_ERR_PEND_LOCKED; /* ... can't PEND when locked */
|
||||
return;
|
||||
}
|
||||
OS_ENTER_CRITICAL();
|
||||
if (pevent->OSEventCnt > 0u) { /* If sem. is positive, resource available ... */
|
||||
pevent->OSEventCnt--; /* ... decrement semaphore only if positive. */
|
||||
OS_EXIT_CRITICAL();
|
||||
*perr = OS_ERR_NONE;
|
||||
return;
|
||||
}
|
||||
/* Otherwise, must wait until event occurs */
|
||||
OSTCBCur->OSTCBStat |= OS_STAT_SEM; /* Resource not available, pend on semaphore */
|
||||
OSTCBCur->OSTCBStatPend = OS_STAT_PEND_OK;
|
||||
OSTCBCur->OSTCBDly = timeout; /* Store pend timeout in TCB */
|
||||
OS_EventTaskWait(pevent); /* Suspend task until event or timeout occurs */
|
||||
OS_EXIT_CRITICAL();
|
||||
OS_Sched(); /* Find next highest priority task ready */
|
||||
OS_ENTER_CRITICAL();
|
||||
switch (OSTCBCur->OSTCBStatPend) { /* See if we timed-out or aborted */
|
||||
case OS_STAT_PEND_OK:
|
||||
*perr = OS_ERR_NONE;
|
||||
break;
|
||||
|
||||
case OS_STAT_PEND_ABORT:
|
||||
*perr = OS_ERR_PEND_ABORT; /* Indicate that we aborted */
|
||||
break;
|
||||
|
||||
case OS_STAT_PEND_TO:
|
||||
default:
|
||||
OS_EventTaskRemove(OSTCBCur, pevent);
|
||||
*perr = OS_ERR_TIMEOUT; /* Indicate that we didn't get event within TO */
|
||||
break;
|
||||
}
|
||||
OSTCBCur->OSTCBStat = OS_STAT_RDY; /* Set task status to ready */
|
||||
OSTCBCur->OSTCBStatPend = OS_STAT_PEND_OK; /* Clear pend status */
|
||||
OSTCBCur->OSTCBEventPtr = (OS_EVENT *)0; /* Clear event pointers */
|
||||
#if (OS_EVENT_MULTI_EN > 0u)
|
||||
OSTCBCur->OSTCBEventMultiPtr = (OS_EVENT **)0;
|
||||
#endif
|
||||
OS_EXIT_CRITICAL();
|
||||
}
|
||||
|
||||
/*$PAGE*/
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* ABORT WAITING ON A SEMAPHORE
|
||||
*
|
||||
* Description: This function aborts & readies any tasks currently waiting on a semaphore. This function
|
||||
* should be used to fault-abort the wait on the semaphore, rather than to normally signal
|
||||
* the semaphore via OSSemPost().
|
||||
*
|
||||
* Arguments : pevent is a pointer to the event control block associated with the desired
|
||||
* semaphore.
|
||||
*
|
||||
* opt determines the type of ABORT performed:
|
||||
* OS_PEND_OPT_NONE ABORT wait for a single task (HPT) waiting on the
|
||||
* semaphore
|
||||
* OS_PEND_OPT_BROADCAST ABORT wait for ALL tasks that are waiting on the
|
||||
* semaphore
|
||||
*
|
||||
* perr is a pointer to where an error message will be deposited. Possible error
|
||||
* messages are:
|
||||
*
|
||||
* OS_ERR_NONE No tasks were waiting on the semaphore.
|
||||
* OS_ERR_PEND_ABORT At least one task waiting on the semaphore was readied
|
||||
* and informed of the aborted wait; check return value
|
||||
* for the number of tasks whose wait on the semaphore
|
||||
* was aborted.
|
||||
* OS_ERR_EVENT_TYPE If you didn't pass a pointer to a semaphore.
|
||||
* OS_ERR_PEVENT_NULL If 'pevent' is a NULL pointer.
|
||||
*
|
||||
* Returns : == 0 if no tasks were waiting on the semaphore, or upon error.
|
||||
* > 0 if one or more tasks waiting on the semaphore are now readied and informed.
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
#if OS_SEM_PEND_ABORT_EN > 0u
|
||||
INT8U OSSemPendAbort (OS_EVENT *pevent,
|
||||
INT8U opt,
|
||||
INT8U *perr)
|
||||
{
|
||||
INT8U nbr_tasks;
|
||||
#if OS_CRITICAL_METHOD == 3u /* Allocate storage for CPU status register */
|
||||
OS_CPU_SR cpu_sr = 0u;
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#ifdef OS_SAFETY_CRITICAL
|
||||
if (perr == (INT8U *)0) {
|
||||
OS_SAFETY_CRITICAL_EXCEPTION();
|
||||
}
|
||||
#endif
|
||||
|
||||
#if OS_ARG_CHK_EN > 0u
|
||||
if (pevent == (OS_EVENT *)0) { /* Validate 'pevent' */
|
||||
*perr = OS_ERR_PEVENT_NULL;
|
||||
return (0u);
|
||||
}
|
||||
#endif
|
||||
if (pevent->OSEventType != OS_EVENT_TYPE_SEM) { /* Validate event block type */
|
||||
*perr = OS_ERR_EVENT_TYPE;
|
||||
return (0u);
|
||||
}
|
||||
OS_ENTER_CRITICAL();
|
||||
if (pevent->OSEventGrp != 0u) { /* See if any task waiting on semaphore? */
|
||||
nbr_tasks = 0u;
|
||||
switch (opt) {
|
||||
case OS_PEND_OPT_BROADCAST: /* Do we need to abort ALL waiting tasks? */
|
||||
while (pevent->OSEventGrp != 0u) { /* Yes, ready ALL tasks waiting on semaphore */
|
||||
(void)OS_EventTaskRdy(pevent, (void *)0, OS_STAT_SEM, OS_STAT_PEND_ABORT);
|
||||
nbr_tasks++;
|
||||
}
|
||||
break;
|
||||
|
||||
case OS_PEND_OPT_NONE:
|
||||
default: /* No, ready HPT waiting on semaphore */
|
||||
(void)OS_EventTaskRdy(pevent, (void *)0, OS_STAT_SEM, OS_STAT_PEND_ABORT);
|
||||
nbr_tasks++;
|
||||
break;
|
||||
}
|
||||
OS_EXIT_CRITICAL();
|
||||
OS_Sched(); /* Find HPT ready to run */
|
||||
*perr = OS_ERR_PEND_ABORT;
|
||||
return (nbr_tasks);
|
||||
}
|
||||
OS_EXIT_CRITICAL();
|
||||
*perr = OS_ERR_NONE;
|
||||
return (0u); /* No tasks waiting on semaphore */
|
||||
}
|
||||
#endif
|
||||
|
||||
/*$PAGE*/
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* POST TO A SEMAPHORE
|
||||
*
|
||||
* Description: This function signals a semaphore
|
||||
*
|
||||
* Arguments : pevent is a pointer to the event control block associated with the desired
|
||||
* semaphore.
|
||||
*
|
||||
* Returns : OS_ERR_NONE The call was successful and the semaphore was signaled.
|
||||
* OS_ERR_SEM_OVF If the semaphore count exceeded its limit. In other words, you have
|
||||
* signalled the semaphore more often than you waited on it with either
|
||||
* OSSemAccept() or OSSemPend().
|
||||
* OS_ERR_EVENT_TYPE If you didn't pass a pointer to a semaphore
|
||||
* OS_ERR_PEVENT_NULL If 'pevent' is a NULL pointer.
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
INT8U OSSemPost (OS_EVENT *pevent)
|
||||
{
|
||||
#if OS_CRITICAL_METHOD == 3u /* Allocate storage for CPU status register */
|
||||
OS_CPU_SR cpu_sr = 0u;
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#if OS_ARG_CHK_EN > 0u
|
||||
if (pevent == (OS_EVENT *)0) { /* Validate 'pevent' */
|
||||
return (OS_ERR_PEVENT_NULL);
|
||||
}
|
||||
#endif
|
||||
if (pevent->OSEventType != OS_EVENT_TYPE_SEM) { /* Validate event block type */
|
||||
return (OS_ERR_EVENT_TYPE);
|
||||
}
|
||||
OS_ENTER_CRITICAL();
|
||||
if (pevent->OSEventGrp != 0u) { /* See if any task waiting for semaphore */
|
||||
/* Ready HPT waiting on event */
|
||||
(void)OS_EventTaskRdy(pevent, (void *)0, OS_STAT_SEM, OS_STAT_PEND_OK);
|
||||
OS_EXIT_CRITICAL();
|
||||
OS_Sched(); /* Find HPT ready to run */
|
||||
return (OS_ERR_NONE);
|
||||
}
|
||||
if (pevent->OSEventCnt < 65535u) { /* Make sure semaphore will not overflow */
|
||||
pevent->OSEventCnt++; /* Increment semaphore count to register event */
|
||||
OS_EXIT_CRITICAL();
|
||||
return (OS_ERR_NONE);
|
||||
}
|
||||
OS_EXIT_CRITICAL(); /* Semaphore value has reached its maximum */
|
||||
return (OS_ERR_SEM_OVF);
|
||||
}
|
||||
|
||||
/*$PAGE*/
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* QUERY A SEMAPHORE
|
||||
*
|
||||
* Description: This function obtains information about a semaphore
|
||||
*
|
||||
* Arguments : pevent is a pointer to the event control block associated with the desired
|
||||
* semaphore
|
||||
*
|
||||
* p_sem_data is a pointer to a structure that will contain information about the
|
||||
* semaphore.
|
||||
*
|
||||
* Returns : OS_ERR_NONE The call was successful and the message was sent
|
||||
* OS_ERR_EVENT_TYPE If you are attempting to obtain data from a non semaphore.
|
||||
* OS_ERR_PEVENT_NULL If 'pevent' is a NULL pointer.
|
||||
* OS_ERR_PDATA_NULL If 'p_sem_data' is a NULL pointer
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
#if OS_SEM_QUERY_EN > 0u
|
||||
INT8U OSSemQuery (OS_EVENT *pevent,
|
||||
OS_SEM_DATA *p_sem_data)
|
||||
{
|
||||
INT8U i;
|
||||
OS_PRIO *psrc;
|
||||
OS_PRIO *pdest;
|
||||
#if OS_CRITICAL_METHOD == 3u /* Allocate storage for CPU status register */
|
||||
OS_CPU_SR cpu_sr = 0u;
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#if OS_ARG_CHK_EN > 0u
|
||||
if (pevent == (OS_EVENT *)0) { /* Validate 'pevent' */
|
||||
return (OS_ERR_PEVENT_NULL);
|
||||
}
|
||||
if (p_sem_data == (OS_SEM_DATA *)0) { /* Validate 'p_sem_data' */
|
||||
return (OS_ERR_PDATA_NULL);
|
||||
}
|
||||
#endif
|
||||
if (pevent->OSEventType != OS_EVENT_TYPE_SEM) { /* Validate event block type */
|
||||
return (OS_ERR_EVENT_TYPE);
|
||||
}
|
||||
OS_ENTER_CRITICAL();
|
||||
p_sem_data->OSEventGrp = pevent->OSEventGrp; /* Copy message mailbox wait list */
|
||||
psrc = &pevent->OSEventTbl[0];
|
||||
pdest = &p_sem_data->OSEventTbl[0];
|
||||
for (i = 0u; i < OS_EVENT_TBL_SIZE; i++) {
|
||||
*pdest++ = *psrc++;
|
||||
}
|
||||
p_sem_data->OSCnt = pevent->OSEventCnt; /* Get semaphore count */
|
||||
OS_EXIT_CRITICAL();
|
||||
return (OS_ERR_NONE);
|
||||
}
|
||||
#endif /* OS_SEM_QUERY_EN */
|
||||
|
||||
/*$PAGE*/
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* SET SEMAPHORE
|
||||
*
|
||||
* Description: This function sets the semaphore count to the value specified as an argument. Typically,
|
||||
* this value would be 0.
|
||||
*
|
||||
* You would typically use this function when a semaphore is used as a signaling mechanism
|
||||
* and, you want to reset the count value.
|
||||
*
|
||||
* Arguments : pevent is a pointer to the event control block
|
||||
*
|
||||
* cnt is the new value for the semaphore count. You would pass 0 to reset the
|
||||
* semaphore count.
|
||||
*
|
||||
* perr is a pointer to an error code returned by the function as follows:
|
||||
*
|
||||
* OS_ERR_NONE The call was successful and the semaphore value was set.
|
||||
* OS_ERR_EVENT_TYPE If you didn't pass a pointer to a semaphore.
|
||||
* OS_ERR_PEVENT_NULL If 'pevent' is a NULL pointer.
|
||||
* OS_ERR_TASK_WAITING If tasks are waiting on the semaphore.
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
#if OS_SEM_SET_EN > 0u
|
||||
void OSSemSet (OS_EVENT *pevent,
|
||||
INT16U cnt,
|
||||
INT8U *perr)
|
||||
{
|
||||
#if OS_CRITICAL_METHOD == 3u /* Allocate storage for CPU status register */
|
||||
OS_CPU_SR cpu_sr = 0u;
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#ifdef OS_SAFETY_CRITICAL
|
||||
if (perr == (INT8U *)0) {
|
||||
OS_SAFETY_CRITICAL_EXCEPTION();
|
||||
}
|
||||
#endif
|
||||
|
||||
#if OS_ARG_CHK_EN > 0u
|
||||
if (pevent == (OS_EVENT *)0) { /* Validate 'pevent' */
|
||||
*perr = OS_ERR_PEVENT_NULL;
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
if (pevent->OSEventType != OS_EVENT_TYPE_SEM) { /* Validate event block type */
|
||||
*perr = OS_ERR_EVENT_TYPE;
|
||||
return;
|
||||
}
|
||||
OS_ENTER_CRITICAL();
|
||||
*perr = OS_ERR_NONE;
|
||||
if (pevent->OSEventCnt > 0u) { /* See if semaphore already has a count */
|
||||
pevent->OSEventCnt = cnt; /* Yes, set it to the new value specified. */
|
||||
} else { /* No */
|
||||
if (pevent->OSEventGrp == 0u) { /* See if task(s) waiting? */
|
||||
pevent->OSEventCnt = cnt; /* No, OK to set the value */
|
||||
} else {
|
||||
*perr = OS_ERR_TASK_WAITING;
|
||||
}
|
||||
}
|
||||
OS_EXIT_CRITICAL();
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* OS_SEM_EN */
|
||||
|
||||
1263
UCOSII/CORE/os_task.c
Normal file
1263
UCOSII/CORE/os_task.c
Normal file
File diff suppressed because it is too large
Load Diff
264
UCOSII/CORE/os_time.c
Normal file
264
UCOSII/CORE/os_time.c
Normal file
@@ -0,0 +1,264 @@
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* uC/OS-II
|
||||
* The Real-Time Kernel
|
||||
* TIME MANAGEMENT
|
||||
*
|
||||
* (c) Copyright 1992-2009, Micrium, Weston, FL
|
||||
* All Rights Reserved
|
||||
*
|
||||
* File : OS_TIME.C
|
||||
* By : Jean J. Labrosse
|
||||
* Version : V2.91
|
||||
*
|
||||
* LICENSING TERMS:
|
||||
* ---------------
|
||||
* uC/OS-II is provided in source form for FREE evaluation, for educational use or for peaceful research.
|
||||
* If you plan on using uC/OS-II in a commercial product you need to contact Micri<72>m to properly license
|
||||
* its use in your product. We provide ALL the source code for your convenience and to help you experience
|
||||
* uC/OS-II. The fact that the source is provided does NOT mean that you can use it without paying a
|
||||
* licensing fee.
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef OS_MASTER_FILE
|
||||
#include <ucos_ii.h>
|
||||
#endif
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* DELAY TASK 'n' TICKS
|
||||
*
|
||||
* Description: This function is called to delay execution of the currently running task until the
|
||||
* specified number of system ticks expires. This, of course, directly equates to delaying
|
||||
* the current task for some time to expire. No delay will result If the specified delay is
|
||||
* 0. If the specified delay is greater than 0 then, a context switch will result.
|
||||
*
|
||||
* Arguments : ticks is the time delay that the task will be suspended in number of clock 'ticks'.
|
||||
* Note that by specifying 0, the task will not be delayed.
|
||||
*
|
||||
* Returns : none
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
void OSTimeDly (INT32U ticks)
|
||||
{
|
||||
INT8U y;
|
||||
#if OS_CRITICAL_METHOD == 3u /* Allocate storage for CPU status register */
|
||||
OS_CPU_SR cpu_sr = 0u;
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
if (OSIntNesting > 0u) { /* See if trying to call from an ISR */
|
||||
return;
|
||||
}
|
||||
if (OSLockNesting > 0u) { /* See if called with scheduler locked */
|
||||
return;
|
||||
}
|
||||
if (ticks > 0u) { /* 0 means no delay! */
|
||||
OS_ENTER_CRITICAL();
|
||||
y = OSTCBCur->OSTCBY; /* Delay current task */
|
||||
OSRdyTbl[y] &= (OS_PRIO)~OSTCBCur->OSTCBBitX;
|
||||
if (OSRdyTbl[y] == 0u) {
|
||||
OSRdyGrp &= (OS_PRIO)~OSTCBCur->OSTCBBitY;
|
||||
}
|
||||
OSTCBCur->OSTCBDly = ticks; /* Load ticks in TCB */
|
||||
OS_EXIT_CRITICAL();
|
||||
OS_Sched(); /* Find next task to run! */
|
||||
}
|
||||
}
|
||||
/*$PAGE*/
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* DELAY TASK FOR SPECIFIED TIME
|
||||
*
|
||||
* Description: This function is called to delay execution of the currently running task until some time
|
||||
* expires. This call allows you to specify the delay time in HOURS, MINUTES, SECONDS and
|
||||
* MILLISECONDS instead of ticks.
|
||||
*
|
||||
* Arguments : hours specifies the number of hours that the task will be delayed (max. is 255)
|
||||
* minutes specifies the number of minutes (max. 59)
|
||||
* seconds specifies the number of seconds (max. 59)
|
||||
* ms specifies the number of milliseconds (max. 999)
|
||||
*
|
||||
* Returns : OS_ERR_NONE
|
||||
* OS_ERR_TIME_INVALID_MINUTES
|
||||
* OS_ERR_TIME_INVALID_SECONDS
|
||||
* OS_ERR_TIME_INVALID_MS
|
||||
* OS_ERR_TIME_ZERO_DLY
|
||||
* OS_ERR_TIME_DLY_ISR
|
||||
*
|
||||
* Note(s) : The resolution on the milliseconds depends on the tick rate. For example, you can't do
|
||||
* a 10 mS delay if the ticker interrupts every 100 mS. In this case, the delay would be
|
||||
* set to 0. The actual delay is rounded to the nearest tick.
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
#if OS_TIME_DLY_HMSM_EN > 0u
|
||||
INT8U OSTimeDlyHMSM (INT8U hours,
|
||||
INT8U minutes,
|
||||
INT8U seconds,
|
||||
INT16U ms)
|
||||
{
|
||||
INT32U ticks;
|
||||
|
||||
|
||||
if (OSIntNesting > 0u) { /* See if trying to call from an ISR */
|
||||
return (OS_ERR_TIME_DLY_ISR);
|
||||
}
|
||||
if (OSLockNesting > 0u) { /* See if called with scheduler locked */
|
||||
return (OS_ERR_SCHED_LOCKED);
|
||||
}
|
||||
#if OS_ARG_CHK_EN > 0u
|
||||
if (hours == 0u) {
|
||||
if (minutes == 0u) {
|
||||
if (seconds == 0u) {
|
||||
if (ms == 0u) {
|
||||
return (OS_ERR_TIME_ZERO_DLY);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (minutes > 59u) {
|
||||
return (OS_ERR_TIME_INVALID_MINUTES); /* Validate arguments to be within range */
|
||||
}
|
||||
if (seconds > 59u) {
|
||||
return (OS_ERR_TIME_INVALID_SECONDS);
|
||||
}
|
||||
if (ms > 999u) {
|
||||
return (OS_ERR_TIME_INVALID_MS);
|
||||
}
|
||||
#endif
|
||||
/* Compute the total number of clock ticks required.. */
|
||||
/* .. (rounded to the nearest tick) */
|
||||
ticks = ((INT32U)hours * 3600uL + (INT32U)minutes * 60uL + (INT32U)seconds) * OS_TICKS_PER_SEC
|
||||
+ OS_TICKS_PER_SEC * ((INT32U)ms + 500uL / OS_TICKS_PER_SEC) / 1000uL;
|
||||
OSTimeDly(ticks);
|
||||
return (OS_ERR_NONE);
|
||||
}
|
||||
#endif
|
||||
/*$PAGE*/
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* RESUME A DELAYED TASK
|
||||
*
|
||||
* Description: This function is used resume a task that has been delayed through a call to either
|
||||
* OSTimeDly() or OSTimeDlyHMSM(). Note that you can call this function to resume a
|
||||
* task that is waiting for an event with timeout. This would make the task look
|
||||
* like a timeout occurred.
|
||||
*
|
||||
* Arguments : prio specifies the priority of the task to resume
|
||||
*
|
||||
* Returns : OS_ERR_NONE Task has been resumed
|
||||
* OS_ERR_PRIO_INVALID if the priority you specify is higher that the maximum allowed
|
||||
* (i.e. >= OS_LOWEST_PRIO)
|
||||
* OS_ERR_TIME_NOT_DLY Task is not waiting for time to expire
|
||||
* OS_ERR_TASK_NOT_EXIST The desired task has not been created or has been assigned to a Mutex.
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
#if OS_TIME_DLY_RESUME_EN > 0u
|
||||
INT8U OSTimeDlyResume (INT8U prio)
|
||||
{
|
||||
OS_TCB *ptcb;
|
||||
#if OS_CRITICAL_METHOD == 3u /* Storage for CPU status register */
|
||||
OS_CPU_SR cpu_sr = 0u;
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
if (prio >= OS_LOWEST_PRIO) {
|
||||
return (OS_ERR_PRIO_INVALID);
|
||||
}
|
||||
OS_ENTER_CRITICAL();
|
||||
ptcb = OSTCBPrioTbl[prio]; /* Make sure that task exist */
|
||||
if (ptcb == (OS_TCB *)0) {
|
||||
OS_EXIT_CRITICAL();
|
||||
return (OS_ERR_TASK_NOT_EXIST); /* The task does not exist */
|
||||
}
|
||||
if (ptcb == OS_TCB_RESERVED) {
|
||||
OS_EXIT_CRITICAL();
|
||||
return (OS_ERR_TASK_NOT_EXIST); /* The task does not exist */
|
||||
}
|
||||
if (ptcb->OSTCBDly == 0u) { /* See if task is delayed */
|
||||
OS_EXIT_CRITICAL();
|
||||
return (OS_ERR_TIME_NOT_DLY); /* Indicate that task was not delayed */
|
||||
}
|
||||
|
||||
ptcb->OSTCBDly = 0u; /* Clear the time delay */
|
||||
if ((ptcb->OSTCBStat & OS_STAT_PEND_ANY) != OS_STAT_RDY) {
|
||||
ptcb->OSTCBStat &= ~OS_STAT_PEND_ANY; /* Yes, Clear status flag */
|
||||
ptcb->OSTCBStatPend = OS_STAT_PEND_TO; /* Indicate PEND timeout */
|
||||
} else {
|
||||
ptcb->OSTCBStatPend = OS_STAT_PEND_OK;
|
||||
}
|
||||
if ((ptcb->OSTCBStat & OS_STAT_SUSPEND) == OS_STAT_RDY) { /* Is task suspended? */
|
||||
OSRdyGrp |= ptcb->OSTCBBitY; /* No, Make ready */
|
||||
OSRdyTbl[ptcb->OSTCBY] |= ptcb->OSTCBBitX;
|
||||
OS_EXIT_CRITICAL();
|
||||
OS_Sched(); /* See if this is new highest priority */
|
||||
} else {
|
||||
OS_EXIT_CRITICAL(); /* Task may be suspended */
|
||||
}
|
||||
return (OS_ERR_NONE);
|
||||
}
|
||||
#endif
|
||||
/*$PAGE*/
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* GET CURRENT SYSTEM TIME
|
||||
*
|
||||
* Description: This function is used by your application to obtain the current value of the 32-bit
|
||||
* counter which keeps track of the number of clock ticks.
|
||||
*
|
||||
* Arguments : none
|
||||
*
|
||||
* Returns : The current value of OSTime
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
#if OS_TIME_GET_SET_EN > 0u
|
||||
INT32U OSTimeGet (void)
|
||||
{
|
||||
INT32U ticks;
|
||||
#if OS_CRITICAL_METHOD == 3u /* Allocate storage for CPU status register */
|
||||
OS_CPU_SR cpu_sr = 0u;
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
OS_ENTER_CRITICAL();
|
||||
ticks = OSTime;
|
||||
OS_EXIT_CRITICAL();
|
||||
return (ticks);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* SET SYSTEM CLOCK
|
||||
*
|
||||
* Description: This function sets the 32-bit counter which keeps track of the number of clock ticks.
|
||||
*
|
||||
* Arguments : ticks specifies the new value that OSTime needs to take.
|
||||
*
|
||||
* Returns : none
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
#if OS_TIME_GET_SET_EN > 0u
|
||||
void OSTimeSet (INT32U ticks)
|
||||
{
|
||||
#if OS_CRITICAL_METHOD == 3u /* Allocate storage for CPU status register */
|
||||
OS_CPU_SR cpu_sr = 0u;
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
OS_ENTER_CRITICAL();
|
||||
OSTime = ticks;
|
||||
OS_EXIT_CRITICAL();
|
||||
}
|
||||
#endif
|
||||
|
||||
1073
UCOSII/CORE/os_tmr.c
Normal file
1073
UCOSII/CORE/os_tmr.c
Normal file
File diff suppressed because it is too large
Load Diff
38
UCOSII/CORE/ucos_ii.c
Normal file
38
UCOSII/CORE/ucos_ii.c
Normal file
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* uC/OS-II
|
||||
* The Real-Time Kernel
|
||||
*
|
||||
* (c) Copyright 1992-2009, Micrium, Weston, FL
|
||||
* All Rights Reserved
|
||||
*
|
||||
* File : uCOS_II.C
|
||||
* By : Jean J. Labrosse
|
||||
* Version : V2.91
|
||||
*
|
||||
* LICENSING TERMS:
|
||||
* ---------------
|
||||
* uC/OS-II is provided in source form for FREE evaluation, for educational use or for peaceful research.
|
||||
* If you plan on using uC/OS-II in a commercial product you need to contact Micri<72>m to properly license
|
||||
* its use in your product. We provide ALL the source code for your convenience and to help you experience
|
||||
* uC/OS-II. The fact that the source is provided does NOT mean that you can use it without paying a
|
||||
* licensing fee.
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
#define OS_GLOBALS /* Declare GLOBAL variables */
|
||||
#include <ucos_ii.h>
|
||||
|
||||
|
||||
#define OS_MASTER_FILE /* Prevent the following files from including includes.h */
|
||||
#include <os_core.c>
|
||||
#include <os_flag.c>
|
||||
#include <os_mbox.c>
|
||||
#include <os_mem.c>
|
||||
#include <os_mutex.c>
|
||||
#include <os_q.c>
|
||||
#include <os_sem.c>
|
||||
#include <os_task.c>
|
||||
#include <os_time.c>
|
||||
#include <os_tmr.c>
|
||||
|
||||
1895
UCOSII/CORE/ucos_ii.h
Normal file
1895
UCOSII/CORE/ucos_ii.h
Normal file
File diff suppressed because it is too large
Load Diff
89
UCOSII/PORT/os_cpu.h
Normal file
89
UCOSII/PORT/os_cpu.h
Normal file
@@ -0,0 +1,89 @@
|
||||
/************************ (C) COPYLEFT 2010 Leafgrass *************************
|
||||
|
||||
* File Name : os_cpu_c.c
|
||||
* Author : Librae
|
||||
* Date : 06/10/2010
|
||||
* Description : <20><>COS-II<49><49>STM32<33>ϵ<EFBFBD><CFB5><EFBFBD>ֲ<EFBFBD><D6B2><EFBFBD><EFBFBD>C<EFBFBD><43><EFBFBD>Բ<EFBFBD><D4B2>֣<EFBFBD>
|
||||
* <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ջ<EFBFBD><D5BB>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><CDB9>Ӻ<EFBFBD><D3BA><EFBFBD><EFBFBD><EFBFBD>
|
||||
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef __OS_CPU_H__
|
||||
#define __OS_CPU_H__
|
||||
|
||||
#ifdef OS_CPU_GLOBALS
|
||||
#define OS_CPU_EXT
|
||||
#else
|
||||
#define OS_CPU_EXT extern
|
||||
#endif
|
||||
|
||||
/******************************************************************************
|
||||
* <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ص<DEB9><D8B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
******************************************************************************/
|
||||
|
||||
typedef unsigned char BOOLEAN;
|
||||
typedef unsigned char INT8U; /* Unsigned 8 bit quantity */
|
||||
typedef signed char INT8S; /* Signed 8 bit quantity */
|
||||
typedef unsigned short INT16U; /* Unsigned 16 bit quantity */
|
||||
typedef signed short INT16S; /* Signed 16 bit quantity */
|
||||
typedef unsigned int INT32U; /* Unsigned 32 bit quantity */
|
||||
typedef signed int INT32S; /* Signed 32 bit quantity */
|
||||
typedef float FP32; /* Single precision floating point*/
|
||||
typedef double FP64; /* Double precision floating point*/
|
||||
|
||||
//STM32<33><32>32λλ<CEBB><CEBB><EFBFBD><EFBFBD>,<2C><><EFBFBD><EFBFBD>OS_STK<54><4B>OS_CPU_SR<53><52>Ӧ<EFBFBD><D3A6>Ϊ32λ<32><CEBB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
typedef unsigned int OS_STK; /* Each stack entry is 32-bit wide*/
|
||||
typedef unsigned int OS_CPU_SR; /* Define size of CPU status register*/
|
||||
/*
|
||||
*******************************************************************************
|
||||
* Cortex M3
|
||||
* Critical Section Management
|
||||
*******************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
*******************************************************************************
|
||||
* ARM Miscellaneous
|
||||
*******************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
//<2F><><EFBFBD><EFBFBD>ջ<EFBFBD><D5BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>.
|
||||
//CM3<4D><33>,ջ<><D5BB><EFBFBD>ɸߵ<C9B8>ַ<EFBFBD><D6B7><EFBFBD>͵<EFBFBD>ַ<EFBFBD><D6B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD>,<2C><><EFBFBD><EFBFBD>OS_STK_GROWTH<54><48><EFBFBD><EFBFBD>Ϊ1
|
||||
#define OS_STK_GROWTH 1 /* Stack grows from HIGH to LOW memory on ARM */
|
||||
//<2F><><EFBFBD><EFBFBD><EFBFBD>л<EFBFBD><D0BB><EFBFBD>,<2C>ɻ<EFBFBD><C9BB><EFBFBD>ʵ<EFBFBD><CAB5>.
|
||||
#define OS_TASK_SW() OSCtxSw()
|
||||
|
||||
/*
|
||||
*******************************************************************************
|
||||
* PROTOTYPES
|
||||
* (see OS_CPU_A.ASM)
|
||||
*******************************************************************************
|
||||
*/
|
||||
//OS_CRITICAL_METHOD = 1 :ֱ<><D6B1>ʹ<EFBFBD>ô<EFBFBD><C3B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ŀ<EFBFBD><C4BF><EFBFBD><EFBFBD>ж<EFBFBD>ָ<EFBFBD><D6B8><EFBFBD><EFBFBD>ʵ<EFBFBD>ֺ<EFBFBD>
|
||||
//OS_CRITICAL_METHOD = 2 :<3A><><EFBFBD>ö<EFBFBD>ջ<EFBFBD><D5BB><EFBFBD><EFBFBD><EFBFBD>ͻָ<CDBB>CPU<50><55>״̬
|
||||
//OS_CRITICAL_METHOD = 3 :<3A><><EFBFBD>ñ<EFBFBD><C3B1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>չ<EFBFBD><D5B9><EFBFBD>ܻ<EFBFBD><DCBB>ó<EFBFBD><C3B3><EFBFBD>״̬<D7B4>֣<EFBFBD><D6A3><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ھֲ<DABE><D6B2><EFBFBD><EFBFBD><EFBFBD>cpu_sr
|
||||
|
||||
#define OS_CRITICAL_METHOD 3 //<2F><><EFBFBD><EFBFBD><EFBFBD>ٽ<EFBFBD><D9BD>εķ<CEB5><C4B7><EFBFBD>
|
||||
|
||||
#if OS_CRITICAL_METHOD == 3
|
||||
#define OS_ENTER_CRITICAL() {cpu_sr = OS_CPU_SR_Save();}
|
||||
#define OS_EXIT_CRITICAL() {OS_CPU_SR_Restore(cpu_sr);}
|
||||
#endif
|
||||
|
||||
void OSCtxSw(void);
|
||||
void OSIntCtxSw(void);
|
||||
void OSStartHighRdy(void);
|
||||
|
||||
void OSPendSV(void);
|
||||
|
||||
#if OS_CRITICAL_METHOD == 3u /* See OS_CPU_A.ASM */
|
||||
OS_CPU_SR OS_CPU_SR_Save(void);
|
||||
void OS_CPU_SR_Restore(OS_CPU_SR cpu_sr);
|
||||
#endif
|
||||
OS_CPU_EXT INT32U OSInterrputSum;
|
||||
|
||||
#endif
|
||||
|
||||
/************************ (C) COPYLEFT 2010 Leafgrass ************************/
|
||||
197
UCOSII/PORT/os_cpu_a.asm
Normal file
197
UCOSII/PORT/os_cpu_a.asm
Normal file
@@ -0,0 +1,197 @@
|
||||
;/*********************** (C) COPYRIGHT 2010 Libraworks *************************
|
||||
;* File Name : os_cpu_a.asm
|
||||
;* Author : Librae
|
||||
;* Version : V1.0
|
||||
;* Date : 06/10/2010
|
||||
;* Description : <20><>COS-II asm port for STM32
|
||||
;*******************************************************************************/
|
||||
|
||||
IMPORT OSRunning ; External references
|
||||
IMPORT OSPrioCur
|
||||
IMPORT OSPrioHighRdy
|
||||
IMPORT OSTCBCur
|
||||
IMPORT OSTCBHighRdy
|
||||
IMPORT OSIntNesting
|
||||
IMPORT OSIntExit
|
||||
IMPORT OSTaskSwHook
|
||||
|
||||
EXPORT OSStartHighRdy
|
||||
EXPORT OSCtxSw
|
||||
EXPORT OSIntCtxSw
|
||||
EXPORT OS_CPU_SR_Save ; Functions declared in this file
|
||||
EXPORT OS_CPU_SR_Restore
|
||||
EXPORT PendSV_Handler
|
||||
|
||||
|
||||
NVIC_INT_CTRL EQU 0xE000ED04 ; <20>жϿ<D0B6><CFBF>ƼĴ<C6BC><C4B4><EFBFBD>
|
||||
NVIC_SYSPRI2 EQU 0xE000ED20 ; ϵͳ<CFB5><CDB3><EFBFBD>ȼ<EFBFBD><C8BC>Ĵ<EFBFBD><C4B4><EFBFBD>(2)
|
||||
NVIC_PENDSV_PRI EQU 0xFFFF0000 ; PendSV<53>жϺ<D0B6>ϵͳ<CFB5><CDB3><EFBFBD><EFBFBD><EFBFBD>ж<EFBFBD>
|
||||
; (<28><>Ϊ<EFBFBD><CEAA><EFBFBD>ͣ<EFBFBD>0xff).
|
||||
NVIC_PENDSVSET EQU 0x10000000 ; <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>жϵ<D0B6>ֵ.
|
||||
|
||||
|
||||
PRESERVE8
|
||||
|
||||
AREA |.text|, CODE, READONLY
|
||||
THUMB
|
||||
|
||||
|
||||
|
||||
;********************************************************************************************************
|
||||
; CRITICAL SECTION METHOD 3 FUNCTIONS
|
||||
;
|
||||
; Description: Disable/Enable interrupts by preserving the state of interrupts. Generally speaking you
|
||||
; would store the state of the interrupt disable flag in the local variable 'cpu_sr' and then
|
||||
; disable interrupts. 'cpu_sr' is allocated in all of uC/OS-II's functions that need to
|
||||
; disable interrupts. You would restore the interrupt disable state by copying back 'cpu_sr'
|
||||
; into the CPU's status register.
|
||||
;
|
||||
; Prototypes : OS_CPU_SR OS_CPU_SR_Save(void);
|
||||
; void OS_CPU_SR_Restore(OS_CPU_SR cpu_sr);
|
||||
;
|
||||
;
|
||||
; Note(s) : 1) These functions are used in general like this:
|
||||
;
|
||||
; void Task (void *p_arg)
|
||||
; {
|
||||
; #if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */
|
||||
; OS_CPU_SR cpu_sr;
|
||||
; #endif
|
||||
;
|
||||
; :
|
||||
; :
|
||||
; OS_ENTER_CRITICAL(); /* cpu_sr = OS_CPU_SaveSR(); */
|
||||
; :
|
||||
; :
|
||||
; OS_EXIT_CRITICAL(); /* OS_CPU_RestoreSR(cpu_sr); */
|
||||
; :
|
||||
; :
|
||||
; }
|
||||
;********************************************************************************************************
|
||||
|
||||
OS_CPU_SR_Save
|
||||
MRS R0, PRIMASK ;<3B><>ȡPRIMASK<53><4B>R0,R0Ϊ<30><CEAA><EFBFBD><EFBFBD>ֵ
|
||||
CPSID I ;PRIMASK=1,<2C><><EFBFBD>ж<EFBFBD>(NMI<4D><49>Ӳ<EFBFBD><D3B2>FAULT<4C><54><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ӧ)
|
||||
BX LR ;<3B><><EFBFBD><EFBFBD>
|
||||
|
||||
OS_CPU_SR_Restore
|
||||
MSR PRIMASK, R0 ;<3B><>ȡR0<52><30>PRIMASK<53><4B>,R0Ϊ<30><CEAA><EFBFBD><EFBFBD>
|
||||
BX LR ;<3B><><EFBFBD><EFBFBD>
|
||||
|
||||
|
||||
;/**************************************************************************************
|
||||
;* <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>: OSStartHighRdy
|
||||
;*
|
||||
;* <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>: ʹ<>õ<EFBFBD><C3B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>е<EFBFBD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
;*
|
||||
;* <20><> <20><>: None
|
||||
;*
|
||||
;* <20><> <20><> ֵ: None
|
||||
;**************************************************************************************/
|
||||
|
||||
OSStartHighRdy
|
||||
LDR R4, =NVIC_SYSPRI2 ; set the PendSV exception priority
|
||||
LDR R5, =NVIC_PENDSV_PRI
|
||||
STR R5, [R4]
|
||||
|
||||
MOV R4, #0 ; set the PSP to 0 for initial context switch call
|
||||
MSR PSP, R4
|
||||
|
||||
LDR R4, =OSRunning ; OSRunning = TRUE
|
||||
MOV R5, #1
|
||||
STRB R5, [R4]
|
||||
|
||||
;<3B>л<EFBFBD><D0BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȼ<EFBFBD><C8BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
LDR R4, =NVIC_INT_CTRL ;rigger the PendSV exception (causes context switch)
|
||||
LDR R5, =NVIC_PENDSVSET
|
||||
STR R5, [R4]
|
||||
|
||||
CPSIE I ;enable interrupts at processor level
|
||||
OSStartHang
|
||||
B OSStartHang ;should never get here
|
||||
|
||||
;/**************************************************************************************
|
||||
;* <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>: OSCtxSw
|
||||
;*
|
||||
;* <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>: <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>л<EFBFBD>
|
||||
;*
|
||||
;* <20><> <20><>: None
|
||||
;*
|
||||
;* <20><> <20><> ֵ: None
|
||||
;***************************************************************************************/
|
||||
|
||||
OSCtxSw
|
||||
PUSH {R4, R5}
|
||||
LDR R4, =NVIC_INT_CTRL ;<3B><><EFBFBD><EFBFBD>PendSV<53>쳣 (causes context switch)
|
||||
LDR R5, =NVIC_PENDSVSET
|
||||
STR R5, [R4]
|
||||
POP {R4, R5}
|
||||
BX LR
|
||||
|
||||
;/**************************************************************************************
|
||||
;* <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>: OSIntCtxSw
|
||||
;*
|
||||
;* <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>: <20>жϼ<D0B6><CFBC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>л<EFBFBD>
|
||||
;*
|
||||
;* <20><> <20><>: None
|
||||
;*
|
||||
;* <20><> <20><> ֵ: None
|
||||
;***************************************************************************************/
|
||||
|
||||
OSIntCtxSw
|
||||
PUSH {R4, R5}
|
||||
LDR R4, =NVIC_INT_CTRL ;<3B><><EFBFBD><EFBFBD>PendSV<53>쳣 (causes context switch)
|
||||
LDR R5, =NVIC_PENDSVSET
|
||||
STR R5, [R4]
|
||||
POP {R4, R5}
|
||||
BX LR
|
||||
NOP
|
||||
|
||||
;/**************************************************************************************
|
||||
;* <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>: OSPendSV
|
||||
;*
|
||||
;* <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>: OSPendSV is used to cause a context switch.
|
||||
;*
|
||||
;* <20><> <20><>: None
|
||||
;*
|
||||
;* <20><> <20><> ֵ: None
|
||||
;***************************************************************************************/
|
||||
|
||||
PendSV_Handler
|
||||
CPSID I ; Prevent interruption during context switch
|
||||
MRS R0, PSP ; PSP is process stack pointer <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>PSP<53><50>ջ,<2C><><EFBFBD><EFBFBD><EFBFBD>Ժ<EFBFBD><D4BA>Ա<EFBFBD><D4B1><EFBFBD><EFBFBD>Ĵ<EFBFBD><C4B4><EFBFBD>,<2C>ο<EFBFBD>CM3Ȩ<33><C8A8><EFBFBD>е<EFBFBD>˫<EFBFBD><CBAB>ջ-<2D>ײ<EFBFBD>ע
|
||||
CBZ R0, PendSV_Handler_Nosave ; Skip register save the first time
|
||||
|
||||
SUBS R0, R0, #0x20 ; Save remaining regs r4-11 on process stack
|
||||
STM R0, {R4-R11}
|
||||
|
||||
LDR R1, =OSTCBCur ; OSTCBCur->OSTCBStkPtr = SP;
|
||||
LDR R1, [R1]
|
||||
STR R0, [R1] ; R0 is SP of process being switched out
|
||||
|
||||
; At this point, entire context of process has been saved
|
||||
PendSV_Handler_Nosave
|
||||
PUSH {R14} ; Save LR exc_return value
|
||||
LDR R0, =OSTaskSwHook ; OSTaskSwHook();
|
||||
BLX R0
|
||||
POP {R14}
|
||||
|
||||
LDR R0, =OSPrioCur ; OSPrioCur = OSPrioHighRdy;
|
||||
LDR R1, =OSPrioHighRdy
|
||||
LDRB R2, [R1]
|
||||
STRB R2, [R0]
|
||||
|
||||
LDR R0, =OSTCBCur ; OSTCBCur = OSTCBHighRdy;
|
||||
LDR R1, =OSTCBHighRdy
|
||||
LDR R2, [R1]
|
||||
STR R2, [R0]
|
||||
|
||||
LDR R0, [R2] ; R0 is new process SP; SP = OSTCBHighRdy->OSTCBStkPtr;
|
||||
LDM R0, {R4-R11} ; Restore r4-11 from new process stack
|
||||
ADDS R0, R0, #0x20
|
||||
MSR PSP, R0 ; Load PSP with new process SP
|
||||
ORR LR, LR, #0x04 ; Ensure exception return uses process stack
|
||||
CPSIE I
|
||||
BX LR ; Exception return will restore remaining context
|
||||
|
||||
end
|
||||
312
UCOSII/PORT/os_cpu_c.c
Normal file
312
UCOSII/PORT/os_cpu_c.c
Normal file
@@ -0,0 +1,312 @@
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* uC/OS-II
|
||||
* The Real-Time Kernel
|
||||
*
|
||||
*
|
||||
* (c) Copyright 2006, Micrium, Weston, FL
|
||||
* All Rights Reserved
|
||||
*
|
||||
* ARM Cortex-M3 Port
|
||||
*
|
||||
* File : OS_CPU_C.C
|
||||
* Version : V2.86
|
||||
* By : Jean J. Labrosse
|
||||
*
|
||||
* For : ARMv7M Cortex-M3
|
||||
* Mode : Thumb2
|
||||
* Toolchain : RealView Development Suite
|
||||
* RealView Microcontroller Development Kit (MDK)
|
||||
* ARM Developer Suite (ADS)
|
||||
* Keil uVision
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
#define OS_CPU_GLOBALS
|
||||
|
||||
#include "includes.h"
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* LOCAL VARIABLES
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
#if OS_TMR_EN > 0
|
||||
static INT16U OSTmrCtr;
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* OS INITIALIZATION HOOK
|
||||
* (BEGINNING)
|
||||
*
|
||||
* Description: This function is called by OSInit() at the beginning of OSInit().
|
||||
*
|
||||
* Arguments : none
|
||||
*
|
||||
* Note(s) : 1) Interrupts should be disabled during this call.
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
#if OS_CPU_HOOKS_EN > 0 && OS_VERSION > 203
|
||||
void OSInitHookBegin (void)
|
||||
{
|
||||
#if OS_TMR_EN > 0
|
||||
OSTmrCtr = 0;
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* OS INITIALIZATION HOOK
|
||||
* (END)
|
||||
*
|
||||
* Description: This function is called by OSInit() at the end of OSInit().
|
||||
*
|
||||
* Arguments : none
|
||||
*
|
||||
* Note(s) : 1) Interrupts should be disabled during this call.
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
#if OS_CPU_HOOKS_EN > 0 && OS_VERSION > 203
|
||||
void OSInitHookEnd (void)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* TASK CREATION HOOK
|
||||
*
|
||||
* Description: This function is called when a task is created.
|
||||
*
|
||||
* Arguments : ptcb is a pointer to the task control block of the task being created.
|
||||
*
|
||||
* Note(s) : 1) Interrupts are disabled during this call.
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
#if OS_CPU_HOOKS_EN > 0
|
||||
void OSTaskCreateHook (OS_TCB *ptcb)
|
||||
{
|
||||
#if OS_APP_HOOKS_EN > 0
|
||||
App_TaskCreateHook(ptcb);
|
||||
#else
|
||||
(void)ptcb; /* Prevent compiler warning */
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* TASK DELETION HOOK
|
||||
*
|
||||
* Description: This function is called when a task is deleted.
|
||||
*
|
||||
* Arguments : ptcb is a pointer to the task control block of the task being deleted.
|
||||
*
|
||||
* Note(s) : 1) Interrupts are disabled during this call.
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
#if OS_CPU_HOOKS_EN > 0
|
||||
void OSTaskDelHook (OS_TCB *ptcb)
|
||||
{
|
||||
#if OS_APP_HOOKS_EN > 0
|
||||
App_TaskDelHook(ptcb);
|
||||
#else
|
||||
(void)ptcb; /* Prevent compiler warning */
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* IDLE TASK HOOK
|
||||
*
|
||||
* Description: This function is called by the idle task. This hook has been added to allow you to do
|
||||
* such things as STOP the CPU to conserve power.
|
||||
*
|
||||
* Arguments : none
|
||||
*
|
||||
* Note(s) : 1) Interrupts are enabled during this call.
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
#if OS_CPU_HOOKS_EN > 0 && OS_VERSION >= 251
|
||||
void OSTaskIdleHook (void)
|
||||
{
|
||||
#if OS_APP_HOOKS_EN > 0
|
||||
App_TaskIdleHook();
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* STATISTIC TASK HOOK
|
||||
*
|
||||
* Description: This function is called every second by uC/OS-II's statistics task. This allows your
|
||||
* application to add functionality to the statistics task.
|
||||
*
|
||||
* Arguments : none
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
#if OS_CPU_HOOKS_EN > 0
|
||||
void OSTaskStatHook (void)
|
||||
{
|
||||
#if OS_APP_HOOKS_EN > 0
|
||||
App_TaskStatHook();
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* INITIALIZE A TASK'S STACK
|
||||
*
|
||||
* Description: This function is called by either OSTaskCreate() or OSTaskCreateExt() to initialize the
|
||||
* stack frame of the task being created. This function is highly processor specific.
|
||||
*
|
||||
* Arguments : task is a pointer to the task code
|
||||
*
|
||||
* p_arg is a pointer to a user supplied data area that will be passed to the task
|
||||
* when the task first executes.
|
||||
*
|
||||
* ptos is a pointer to the top of stack. It is assumed that 'ptos' points to
|
||||
* a 'free' entry on the task stack. If OS_STK_GROWTH is set to 1 then
|
||||
* 'ptos' will contain the HIGHEST valid address of the stack. Similarly, if
|
||||
* OS_STK_GROWTH is set to 0, the 'ptos' will contains the LOWEST valid address
|
||||
* of the stack.
|
||||
*
|
||||
* opt specifies options that can be used to alter the behavior of OSTaskStkInit().
|
||||
* (see uCOS_II.H for OS_TASK_OPT_xxx).
|
||||
*
|
||||
* Returns : Always returns the location of the new top-of-stack once the processor registers have
|
||||
* been placed on the stack in the proper order.
|
||||
*
|
||||
* Note(s) : 1) Interrupts are enabled when your task starts executing.
|
||||
* 2) All tasks run in Thread mode, using process stack.
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
OS_STK *OSTaskStkInit (void (*task)(void *p_arg), void *p_arg, OS_STK *ptos, INT16U opt)
|
||||
{
|
||||
OS_STK *stk;
|
||||
|
||||
|
||||
(void)opt; /* 'opt' is not used, prevent warning */
|
||||
stk = ptos; /* Load stack pointer */
|
||||
|
||||
/* Registers stacked as if auto-saved on exception */
|
||||
*(stk) = (INT32U)0x01000000L; /* xPSR */
|
||||
*(--stk) = (INT32U)task; /* Entry Point */
|
||||
*(--stk) = (INT32U)0xFFFFFFFEL; /* R14 (LR) (init value will cause fault if ever used)*/
|
||||
*(--stk) = (INT32U)0x12121212L; /* R12 */
|
||||
*(--stk) = (INT32U)0x03030303L; /* R3 */
|
||||
*(--stk) = (INT32U)0x02020202L; /* R2 */
|
||||
*(--stk) = (INT32U)0x01010101L; /* R1 */
|
||||
*(--stk) = (INT32U)p_arg; /* R0 : argument */
|
||||
|
||||
/* Remaining registers saved on process stack */
|
||||
*(--stk) = (INT32U)0x11111111L; /* R11 */
|
||||
*(--stk) = (INT32U)0x10101010L; /* R10 */
|
||||
*(--stk) = (INT32U)0x09090909L; /* R9 */
|
||||
*(--stk) = (INT32U)0x08080808L; /* R8 */
|
||||
*(--stk) = (INT32U)0x07070707L; /* R7 */
|
||||
*(--stk) = (INT32U)0x06060606L; /* R6 */
|
||||
*(--stk) = (INT32U)0x05050505L; /* R5 */
|
||||
*(--stk) = (INT32U)0x04040404L; /* R4 */
|
||||
|
||||
return (stk);
|
||||
}
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* TASK SWITCH HOOK
|
||||
*
|
||||
* Description: This function is called when a task switch is performed. This allows you to perform other
|
||||
* operations during a context switch.
|
||||
*
|
||||
* Arguments : none
|
||||
*
|
||||
* Note(s) : 1) Interrupts are disabled during this call.
|
||||
* 2) It is assumed that the global pointer 'OSTCBHighRdy' points to the TCB of the task that
|
||||
* will be 'switched in' (i.e. the highest priority task) and, 'OSTCBCur' points to the
|
||||
* task being switched out (i.e. the preempted task).
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
#if (OS_CPU_HOOKS_EN > 0) && (OS_TASK_SW_HOOK_EN > 0)
|
||||
void OSTaskSwHook (void)
|
||||
{
|
||||
#if OS_APP_HOOKS_EN > 0
|
||||
App_TaskSwHook();
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* OS_TCBInit() HOOK
|
||||
*
|
||||
* Description: This function is called by OS_TCBInit() after setting up most of the TCB.
|
||||
*
|
||||
* Arguments : ptcb is a pointer to the TCB of the task being created.
|
||||
*
|
||||
* Note(s) : 1) Interrupts may or may not be ENABLED during this call.
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
#if OS_CPU_HOOKS_EN > 0 && OS_VERSION > 203
|
||||
void OSTCBInitHook (OS_TCB *ptcb)
|
||||
{
|
||||
#if OS_APP_HOOKS_EN > 0
|
||||
App_TCBInitHook(ptcb);
|
||||
#else
|
||||
(void)ptcb; /* Prevent compiler warning */
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* TICK HOOK
|
||||
*
|
||||
* Description: This function is called every tick.
|
||||
*
|
||||
* Arguments : none
|
||||
*
|
||||
* Note(s) : 1) Interrupts may or may not be ENABLED during this call.
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
#if (OS_CPU_HOOKS_EN > 0) && (OS_TIME_TICK_HOOK_EN > 0)
|
||||
void OSTimeTickHook (void)
|
||||
{
|
||||
#if OS_APP_HOOKS_EN > 0
|
||||
App_TimeTickHook();
|
||||
#endif
|
||||
|
||||
#if OS_TMR_EN > 0
|
||||
OSTmrCtr++;
|
||||
if (OSTmrCtr >= (OS_TICKS_PER_SEC / OS_TMR_CFG_TICKS_PER_SEC)) {
|
||||
OSTmrCtr = 0;
|
||||
OSTmrSignal();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
#if OS_CPU_HOOKS_EN > 0u && OS_VERSION > 290u
|
||||
|
||||
void OSTaskReturnHook(OS_TCB *ptcb)
|
||||
{
|
||||
(void)ptcb;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/*----------------------- (C) COPYRIGHT @ 2012 liycobl ----------------- end of file -----------------*/
|
||||
265
UCOSII/PORT/os_dbg.c
Normal file
265
UCOSII/PORT/os_dbg.c
Normal file
@@ -0,0 +1,265 @@
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* uC/OS-II
|
||||
* The Real-Time Kernel
|
||||
* DEBUGGER CONSTANTS
|
||||
*
|
||||
* (c) Copyright 2006, Micrium, Weston, FL
|
||||
* All Rights Reserved
|
||||
*
|
||||
* ARM Cortex-M3 Port
|
||||
*
|
||||
* File : OS_DBG.C
|
||||
* Version : V2.86
|
||||
* By : Jean J. Labrosse
|
||||
*
|
||||
* For : ARMv7M Cortex-M3
|
||||
* Mode : Thumb2
|
||||
* Toolchain : RealView Development Suite
|
||||
* RealView Microcontroller Development Kit (MDK)
|
||||
* ARM Developer Suite (ADS)
|
||||
* Keil uVision
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
#include <ucos_ii.h>
|
||||
|
||||
#define OS_COMPILER_OPT
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* DEBUG DATA
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
OS_COMPILER_OPT INT16U const OSDebugEn = OS_DEBUG_EN; /* Debug constants are defined below */
|
||||
|
||||
#if OS_DEBUG_EN > 0
|
||||
|
||||
OS_COMPILER_OPT INT32U const OSEndiannessTest = 0x12345678L; /* Variable to test CPU endianness */
|
||||
|
||||
OS_COMPILER_OPT INT16U const OSEventMax = OS_MAX_EVENTS; /* Number of event control blocks */
|
||||
OS_COMPILER_OPT INT16U const OSEventNameSize = OS_EVENT_NAME_SIZE; /* Size (in bytes) of event names */
|
||||
OS_COMPILER_OPT INT16U const OSEventEn = OS_EVENT_EN;
|
||||
#if (OS_EVENT_EN > 0) && (OS_MAX_EVENTS > 0)
|
||||
OS_COMPILER_OPT INT16U const OSEventSize = sizeof(OS_EVENT); /* Size in Bytes of OS_EVENT */
|
||||
OS_COMPILER_OPT INT16U const OSEventTblSize = sizeof(OSEventTbl); /* Size of OSEventTbl[] in bytes */
|
||||
#else
|
||||
OS_COMPILER_OPT INT16U const OSEventSize = 0;
|
||||
OS_COMPILER_OPT INT16U const OSEventTblSize = 0;
|
||||
#endif
|
||||
|
||||
OS_COMPILER_OPT INT16U const OSFlagEn = OS_FLAG_EN;
|
||||
#if (OS_FLAG_EN > 0) && (OS_MAX_FLAGS > 0)
|
||||
OS_COMPILER_OPT INT16U const OSFlagGrpSize = sizeof(OS_FLAG_GRP); /* Size in Bytes of OS_FLAG_GRP */
|
||||
OS_COMPILER_OPT INT16U const OSFlagNodeSize = sizeof(OS_FLAG_NODE); /* Size in Bytes of OS_FLAG_NODE */
|
||||
OS_COMPILER_OPT INT16U const OSFlagWidth = sizeof(OS_FLAGS); /* Width (in bytes) of OS_FLAGS */
|
||||
#else
|
||||
OS_COMPILER_OPT INT16U const OSFlagGrpSize = 0;
|
||||
OS_COMPILER_OPT INT16U const OSFlagNodeSize = 0;
|
||||
OS_COMPILER_OPT INT16U const OSFlagWidth = 0;
|
||||
#endif
|
||||
OS_COMPILER_OPT INT16U const OSFlagMax = OS_MAX_FLAGS;
|
||||
OS_COMPILER_OPT INT16U const OSFlagNameSize = OS_FLAG_NAME_SIZE; /* Size (in bytes) of flag names */
|
||||
|
||||
OS_COMPILER_OPT INT16U const OSLowestPrio = OS_LOWEST_PRIO;
|
||||
|
||||
OS_COMPILER_OPT INT16U const OSMboxEn = OS_MBOX_EN;
|
||||
|
||||
OS_COMPILER_OPT INT16U const OSMemEn = OS_MEM_EN;
|
||||
OS_COMPILER_OPT INT16U const OSMemMax = OS_MAX_MEM_PART; /* Number of memory partitions */
|
||||
OS_COMPILER_OPT INT16U const OSMemNameSize = OS_MEM_NAME_SIZE; /* Size (in bytes) of partition names */
|
||||
#if (OS_MEM_EN > 0) && (OS_MAX_MEM_PART > 0)
|
||||
OS_COMPILER_OPT INT16U const OSMemSize = sizeof(OS_MEM); /* Mem. Partition header sine (bytes) */
|
||||
OS_COMPILER_OPT INT16U const OSMemTblSize = sizeof(OSMemTbl);
|
||||
#else
|
||||
OS_COMPILER_OPT INT16U const OSMemSize = 0;
|
||||
OS_COMPILER_OPT INT16U const OSMemTblSize = 0;
|
||||
#endif
|
||||
OS_COMPILER_OPT INT16U const OSMutexEn = OS_MUTEX_EN;
|
||||
|
||||
OS_COMPILER_OPT INT16U const OSPtrSize = sizeof(void *); /* Size in Bytes of a pointer */
|
||||
|
||||
OS_COMPILER_OPT INT16U const OSQEn = OS_Q_EN;
|
||||
OS_COMPILER_OPT INT16U const OSQMax = OS_MAX_QS; /* Number of queues */
|
||||
#if (OS_Q_EN > 0) && (OS_MAX_QS > 0)
|
||||
OS_COMPILER_OPT INT16U const OSQSize = sizeof(OS_Q); /* Size in bytes of OS_Q structure */
|
||||
#else
|
||||
OS_COMPILER_OPT INT16U const OSQSize = 0;
|
||||
#endif
|
||||
|
||||
OS_COMPILER_OPT INT16U const OSRdyTblSize = OS_RDY_TBL_SIZE; /* Number of bytes in the ready table */
|
||||
|
||||
OS_COMPILER_OPT INT16U const OSSemEn = OS_SEM_EN;
|
||||
|
||||
OS_COMPILER_OPT INT16U const OSStkWidth = sizeof(OS_STK); /* Size in Bytes of a stack entry */
|
||||
|
||||
OS_COMPILER_OPT INT16U const OSTaskCreateEn = OS_TASK_CREATE_EN;
|
||||
OS_COMPILER_OPT INT16U const OSTaskCreateExtEn = OS_TASK_CREATE_EXT_EN;
|
||||
OS_COMPILER_OPT INT16U const OSTaskDelEn = OS_TASK_DEL_EN;
|
||||
OS_COMPILER_OPT INT16U const OSTaskIdleStkSize = OS_TASK_IDLE_STK_SIZE;
|
||||
OS_COMPILER_OPT INT16U const OSTaskProfileEn = OS_TASK_PROFILE_EN;
|
||||
OS_COMPILER_OPT INT16U const OSTaskMax = OS_MAX_TASKS + OS_N_SYS_TASKS; /* Total max. number of tasks */
|
||||
OS_COMPILER_OPT INT16U const OSTaskNameSize = OS_TASK_NAME_SIZE; /* Size (in bytes) of task names */
|
||||
OS_COMPILER_OPT INT16U const OSTaskStatEn = OS_TASK_STAT_EN;
|
||||
OS_COMPILER_OPT INT16U const OSTaskStatStkSize = OS_TASK_STAT_STK_SIZE;
|
||||
OS_COMPILER_OPT INT16U const OSTaskStatStkChkEn = OS_TASK_STAT_STK_CHK_EN;
|
||||
OS_COMPILER_OPT INT16U const OSTaskSwHookEn = OS_TASK_SW_HOOK_EN;
|
||||
|
||||
OS_COMPILER_OPT INT16U const OSTCBPrioTblMax = OS_LOWEST_PRIO + 1; /* Number of entries in OSTCBPrioTbl[] */
|
||||
OS_COMPILER_OPT INT16U const OSTCBSize = sizeof(OS_TCB); /* Size in Bytes of OS_TCB */
|
||||
OS_COMPILER_OPT INT16U const OSTicksPerSec = OS_TICKS_PER_SEC;
|
||||
OS_COMPILER_OPT INT16U const OSTimeTickHookEn = OS_TIME_TICK_HOOK_EN;
|
||||
OS_COMPILER_OPT INT16U const OSVersionNbr = OS_VERSION;
|
||||
|
||||
#endif
|
||||
|
||||
/*$PAGE*/
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* DEBUG DATA
|
||||
* TOTAL DATA SPACE (i.e. RAM) USED BY uC/OS-II
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
#if OS_DEBUG_EN > 0
|
||||
|
||||
OS_COMPILER_OPT INT16U const OSDataSize = sizeof(OSCtxSwCtr)
|
||||
#if (OS_EVENT_EN > 0) && (OS_MAX_EVENTS > 0)
|
||||
+ sizeof(OSEventFreeList)
|
||||
+ sizeof(OSEventTbl)
|
||||
#endif
|
||||
#if (OS_VERSION >= 251) && (OS_FLAG_EN > 0) && (OS_MAX_FLAGS > 0)
|
||||
+ sizeof(OSFlagTbl)
|
||||
+ sizeof(OSFlagFreeList)
|
||||
#endif
|
||||
#if OS_TASK_STAT_EN > 0
|
||||
+ sizeof(OSCPUUsage)
|
||||
+ sizeof(OSIdleCtrMax)
|
||||
+ sizeof(OSIdleCtrRun)
|
||||
+ sizeof(OSStatRdy)
|
||||
+ sizeof(OSTaskStatStk)
|
||||
#endif
|
||||
#if OS_TICK_STEP_EN > 0
|
||||
+ sizeof(OSTickStepState)
|
||||
#endif
|
||||
#if (OS_MEM_EN > 0) && (OS_MAX_MEM_PART > 0)
|
||||
+ sizeof(OSMemFreeList)
|
||||
+ sizeof(OSMemTbl)
|
||||
#endif
|
||||
#if (OS_Q_EN > 0) && (OS_MAX_QS > 0)
|
||||
+ sizeof(OSQFreeList)
|
||||
+ sizeof(OSQTbl)
|
||||
#endif
|
||||
#if OS_TIME_GET_SET_EN > 0
|
||||
+ sizeof(OSTime)
|
||||
#endif
|
||||
+ sizeof(OSIntNesting)
|
||||
+ sizeof(OSLockNesting)
|
||||
+ sizeof(OSPrioCur)
|
||||
+ sizeof(OSPrioHighRdy)
|
||||
+ sizeof(OSRdyGrp)
|
||||
+ sizeof(OSRdyTbl)
|
||||
+ sizeof(OSRunning)
|
||||
+ sizeof(OSTaskCtr)
|
||||
+ sizeof(OSIdleCtr)
|
||||
+ sizeof(OSTaskIdleStk)
|
||||
+ sizeof(OSTCBCur)
|
||||
+ sizeof(OSTCBFreeList)
|
||||
+ sizeof(OSTCBHighRdy)
|
||||
+ sizeof(OSTCBList)
|
||||
+ sizeof(OSTCBPrioTbl)
|
||||
+ sizeof(OSTCBTbl);
|
||||
|
||||
#endif
|
||||
|
||||
/*$PAGE*/
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* OS DEBUG INITIALIZAZTION
|
||||
*
|
||||
* Description: This function is used to make sure that debug variables that are unused in the application
|
||||
* are not optimized away. This function might not be necessary for all compilers. In this
|
||||
* case, you should simply DELETE the code in this function while still leaving the declaration
|
||||
* of the function itself.
|
||||
*
|
||||
* Arguments : none
|
||||
*
|
||||
* Returns : none
|
||||
*
|
||||
* Note(s) : (1) This code doesn't do anything, it simply prevents the compiler from optimizing out
|
||||
* the 'const' variables which are declared in this file.
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
#if OS_VERSION >= 270 && OS_DEBUG_EN > 0
|
||||
void OSDebugInit (void)
|
||||
{
|
||||
void *ptemp;
|
||||
|
||||
|
||||
ptemp = (void *)&OSDebugEn;
|
||||
|
||||
ptemp = (void *)&OSEndiannessTest;
|
||||
|
||||
ptemp = (void *)&OSEventMax;
|
||||
ptemp = (void *)&OSEventNameSize;
|
||||
ptemp = (void *)&OSEventEn;
|
||||
ptemp = (void *)&OSEventSize;
|
||||
ptemp = (void *)&OSEventTblSize;
|
||||
|
||||
ptemp = (void *)&OSFlagEn;
|
||||
ptemp = (void *)&OSFlagGrpSize;
|
||||
ptemp = (void *)&OSFlagNodeSize;
|
||||
ptemp = (void *)&OSFlagWidth;
|
||||
ptemp = (void *)&OSFlagMax;
|
||||
ptemp = (void *)&OSFlagNameSize;
|
||||
|
||||
ptemp = (void *)&OSLowestPrio;
|
||||
|
||||
ptemp = (void *)&OSMboxEn;
|
||||
|
||||
ptemp = (void *)&OSMemEn;
|
||||
ptemp = (void *)&OSMemMax;
|
||||
ptemp = (void *)&OSMemNameSize;
|
||||
ptemp = (void *)&OSMemSize;
|
||||
ptemp = (void *)&OSMemTblSize;
|
||||
|
||||
ptemp = (void *)&OSMutexEn;
|
||||
|
||||
ptemp = (void *)&OSPtrSize;
|
||||
|
||||
ptemp = (void *)&OSQEn;
|
||||
ptemp = (void *)&OSQMax;
|
||||
ptemp = (void *)&OSQSize;
|
||||
|
||||
ptemp = (void *)&OSRdyTblSize;
|
||||
|
||||
ptemp = (void *)&OSSemEn;
|
||||
|
||||
ptemp = (void *)&OSStkWidth;
|
||||
|
||||
ptemp = (void *)&OSTaskCreateEn;
|
||||
ptemp = (void *)&OSTaskCreateExtEn;
|
||||
ptemp = (void *)&OSTaskDelEn;
|
||||
ptemp = (void *)&OSTaskIdleStkSize;
|
||||
ptemp = (void *)&OSTaskProfileEn;
|
||||
ptemp = (void *)&OSTaskMax;
|
||||
ptemp = (void *)&OSTaskNameSize;
|
||||
ptemp = (void *)&OSTaskStatEn;
|
||||
ptemp = (void *)&OSTaskStatStkSize;
|
||||
ptemp = (void *)&OSTaskStatStkChkEn;
|
||||
ptemp = (void *)&OSTaskSwHookEn;
|
||||
|
||||
ptemp = (void *)&OSTCBPrioTblMax;
|
||||
ptemp = (void *)&OSTCBSize;
|
||||
|
||||
ptemp = (void *)&OSTicksPerSec;
|
||||
ptemp = (void *)&OSTimeTickHookEn;
|
||||
|
||||
ptemp = (void *)&OSVersionNbr;
|
||||
|
||||
ptemp = (void *)&OSDataSize;
|
||||
|
||||
ptemp = ptemp; /* Prevent compiler warning for 'ptemp' not being used! */
|
||||
}
|
||||
#endif
|
||||
314
UCOSII/PORT/os_dbg_r.c
Normal file
314
UCOSII/PORT/os_dbg_r.c
Normal file
@@ -0,0 +1,314 @@
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* uC/OS-II
|
||||
* The Real-Time Kernel
|
||||
* DEBUGGER CONSTANTS
|
||||
*
|
||||
* (c) Copyright 1992-2009, Micrium, Weston, FL
|
||||
* All Rights Reserved
|
||||
*
|
||||
* File : OS_DBG.C
|
||||
* By : Jean J. Labrosse
|
||||
* Version : V2.91
|
||||
*
|
||||
* LICENSING TERMS:
|
||||
* ---------------
|
||||
* uC/OS-II is provided in source form for FREE evaluation, for educational use or for peaceful research.
|
||||
* If you plan on using uC/OS-II in a commercial product you need to contact Micri<72>m to properly license
|
||||
* its use in your product. We provide ALL the source code for your convenience and to help you experience
|
||||
* uC/OS-II. The fact that the source is provided does NOT mean that you can use it without paying a
|
||||
* licensing fee.
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
#include <ucos_ii.h>
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* DEBUG DATA
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
INT16U const OSDebugEn = OS_DEBUG_EN; /* Debug constants are defined below */
|
||||
|
||||
#if OS_DEBUG_EN > 0u
|
||||
|
||||
INT32U const OSEndiannessTest = 0x12345678uL; /* Variable to test CPU endianness */
|
||||
|
||||
INT16U const OSEventEn = OS_EVENT_EN;
|
||||
INT16U const OSEventMax = OS_MAX_EVENTS; /* Number of event control blocks */
|
||||
INT16U const OSEventNameEn = OS_EVENT_NAME_EN;
|
||||
#if (OS_EVENT_EN) && (OS_MAX_EVENTS > 0u)
|
||||
INT16U const OSEventSize = sizeof(OS_EVENT); /* Size in Bytes of OS_EVENT */
|
||||
INT16U const OSEventTblSize = sizeof(OSEventTbl); /* Size of OSEventTbl[] in bytes */
|
||||
#else
|
||||
INT16U const OSEventSize = 0u;
|
||||
INT16U const OSEventTblSize = 0u;
|
||||
#endif
|
||||
INT16U const OSEventMultiEn = OS_EVENT_MULTI_EN;
|
||||
|
||||
|
||||
INT16U const OSFlagEn = OS_FLAG_EN;
|
||||
#if (OS_FLAG_EN > 0u) && (OS_MAX_FLAGS > 0u)
|
||||
INT16U const OSFlagGrpSize = sizeof(OS_FLAG_GRP); /* Size in Bytes of OS_FLAG_GRP */
|
||||
INT16U const OSFlagNodeSize = sizeof(OS_FLAG_NODE); /* Size in Bytes of OS_FLAG_NODE */
|
||||
INT16U const OSFlagWidth = sizeof(OS_FLAGS); /* Width (in bytes) of OS_FLAGS */
|
||||
#else
|
||||
INT16U const OSFlagGrpSize = 0u;
|
||||
INT16U const OSFlagNodeSize = 0u;
|
||||
INT16U const OSFlagWidth = 0u;
|
||||
#endif
|
||||
INT16U const OSFlagMax = OS_MAX_FLAGS;
|
||||
INT16U const OSFlagNameEn = OS_FLAG_NAME_EN;
|
||||
|
||||
INT16U const OSLowestPrio = OS_LOWEST_PRIO;
|
||||
|
||||
INT16U const OSMboxEn = OS_MBOX_EN;
|
||||
|
||||
INT16U const OSMemEn = OS_MEM_EN;
|
||||
INT16U const OSMemMax = OS_MAX_MEM_PART; /* Number of memory partitions */
|
||||
INT16U const OSMemNameEn = OS_MEM_NAME_EN;
|
||||
#if (OS_MEM_EN > 0u) && (OS_MAX_MEM_PART > 0u)
|
||||
INT16U const OSMemSize = sizeof(OS_MEM); /* Mem. Partition header sine (bytes) */
|
||||
INT16U const OSMemTblSize = sizeof(OSMemTbl);
|
||||
#else
|
||||
INT16U const OSMemSize = 0u;
|
||||
INT16U const OSMemTblSize = 0u;
|
||||
#endif
|
||||
INT16U const OSMutexEn = OS_MUTEX_EN;
|
||||
|
||||
INT16U const OSPtrSize = sizeof(void *); /* Size in Bytes of a pointer */
|
||||
|
||||
INT16U const OSQEn = OS_Q_EN;
|
||||
INT16U const OSQMax = OS_MAX_QS; /* Number of queues */
|
||||
#if (OS_Q_EN > 0u) && (OS_MAX_QS > 0u)
|
||||
INT16U const OSQSize = sizeof(OS_Q); /* Size in bytes of OS_Q structure */
|
||||
#else
|
||||
INT16U const OSQSize = 0u;
|
||||
#endif
|
||||
|
||||
INT16U const OSRdyTblSize = OS_RDY_TBL_SIZE; /* Number of bytes in the ready table */
|
||||
|
||||
INT16U const OSSemEn = OS_SEM_EN;
|
||||
|
||||
INT16U const OSStkWidth = sizeof(OS_STK); /* Size in Bytes of a stack entry */
|
||||
|
||||
INT16U const OSTaskCreateEn = OS_TASK_CREATE_EN;
|
||||
INT16U const OSTaskCreateExtEn = OS_TASK_CREATE_EXT_EN;
|
||||
INT16U const OSTaskDelEn = OS_TASK_DEL_EN;
|
||||
INT16U const OSTaskIdleStkSize = OS_TASK_IDLE_STK_SIZE;
|
||||
INT16U const OSTaskProfileEn = OS_TASK_PROFILE_EN;
|
||||
INT16U const OSTaskMax = OS_MAX_TASKS + OS_N_SYS_TASKS; /* Total max. number of tasks */
|
||||
INT16U const OSTaskNameEn = OS_TASK_NAME_EN;
|
||||
INT16U const OSTaskStatEn = OS_TASK_STAT_EN;
|
||||
INT16U const OSTaskStatStkSize = OS_TASK_STAT_STK_SIZE;
|
||||
INT16U const OSTaskStatStkChkEn = OS_TASK_STAT_STK_CHK_EN;
|
||||
INT16U const OSTaskSwHookEn = OS_TASK_SW_HOOK_EN;
|
||||
INT16U const OSTaskRegTblSize = OS_TASK_REG_TBL_SIZE;
|
||||
|
||||
INT16U const OSTCBPrioTblMax = OS_LOWEST_PRIO + 1u; /* Number of entries in OSTCBPrioTbl[] */
|
||||
INT16U const OSTCBSize = sizeof(OS_TCB); /* Size in Bytes of OS_TCB */
|
||||
INT16U const OSTicksPerSec = OS_TICKS_PER_SEC;
|
||||
INT16U const OSTimeTickHookEn = OS_TIME_TICK_HOOK_EN;
|
||||
INT16U const OSVersionNbr = OS_VERSION;
|
||||
|
||||
INT16U const OSTmrEn = OS_TMR_EN;
|
||||
INT16U const OSTmrCfgMax = OS_TMR_CFG_MAX;
|
||||
INT16U const OSTmrCfgNameEn = OS_TMR_CFG_NAME_EN;
|
||||
INT16U const OSTmrCfgWheelSize = OS_TMR_CFG_WHEEL_SIZE;
|
||||
INT16U const OSTmrCfgTicksPerSec = OS_TMR_CFG_TICKS_PER_SEC;
|
||||
|
||||
#if (OS_TMR_EN > 0u) && (OS_TMR_CFG_MAX > 0u)
|
||||
INT16U const OSTmrSize = sizeof(OS_TMR);
|
||||
INT16U const OSTmrTblSize = sizeof(OSTmrTbl);
|
||||
INT16U const OSTmrWheelSize = sizeof(OS_TMR_WHEEL);
|
||||
INT16U const OSTmrWheelTblSize = sizeof(OSTmrWheelTbl);
|
||||
#else
|
||||
INT16U const OSTmrSize = 0u;
|
||||
INT16U const OSTmrTblSize = 0u;
|
||||
INT16U const OSTmrWheelSize = 0u;
|
||||
INT16U const OSTmrWheelTblSize = 0u;
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
/*$PAGE*/
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* DEBUG DATA
|
||||
* TOTAL DATA SPACE (i.e. RAM) USED BY uC/OS-II
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
#if OS_DEBUG_EN > 0u
|
||||
|
||||
INT16U const OSDataSize = sizeof(OSCtxSwCtr)
|
||||
#if (OS_EVENT_EN) && (OS_MAX_EVENTS > 0u)
|
||||
+ sizeof(OSEventFreeList)
|
||||
+ sizeof(OSEventTbl)
|
||||
#endif
|
||||
#if (OS_FLAG_EN > 0u) && (OS_MAX_FLAGS > 0u)
|
||||
+ sizeof(OSFlagTbl)
|
||||
+ sizeof(OSFlagFreeList)
|
||||
#endif
|
||||
#if OS_TASK_STAT_EN > 0u
|
||||
+ sizeof(OSCPUUsage)
|
||||
+ sizeof(OSIdleCtrMax)
|
||||
+ sizeof(OSIdleCtrRun)
|
||||
+ sizeof(OSStatRdy)
|
||||
+ sizeof(OSTaskStatStk)
|
||||
#endif
|
||||
#if OS_TICK_STEP_EN > 0u
|
||||
+ sizeof(OSTickStepState)
|
||||
#endif
|
||||
#if (OS_MEM_EN > 0u) && (OS_MAX_MEM_PART > 0u)
|
||||
+ sizeof(OSMemFreeList)
|
||||
+ sizeof(OSMemTbl)
|
||||
#endif
|
||||
#if (OS_Q_EN > 0u) && (OS_MAX_QS > 0u)
|
||||
+ sizeof(OSQFreeList)
|
||||
+ sizeof(OSQTbl)
|
||||
#endif
|
||||
#if OS_TIME_GET_SET_EN > 0u
|
||||
+ sizeof(OSTime)
|
||||
#endif
|
||||
#if (OS_TMR_EN > 0u) && (OS_TMR_CFG_MAX > 0u)
|
||||
+ sizeof(OSTmrFree)
|
||||
+ sizeof(OSTmrUsed)
|
||||
+ sizeof(OSTmrTime)
|
||||
+ sizeof(OSTmrSem)
|
||||
+ sizeof(OSTmrSemSignal)
|
||||
+ sizeof(OSTmrTbl)
|
||||
+ sizeof(OSTmrFreeList)
|
||||
+ sizeof(OSTmrTaskStk)
|
||||
+ sizeof(OSTmrWheelTbl)
|
||||
#endif
|
||||
+ sizeof(OSIntNesting)
|
||||
+ sizeof(OSLockNesting)
|
||||
+ sizeof(OSPrioCur)
|
||||
+ sizeof(OSPrioHighRdy)
|
||||
+ sizeof(OSRdyGrp)
|
||||
+ sizeof(OSRdyTbl)
|
||||
+ sizeof(OSRunning)
|
||||
+ sizeof(OSTaskCtr)
|
||||
+ sizeof(OSIdleCtr)
|
||||
+ sizeof(OSTaskIdleStk)
|
||||
+ sizeof(OSTCBCur)
|
||||
+ sizeof(OSTCBFreeList)
|
||||
+ sizeof(OSTCBHighRdy)
|
||||
+ sizeof(OSTCBList)
|
||||
+ sizeof(OSTCBPrioTbl)
|
||||
+ sizeof(OSTCBTbl);
|
||||
|
||||
#endif
|
||||
|
||||
/*$PAGE*/
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* OS DEBUG INITIALIZATION
|
||||
*
|
||||
* Description: This function is used to make sure that debug variables that are unused in the application
|
||||
* are not optimized away. This function might not be necessary for all compilers. In this
|
||||
* case, you should simply DELETE the code in this function while still leaving the declaration
|
||||
* of the function itself.
|
||||
*
|
||||
* Arguments : none
|
||||
*
|
||||
* Returns : none
|
||||
*
|
||||
* Note(s) : (1) This code doesn't do anything, it simply prevents the compiler from optimizing out
|
||||
* the 'const' variables which are declared in this file.
|
||||
* (2) You may decide to 'compile out' the code (by using #if 0/#endif) INSIDE the function
|
||||
* if your compiler DOES NOT optimize out the 'const' variables above.
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
#if OS_DEBUG_EN > 0u
|
||||
void OSDebugInit (void)
|
||||
{
|
||||
void const *ptemp;
|
||||
|
||||
|
||||
ptemp = (void const *)&OSDebugEn;
|
||||
|
||||
ptemp = (void const *)&OSEndiannessTest;
|
||||
|
||||
ptemp = (void const *)&OSEventMax;
|
||||
ptemp = (void const *)&OSEventNameEn;
|
||||
ptemp = (void const *)&OSEventEn;
|
||||
ptemp = (void const *)&OSEventSize;
|
||||
ptemp = (void const *)&OSEventTblSize;
|
||||
ptemp = (void const *)&OSEventMultiEn;
|
||||
|
||||
ptemp = (void const *)&OSFlagEn;
|
||||
ptemp = (void const *)&OSFlagGrpSize;
|
||||
ptemp = (void const *)&OSFlagNodeSize;
|
||||
ptemp = (void const *)&OSFlagWidth;
|
||||
ptemp = (void const *)&OSFlagMax;
|
||||
ptemp = (void const *)&OSFlagNameEn;
|
||||
|
||||
ptemp = (void const *)&OSLowestPrio;
|
||||
|
||||
ptemp = (void const *)&OSMboxEn;
|
||||
|
||||
ptemp = (void const *)&OSMemEn;
|
||||
ptemp = (void const *)&OSMemMax;
|
||||
ptemp = (void const *)&OSMemNameEn;
|
||||
ptemp = (void const *)&OSMemSize;
|
||||
ptemp = (void const *)&OSMemTblSize;
|
||||
|
||||
ptemp = (void const *)&OSMutexEn;
|
||||
|
||||
ptemp = (void const *)&OSPtrSize;
|
||||
|
||||
ptemp = (void const *)&OSQEn;
|
||||
ptemp = (void const *)&OSQMax;
|
||||
ptemp = (void const *)&OSQSize;
|
||||
|
||||
ptemp = (void const *)&OSRdyTblSize;
|
||||
|
||||
ptemp = (void const *)&OSSemEn;
|
||||
|
||||
ptemp = (void const *)&OSStkWidth;
|
||||
|
||||
ptemp = (void const *)&OSTaskCreateEn;
|
||||
ptemp = (void const *)&OSTaskCreateExtEn;
|
||||
ptemp = (void const *)&OSTaskDelEn;
|
||||
ptemp = (void const *)&OSTaskIdleStkSize;
|
||||
ptemp = (void const *)&OSTaskProfileEn;
|
||||
ptemp = (void const *)&OSTaskMax;
|
||||
ptemp = (void const *)&OSTaskNameEn;
|
||||
ptemp = (void const *)&OSTaskStatEn;
|
||||
ptemp = (void const *)&OSTaskStatStkSize;
|
||||
ptemp = (void const *)&OSTaskStatStkChkEn;
|
||||
ptemp = (void const *)&OSTaskSwHookEn;
|
||||
|
||||
ptemp = (void const *)&OSTCBPrioTblMax;
|
||||
ptemp = (void const *)&OSTCBSize;
|
||||
|
||||
ptemp = (void const *)&OSTicksPerSec;
|
||||
ptemp = (void const *)&OSTimeTickHookEn;
|
||||
|
||||
#if OS_TMR_EN > 0u
|
||||
ptemp = (void const *)&OSTmrTbl[0];
|
||||
ptemp = (void const *)&OSTmrWheelTbl[0];
|
||||
|
||||
ptemp = (void const *)&OSTmrEn;
|
||||
ptemp = (void const *)&OSTmrCfgMax;
|
||||
ptemp = (void const *)&OSTmrCfgNameEn;
|
||||
ptemp = (void const *)&OSTmrCfgWheelSize;
|
||||
ptemp = (void const *)&OSTmrCfgTicksPerSec;
|
||||
ptemp = (void const *)&OSTmrSize;
|
||||
ptemp = (void const *)&OSTmrTblSize;
|
||||
|
||||
ptemp = (void const *)&OSTmrWheelSize;
|
||||
ptemp = (void const *)&OSTmrWheelTblSize;
|
||||
#endif
|
||||
|
||||
ptemp = (void const *)&OSVersionNbr;
|
||||
|
||||
ptemp = (void const *)&OSDataSize;
|
||||
|
||||
ptemp = ptemp; /* Prevent compiler warning for 'ptemp' not being used! */
|
||||
}
|
||||
#endif
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -775,14 +775,233 @@
|
||||
</Group>
|
||||
|
||||
<Group>
|
||||
<GroupName>ReadMe</GroupName>
|
||||
<tvExp>1</tvExp>
|
||||
<GroupName>UCOSII-CORE</GroupName>
|
||||
<tvExp>0</tvExp>
|
||||
<tvExpOptDlg>0</tvExpOptDlg>
|
||||
<cbSel>0</cbSel>
|
||||
<RteFlg>0</RteFlg>
|
||||
<File>
|
||||
<GroupNumber>6</GroupNumber>
|
||||
<FileNumber>39</FileNumber>
|
||||
<FileType>1</FileType>
|
||||
<tvExp>0</tvExp>
|
||||
<Focus>0</Focus>
|
||||
<tvExpOptDlg>0</tvExpOptDlg>
|
||||
<bDave2>0</bDave2>
|
||||
<PathWithFileName>..\UCOSII\CORE\os_core.c</PathWithFileName>
|
||||
<FilenameWithoutPath>os_core.c</FilenameWithoutPath>
|
||||
<RteFlg>0</RteFlg>
|
||||
<bShared>0</bShared>
|
||||
</File>
|
||||
<File>
|
||||
<GroupNumber>6</GroupNumber>
|
||||
<FileNumber>40</FileNumber>
|
||||
<FileType>1</FileType>
|
||||
<tvExp>0</tvExp>
|
||||
<Focus>0</Focus>
|
||||
<tvExpOptDlg>0</tvExpOptDlg>
|
||||
<bDave2>0</bDave2>
|
||||
<PathWithFileName>..\UCOSII\CORE\os_flag.c</PathWithFileName>
|
||||
<FilenameWithoutPath>os_flag.c</FilenameWithoutPath>
|
||||
<RteFlg>0</RteFlg>
|
||||
<bShared>0</bShared>
|
||||
</File>
|
||||
<File>
|
||||
<GroupNumber>6</GroupNumber>
|
||||
<FileNumber>41</FileNumber>
|
||||
<FileType>1</FileType>
|
||||
<tvExp>0</tvExp>
|
||||
<Focus>0</Focus>
|
||||
<tvExpOptDlg>0</tvExpOptDlg>
|
||||
<bDave2>0</bDave2>
|
||||
<PathWithFileName>..\UCOSII\CORE\os_mbox.c</PathWithFileName>
|
||||
<FilenameWithoutPath>os_mbox.c</FilenameWithoutPath>
|
||||
<RteFlg>0</RteFlg>
|
||||
<bShared>0</bShared>
|
||||
</File>
|
||||
<File>
|
||||
<GroupNumber>6</GroupNumber>
|
||||
<FileNumber>42</FileNumber>
|
||||
<FileType>1</FileType>
|
||||
<tvExp>0</tvExp>
|
||||
<Focus>0</Focus>
|
||||
<tvExpOptDlg>0</tvExpOptDlg>
|
||||
<bDave2>0</bDave2>
|
||||
<PathWithFileName>..\UCOSII\CORE\os_mem.c</PathWithFileName>
|
||||
<FilenameWithoutPath>os_mem.c</FilenameWithoutPath>
|
||||
<RteFlg>0</RteFlg>
|
||||
<bShared>0</bShared>
|
||||
</File>
|
||||
<File>
|
||||
<GroupNumber>6</GroupNumber>
|
||||
<FileNumber>43</FileNumber>
|
||||
<FileType>1</FileType>
|
||||
<tvExp>0</tvExp>
|
||||
<Focus>0</Focus>
|
||||
<tvExpOptDlg>0</tvExpOptDlg>
|
||||
<bDave2>0</bDave2>
|
||||
<PathWithFileName>..\UCOSII\CORE\os_mutex.c</PathWithFileName>
|
||||
<FilenameWithoutPath>os_mutex.c</FilenameWithoutPath>
|
||||
<RteFlg>0</RteFlg>
|
||||
<bShared>0</bShared>
|
||||
</File>
|
||||
<File>
|
||||
<GroupNumber>6</GroupNumber>
|
||||
<FileNumber>44</FileNumber>
|
||||
<FileType>1</FileType>
|
||||
<tvExp>0</tvExp>
|
||||
<Focus>0</Focus>
|
||||
<tvExpOptDlg>0</tvExpOptDlg>
|
||||
<bDave2>0</bDave2>
|
||||
<PathWithFileName>..\UCOSII\CORE\os_q.c</PathWithFileName>
|
||||
<FilenameWithoutPath>os_q.c</FilenameWithoutPath>
|
||||
<RteFlg>0</RteFlg>
|
||||
<bShared>0</bShared>
|
||||
</File>
|
||||
<File>
|
||||
<GroupNumber>6</GroupNumber>
|
||||
<FileNumber>45</FileNumber>
|
||||
<FileType>1</FileType>
|
||||
<tvExp>0</tvExp>
|
||||
<Focus>0</Focus>
|
||||
<tvExpOptDlg>0</tvExpOptDlg>
|
||||
<bDave2>0</bDave2>
|
||||
<PathWithFileName>..\UCOSII\CORE\os_sem.c</PathWithFileName>
|
||||
<FilenameWithoutPath>os_sem.c</FilenameWithoutPath>
|
||||
<RteFlg>0</RteFlg>
|
||||
<bShared>0</bShared>
|
||||
</File>
|
||||
<File>
|
||||
<GroupNumber>6</GroupNumber>
|
||||
<FileNumber>46</FileNumber>
|
||||
<FileType>1</FileType>
|
||||
<tvExp>0</tvExp>
|
||||
<Focus>0</Focus>
|
||||
<tvExpOptDlg>0</tvExpOptDlg>
|
||||
<bDave2>0</bDave2>
|
||||
<PathWithFileName>..\UCOSII\CORE\os_task.c</PathWithFileName>
|
||||
<FilenameWithoutPath>os_task.c</FilenameWithoutPath>
|
||||
<RteFlg>0</RteFlg>
|
||||
<bShared>0</bShared>
|
||||
</File>
|
||||
<File>
|
||||
<GroupNumber>6</GroupNumber>
|
||||
<FileNumber>47</FileNumber>
|
||||
<FileType>1</FileType>
|
||||
<tvExp>0</tvExp>
|
||||
<Focus>0</Focus>
|
||||
<tvExpOptDlg>0</tvExpOptDlg>
|
||||
<bDave2>0</bDave2>
|
||||
<PathWithFileName>..\UCOSII\CORE\os_time.c</PathWithFileName>
|
||||
<FilenameWithoutPath>os_time.c</FilenameWithoutPath>
|
||||
<RteFlg>0</RteFlg>
|
||||
<bShared>0</bShared>
|
||||
</File>
|
||||
<File>
|
||||
<GroupNumber>6</GroupNumber>
|
||||
<FileNumber>48</FileNumber>
|
||||
<FileType>1</FileType>
|
||||
<tvExp>0</tvExp>
|
||||
<Focus>0</Focus>
|
||||
<tvExpOptDlg>0</tvExpOptDlg>
|
||||
<bDave2>0</bDave2>
|
||||
<PathWithFileName>..\UCOSII\CORE\os_tmr.c</PathWithFileName>
|
||||
<FilenameWithoutPath>os_tmr.c</FilenameWithoutPath>
|
||||
<RteFlg>0</RteFlg>
|
||||
<bShared>0</bShared>
|
||||
</File>
|
||||
</Group>
|
||||
|
||||
<Group>
|
||||
<GroupName>UCOSII-PORT</GroupName>
|
||||
<tvExp>0</tvExp>
|
||||
<tvExpOptDlg>0</tvExpOptDlg>
|
||||
<cbSel>0</cbSel>
|
||||
<RteFlg>0</RteFlg>
|
||||
<File>
|
||||
<GroupNumber>7</GroupNumber>
|
||||
<FileNumber>49</FileNumber>
|
||||
<FileType>1</FileType>
|
||||
<tvExp>0</tvExp>
|
||||
<Focus>0</Focus>
|
||||
<tvExpOptDlg>0</tvExpOptDlg>
|
||||
<bDave2>0</bDave2>
|
||||
<PathWithFileName>..\UCOSII\PORT\os_cpu_c.c</PathWithFileName>
|
||||
<FilenameWithoutPath>os_cpu_c.c</FilenameWithoutPath>
|
||||
<RteFlg>0</RteFlg>
|
||||
<bShared>0</bShared>
|
||||
</File>
|
||||
<File>
|
||||
<GroupNumber>7</GroupNumber>
|
||||
<FileNumber>50</FileNumber>
|
||||
<FileType>5</FileType>
|
||||
<tvExp>0</tvExp>
|
||||
<Focus>0</Focus>
|
||||
<tvExpOptDlg>0</tvExpOptDlg>
|
||||
<bDave2>0</bDave2>
|
||||
<PathWithFileName>..\UCOSII\PORT\os_cpu.h</PathWithFileName>
|
||||
<FilenameWithoutPath>os_cpu.h</FilenameWithoutPath>
|
||||
<RteFlg>0</RteFlg>
|
||||
<bShared>0</bShared>
|
||||
</File>
|
||||
<File>
|
||||
<GroupNumber>7</GroupNumber>
|
||||
<FileNumber>51</FileNumber>
|
||||
<FileType>2</FileType>
|
||||
<tvExp>0</tvExp>
|
||||
<Focus>0</Focus>
|
||||
<tvExpOptDlg>0</tvExpOptDlg>
|
||||
<bDave2>0</bDave2>
|
||||
<PathWithFileName>..\UCOSII\PORT\os_cpu_a.asm</PathWithFileName>
|
||||
<FilenameWithoutPath>os_cpu_a.asm</FilenameWithoutPath>
|
||||
<RteFlg>0</RteFlg>
|
||||
<bShared>0</bShared>
|
||||
</File>
|
||||
</Group>
|
||||
|
||||
<Group>
|
||||
<GroupName>UCOSII-CONFIG</GroupName>
|
||||
<tvExp>0</tvExp>
|
||||
<tvExpOptDlg>0</tvExpOptDlg>
|
||||
<cbSel>0</cbSel>
|
||||
<RteFlg>0</RteFlg>
|
||||
<File>
|
||||
<GroupNumber>8</GroupNumber>
|
||||
<FileNumber>52</FileNumber>
|
||||
<FileType>5</FileType>
|
||||
<tvExp>0</tvExp>
|
||||
<Focus>0</Focus>
|
||||
<tvExpOptDlg>0</tvExpOptDlg>
|
||||
<bDave2>0</bDave2>
|
||||
<PathWithFileName>..\UCOSII\CONFIG\includes.h</PathWithFileName>
|
||||
<FilenameWithoutPath>includes.h</FilenameWithoutPath>
|
||||
<RteFlg>0</RteFlg>
|
||||
<bShared>0</bShared>
|
||||
</File>
|
||||
<File>
|
||||
<GroupNumber>8</GroupNumber>
|
||||
<FileNumber>53</FileNumber>
|
||||
<FileType>5</FileType>
|
||||
<tvExp>0</tvExp>
|
||||
<Focus>0</Focus>
|
||||
<tvExpOptDlg>0</tvExpOptDlg>
|
||||
<bDave2>0</bDave2>
|
||||
<PathWithFileName>..\UCOSII\CONFIG\os_cfg.h</PathWithFileName>
|
||||
<FilenameWithoutPath>os_cfg.h</FilenameWithoutPath>
|
||||
<RteFlg>0</RteFlg>
|
||||
<bShared>0</bShared>
|
||||
</File>
|
||||
</Group>
|
||||
|
||||
<Group>
|
||||
<GroupName>ReadMe</GroupName>
|
||||
<tvExp>0</tvExp>
|
||||
<tvExpOptDlg>0</tvExpOptDlg>
|
||||
<cbSel>0</cbSel>
|
||||
<RteFlg>0</RteFlg>
|
||||
<File>
|
||||
<GroupNumber>9</GroupNumber>
|
||||
<FileNumber>54</FileNumber>
|
||||
<FileType>5</FileType>
|
||||
<tvExp>0</tvExp>
|
||||
<Focus>0</Focus>
|
||||
|
||||
@@ -373,7 +373,7 @@
|
||||
<MiscControls></MiscControls>
|
||||
<Define>STM32F10X_HD,USE_STDPERIPH_DRIVER</Define>
|
||||
<Undefine></Undefine>
|
||||
<IncludePath>..\USER;..\SYSTEM\delay;..\SYSTEM\sys;..\SYSTEM\usart;..\STM32F10x_FWLib\inc;..\CORE;..\HARDWARE\GPIO_Motor;..\HARDWARE\TIMER;..\HARDWARE\KEY;..\HARDWARE\EXTI;..\HARDWARE\PWM;..\HARDWARE\IronHand;..\HARDWARE\MOTOR_CTRL;..\HARDWARE\USART</IncludePath>
|
||||
<IncludePath>..\USER;..\SYSTEM\delay;..\SYSTEM\sys;..\SYSTEM\usart;..\STM32F10x_FWLib\inc;..\CORE;..\HARDWARE\GPIO_Motor;..\HARDWARE\TIMER;..\HARDWARE\KEY;..\HARDWARE\EXTI;..\HARDWARE\PWM;..\HARDWARE\IronHand;..\HARDWARE\MOTOR_CTRL;..\HARDWARE\USART;..\UCOSII\CONFIG;..\UCOSII\CORE;..\UCOSII\PORT</IncludePath>
|
||||
</VariousControls>
|
||||
</Cads>
|
||||
<Aads>
|
||||
@@ -628,6 +628,96 @@
|
||||
</File>
|
||||
</Files>
|
||||
</Group>
|
||||
<Group>
|
||||
<GroupName>UCOSII-CORE</GroupName>
|
||||
<Files>
|
||||
<File>
|
||||
<FileName>os_core.c</FileName>
|
||||
<FileType>1</FileType>
|
||||
<FilePath>..\UCOSII\CORE\os_core.c</FilePath>
|
||||
</File>
|
||||
<File>
|
||||
<FileName>os_flag.c</FileName>
|
||||
<FileType>1</FileType>
|
||||
<FilePath>..\UCOSII\CORE\os_flag.c</FilePath>
|
||||
</File>
|
||||
<File>
|
||||
<FileName>os_mbox.c</FileName>
|
||||
<FileType>1</FileType>
|
||||
<FilePath>..\UCOSII\CORE\os_mbox.c</FilePath>
|
||||
</File>
|
||||
<File>
|
||||
<FileName>os_mem.c</FileName>
|
||||
<FileType>1</FileType>
|
||||
<FilePath>..\UCOSII\CORE\os_mem.c</FilePath>
|
||||
</File>
|
||||
<File>
|
||||
<FileName>os_mutex.c</FileName>
|
||||
<FileType>1</FileType>
|
||||
<FilePath>..\UCOSII\CORE\os_mutex.c</FilePath>
|
||||
</File>
|
||||
<File>
|
||||
<FileName>os_q.c</FileName>
|
||||
<FileType>1</FileType>
|
||||
<FilePath>..\UCOSII\CORE\os_q.c</FilePath>
|
||||
</File>
|
||||
<File>
|
||||
<FileName>os_sem.c</FileName>
|
||||
<FileType>1</FileType>
|
||||
<FilePath>..\UCOSII\CORE\os_sem.c</FilePath>
|
||||
</File>
|
||||
<File>
|
||||
<FileName>os_task.c</FileName>
|
||||
<FileType>1</FileType>
|
||||
<FilePath>..\UCOSII\CORE\os_task.c</FilePath>
|
||||
</File>
|
||||
<File>
|
||||
<FileName>os_time.c</FileName>
|
||||
<FileType>1</FileType>
|
||||
<FilePath>..\UCOSII\CORE\os_time.c</FilePath>
|
||||
</File>
|
||||
<File>
|
||||
<FileName>os_tmr.c</FileName>
|
||||
<FileType>1</FileType>
|
||||
<FilePath>..\UCOSII\CORE\os_tmr.c</FilePath>
|
||||
</File>
|
||||
</Files>
|
||||
</Group>
|
||||
<Group>
|
||||
<GroupName>UCOSII-PORT</GroupName>
|
||||
<Files>
|
||||
<File>
|
||||
<FileName>os_cpu_c.c</FileName>
|
||||
<FileType>1</FileType>
|
||||
<FilePath>..\UCOSII\PORT\os_cpu_c.c</FilePath>
|
||||
</File>
|
||||
<File>
|
||||
<FileName>os_cpu.h</FileName>
|
||||
<FileType>5</FileType>
|
||||
<FilePath>..\UCOSII\PORT\os_cpu.h</FilePath>
|
||||
</File>
|
||||
<File>
|
||||
<FileName>os_cpu_a.asm</FileName>
|
||||
<FileType>2</FileType>
|
||||
<FilePath>..\UCOSII\PORT\os_cpu_a.asm</FilePath>
|
||||
</File>
|
||||
</Files>
|
||||
</Group>
|
||||
<Group>
|
||||
<GroupName>UCOSII-CONFIG</GroupName>
|
||||
<Files>
|
||||
<File>
|
||||
<FileName>includes.h</FileName>
|
||||
<FileType>5</FileType>
|
||||
<FilePath>..\UCOSII\CONFIG\includes.h</FilePath>
|
||||
</File>
|
||||
<File>
|
||||
<FileName>os_cfg.h</FileName>
|
||||
<FileType>5</FileType>
|
||||
<FilePath>..\UCOSII\CONFIG\os_cfg.h</FilePath>
|
||||
</File>
|
||||
</Files>
|
||||
</Group>
|
||||
<Group>
|
||||
<GroupName>ReadMe</GroupName>
|
||||
<Files>
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
531
USER/Listings/os_cpu_a.lst
Normal file
531
USER/Listings/os_cpu_a.lst
Normal file
@@ -0,0 +1,531 @@
|
||||
|
||||
|
||||
|
||||
ARM Macro Assembler Page 1
|
||||
|
||||
|
||||
1 00000000 ;/*********************** (C) COPYRIGHT 2010 Libraworks
|
||||
*************************
|
||||
2 00000000 ;* File Name : os_cpu_a.asm
|
||||
3 00000000 ;* Author : Librae
|
||||
4 00000000 ;* Version : V1.0
|
||||
5 00000000 ;* Date : 06/10/2010
|
||||
6 00000000 ;* Description : <20><>COS-II asm port for STM32
|
||||
7 00000000 ;*******************************************************
|
||||
************************/
|
||||
8 00000000
|
||||
9 00000000 IMPORT OSRunning ; External referenc
|
||||
es
|
||||
10 00000000 IMPORT OSPrioCur
|
||||
11 00000000 IMPORT OSPrioHighRdy
|
||||
12 00000000 IMPORT OSTCBCur
|
||||
13 00000000 IMPORT OSTCBHighRdy
|
||||
14 00000000 IMPORT OSIntNesting
|
||||
15 00000000 IMPORT OSIntExit
|
||||
16 00000000 IMPORT OSTaskSwHook
|
||||
17 00000000
|
||||
18 00000000 EXPORT OSStartHighRdy
|
||||
19 00000000 EXPORT OSCtxSw
|
||||
20 00000000 EXPORT OSIntCtxSw
|
||||
21 00000000 EXPORT OS_CPU_SR_Save ; Functions decl
|
||||
ared in this file
|
||||
22 00000000 EXPORT OS_CPU_SR_Restore
|
||||
23 00000000 EXPORT PendSV_Handler
|
||||
24 00000000
|
||||
25 00000000
|
||||
26 00000000 E000ED04
|
||||
NVIC_INT_CTRL
|
||||
EQU 0xE000ED04 ; <20>жϿ<D0B6><CFBF>ƼĴ<C6BC><C4B4><EFBFBD>
|
||||
27 00000000 E000ED20
|
||||
NVIC_SYSPRI2
|
||||
EQU 0xE000ED20 ; ϵͳ<CFB5><CDB3><EFBFBD>ȼ<EFBFBD><C8BC>Ĵ<EFBFBD><C4B4><EFBFBD>(
|
||||
2)
|
||||
28 00000000 FFFF0000
|
||||
NVIC_PENDSV_PRI
|
||||
EQU 0xFFFF0000 ; PendSV<53>жϺ<D0B6>ϵͳ<CFB5>
|
||||
<20><><EFBFBD><EFBFBD>ж<EFBFBD>
|
||||
29 00000000 ; (<28><>Ϊ<EFBFBD><CEAA><EFBFBD>ͣ<EFBFBD>0xff).
|
||||
30 00000000 10000000
|
||||
NVIC_PENDSVSET
|
||||
EQU 0x10000000 ; <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>жϵ<D0B6>ֵ.
|
||||
|
||||
31 00000000
|
||||
32 00000000
|
||||
33 00000000 PRESERVE8
|
||||
34 00000000
|
||||
35 00000000 AREA |.text|, CODE, READONLY
|
||||
36 00000000 THUMB
|
||||
37 00000000
|
||||
38 00000000
|
||||
39 00000000
|
||||
40 00000000 ;*******************************************************
|
||||
*************************************************
|
||||
41 00000000 ; CRITICAL SECTION MET
|
||||
HOD 3 FUNCTIONS
|
||||
42 00000000 ;
|
||||
|
||||
|
||||
|
||||
ARM Macro Assembler Page 2
|
||||
|
||||
|
||||
43 00000000 ; Description: Disable/Enable interrupts by preserving t
|
||||
he state of interrupts. Generally speaking you
|
||||
44 00000000 ; would store the state of the interrupt di
|
||||
sable flag in the local variable 'cpu_sr' and then
|
||||
45 00000000 ; disable interrupts. 'cpu_sr' is allocate
|
||||
d in all of uC/OS-II's functions that need to
|
||||
46 00000000 ; disable interrupts. You would restore th
|
||||
e interrupt disable state by copying back 'cpu_sr'
|
||||
47 00000000 ; into the CPU's status register.
|
||||
48 00000000 ;
|
||||
49 00000000 ; Prototypes : OS_CPU_SR OS_CPU_SR_Save(void);
|
||||
50 00000000 ; void OS_CPU_SR_Restore(OS_CPU_S
|
||||
R cpu_sr);
|
||||
51 00000000 ;
|
||||
52 00000000 ;
|
||||
53 00000000 ; Note(s) : 1) These functions are used in general li
|
||||
ke this:
|
||||
54 00000000 ;
|
||||
55 00000000 ; void Task (void *p_arg)
|
||||
56 00000000 ; {
|
||||
57 00000000 ; #if OS_CRITICAL_METHOD == 3 /
|
||||
* Allocate storage for CPU status register */
|
||||
58 00000000 ; OS_CPU_SR cpu_sr;
|
||||
59 00000000 ; #endif
|
||||
60 00000000 ;
|
||||
61 00000000 ; :
|
||||
62 00000000 ; :
|
||||
63 00000000 ; OS_ENTER_CRITICAL(); /
|
||||
* cpu_sr = OS_CPU_SaveSR(); */
|
||||
64 00000000 ; :
|
||||
65 00000000 ; :
|
||||
66 00000000 ; OS_EXIT_CRITICAL(); /
|
||||
* OS_CPU_RestoreSR(cpu_sr); */
|
||||
67 00000000 ; :
|
||||
68 00000000 ; :
|
||||
69 00000000 ; }
|
||||
70 00000000 ;*******************************************************
|
||||
*************************************************
|
||||
71 00000000
|
||||
72 00000000 OS_CPU_SR_Save
|
||||
73 00000000 F3EF 8010 MRS R0, PRIMASK ;<3B><>ȡPRIMASK<53><4B>R0,R0
|
||||
Ϊ<><CEAA><EFBFBD><EFBFBD>ֵ
|
||||
74 00000004 B672 CPSID I ;PRIMASK=1,<2C><><EFBFBD>ж<EFBFBD>(N
|
||||
MI<4D><49>Ӳ<EFBFBD><D3B2>FAULT<4C><54><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
Ӧ)
|
||||
75 00000006 4770 BX LR ;<3B><><EFBFBD><EFBFBD>
|
||||
76 00000008
|
||||
77 00000008 OS_CPU_SR_Restore
|
||||
78 00000008 F380 8810 MSR PRIMASK, R0 ;<3B><>ȡR0<52><30>PRIMASK<53><4B>,
|
||||
R0Ϊ<30><CEAA><EFBFBD><EFBFBD>
|
||||
79 0000000C 4770 BX LR ;<3B><><EFBFBD><EFBFBD>
|
||||
80 0000000E
|
||||
81 0000000E
|
||||
82 0000000E ;/******************************************************
|
||||
********************************
|
||||
83 0000000E ;* <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>: OSStartHighRdy
|
||||
84 0000000E ;*
|
||||
85 0000000E ;* <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>: ʹ<>õ<EFBFBD><C3B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>е<EFBFBD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
86 0000000E ;*
|
||||
|
||||
|
||||
|
||||
ARM Macro Assembler Page 3
|
||||
|
||||
|
||||
87 0000000E ;* <20><> <20><>: None
|
||||
88 0000000E ;*
|
||||
89 0000000E ;* <20><> <20><> ֵ: None
|
||||
90 0000000E ;*******************************************************
|
||||
*******************************/
|
||||
91 0000000E
|
||||
92 0000000E OSStartHighRdy
|
||||
93 0000000E 4C20 LDR R4, =NVIC_SYSPRI2 ; set the Pen
|
||||
dSV exception prior
|
||||
ity
|
||||
94 00000010 4D20 LDR R5, =NVIC_PENDSV_PRI
|
||||
95 00000012 6025 STR R5, [R4]
|
||||
96 00000014
|
||||
97 00000014 F04F 0400 MOV R4, #0 ; set the PSP to 0
|
||||
for initial context
|
||||
switch call
|
||||
98 00000018 F384 8809 MSR PSP, R4
|
||||
99 0000001C
|
||||
100 0000001C 4C1E LDR R4, =OSRunning
|
||||
; OSRunning = TRUE
|
||||
101 0000001E F04F 0501 MOV R5, #1
|
||||
102 00000022 7025 STRB R5, [R4]
|
||||
103 00000024
|
||||
104 00000024 ;<3B>л<EFBFBD><D0BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȼ<EFBFBD><C8BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
105 00000024 4C1D LDR R4, =NVIC_INT_CTRL ;rigger the
|
||||
PendSV exception (c
|
||||
auses context switc
|
||||
h)
|
||||
106 00000026 F04F 5580 LDR R5, =NVIC_PENDSVSET
|
||||
107 0000002A 6025 STR R5, [R4]
|
||||
108 0000002C
|
||||
109 0000002C B662 CPSIE I ;enable interrupts
|
||||
at processor level
|
||||
110 0000002E OSStartHang
|
||||
111 0000002E E7FE B OSStartHang ;should never get h
|
||||
ere
|
||||
112 00000030
|
||||
113 00000030 ;/******************************************************
|
||||
********************************
|
||||
114 00000030 ;* <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>: OSCtxSw
|
||||
115 00000030 ;*
|
||||
116 00000030 ;* <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>: <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>л<EFBFBD>
|
||||
117 00000030 ;*
|
||||
118 00000030 ;* <20><> <20><>: None
|
||||
119 00000030 ;*
|
||||
120 00000030 ;* <20><> <20><> ֵ: None
|
||||
121 00000030 ;*******************************************************
|
||||
********************************/
|
||||
122 00000030
|
||||
123 00000030 OSCtxSw
|
||||
124 00000030 B430 PUSH {R4, R5}
|
||||
125 00000032 4C1A LDR R4, =NVIC_INT_CTRL ;<3B><><EFBFBD><EFBFBD>PendSV<53>
|
||||
쳣 (causes context
|
||||
switch)
|
||||
126 00000034 F04F 5580 LDR R5, =NVIC_PENDSVSET
|
||||
127 00000038 6025 STR R5, [R4]
|
||||
128 0000003A BC30 POP {R4, R5}
|
||||
129 0000003C 4770 BX LR
|
||||
130 0000003E
|
||||
|
||||
|
||||
|
||||
ARM Macro Assembler Page 4
|
||||
|
||||
|
||||
131 0000003E ;/******************************************************
|
||||
********************************
|
||||
132 0000003E ;* <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>: OSIntCtxSw
|
||||
133 0000003E ;*
|
||||
134 0000003E ;* <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>: <20>жϼ<D0B6><CFBC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>л<EFBFBD>
|
||||
135 0000003E ;*
|
||||
136 0000003E ;* <20><> <20><>: None
|
||||
137 0000003E ;*
|
||||
138 0000003E ;* <20><> <20><> ֵ: None
|
||||
139 0000003E ;*******************************************************
|
||||
********************************/
|
||||
140 0000003E
|
||||
141 0000003E OSIntCtxSw
|
||||
142 0000003E B430 PUSH {R4, R5}
|
||||
143 00000040 4C16 LDR R4, =NVIC_INT_CTRL ;<3B><><EFBFBD><EFBFBD>PendSV<53>
|
||||
쳣 (causes context
|
||||
switch)
|
||||
144 00000042 F04F 5580 LDR R5, =NVIC_PENDSVSET
|
||||
145 00000046 6025 STR R5, [R4]
|
||||
146 00000048 BC30 POP {R4, R5}
|
||||
147 0000004A 4770 BX LR
|
||||
148 0000004C BF00 NOP
|
||||
149 0000004E
|
||||
150 0000004E ;/******************************************************
|
||||
********************************
|
||||
151 0000004E ;* <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>: OSPendSV
|
||||
152 0000004E ;*
|
||||
153 0000004E ;* <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>: OSPendSV is used to cause a context switch.
|
||||
|
||||
154 0000004E ;*
|
||||
155 0000004E ;* <20><> <20><>: None
|
||||
156 0000004E ;*
|
||||
157 0000004E ;* <20><> <20><> ֵ: None
|
||||
158 0000004E ;*******************************************************
|
||||
********************************/
|
||||
159 0000004E
|
||||
160 0000004E PendSV_Handler
|
||||
161 0000004E B672 CPSID I ; Prevent interrupt
|
||||
ion during context
|
||||
switch
|
||||
162 00000050 F3EF 8009 MRS R0, PSP ; PSP is process st
|
||||
ack pointer <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
<20>PSP<53><50>ջ,<2C><><EFBFBD><EFBFBD><EFBFBD>Ժ<EFBFBD><D4BA><EFBFBD>
|
||||
<20><><EFBFBD><EFBFBD><EFBFBD>Ĵ<EFBFBD><C4B4><EFBFBD>,<2C>ο<EFBFBD>CM3<4D>
|
||||
<20><><EFBFBD><EFBFBD>е<EFBFBD>˫<EFBFBD><CBAB>ջ-<2D>ײ<EFBFBD><D7B2>
|
||||
<20>
|
||||
163 00000054 B128 CBZ R0, PendSV_Handler_Nosave ; Ski
|
||||
p register save the
|
||||
first time
|
||||
164 00000056
|
||||
165 00000056 3820 SUBS R0, R0, #0x20 ; Save remaining
|
||||
regs r4-11 on proce
|
||||
ss stack
|
||||
166 00000058 E880 0FF0 STM R0, {R4-R11}
|
||||
167 0000005C
|
||||
168 0000005C 4910 LDR R1, =OSTCBCur ; OSTCBCur->OSTCB
|
||||
StkPtr = SP;
|
||||
169 0000005E 6809 LDR R1, [R1]
|
||||
170 00000060 6008 STR R0, [R1] ; R0 is SP of proce
|
||||
|
||||
|
||||
|
||||
ARM Macro Assembler Page 5
|
||||
|
||||
|
||||
ss being switched o
|
||||
ut
|
||||
171 00000062
|
||||
172 00000062 ; At this point, entire context of process has been save
|
||||
d
|
||||
173 00000062 PendSV_Handler_Nosave
|
||||
174 00000062 B500 PUSH {R14} ; Save LR exc_retur
|
||||
n value
|
||||
175 00000064 480F LDR R0, =OSTaskSwHook
|
||||
; OSTaskSwHook();
|
||||
176 00000066 4780 BLX R0
|
||||
177 00000068 F85D EB04 POP {R14}
|
||||
178 0000006C
|
||||
179 0000006C 480E LDR R0, =OSPrioCur ; OSPrioCur = OS
|
||||
PrioHighRdy;
|
||||
180 0000006E 490F LDR R1, =OSPrioHighRdy
|
||||
181 00000070 780A LDRB R2, [R1]
|
||||
182 00000072 7002 STRB R2, [R0]
|
||||
183 00000074
|
||||
184 00000074 480A LDR R0, =OSTCBCur ; OSTCBCur = OST
|
||||
CBHighRdy;
|
||||
185 00000076 490E LDR R1, =OSTCBHighRdy
|
||||
186 00000078 680A LDR R2, [R1]
|
||||
187 0000007A 6002 STR R2, [R0]
|
||||
188 0000007C
|
||||
189 0000007C 6810 LDR R0, [R2] ; R0 is new process
|
||||
SP; SP = OSTCBHigh
|
||||
Rdy->OSTCBStkPtr;
|
||||
190 0000007E E890 0FF0 LDM R0, {R4-R11} ; Restore r4-11 fr
|
||||
om new process stac
|
||||
k
|
||||
191 00000082 3020 ADDS R0, R0, #0x20
|
||||
192 00000084 F380 8809 MSR PSP, R0 ; Load PSP with new
|
||||
process SP
|
||||
193 00000088 F04E 0E04 ORR LR, LR, #0x04 ; Ensure exceptio
|
||||
n return uses proce
|
||||
ss stack
|
||||
194 0000008C B662 CPSIE I
|
||||
195 0000008E 4770 BX LR ; Exception return
|
||||
will restore remain
|
||||
ing context
|
||||
196 00000090
|
||||
197 00000090 end
|
||||
E000ED20
|
||||
FFFF0000
|
||||
00000000
|
||||
E000ED04
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
Command Line: --debug --xref --diag_suppress=9931 --cpu=Cortex-M3 --apcs=interw
|
||||
ork --depend=..\obj\os_cpu_a.d -o..\obj\os_cpu_a.o -I"G:\ǰ<><C7B0><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʵϰ\for Githu
|
||||
b\4StepperMotorsDriveBySTM32F103x\USER\RTE" -IE:\Keil5\ARM\PACK\Keil\STM32F1xx_
|
||||
DFP\1.0.2\Device\Include -IE:\Keil5\ARM\CMSIS\Include --predefine="__UVISION_VE
|
||||
RSION SETA 516" --predefine="STM32F10X_HD SETA 1" --list=.\listings\os_cpu_a.ls
|
||||
t ..\UCOSII\PORT\os_cpu_a.asm
|
||||
|
||||
|
||||
|
||||
ARM Macro Assembler Page 1 Alphabetic symbol ordering
|
||||
Relocatable symbols
|
||||
|
||||
.text 00000000
|
||||
|
||||
Symbol: .text
|
||||
Definitions
|
||||
At line 35 in file ..\UCOSII\PORT\os_cpu_a.asm
|
||||
Uses
|
||||
None
|
||||
Comment: .text unused
|
||||
OSCtxSw 00000030
|
||||
|
||||
Symbol: OSCtxSw
|
||||
Definitions
|
||||
At line 123 in file ..\UCOSII\PORT\os_cpu_a.asm
|
||||
Uses
|
||||
At line 19 in file ..\UCOSII\PORT\os_cpu_a.asm
|
||||
Comment: OSCtxSw used once
|
||||
OSIntCtxSw 0000003E
|
||||
|
||||
Symbol: OSIntCtxSw
|
||||
Definitions
|
||||
At line 141 in file ..\UCOSII\PORT\os_cpu_a.asm
|
||||
Uses
|
||||
At line 20 in file ..\UCOSII\PORT\os_cpu_a.asm
|
||||
Comment: OSIntCtxSw used once
|
||||
OSStartHang 0000002E
|
||||
|
||||
Symbol: OSStartHang
|
||||
Definitions
|
||||
At line 110 in file ..\UCOSII\PORT\os_cpu_a.asm
|
||||
Uses
|
||||
At line 111 in file ..\UCOSII\PORT\os_cpu_a.asm
|
||||
Comment: OSStartHang used once
|
||||
OSStartHighRdy 0000000E
|
||||
|
||||
Symbol: OSStartHighRdy
|
||||
Definitions
|
||||
At line 92 in file ..\UCOSII\PORT\os_cpu_a.asm
|
||||
Uses
|
||||
At line 18 in file ..\UCOSII\PORT\os_cpu_a.asm
|
||||
Comment: OSStartHighRdy used once
|
||||
OS_CPU_SR_Restore 00000008
|
||||
|
||||
Symbol: OS_CPU_SR_Restore
|
||||
Definitions
|
||||
At line 77 in file ..\UCOSII\PORT\os_cpu_a.asm
|
||||
Uses
|
||||
At line 22 in file ..\UCOSII\PORT\os_cpu_a.asm
|
||||
Comment: OS_CPU_SR_Restore used once
|
||||
OS_CPU_SR_Save 00000000
|
||||
|
||||
Symbol: OS_CPU_SR_Save
|
||||
Definitions
|
||||
At line 72 in file ..\UCOSII\PORT\os_cpu_a.asm
|
||||
Uses
|
||||
At line 21 in file ..\UCOSII\PORT\os_cpu_a.asm
|
||||
Comment: OS_CPU_SR_Save used once
|
||||
PendSV_Handler 0000004E
|
||||
|
||||
Symbol: PendSV_Handler
|
||||
|
||||
|
||||
|
||||
ARM Macro Assembler Page 2 Alphabetic symbol ordering
|
||||
Relocatable symbols
|
||||
|
||||
Definitions
|
||||
At line 160 in file ..\UCOSII\PORT\os_cpu_a.asm
|
||||
Uses
|
||||
At line 23 in file ..\UCOSII\PORT\os_cpu_a.asm
|
||||
Comment: PendSV_Handler used once
|
||||
PendSV_Handler_Nosave 00000062
|
||||
|
||||
Symbol: PendSV_Handler_Nosave
|
||||
Definitions
|
||||
At line 173 in file ..\UCOSII\PORT\os_cpu_a.asm
|
||||
Uses
|
||||
At line 163 in file ..\UCOSII\PORT\os_cpu_a.asm
|
||||
Comment: PendSV_Handler_Nosave used once
|
||||
9 symbols
|
||||
|
||||
|
||||
|
||||
ARM Macro Assembler Page 1 Alphabetic symbol ordering
|
||||
Absolute symbols
|
||||
|
||||
NVIC_INT_CTRL E000ED04
|
||||
|
||||
Symbol: NVIC_INT_CTRL
|
||||
Definitions
|
||||
At line 26 in file ..\UCOSII\PORT\os_cpu_a.asm
|
||||
Uses
|
||||
At line 105 in file ..\UCOSII\PORT\os_cpu_a.asm
|
||||
At line 125 in file ..\UCOSII\PORT\os_cpu_a.asm
|
||||
At line 143 in file ..\UCOSII\PORT\os_cpu_a.asm
|
||||
|
||||
NVIC_PENDSVSET 10000000
|
||||
|
||||
Symbol: NVIC_PENDSVSET
|
||||
Definitions
|
||||
At line 30 in file ..\UCOSII\PORT\os_cpu_a.asm
|
||||
Uses
|
||||
At line 106 in file ..\UCOSII\PORT\os_cpu_a.asm
|
||||
At line 126 in file ..\UCOSII\PORT\os_cpu_a.asm
|
||||
At line 144 in file ..\UCOSII\PORT\os_cpu_a.asm
|
||||
|
||||
NVIC_PENDSV_PRI FFFF0000
|
||||
|
||||
Symbol: NVIC_PENDSV_PRI
|
||||
Definitions
|
||||
At line 28 in file ..\UCOSII\PORT\os_cpu_a.asm
|
||||
Uses
|
||||
At line 94 in file ..\UCOSII\PORT\os_cpu_a.asm
|
||||
Comment: NVIC_PENDSV_PRI used once
|
||||
NVIC_SYSPRI2 E000ED20
|
||||
|
||||
Symbol: NVIC_SYSPRI2
|
||||
Definitions
|
||||
At line 27 in file ..\UCOSII\PORT\os_cpu_a.asm
|
||||
Uses
|
||||
At line 93 in file ..\UCOSII\PORT\os_cpu_a.asm
|
||||
Comment: NVIC_SYSPRI2 used once
|
||||
4 symbols
|
||||
|
||||
|
||||
|
||||
ARM Macro Assembler Page 1 Alphabetic symbol ordering
|
||||
External symbols
|
||||
|
||||
OSIntExit 00000000
|
||||
|
||||
Symbol: OSIntExit
|
||||
Definitions
|
||||
At line 15 in file ..\UCOSII\PORT\os_cpu_a.asm
|
||||
Uses
|
||||
None
|
||||
Comment: OSIntExit unused
|
||||
OSIntNesting 00000000
|
||||
|
||||
Symbol: OSIntNesting
|
||||
Definitions
|
||||
At line 14 in file ..\UCOSII\PORT\os_cpu_a.asm
|
||||
Uses
|
||||
None
|
||||
Comment: OSIntNesting unused
|
||||
OSPrioCur 00000000
|
||||
|
||||
Symbol: OSPrioCur
|
||||
Definitions
|
||||
At line 10 in file ..\UCOSII\PORT\os_cpu_a.asm
|
||||
Uses
|
||||
At line 179 in file ..\UCOSII\PORT\os_cpu_a.asm
|
||||
Comment: OSPrioCur used once
|
||||
OSPrioHighRdy 00000000
|
||||
|
||||
Symbol: OSPrioHighRdy
|
||||
Definitions
|
||||
At line 11 in file ..\UCOSII\PORT\os_cpu_a.asm
|
||||
Uses
|
||||
At line 180 in file ..\UCOSII\PORT\os_cpu_a.asm
|
||||
Comment: OSPrioHighRdy used once
|
||||
OSRunning 00000000
|
||||
|
||||
Symbol: OSRunning
|
||||
Definitions
|
||||
At line 9 in file ..\UCOSII\PORT\os_cpu_a.asm
|
||||
Uses
|
||||
At line 100 in file ..\UCOSII\PORT\os_cpu_a.asm
|
||||
Comment: OSRunning used once
|
||||
OSTCBCur 00000000
|
||||
|
||||
Symbol: OSTCBCur
|
||||
Definitions
|
||||
At line 12 in file ..\UCOSII\PORT\os_cpu_a.asm
|
||||
Uses
|
||||
At line 168 in file ..\UCOSII\PORT\os_cpu_a.asm
|
||||
At line 184 in file ..\UCOSII\PORT\os_cpu_a.asm
|
||||
|
||||
OSTCBHighRdy 00000000
|
||||
|
||||
Symbol: OSTCBHighRdy
|
||||
Definitions
|
||||
At line 13 in file ..\UCOSII\PORT\os_cpu_a.asm
|
||||
Uses
|
||||
At line 185 in file ..\UCOSII\PORT\os_cpu_a.asm
|
||||
Comment: OSTCBHighRdy used once
|
||||
OSTaskSwHook 00000000
|
||||
|
||||
|
||||
|
||||
|
||||
ARM Macro Assembler Page 2 Alphabetic symbol ordering
|
||||
External symbols
|
||||
|
||||
Symbol: OSTaskSwHook
|
||||
Definitions
|
||||
At line 16 in file ..\UCOSII\PORT\os_cpu_a.asm
|
||||
Uses
|
||||
At line 175 in file ..\UCOSII\PORT\os_cpu_a.asm
|
||||
Comment: OSTaskSwHook used once
|
||||
8 symbols
|
||||
355 symbols in table
|
||||
@@ -47,7 +47,9 @@
|
||||
#include "stm32f10x_it.h"
|
||||
|
||||
|
||||
|
||||
// <20><><EFBFBD><EFBFBD>ʹ<EFBFBD><CAB9><EFBFBD><EFBFBD>UCOSIIϵͳ<CFB5><CDB3>1
|
||||
#define USE_UCOSII 0
|
||||
|
||||
void NMI_Handler(void)
|
||||
{
|
||||
}
|
||||
@@ -92,15 +94,20 @@ void SVC_Handler(void)
|
||||
void DebugMon_Handler(void)
|
||||
{
|
||||
}
|
||||
|
||||
void PendSV_Handler(void)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
#if USE_UCOSII
|
||||
|
||||
// <20><><EFBFBD><EFBFBD>û<EFBFBD><C3BB>ʹ<EFBFBD><CAB9> UCOSII <20><><EFBFBD><EFBFBD>ϵͳ<CFB5><CDB3><EFBFBD>Ż<EFBFBD><C5BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>жϷ<D0B6><CFB7><EFBFBD><EFBFBD>ӳ<EFBFBD><D3B3><EFBFBD>
|
||||
#else
|
||||
// ʹ<><CAB9> UCOSII ϵͳʱ<CDB3><CAB1>PendSV_Handler<65>Ѿ<EFBFBD><D1BE><EFBFBD> os-cpu_a.asm <20>ļ<EFBFBD><C4BC>ж<EFBFBD><D0B6><EFBFBD><EFBFBD><EFBFBD>
|
||||
//void PendSV_Handler(void)
|
||||
//{
|
||||
//}
|
||||
|
||||
void SysTick_Handler(void)
|
||||
{
|
||||
}
|
||||
|
||||
#endif
|
||||
/******************************************************************************/
|
||||
/* STM32F10x Peripherals Interrupt Handlers */
|
||||
/* Add here the Interrupt Handler for the used peripheral(s) (PPP), for the */
|
||||
|
||||
Reference in New Issue
Block a user