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

📄 rtos_services.c

📁 嵌入式操作系统EOS(Embedded OperatingSystem)是一种用途广泛的系统软件
💻 C
📖 第 1 页 / 共 2 页
字号:
		case eTimerSuspended:
			return 0 ;

		default:
		{
		}
	}

	return 0 ;
}

static void s_update_timers()
{
	int8u 		l_timer ;
	timer_info *lp_timer ;

	// update user defined timers
	for (l_timer = 0; l_timer < s_number_of_timers ; l_timer++)
	{
		lp_timer = s_timers + l_timer ;

		if (s_updatable_timer(l_timer) )
		{
			switch (lp_timer->type)
			// WAR STORY
			// it is always good practice to place the most common cases at the beginning
			// of the switch block, due to performnce reasons (pipeline prefetch related issues...)
			{
				case eOneShotNonRelease:
                {
					if (--(lp_timer->deadline) == 0)
					{
						lp_timer->callback(lp_timer->parameter) ; // fire the callback
						
						// prevent continuous unnecessary updates (let 's_updatable_timer' filter 
						// out unnecessary timers)
						lp_timer->state = eTimerAllocated ;
					}
					break ;
                }

				case ePeriod:
				{					
					if (--(lp_timer->deadline) == 0)
					{
						lp_timer->callback(lp_timer->parameter) ; // fire the callback
						lp_timer->deadline = lp_timer->period ; // reload the l_timer
					}
					
					break ;
				}

				case eFlag:	// see also 'rtos_flag_timer_inform_in'.
				{
					// if the timer has already expired before this timer tick,
					// its 'too late' counter needs to be incremented
					if (lp_timer->deadline == 0)
					{
						// once the timer has expired, start counting 
						(*(lp_timer->missed_deadline_counter))++ ;
						lp_timer->state = eTimerNotAllocated ; // free this timer - it is done	
					}
					else
					{
						// the client module (timer owner) should
						// poll the timer until the pointed value (int32s*) that it passed
						// to EOS is not 0. once that occurs, that pointer to a positive 
						// value indicating how late the timer was polled in comparison 
						// with the original deadline.
						--lp_timer->deadline ;
					}

					break ;
				}
	
				case eOneShot:
				{
					if (--(lp_timer->deadline) == 0)
					{
						lp_timer->callback(lp_timer->parameter) ; // fire the callback
						lp_timer->state = eTimerNotAllocated ; // free this timer - it is done	
					}
					break ;
				}
			}
		}
	}
}

static void s_timer3_irq (void) interrupt 0x23
{
	g_tick_count++ ;
}

static void s_timer6_irq (void) interrupt 0x26
{
#ifdef _DEBUG  // a fix for saturation of timer interrupts on PC environment
	GPT12E_T6IC = 0 ;
#endif
	s_update_timers() ;
#ifdef _DEBUG
	GPT12E_T6IC = IC_IE(1) | IC_ILVL(7) | IC_GLVL(1) ; /* Timer 6 interrupt enabled, Level 7, Group 1 */
#endif
}

// setup GPT3, used for timing services
static void s_timer3_setup() 
{		  
#ifdef _DEBUG
  	GPT12E_T3CON = 0x0480 ;      // load timer 3 control register
  	GPT12E_T3 	 = 0x00F9 ;      // load timer 3 register
  	GPT12E_T2CON = 0x0027 ;      // load timer 2 control register
  	GPT12E_T2 	  = 0x0F9 ;      // load timer 2 register
#else
	///  - prescaler for timer block 1 is 8
  	///  -----------------------------------------------------------------------
  	///  Configuration of the GPT1 Core Timer 3:
  	///  -----------------------------------------------------------------------
  	///  - timer 3 works in timer mode
  	///  - external up/down control is disabled
  	///  - prescaler factor is 8
  	///  - up/down control bit is set
  	///  - alternate output function T3OUT (P3.3) is disabled
  	///  - timer 3 output toggle latch (T3OTL) is set to 0

  	// will generate an interrupt every 100[祍] at 40[MHz]
	GPT12E_T3CON   =  0x0080 ;      // load timer 3 control register
  	GPT12E_T3      =  0x01F3 ;      // load timer 3 register

  	///  -----------------------------------------------------------------------
  	///  Configuration of the GPT1 Auxiliary Timer 2:
  	///  -----------------------------------------------------------------------
  	///  - timer 2 works in reload mode
  	///  - external up/down control is disabled
  	///  - timer 2 is disabled
  	///  - timer 2 run bit is reset

	GPT12E_T2CON   =  0x0020 ;      // load timer 2 control register
  	GPT12E_T2      =  0x01F3 ;      // load timer 2 register

#endif
	GPT12E_T3IC  = IC_IE(1) | IC_ILVL(7) | IC_GLVL(2) ; /* Timer 3 interrupt enabled, Level 7, Group 1 */	
	GPT12E_T3CON_T3R   = 1 ; /* Start Timer */
}

