RT-Thread物联网操作系统介绍:11.1、多值信号量(优先级翻转)

本文探讨了在RTOS(实时操作系统)环境中,当高优先级任务阻塞时,中优先级任务是否优先执行的问题。通过实例展示了如何使用多值信号量实现代理优先级,揭示了优先级翻转现象,并以RT-Thread为例,详细介绍了创建线程和信号量的操作。
摘要由CSDN通过智能技术生成

程序运行,创建一个LED任务(中优先级),2个任务TASK1(低优先级)和TASK2(高优先级),
LED任务每隔1S翻转D3彩灯的红色指示, 通过usb串口输出观察任务运行情况,看看在高优先级任务阻塞的情况下,
中优先级任务会不会优先运行(发生优先级翻转),多值信号量,发现是会发生翻转的,串口波特率115200

主要问题:高优先级任务在阻塞下,中优先级任务会运行,发生优先级的翻转
工程参考例程在:
RT-Thread物联网操作系统介绍

/* 创建一个信号量 */
	Sample_sem = rt_sem_create("Sample_sem", /* 信号量名字 */
                  1,                   /* 信号量初始值,默认有一个信号量 */
                  RT_IPC_FLAG_FIFO);   /* 信号量模式 FIFO(0x00)*/

 rt_sem_take(Sample_sem,	            /* 获取信号量 */
                  RT_WAITING_FOREVER); 	/* 等待时间:一直等 */  
        printf("Task1 Pend Mutex OK\r\n");        
#include "MyIncludes.h"

static rt_sem_t Sample_sem = RT_NULL;   /* 信号量控制块 */
static rt_thread_t TASK1_Thread = RT_NULL;
/*******************************************************************************
* Function Name  : TASK1_Thread_Process
* Description    : 任务1线程函数
* Input          : None
* Output         : None
* Return         : None
* Note			 : None
*******************************************************************************/
static void TASK1_Thread_Process(void* parameter)
{	
    u32 times;
    while(1)
    {				
		rt_sem_take(Sample_sem,	            /* 获取信号量 */
                  RT_WAITING_FOREVER); 	/* 等待时间:一直等 */  
        printf("Task1 Pend Mutex OK\r\n");        
        //使低优先级任务占用信号量一段时间
        for(times = 0; times < 2000000; times++) 
        {     
            rt_thread_yield();   //主动发起调度
        }
		printf("Task1 Post Mutex!\r\n");
		rt_sem_release(Sample_sem);	    /* 释放二值信号量 */		
		rt_thread_delay(1000);  				  /* 每1s读一次 */			
  }
}

static rt_thread_t TASK2_Thread = RT_NULL;
/*******************************************************************************
* Function Name  : TASK2_Thread_Process
* Description    : 任务2线程函数
* Input          : None
* Output         : None
* Return         : None
* Note			 : None
*******************************************************************************/
static void TASK2_Thread_Process(void* parameter)
{	
    while(1)
	{
        printf("Task2 Pend Mutex...\r\n");
		rt_sem_take(Sample_sem,	            /* 获取信号量 */
                  RT_WAITING_FOREVER); 	/* 等待时间:一直等 */		

        printf("Task2 Pend Mutex OK\r\n");
		printf("Task2 Post Mutex!\r\n");
		rt_sem_release(Sample_sem);	    /* 释放二值信号量 */
		
        rt_thread_delay(1000);	
	}
}

static rt_thread_t LED_Thread = RT_NULL;
/*******************************************************************************
* Function Name  : LED_Thread_Process
* Description    : LED线程函数
* Input          : None
* Output         : None
* Return         : None
* Note			 : None
*******************************************************************************/
static void LED_Thread_Process(void* parameter)
{	
    while (1)
    {
        LED_Toggle(LED_R);       //翻转LED
        printf("LED Run!\r\n");
        rt_thread_delay(1000);                  /* 延时1000个tick,即1000毫秒 */		 		
    }
}

int main(void)
{
    /* 创建一个信号量 */
	Sample_sem = rt_sem_create("Sample_sem",         /* 信号量名字 */
                                1,                   /* 信号量初始值,默认有一个信号量 */
                                RT_IPC_FLAG_FIFO);   /* 信号量模式 FIFO(0x00)*/
    if (Sample_sem != RT_NULL)
        rt_kprintf("信号量创建成功!\n\n"); 
        
    //TASK1线程,优先级最小
	TASK1_Thread =                        /* 线程控制块指针 */
	rt_thread_create("TASK1",             /* 线程名字 */
                    TASK1_Thread_Process, /* 线程入口函数 */
                    RT_NULL,             /* 线程入口函数参数 */
                    512,                 /* 线程栈大小 */
                    11,                   /* 线程的优先级 */
                    20);                 /* 线程时间片 */
								 
	/* 启动线程,开启调度 */
    if (TASK1_Thread != RT_NULL)
        rt_thread_startup(TASK1_Thread);
    else		
        return -1;
    
    //TASK2线程,优先级最大
    TASK2_Thread =                        /* 线程控制块指针 */
	rt_thread_create("TASK2",             /* 线程名字 */
                    TASK2_Thread_Process, /* 线程入口函数 */
                    RT_NULL,             /* 线程入口函数参数 */
                    512,                 /* 线程栈大小 */
                    9,                   /* 线程的优先级 */
                    20);                 /* 线程时间片 */
								 
	/* 启动线程,开启调度 */
    if (TASK2_Thread != RT_NULL)
        rt_thread_startup(TASK2_Thread);
    else		
        return -1;
    
     //LED线程,优先级中等
	LED_Thread =                        /* 线程控制块指针 */
	rt_thread_create("LED",             /* 线程名字 */
                    LED_Thread_Process, /* 线程入口函数 */
                    RT_NULL,             /* 线程入口函数参数 */
                    512,                 /* 线程栈大小 */
                    10,                   /* 线程的优先级 */
                    20);                 /* 线程时间片 */
								 
	/* 启动线程,开启调度 */
    if (LED_Thread != RT_NULL)
        rt_thread_startup(LED_Thread);
    else		
        return -1;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值