uC/OS-III之资源管理
来源:互联网 发布:扫描识别文字软件 编辑:程序博客网 时间:2024/05/16 11:56
1.最常用的独占共享资源和创建临界区的方法有4种:关中断、禁止任务调度、使用信号量、使用互斥型信号量。
一般推荐使用互斥信号量。
在访问数据量极少的时候,可以使用关中断的方式。
在访问数据量少且资源同步是在任务与任务之间的时候,可以使用关调度的方式。
2.关中断/开中断
(1)在使用关中断/开中断时,必须先调用宏CPU_SR_ALLOC()。它的作用是分配存储空间来存储当前CPU的中断状态。
(2)关中断/开中断属于CPU相关的函数,所以它们的定义位于cpu.h中,319行 - 320行
#define CPU_CRITICAL_ENTER() do { CPU_INT_DIS(); } while (0) // 关中断#define CPU_CRITICAL_EXIT() do { CPU_INT_EN(); } while (0) // 开中断#define CPU_INT_DIS() do { cpu_sr = CPU_SR_Save(); } while (0) // 保存CPU的状态,并关中断#define CPU_INT_EN() do { CPU_SR_Restore(cpu_sr); } while (0) // 恢复CPU的状态// 以下是汇编代码CPU_SR_Save MRS R0, PRIMASK // 保存CPU的状态到R0中--子函数返回时,R0存放返回值 CPSID I // 关闭中断 BX LRCPU_SR_Restore MSR PRIMASK, R0 // 把R0的值复制到CPU的状态寄存器中--函数调用时,R0存放第一个参数 BX LR
(3)需要注意的是关中断/开中断是一个任务和一个中断服务程序共享变量或者数据结构的唯一方法
3.给调度器上锁/解锁
(1)给调度器上锁/解锁,可以防止两个以上的任务出现竞争。但如果没有关闭中断,一旦中断发生,即便在临界区内,中断服务程序也会立即执行。
(2)给调度器上锁使用OSSchedLock()函数实现,解锁使用OSSchedUnlock()函数实现,它们的定义位于os_core.c中。
// 调度器最多可以void OSSchedLock (OS_ERR *p_err) // 在os_core.c中 441行 - 448行{ CPU_SR_ALLOC(); // 宏,声明存储空间,用来存储当前CPU的中断状态#ifdef OS_SAFETY_CRITICAL // ??? if (p_err == (OS_ERR *)0) { OS_SAFETY_CRITICAL_EXCEPTION(); return; }#endif#if OS_CFG_CALLED_FROM_ISR_CHK_EN > 0u if (OSIntNestingCtr > (OS_NESTING_CTR)0) { // 不允许在ISR中调用 *p_err = OS_ERR_SCHED_LOCK_ISR; return; }#endif if (OSRunning != OS_STATE_OS_RUNNING) { // 确保操作是在运行状态 *p_err = OS_ERR_OS_NOT_RUNNING; return; } // OSSchedLockNestingCtr最大值为250,也就是说OSSchedLock()最多可以嵌套250次 if (OSSchedLockNestingCtr >= (OS_NESTING_CTR)250u) { // 预防OSSchedLockNestingCtr溢出 *p_err = OS_ERR_LOCK_NESTING_OVF; return; } CPU_CRITICAL_ENTER(); // 进入临界区 OSSchedLockNestingCtr++; // 嵌套层数加1#if OS_CFG_SCHED_LOCK_TIME_MEAS_EN > 0u // 允许测量调度器锁定时间 OS_SchedLockTimeMeasStart();#endif CPU_CRITICAL_EXIT(); // 退出临界区 *p_err = OS_ERR_NONE;}
void OSSchedUnlock (OS_ERR *p_err) // 在os_core.c中 472行 - 517行{ CPU_SR_ALLOC(); // 宏,声明存储空间,用来存储当前CPU的中断状态#ifdef OS_SAFETY_CRITICAL // ??? if (p_err == (OS_ERR *)0) { OS_SAFETY_CRITICAL_EXCEPTION(); return; }#endif#if OS_CFG_CALLED_FROM_ISR_CHK_EN > 0u if (OSIntNestingCtr > (OS_NESTING_CTR)0) { // 不允许在ISR中调用 *p_err = OS_ERR_SCHED_UNLOCK_ISR; return; }#endif if (OSRunning != OS_STATE_OS_RUNNING) { // 确保操作正在运行 *p_err = OS_ERR_OS_NOT_RUNNING; return; } if (OSSchedLockNestingCtr == (OS_NESTING_CTR)0) {// 查看调度器是否已锁定 *p_err = OS_ERR_SCHED_NOT_LOCKED; return; } CPU_CRITICAL_ENTER(); // 进入临界区 OSSchedLockNestingCtr--; // 嵌套层数减1 if (OSSchedLockNestingCtr > (OS_NESTING_CTR)0) { // 调度器仍然锁定 CPU_CRITICAL_EXIT(); // 退出临界区 *p_err = OS_ERR_SCHED_LOCKED; return; }#if OS_CFG_SCHED_LOCK_TIME_MEAS_EN > 0u // 允许测量任务调度的锁定时间 OS_SchedLockTimeMeasStop();#endif CPU_CRITICAL_EXIT(); // 退出临界区 OSSched(); // 执行任务调度 *p_err = OS_ERR_NONE;}
(3)在调度器上锁时,uC/OS-III会禁止用户进行阻塞调用。
4.信号量
(1)信号量通常分为两种:二进制信号量与计数型信号量。
(2)建议在使用信号量时,可以把信号量放入到函数中包起来。
(3)一般建议用信号量来访问IO设备,而不用它来访问存储单元;请求和释放信号量的过程是很费时的,因此在处理简单的、CPU能在很短时间内完成的操作时,使用关中断的方式更合理。
(4)信号量的数据结构类型为OS_SEM,它的定义位于os.h中。
typedef struct os_sem OS_SEM; // 631行struct os_sem { // 858行 - 869行 OS_OBJ_TYPE Type; // 类型 Semaphore */ CPU_CHAR *NamePtr; /* Should be set to OS_OBJ_TYPE_SEM */ OS_PEND_LIST PendList; /* Pointer to Semaphore Name (NUL terminated ASCII) */#if OS_CFG_DBG_EN > 0u OS_SEM *DbgPrevPtr; OS_SEM *DbgNextPtr; CPU_CHAR *DbgNamePtr;#endif OS_SEM_CTR Ctr; /* List of tasks waiting on event flag group */ CPU_TS TS;};
阅读全文
0 0
- uC/OS-III之资源管理
- uC/OS-III之资源管理--互斥型信号量
- uC/OS-III之信号量
- uC/OS-III之系统内部任务
- uC/OS-III之任务调度总结
- uC/OS-III之中断管理总结
- uC/OS-III之学习总结
- uC/OS-III之时钟节拍列表
- uC/OS-III之时间管理
- uC/OS-III之定时器管理
- uC/OS-III之任务挂起表
- uC/OS-III之任务同步
- uC/OS-III之任务信号量
- uC/OS-III之事件标志组
- uC/OS-III之消息传递
- uC/OS-III Note
- uc/os-iii学习笔记-资源管理(中断、信号、信号量、互斥信号量)
- uC/OS iii(三)任务管理之任务状态
- ISCC2017部分题目wp
- Emailcamel.com
- Android Studio一直Building的解决
- spark 2.1 ResultTask run process
- UML学习一
- uC/OS-III之资源管理
- Python中字典(dict)详解
- 前端JSZIP库的使用
- 第 17 章 MySQL错误代码和消息的使用
- Tensor Tensor
- Dapper,大规模分布式系统的跟踪系统
- a+b problem
- java 发送邮件
- Unity Editor VR告诉你,建立VR场景很简单