资讯详情

嵌入式实时操作系统10——系统时钟节拍

1.什么是系统节拍?

时间管理在操作系统内核中起着非常重要的作用,操作系统内核具有大量的时间驱动功能。有些任务需要周期执行。例如,软件定时器每秒需要周期运行100次;有些功能任务在运行前需要延迟一段时间。例如,传感器读取操作需要延迟2万次ms;例如,操作系统内核还需要计算运行时间,统计不同任务的运行时间和处理器的使用情况。

大多数操作系统的核心需要一个周期性的时钟源,这个时钟源被称为。为了生成时钟节拍,通常需要使用硬件定时器,配置硬件定时器产生10个频率~1000Hz当时钟中断发生时,中断服务程序调用操作系统中的一个特殊程序:

。时钟节拍中断不一定是硬件定时器产生的,也可以是其他周期性时钟来源,比如50频率的电力系统Hz的时钟源。 请添加图片描述 系统时钟节拍可设置为10Hz,也可设置为100000Hz。时钟节拍值越大,硬件定时器中断越频繁,系统时钟节拍服务执行越频繁。

1、提高操作系统内核时间管理精度 2.提高任务抢占的准确性

比如10Hz时钟节拍的执行粒度为100ms,系统中最快的周期性事件是100ms一次,精度更高是不可能的。例如,1万Hz此时,时钟节拍的执行粒度增加了100倍,系统中的周期性事件最快为1ms一次,时间精度可达1ms。

时钟节拍越高,意味着时钟中断越频繁,处理器需要花时间执行中断程序,如果时钟节拍大到一定程度比如1MHz,此时,处理器将始终定期执行时钟中断程序,用户程序几乎无法执行。

2.实现系统时钟节拍服务

实现系统时钟节拍取决于以下两部分:

硬件定时器 2.系统时钟节拍服务

硬件定时器用于中断,硬件定时器的配置频率为10~1000Hz当定时器中断发生时,硬件定时器定期触发中断。

系统时钟节拍服务用于执行系统时间管理相关操作,定时器中断程序调用系统时钟节拍服务。系统时钟节拍服务完成以下操作: 每次定时器中断调用系统时钟节拍服务时,完成系统节拍时间更新,增加系统节拍时间计值1。通常,系统节拍时间计值为32位变量,时间计值需要考虑溢出值。

每次进入系统时钟节拍服务更新系统节拍时间后,操作系统内核检查等待表是否有任务完成等待。如果有任务完成等待,操作系统内核将从等待表中删除任务,并将任务添加到就绪表中,完成等待表和就绪表的更新。

每次进入系统时钟节拍服务,操作系统内核都会检查进行时间片轮询操作。

每次进入系统时钟节拍服务等待表和就绪表更新后,如果有更高的优先任务就绪,操作系统核心将启动任务切换。

3.FreeRTOS实现系统时钟节拍

分析对象为:cortex-m4硬件平台,FreeRTOS操作系统。 实现系统时钟节拍依靠实现cortex-m4中的SysTick硬件定时器产生时钟中断,时钟中断服务为:

SysTick_Handler

FreeRTOS操作系统中的系统时钟节拍服务是

xTaskIncrementTick

/*配置定时器 1ms中断 */ HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/8000); HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK_DIV8); 

#define xPortSysTickHandler SysTick_Handler  void xPortSysTickHandler( void )  { 
           /* 屏蔽相关中断 */   vPortRaiseBASEPRI();   { 
            /* 调用系统时钟节拍服务 */    if( xTaskIncrementTick() != pdFALSE )    { 
             /* 如果高任务就绪,切换任务*/     portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT;
			}
		}
		/* 开启相关中断 */
		vPortClearBASEPRIFromISR();
	}

