⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 os_semaphores.c

📁 一个简单易用的可裁减的小型实时操作系统 移植非常简单
💻 C
字号:
/*
 *******************************************************************************
 *
 * MicroROS
 *
 * Copyright (C) 2007 <amwox@163.com>			
 *
 * Description	: 信号量
 *
 * File			: os_semaphore.h
 * Author		: amwox
 * Edition		: V0.1
 * History		: 2007-10-29  created 
 *				  2008-01-28  增加事件列表指针,并对处理方式作了相应的变化
 *******************************************************************************
 */
#include "..\include\MicroROS.h"
#include "..\include\os_cpu.h"

#if SEMAPHORE_EN > 0

/* 
 * Description	: 创建信号量,并初始化其有cnt个资源
 * Arguments	: pSem		信号量指针
 *				  cnt		资源的个数
 * Returns		:
 */
void OS_SemaphoreCreate(pSEM pSem, WORD cnt)
{
#if EVENT_BLOCK_COUNT > 0
	pSem->BlockCnt = 0;									/*没有被阻塞的进程*/
#endif
	pSem->SemCnt = cnt;
	pSem->pSemList = NULL;
}

/* 
 * Description	: 从psem中获得cnt个资源,等待timeout个tick
 *				  该函数不能在中断和IDLE任务中运行
 * Arguments	: pSem
 *				  cnt		从psem中获得资源的个数
 *				  timeout	超时时间,0不等待,0xFFFF不限时等待
 * Returns		:
 */ 
BYTE OS_SemaphorePend(pSEM pSem, WORD cnt,WORD timeout)
{
	CPU_SREG cpu_sreg;
	
	OS_ENTER_CRITICAL();
	if (pSem->SemCnt >= cnt) {	/*在信号量中拥有足够的资源数*/
		pSem->SemCnt -= cnt;							/*拿走所需的资源*/
		OS_EXIT_CRITICAL();
		return NO_ERROR;
	}	
	BYTE err;
	pPID pPid;
    pPid = os_kernel.pRunning;
	_AppendEvent(&pSem->pSemList,pPid);
	pPid->TimerCnt = timeout;
	pPid->State |= BV(PID_SEMAPHARE);
#if EVENT_BLOCK_COUNT > 0
	pSem->BlockCnt ++;
#endif
	err = TIME_OUT;
	while (pPid->TimerCnt) {
		OS_TaskSuspend(pPid);
		if (pPid->TimerCnt != LIMITLESS) {
			_QueueTimer(pPid);
		}
		OS_EXIT_CRITICAL();
		_Schedule();
		OS_ENTER_CRITICAL();
		if (pSem->SemCnt >= cnt) { 
			pSem->SemCnt -= cnt;
			err = NO_ERROR;
			break;
		}
	}
#if EVENT_BLOCK_COUNT > 0
	pSem->BlockCnt --;
#endif
	_RemoveEvent(&pSem->pSemList,pPid);
	pPid->State &= ~BV(PID_SEMAPHARE);
	OS_EXIT_CRITICAL();
	return err;		 
} 

/* 
 * Description	: 释放cnt个资源到psem
 * Arguments	: pSem
 *				  cnt	释放的资源的个数
 * Returns		:
 */ 
void OS_SemaphorePost(pSEM pSem,WORD cnt)
{
	CPU_SREG cpu_sreg;

	OS_ENTER_CRITICAL();
	pSem->SemCnt += cnt;
	OS_EXIT_CRITICAL();
	if (pSem->pSemList == NULL) {						/*没有被阻塞的进程*/
		return;
	}
	_WakeupEvent(pSem->pSemList);
	_Schedule();										/*按新的排序,重新调度*/
}
#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -