Freertos(Free Real-Time Operating System)是一款开源的实时操作系统,可在嵌入式系统中使用。在使用Freertos时,尤为需要注意其临界段保护机制,以确保数据在多任务并发执行时的正确性。下面将详细讲解如何开启临界段保护、如何开关中断、以及进入和退出临界段的方法。
一、开启临界段保护
在单核处理器中,开启临界段保护需要关闭中断,以免在关键时刻被打断。在FreeRTOS中,可以通过以下代码段来开启临界段保护:
taskENTER_CRITICAL( );
// 访问保护数据
taskEXIT_CRITICAL( );
taskENTER_CRITICAL()
函数将禁用所有可中断的中断源,并记录当前中断计数器(在多核处理器中有所不同,并不能完全禁用中断)。在taskENTER_CRITICAL()
函数之后和taskEXIT_CRITICAL()
函数之前,所有可中断的中断源均会被禁用。同时,这两个函数是可嵌套的,即可以多次调用,但需要满足进入与退出次数的匹配关系,即进入与退出的次数必须一致。
临界段保护的开启可以帮助对共享数据进行正确而安全的访问。
二、开关中断
在开启临界段保护之前,我们需要关闭中断,避免在关键时刻被打断。而在任务执行完毕,退出临界段时,需要重新开启中断,使其他任务可以正常执行。在FreeRTOS中,我们可以通过以下代码段开关中断:
portDISABLE_INTERRUPTS( ); // 关闭中断
// 访问保护数据
portENABLE_INTERRUPTS( ); // 重新开启中断
其中,portDISABLE_INTERRUPTS()
函数用于禁用中断,portENABLE_INTERRUPTS()
函数用于重新开启中断。需要注意的是,在调用portDISABLE_INTERRUPTS()
函数禁用中断后,一定要严格遵守上述说明,在临界段结束之前一定要调用portENABLE_INTERRUPTS()
函数重新开启中断,否则会导致系统中断无效甚至死机等问题。
三、进入和退出临界段
在任务执行过程中,我们需要进入和退出临界段,以确保对共享数据的访问是正确和安全的。在进入临界段时,通过禁止中断、调用taskENTER_CRITICAL()
函数获取系统锁和记录进入次数等方式保证了访问共享数据的独占性。而在任务执行完毕退出临界段时,同样需要释放系统锁、解除对共享数据的访问限制,重新开启中断等操作。下面通过两个示例来详细说明。
示例一:
uint32_t shared_data; // 定义全局共享变量
void task1( void *pvParameters )
{
while(1)
{
vTaskDelay(500); // 延时500毫秒
taskENTER_CRITICAL( ); // 进入临界段
shared_data = 1; // 访问共享变量
taskEXIT_CRITICAL( ); // 退出临界段
}
}
void task2( void *pvParameters )
{
while(1)
{
vTaskDelay(1000); // 延时1000毫秒
taskENTER_CRITICAL( ); // 进入临界段
shared_data = 2; // 访问共享变量
taskEXIT_CRITICAL( ); // 退出临界段
}
}
这个例子中,shared_data
是两个任务都要使用的共享变量。在两个任务中,通过vTaskDelay()
函数进行延时操作,以模拟实际场景中的任务间隙。进入和退出临界段时,分别使用taskENTER_CRITICAL()
和taskEXIT_CRITICAL()
函数。
示例二:
uint32_t shared_data; // 定义全局共享变量
void task1( void *pvParameters )
{
while(1)
{
vTaskDelay(50); // 延时50毫秒
portDISABLE_INTERRUPTS(); // 关闭所有中断
shared_data += 1; // 访问共享变量
portENABLE_INTERRUPTS(); // 重新开启所有中断
}
}
void task2( void *pvParameters )
{
while(1)
{
vTaskDelay(100); // 延时100毫秒
portDISABLE_INTERRUPTS(); // 关闭所有中断
shared_data += 2; // 访问共享变量
portENABLE_INTERRUPTS(); // 重新开启所有中断
}
}
这个例子中,shared_data
同样是两个任务都要使用的共享变量。在两个任务中,通过vTaskDelay()
函数进行延时操作,以模拟实际场景中的任务间隙。在访问shared_data
前,分别使用portDISABLE_INTERRUPTS()
函数和portENABLE_INTERRUPTS()
函数关闭和开启所有中断。同时,使用这种方法进入和退出临界段时并不需要使用taskENTER_CRITICAL()
以及taskEXIT_CRITICAL()
函数,而是通过开关中断的方式实现。
以上就是使用FreeRTOS时开启临界段保护、开关中断以及进入和退出临界段的详细攻略。在设计多任务嵌入式系统时,建议对共享数据进行特别关注和保护,确保多任务并发执行的安全和正确性。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:freertos实时操作系统临界段保护开关中断及进入退出 - Python技术站