BaseType_t xTaskIncrementTick( void )
{ 
        
	TCB_t * pxTCB;
	TickType_t xItemValue;
	BaseType_t xSwitchRequired = pdFALSE;

	traceTASK_INCREMENT_TICK( xTickCount );
	/* 调度器是否打开 */
	if( uxSchedulerSuspended == ( UBaseType_t ) pdFALSE )
	{ 
        
		/* 系统节拍计数器xTickCount 镜像 */
		const TickType_t xConstTickCount = xTickCount + ( TickType_t ) 1;
		/* 系统节拍计数器xTickCount 加1*/
		xTickCount = xConstTickCount;
		/* 系统节拍计数器xTickCount 是否溢出*/
		if( xConstTickCount == ( TickType_t ) 0U ) 
		{ 
        
			taskSWITCH_DELAYED_LISTS();
		}
		else
		{ 
        
			mtCOVERAGE_TEST_MARKER();
		}

		if( xConstTickCount >= xNextTaskUnblockTime )
		{ 
        
			
			for( ;; )/* 将完成延时等待的相关任务移除等待表 */
			{ 
        
				/* 等待表是否为空*/
				if( listLIST_IS_EMPTY( pxDelayedTaskList ) != pdFALSE )
				{ 
        
					/* 等待表为空 则将xNextTaskUnblockTime赋值成最大值 */
					xNextTaskUnblockTime = portMAX_DELAY; 
					break;
				}
				else/* 等待表不为空*/
				{ 
        					
					/*读取等待表中的第一个任务对象 等待表队列时按照等待时间大小进行排序,等待表队列的第一个对象就是最小等待时间对象 */
					pxTCB = listGET_OWNER_OF_HEAD_ENTRY( pxDelayedTaskList );
					/* 读取任务的延时完成时间 */
					xItemValue = listGET_LIST_ITEM_VALUE( &( pxTCB->xStateListItem ) );
					/* 比较延时完成时间和当前时间 */
					if( xConstTickCount < xItemValue )
					{ 
        
						/* 比较延时完成时间未到 退出for循环 */
						xNextTaskUnblockTime = xItemValue;
						break;
					}
					else
					{ 
        
						mtCOVERAGE_TEST_MARKER();
					}

					/* 将任务从等待表中移除*/
					( void ) uxListRemove( &( pxTCB->xStateListItem ) );

					/* 将任务从等待事情的挂起表中移除*/
					if( listLIST_ITEM_CONTAINER( &( pxTCB->xEventListItem ) ) != NULL )
					{ 
        
						( void ) uxListRemove( &( pxTCB->xEventListItem ) );
					}
					else
					{ 
        
						mtCOVERAGE_TEST_MARKER();
					}

					/* 将任务添加到就绪表中*/
					prvAddTaskToReadyList( pxTCB );

					#if ( configUSE_PREEMPTION == 1 )
					{ 
        
						/* 如果等待中的任务的优先级高于当前任务 触发任务切换*/
						if( pxTCB->uxPriority >= pxCurrentTCB->uxPriority )
						{ 
        
							xSwitchRequired = pdTRUE;/* 设置任务切换标志 */
						}
						else
						{ 
        
							mtCOVERAGE_TEST_MARKER();
						}
					}
					#endif 
				}
			}
		}

		/* 任务时间片轮询功能 */
		#if ( ( configUSE_PREEMPTION == 1 ) && ( configUSE_TIME_SLICING == 1 ) )
		{ 
        
			/* 每次节拍进行一次当前优先级任务轮询操作 当前优先级下任务数量大于1时执行轮询操作 */
			if( listCURRENT_LIST_LENGTH( &( pxReadyTasksLists[ pxCurrentTCB->uxPriority ] ) ) > ( UBaseType_t ) 1 )
			{ 
        
				xSwitchRequired = pdTRUE;/* 设置任务切换标志 */
			}
			else
			{ 
        
				mtCOVERAGE_TEST_MARKER();
			}
		}
		#endif 

		#if ( configUSE_TICK_HOOK == 1 )
		{ 
        
			/* tick 钩子函数 */
			if( uxPendedTicks == ( UBaseType_t ) 0U )
			{ 
        
				vApplicationTickHook();
			}
			else
			{ 
        
				mtCOVERAGE_TEST_MARKER();
			}
		}
		#endif 
	}
	else
	{ 
        
		++uxPendedTicks;

		/* tick 钩子函数 */
		#if ( configUSE_TICK_HOOK == 1 )
		{ 
        
			vApplicationTickHook();
		}
		#endif
	}

	#if ( configUSE_PREEMPTION == 1 )
	{ 
        
		if( xYieldPending != pdFALSE )
		{ 
        
			xSwitchRequired = pdTRUE;
		}
		else
		{ 
        
			mtCOVERAGE_TEST_MARKER();
		}
	}
	#endif 

	return xSwitchRequired;
}

标签: 传感器tcb

锐单商城拥有海量元器件数据手册IC替代型号,打造 电子元器件IC百科大全!

锐单商城 - 一站式电子元器件采购平台