static void s_timer6_setup()
{
	GPT12E_T6CON  =  0x8081 ;      // load timer 6 control register
#ifdef _DEBUG
  	GPT12E_T6     =  0x00F9 ;      // load timer 6 register
  	GPT12E_CAPREL =  0x00F9 ;      // load CAPREL register
#else
	///  -----------------------------------------------------------------------
  	///  Configuration of the GPT2 Core Timer 6:
  	///  -----------------------------------------------------------------------
  	///  - timer 6 works in timer mode
  	///  - prescaler factor is 4
  	///  - up/down control bit is set
  	///  - external up/down control is disabled
  	///  - alternate output function T6OUT (P3.1) is disabled
  	///  - timer 6 output toggle latch (T6OTL) is set to 0
  	///  - CAPREL is used as a reload register for the core timer T6
  	///  - timer 6 is not cleared on a capture

  	GPT12E_T6CON   =  0x8080;      // load timer 6 control register
  	GPT12E_T6      =  0x03E7;      // load timer 6 register

  	///  -----------------------------------------------------------------------
  	///  Configuration of the GPT2 CAPREL:
  	///  -----------------------------------------------------------------------
  	///  - capture T5 into CAPREL is disabled
  	///  - capture trigger from pin CAPIN
  	///  - capure is disabled
  	///  - timer 5 is not cleared on a capture
  	///  - timer 5 is just captured without any correction

  	GPT12E_CAPREL  =  0x03E7;      // load CAPREL register

#endif
	GPT12E_T6IC   =  IC_IE(1) | IC_ILVL(7) | IC_GLVL(1) ; /* Timer 6 interrupt enabled, Level 6, Group 2 */
	GPT12E_T6CON_T6R    =  1 ;           // timer 6 run bit is set
}

static int8u s_find_task(int16s id, int16s *index)
{
	int16s n ;
	task_info *lp_task ;

	for (n = 0; n < MAX_TASKS; n++)
	{
		lp_task = g_tcb + n ;

		if ( (lp_task->id == id) && (lp_task->status != eTaskNotAllocated) )
		{
			*index = n ;
			return 1 ;
		}
	}

	return 0 ;
}

static int16s s_find_next_available_task_index()
{
	int16s		l_task ;
	task_info 	*lp_task ;

	for (l_task = 0; l_task < MAX_TASKS; l_task++)
	{
		lp_task = g_tcb + l_task ;

		if (lp_task->status == eTaskNotAllocated)
		{
			return l_task ;
		}
	}

	return ERR_MAX_TASKS_ALLOCATED ;
}

static int8u s_find_timer(int16s a_id, int16u *ap_index)
{
	int16u 		l_timer ;
	timer_info *lp_timer ;

	for (l_timer = 0; l_timer < MAX_TIMERS; l_timer++)
	{
		lp_timer = s_timers + l_timer ;

		if ( (lp_timer->id == a_id) && (lp_timer->state != eTimerNotAllocated) )
		{
			*ap_index = l_timer ;

			return 1 ;
		}
	}

	return 0 ;
}

// this callback is invoked is a timeout waiting for a message has elapsed. see 'rtos_msg_wait'.
static void s_task_wait_msg_timer_expired(int32s a_param)
{
	int16s 		l_index, l_result ;
	task_info 	*lp_task ;

	if ( !s_find_task( (int16s)a_param, &l_index))
	{
		software_error("%s %s %d", resolve_system_message(ERR_TASK_NOT_FOUND), __FILE__, __LINE__ ) ;
	}

    // WAR STORY
    // the test whether the task's status is indeed 'eTaskWaitingForMessage' is needed due to the scenario
    // described in the following timing diagram:
    // 
    //         wait for message     timeout
    // task1 ----|

⌨️ 快捷键说明

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