FreeRTOS标准库例程代码

news2025/2/24 19:29:42

1.设备STM32F103C8T6

2.工程模板

单片机: 部分单片机的程序例程 - Gitee.comicon-default.png?t=N7T8https://gitee.com/lovefoolnotme/singlechip/tree/master/STM32_FREERTOS/1.%E5%B7%A5%E7%A8%8B%E6%A8%A1%E6%9D%BF

3.代码

1-FreeRTOS移植模板

#include "system.h"
#include "SysTick.h"
#include "led.h"
#include "usart.h"
#include "FreeRTOS.h"
#include "task.h"

//任务优先级
#define START_TASK_PRIO		1
//任务堆栈大小	
#define START_STK_SIZE 		128  
//任务句柄
TaskHandle_t StartTask_Handler;
//任务函数
void start_task(void *pvParameters);

//任务优先级
#define LED1_TASK_PRIO		2
//任务堆栈大小	(单位字)
#define LED1_STK_SIZE 		50  
//任务句柄
TaskHandle_t LED1Task_Handler;
//任务函数
void led1_task(void *pvParameters);


/*******************************************************************************
* 函 数 名         : main
* 函数功能		   : 主函数
* 输    入         : 无
* 输    出         : 无
*******************************************************************************/
int main()
{
	SysTick_Init(72);
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);//设置系统中断优先级分组4
	LED_Init();
	USART1_Init(115200);
	
	//创建开始任务
    xTaskCreate((TaskFunction_t )start_task,            //任务函数
                (const char*    )"start_task",          //任务名称
                (uint16_t       )START_STK_SIZE,        //任务堆栈大小
                (void*          )NULL,                  //传递给任务函数的参数
                (UBaseType_t    )START_TASK_PRIO,       //任务优先级
                (TaskHandle_t*  )&StartTask_Handler);   //任务句柄              
    vTaskStartScheduler();          //开启任务调度
}

//开始任务任务函数
void start_task(void *pvParameters)
{
    taskENTER_CRITICAL();           //进入临界区
      
    //创建LED1任务
    xTaskCreate((TaskFunction_t )led1_task,     
                (const char*    )"led1_task",   
                (uint16_t       )LED1_STK_SIZE, 
                (void*          )NULL,
                (UBaseType_t    )LED1_TASK_PRIO,
                (TaskHandle_t*  )&LED1Task_Handler); 
				
    vTaskDelete(StartTask_Handler); //删除开始任务
    taskEXIT_CRITICAL();            //退出临界区
} 

//LED1任务函数
void led1_task(void *pvParameters)
{
    while(1)
    {
        LED1=!LED1;
			  LED2=!LED2;
			  LED3=!LED3;
			  LED4=!LED4;
        vTaskDelay(500);
    }
}

2-FreeRTOS任务挂起实验

#include "system.h"
#include "SysTick.h"
#include "led.h"
#include "key.h"
#include "usart.h"
#include "FreeRTOS.h"
#include "task.h"

//任务优先级
#define START_TASK_PRIO		1
//任务堆栈大小	
#define START_STK_SIZE 		128  
//任务句柄
TaskHandle_t StartTask_Handler;
//任务函数
void start_task(void *pvParameters);
/****************************************************************/
//任务优先级
#define LED1_TASK_PRIO		2
//任务堆栈大小	(单位字)
#define LED1_STK_SIZE 		50  
//任务句柄
TaskHandle_t LED1Task_Handler;
//任务函数
void led1_task(void *pvParameters);
/****************************************************************/
//任务优先级
#define LED2_TASK_PRIO		3
//任务堆栈大小	(单位字)
#define LED2_STK_SIZE 		50  
//任务句柄
TaskHandle_t LED2Task_Handler;
//任务函数
void led2_task(void *pvParameters);

//任务优先级
#define KEY_TASK_PRIO		4
//任务堆栈大小	(单位字)
#define KEY_STK_SIZE 		50  
//任务句柄
TaskHandle_t KEYTask_Handler;
//任务函数
void key_task(void *pvParameters);


/*******************************************************************************
* 函 数 名         : main
* 函数功能		   : 主函数
* 输    入         : 无
* 输    出         : 无
*******************************************************************************/
int main()
{
	SysTick_Init(72);
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);//设置系统中断优先级分组4
	LED_Init();
	KEY_Init();
	USART1_Init(115200);
	
	//创建开始任务
    xTaskCreate((TaskFunction_t )start_task,            //任务函数
                (const char*    )"start_task",          //任务名称
                (uint16_t       )START_STK_SIZE,        //任务堆栈大小
                (void*          )NULL,                  //传递给任务函数的参数
                (UBaseType_t    )START_TASK_PRIO,       //任务优先级
                (TaskHandle_t*  )&StartTask_Handler);   //任务句柄              
    vTaskStartScheduler();          //开启任务调度
}

//开始任务任务函数
void start_task(void *pvParameters)
{
    taskENTER_CRITICAL();           //进入临界区
      
    //创建LED1任务
    xTaskCreate((TaskFunction_t )led1_task,     
                (const char*    )"led1_task",   
                (uint16_t       )LED1_STK_SIZE, 
                (void*          )NULL,
                (UBaseType_t    )LED1_TASK_PRIO,
                (TaskHandle_t*  )&LED1Task_Handler); 
								
		//创建LED2任务
    xTaskCreate((TaskFunction_t )led2_task,     
                (const char*    )"led2_task",   
                (uint16_t       )LED2_STK_SIZE, 
                (void*          )NULL,
                (UBaseType_t    )LED2_TASK_PRIO,
                (TaskHandle_t*  )&LED2Task_Handler); 
								
		//创建KEY任务
    xTaskCreate((TaskFunction_t )key_task,     
                (const char*    )"key_task",   
                (uint16_t       )KEY_STK_SIZE, 
                (void*          )NULL,
                (UBaseType_t    )KEY_TASK_PRIO,
                (TaskHandle_t*  )&KEYTask_Handler);
				
    vTaskDelete(StartTask_Handler); //删除开始任务
    taskEXIT_CRITICAL();            //退出临界区
} 

//LED1任务函数
void led1_task(void *pvParameters)
{
    while(1)
    {
        LED1=!LED1;
        vTaskDelay(500);
    }
}

//LED1任务函数
void led2_task(void *pvParameters)
{
    while(1)
    {
			  LED2=!LED2;
        vTaskDelay(500);
    }
}

//LED1任务函数
void key_task(void *pvParameters)
{
    while(1)
    {
     if(KEY==1) vTaskSuspend(LED2Task_Handler); 
			else vTaskResume(LED2Task_Handler);
			vTaskDelay(100);
    }
}

3-FreeRTOS消息队列实验

/******************************2023年10月14日*************************************
此为一个消息队列实验,主要使用使用按键、OLED屏幕来观察现象。
主要创建两个任务一个接收,一个发送
发送不等待,但是需要按键触发
接收是一直等待,直到接收到队列里面的消息,使用本次实验中的函数接收数据后会删除队列中的数据
宏定义队列长度和单个消息大小都为4
需定义队列句柄
*********************************************************************************/
#include "system.h"
#include "SysTick.h"
#include "led.h"
#include "key.h"
#include "oled.h"
#include "usart.h"
#include "FreeRTOS.h"
#include "task.h"
#include "queue.h"
//任务优先级
#define START_TASK_PRIO		1
//任务堆栈大小	
#define START_STK_SIZE 		128  
//任务句柄
TaskHandle_t StartTask_Handler;
//任务函数
void start_task(void *pvParameters);

//任务优先级
#define LED1_TASK_PRIO		2
//任务堆栈大小	(单位字)
#define LED1_STK_SIZE 		50  
//任务句柄
TaskHandle_t LED1Task_Handler;
//任务函数
void led1_task(void *pvParameters);
/*******************************************************************************/
//任务优先级
#define SEND_TASK_PRIO		3
//任务堆栈大小	
#define SEND_STK_SIZE 		50  
//任务句柄
TaskHandle_t SendTask_Handler;
//任务函数
void send_task(void *pvParameters);
/*******************************************************************************/
//任务优先级
#define RECEIVE_TASK_PRIO		4
//任务堆栈大小	
#define RECEIVE_STK_SIZE 		50  
//任务句柄
TaskHandle_t ReceiveTask_Handler;
//任务函数
void receive_task(void *pvParameters);


QueueHandle_t Test_Queue =NULL;    //句柄
#define  QUEUE_LEN    4            // 队列的长度,最大可包含多少个消息 */
#define  QUEUE_SIZE   4            // 队列中每个消息大小(字节) */

/*******************************************************************************
* 函 数 名         : main
* 函数功能		   : 主函数
* 输    入         : 无
* 输    出         : 无
*******************************************************************************/
int main()
{
	SysTick_Init(72);
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);//设置系统中断优先级分组4
	USART1_Init(115200);
	KEY_Init();
	LED_Init();
	OLED_Init();
	OLED_ColorTurn(0);//0正常显示,1 反色显示             
  OLED_DisplayTurn(0);
	OLED_Clear();
	//创建开始任务
    xTaskCreate((TaskFunction_t )start_task,            //任务函数
                (const char*    )"start_task",          //任务名称
                (uint16_t       )START_STK_SIZE,        //任务堆栈大小
                (void*          )NULL,                  //传递给任务函数的参数
                (UBaseType_t    )START_TASK_PRIO,       //任务优先级
                (TaskHandle_t*  )&StartTask_Handler);   //任务句柄              
    vTaskStartScheduler();          //开启任务调度
}

//开始任务任务函数
void start_task(void *pvParameters)
{
    taskENTER_CRITICAL();           //进入临界区
    
	  /* 创建Test_Queue */
	  Test_Queue = xQueueCreate((UBaseType_t ) QUEUE_LEN,/* 消息队列的长度 */
                             (UBaseType_t ) QUEUE_SIZE);/* 消息的大小 */
	  
    //创建LED1任务
    xTaskCreate((TaskFunction_t )led1_task,     
                (const char*    )"led1_task",   
                (uint16_t       )LED1_STK_SIZE, 
                (void*          )NULL,
                (UBaseType_t    )LED1_TASK_PRIO,
                (TaskHandle_t*  )&LED1Task_Handler); 						
		
		
		//创建接收任务
    xTaskCreate((TaskFunction_t )receive_task,     
                (const char*    )"receive_task",   
                (uint16_t       )RECEIVE_STK_SIZE, 
                (void*          )NULL,
                (UBaseType_t    )RECEIVE_TASK_PRIO,
                (TaskHandle_t*  )&ReceiveTask_Handler);

	//创建发送任务
    xTaskCreate((TaskFunction_t )send_task,     
                (const char*    )"send_task",   
                (uint16_t       )SEND_STK_SIZE, 
                (void*          )NULL,
                (UBaseType_t    )SEND_TASK_PRIO,
                (TaskHandle_t*  )&SendTask_Handler);
								
    vTaskDelete(StartTask_Handler); //删除开始任务
    taskEXIT_CRITICAL();            //退出临界区
} 

//LED1任务函数
void led1_task(void *pvParameters)
{
    while(1)
    {
        LED1=!LED1;
			  LED2=!LED2;
			  LED3=!LED3;
			  LED4=!LED4;
        vTaskDelay(500);
    }
}


void send_task(void *pvParameters)
{   
	
	BaseType_t xReturn = pdPASS;/* 定义一个创建信息返回值,默认为pdPASS */
	static uint32_t send_data1 = 1;
    while(1)
    {
     if(KEY==1) 
		{
		xReturn = xQueueSend( Test_Queue, /* 消息队列的句柄 */
								&send_data1,/* 发送的消息内容 */
								0 );        /* 等待时间 0 */ 
		if(xReturn==pdPASS)
		{
		 OLED_ShowString(3,0,"ok",8,1);                      //按下显示"ok"
		 OLED_ShowNum(3,20,send_data1,2,8,1);
		 OLED_Refresh();
		 send_data1+=1;         //递增
		}
		}
		else {OLED_ShowString(3,0,"no",8,1);OLED_ShowString(3,40,"   ",8,1);OLED_Refresh();} //没按下时显示"no"
		vTaskDelay(100);
    }
}

//接收任务函数
void receive_task(void *pvParameters)
{
  BaseType_t xReturn = pdTRUE;/* 定义一个创建信息返回值,默认为pdTRUE */
	uint32_t r_queue;	/* 定义一个接收消息的变量 */
	
	while(1)
    {
        xReturn = xQueueReceive( Test_Queue,    /* 消息队列的句柄 */
								&r_queue,      /* 发送的消息内容 */
								portMAX_DELAY); /* 等待时间 一直等(等不到则下面的程序不执行)  ,为0则不等*/   
	
		if(pdTRUE == xReturn)    //接收成功
		{
			OLED_ShowString(3,40,"get",8,1);
		  OLED_Refresh();
		}
	  else                     //接收失败
		{
			OLED_ShowString(3,40,"fal",8,1);
		  OLED_Refresh();
		}
		
		vTaskDelay(100);
    }
}

4-FreeRTOS二值信号量实验

/******************************2023年10月15日*************************************
此为一个二值信号量实验,主要使用使用按键、OLED屏幕来观察现象。
主要创建两个任务一个接收,一个发送
二值信号量,需要按键触发,按下按键则send任务释放二值信号量、LED4翻转;receive获取二值信号量、LED3翻转
receive任务是一直等待,只要send任务释放则receive获取二值信号量。
需定义二值信号量句柄
*********************************************************************************/
#include "system.h"
#include "SysTick.h"
#include "led.h"
#include "key.h"
#include "oled.h"
#include "usart.h"
#include "FreeRTOS.h"
#include "task.h"
#include "queue.h"
#include "semphr.h"

//任务优先级
#define START_TASK_PRIO		1
//任务堆栈大小	
#define START_STK_SIZE 		128  
//任务句柄
TaskHandle_t StartTask_Handler;
//任务函数
void start_task(void *pvParameters);

//任务优先级
#define LED1_TASK_PRIO		2
//任务堆栈大小	(单位字)
#define LED1_STK_SIZE 		50  
//任务句柄
TaskHandle_t LED1Task_Handler;
//任务函数
void led1_task(void *pvParameters);
/*******************************************************************************/
//任务优先级
#define SEND_TASK_PRIO		3
//任务堆栈大小	
#define SEND_STK_SIZE 		50  
//任务句柄
TaskHandle_t SendTask_Handler;
//任务函数
void send_task(void *pvParameters);
/*******************************************************************************/
//任务优先级
#define RECEIVE_TASK_PRIO		4
//任务堆栈大小	
#define RECEIVE_STK_SIZE 		50  
//任务句柄
TaskHandle_t ReceiveTask_Handler;
//任务函数
void receive_task(void *pvParameters);

//创建句柄
SemaphoreHandle_t BinarySem_Handle =NULL;

/*******************************************************************************
* 函 数 名         : main
* 函数功能		   : 主函数
* 输    入         : 无
* 输    出         : 无
*******************************************************************************/
int main()
{
	SysTick_Init(72);
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);//设置系统中断优先级分组4
	USART1_Init(115200);
	KEY_Init();
	LED_Init();
	OLED_Init();
	OLED_ColorTurn(0);//0正常显示,1 反色显示             
  OLED_DisplayTurn(0);
	OLED_Clear();
	//创建开始任务
    xTaskCreate((TaskFunction_t )start_task,            //任务函数
                (const char*    )"start_task",          //任务名称
                (uint16_t       )START_STK_SIZE,        //任务堆栈大小
                (void*          )NULL,                  //传递给任务函数的参数
                (UBaseType_t    )START_TASK_PRIO,       //任务优先级
                (TaskHandle_t*  )&StartTask_Handler);   //任务句柄              
    vTaskStartScheduler();          //开启任务调度
}

//开始任务任务函数
void start_task(void *pvParameters)
{
    taskENTER_CRITICAL();           //进入临界区
    
	  /* 创建 BinarySem */
	  BinarySem_Handle = xSemaphoreCreateBinary();
	  
    //创建LED1任务
    xTaskCreate((TaskFunction_t )led1_task,     
                (const char*    )"led1_task",   
                (uint16_t       )LED1_STK_SIZE, 
                (void*          )NULL,
                (UBaseType_t    )LED1_TASK_PRIO,
                (TaskHandle_t*  )&LED1Task_Handler); 						
		
		
		//创建接收任务
    xTaskCreate((TaskFunction_t )receive_task,     
                (const char*    )"receive_task",   
                (uint16_t       )RECEIVE_STK_SIZE, 
                (void*          )NULL,
                (UBaseType_t    )RECEIVE_TASK_PRIO,
                (TaskHandle_t*  )&ReceiveTask_Handler);

	//创建发送任务
    xTaskCreate((TaskFunction_t )send_task,     
                (const char*    )"send_task",   
                (uint16_t       )SEND_STK_SIZE, 
                (void*          )NULL,
                (UBaseType_t    )SEND_TASK_PRIO,
                (TaskHandle_t*  )&SendTask_Handler);
								
    vTaskDelete(StartTask_Handler); //删除开始任务
    taskEXIT_CRITICAL();            //退出临界区
} 

//LED1任务函数
void led1_task(void *pvParameters)
{
    while(1)
    {
        LED1=!LED1;
        vTaskDelay(500);
    }
}


void send_task(void *pvParameters)
{   
	
	BaseType_t xReturn = pdPASS;/* 定义一个创建信息返回值,默认为pdPASS */
    while(1)
    {
     if(KEY==1) 
		{
	   xReturn = xSemaphoreGive( BinarySem_Handle );//释放二值信号量
		 if(xReturn==pdPASS) {LED4=!LED4;OLED_ShowString(3,0,"release",8,1);}   //释放成功则LED4反转
		 else OLED_ShowString(3,0,"failed!",8,1);
		}
		else OLED_ShowString(3,0,"nopress",8,1); //没按下时显示"nopress"
		OLED_Refresh();
		vTaskDelay(100);
    }
}

//接收任务函数
void receive_task(void *pvParameters)
{
  BaseType_t xReturn = pdTRUE;/* 定义一个创建信息返回值,默认为pdTRUE */
	
	while(1)
    {
        //获取二值信号量 xSemaphore,没获取到则一直等待
		xReturn = xSemaphoreTake(BinarySem_Handle,/* 二值信号量句柄 */
								portMAX_DELAY); /* 等待时间 */
	
		if(pdTRUE == xReturn)    //获取二值信号量成功
		{
			OLED_ShowString(3,40,"receive",8,1);
			LED3=!LED3;            //获取成功则LED3反转
		}
	  else                     //获取二值信号量失败
		{
			OLED_ShowString(3,40,"nochange",8,1);
		}
		OLED_Refresh();
		vTaskDelay(100);
    }
}

5-FreeRTOS计数信号量实验

/******************************2023年10月15日*************************************
此为一个计数信号量实验,主要使用使用按键、OLED屏幕来观察现象。
主要创建两个任务一个接收,一个发送
计数信号量,需要按键触发,按下按键则send任务释放计数信号量、LED4翻转;receive获取计数信号量、LED3翻转
receive任务是不等待,只要send任务释放则receive才能成功获取二值信号量。
需定义计数信号量句柄
需要修改FreeRTOSConfig.h中的宏定义:
//为1时使用计数信号量
#define configUSE_COUNTING_SEMAPHORES		1
*********************************************************************************/
#include "system.h"
#include "SysTick.h"
#include "led.h"
#include "key.h"
#include "oled.h"
#include "usart.h"
#include "FreeRTOS.h"
#include "task.h"
#include "queue.h"
#include "semphr.h"

//任务优先级
#define START_TASK_PRIO		1
//任务堆栈大小	
#define START_STK_SIZE 		128  
//任务句柄
TaskHandle_t StartTask_Handler;
//任务函数
void start_task(void *pvParameters);

//任务优先级
#define LED1_TASK_PRIO		2
//任务堆栈大小	(单位字)
#define LED1_STK_SIZE 		50  
//任务句柄
TaskHandle_t LED1Task_Handler;
//任务函数
void led1_task(void *pvParameters);
/*******************************************************************************/
//任务优先级
#define SEND_TASK_PRIO		3
//任务堆栈大小	
#define SEND_STK_SIZE 		50  
//任务句柄
TaskHandle_t SendTask_Handler;
//任务函数
void send_task(void *pvParameters);
/*******************************************************************************/
//任务优先级
#define RECEIVE_TASK_PRIO		4
//任务堆栈大小	
#define RECEIVE_STK_SIZE 		50  
//任务句柄
TaskHandle_t ReceiveTask_Handler;
//任务函数
void receive_task(void *pvParameters);

//创建句柄
SemaphoreHandle_t CountSem_Handle =NULL;

/*******************************************************************************
* 函 数 名         : main
* 函数功能		   : 主函数
* 输    入         : 无
* 输    出         : 无
*******************************************************************************/
int main()
{
	SysTick_Init(72);
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);//设置系统中断优先级分组4
	USART1_Init(115200);
	KEY_Init();
	LED_Init();
	OLED_Init();
	OLED_ColorTurn(0);//0正常显示,1 反色显示             
  OLED_DisplayTurn(0);
	OLED_Clear();
	//创建开始任务
    xTaskCreate((TaskFunction_t )start_task,            //任务函数
                (const char*    )"start_task",          //任务名称
                (uint16_t       )START_STK_SIZE,        //任务堆栈大小
                (void*          )NULL,                  //传递给任务函数的参数
                (UBaseType_t    )START_TASK_PRIO,       //任务优先级
                (TaskHandle_t*  )&StartTask_Handler);   //任务句柄              
    vTaskStartScheduler();          //开启任务调度
}

//开始任务任务函数
void start_task(void *pvParameters)
{
    taskENTER_CRITICAL();           //进入临界区
    
	/* 创建 CountSem */
	CountSem_Handle = xSemaphoreCreateCounting(5,5);
	  
    //创建LED1任务
    xTaskCreate((TaskFunction_t )led1_task,     
                (const char*    )"led1_task",   
                (uint16_t       )LED1_STK_SIZE, 
                (void*          )NULL,
                (UBaseType_t    )LED1_TASK_PRIO,
                (TaskHandle_t*  )&LED1Task_Handler); 						
		
		
		//创建接收任务
    xTaskCreate((TaskFunction_t )receive_task,     
                (const char*    )"receive_task",   
                (uint16_t       )RECEIVE_STK_SIZE, 
                (void*          )NULL,
                (UBaseType_t    )RECEIVE_TASK_PRIO,
                (TaskHandle_t*  )&ReceiveTask_Handler);

	//创建发送任务
    xTaskCreate((TaskFunction_t )send_task,     
                (const char*    )"send_task",   
                (uint16_t       )SEND_STK_SIZE, 
                (void*          )NULL,
                (UBaseType_t    )SEND_TASK_PRIO,
                (TaskHandle_t*  )&SendTask_Handler);
								
    vTaskDelete(StartTask_Handler); //删除开始任务
    taskEXIT_CRITICAL();            //退出临界区
} 

//LED1任务函数
void led1_task(void *pvParameters)
{
    while(1)
    {
        LED1=!LED1;
        vTaskDelay(500);
    }
}


void send_task(void *pvParameters)
{   
	
	BaseType_t xReturn = pdPASS;/* 定义一个创建信息返回值,默认为pdPASS */
    while(1)
    {
     if(KEY==1) 
		{
	   xReturn = xSemaphoreGive( CountSem_Handle );//释放计数信号量
		 if(xReturn==pdPASS) {LED4=!LED4;OLED_ShowString(3,0,"release",8,1);}   //释放成功则LED4反转
		 else OLED_ShowString(3,0,"failed!",8,1);
		}
		else OLED_ShowString(3,0,"nopress",8,1); //没按下时显示"nopress"
		OLED_Refresh();
		vTaskDelay(100);
    }
}

//接收任务函数
void receive_task(void *pvParameters)
{
  BaseType_t xReturn = pdTRUE;/* 定义一个创建信息返回值,默认为pdTRUE */
	
	while(1)
    {
        //获取计数信号量 xSemaphore,没获取到则不等待
		xReturn = xSemaphoreTake(CountSem_Handle,/* 计数信号量句柄 */
								0); /* 等待时间 */
	
		if(pdTRUE == xReturn)    //获取计数信号量成功
		{
			OLED_ShowString(3,40,"receive",8,1);
			LED3=!LED3;            //获取成功则LED3反转
		}
	  else                     //获取计数信号量失败
		{
			OLED_ShowString(3,40,"nochang",8,1);
		}
		OLED_Refresh();
		vTaskDelay(100);
    }
}

6-FreeRTOS互斥信号量实验 - 优先级翻转

/******************************2023年10月17日*************************************
此为一个优先级翻转实验,主要使用使用OLED屏幕来观察现象。
主要创建三个任务高优先级、中优先级、低优先级
模拟优先级翻转、低优先级任务运行时高优先级任务等待
需定义二值信号量句柄
由于高优先级任务需要的资源(二值信号量)被低优先级任务占据,所以无法执行,挂起(此时任务优先级翻转)
中优先级任务没有使用到被占据的资源(二值信号量),所以中优先级任务不用等待低优先级任务执行完毕

需更改宏定义
//使用互斥信号量
#define configUSE_MUTEXES						    1  
*********************************************************************************/
#include "system.h"
#include "SysTick.h"
#include "led.h"
#include "key.h"
#include "oled.h"
#include "usart.h"
#include "FreeRTOS.h"
#include "task.h"
#include "queue.h"
#include "semphr.h"

//任务优先级
#define START_TASK_PRIO		1
//任务堆栈大小	
#define START_STK_SIZE 		128  
//任务句柄
TaskHandle_t StartTask_Handler;
//任务函数
void start_task(void *pvParameters);

//任务优先级
#define LED1_TASK_PRIO		3                  //这里提高LED任务优先级,防止低优先级任务阻塞了LED任务
//任务堆栈大小	(单位字)
#define LED1_STK_SIZE 		50  
//任务句柄
TaskHandle_t LED1Task_Handler;
//任务函数
void led1_task(void *pvParameters);
/*******************************************************************************/
//任务优先级
#define LowPriority_TASK_PRIO		2             //比LED优先级低
//任务堆栈大小	
#define LowPriority_STK_SIZE 		512  
//任务句柄
TaskHandle_t LowPriority_Task_Handle;
//任务函数
void LowPriority_Task(void *pvParameters);
/*******************************************************************************/
//任务优先级
#define MidPriority_TASK_PRIO		4
//任务堆栈大小	
#define MidPriority_STK_SIZE 		512  
//任务句柄
TaskHandle_t MidPriority_Task_Handle;
//任务函数
void MidPriority_Task(void *pvParameters);
/*******************************************************************************/
//任务优先级
#define HighPriority_TASK_PRIO		5
//任务堆栈大小	
#define HighPriority_STK_SIZE 		512  
//任务句柄
TaskHandle_t HighPriority_Task_Handle;
//任务函数
void HighPriority_Task(void *pvParameters);

//创建句柄
SemaphoreHandle_t BinarySem_Handle =NULL;
/*******************************************************************************
* 函 数 名         : main
* 函数功能		   : 主函数
* 输    入         : 无
* 输    出         : 无
*******************************************************************************/
int main()
{
	SysTick_Init(72);
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);//设置系统中断优先级分组4
	USART1_Init(115200);
	KEY_Init();
	LED_Init();
	OLED_Init();
	OLED_ColorTurn(0);//0正常显示,1 反色显示             
  OLED_DisplayTurn(0);
	OLED_Clear();
	//创建开始任务
    xTaskCreate((TaskFunction_t )start_task,            //任务函数
                (const char*    )"start_task",          //任务名称
                (uint16_t       )START_STK_SIZE,        //任务堆栈大小
                (void*          )NULL,                  //传递给任务函数的参数
                (UBaseType_t    )START_TASK_PRIO,       //任务优先级
                (TaskHandle_t*  )&StartTask_Handler);   //任务句柄              
    vTaskStartScheduler();          //开启任务调度
}

//开始任务任务函数
void start_task(void *pvParameters)
{   
	  BaseType_t xReturn = pdPASS;
    taskENTER_CRITICAL();           //进入临界区
    
	  /* 创建 BinarySem */
	  BinarySem_Handle = xSemaphoreCreateBinary();
	  xReturn = xSemaphoreGive( BinarySem_Handle );//给出二值信号量	
    //创建LED1任务
    xTaskCreate((TaskFunction_t )led1_task,     
                (const char*    )"led1_task",   
                (uint16_t       )LED1_STK_SIZE, 
                (void*          )NULL,
                (UBaseType_t    )LED1_TASK_PRIO,
                (TaskHandle_t*  )&LED1Task_Handler); 						
		
		
		//创建低优先级任务
    xTaskCreate((TaskFunction_t )LowPriority_Task,     
                (const char*    )"LowPriority_Task",   
                (uint16_t       )LowPriority_STK_SIZE, 
                (void*          )NULL,
                (UBaseType_t    )LowPriority_TASK_PRIO,
                (TaskHandle_t*  )&LowPriority_Task_Handle);

    //创建中优先级任务
    xTaskCreate((TaskFunction_t )MidPriority_Task,     
                (const char*    )"MidPriority_Task",   
                (uint16_t       )MidPriority_STK_SIZE, 
                (void*          )NULL,
                (UBaseType_t    )MidPriority_TASK_PRIO,
                (TaskHandle_t*  )&MidPriority_Task_Handle);
								
		//创建高优先级任务
    xTaskCreate((TaskFunction_t )HighPriority_Task,     
                (const char*    )"HighPriority_Task",   
                (uint16_t       )HighPriority_STK_SIZE, 
                (void*          )NULL,
                (UBaseType_t    )HighPriority_TASK_PRIO,
                (TaskHandle_t*  )&HighPriority_Task_Handle);
								
    vTaskDelete(StartTask_Handler); //删除开始任务
    taskEXIT_CRITICAL();            //退出临界区
} 

//LED1任务函数
void led1_task(void *pvParameters)
{
    while(1)
    {
        LED1=!LED1;
        vTaskDelay(500);
    }
}


//低优先级任务函数
void LowPriority_Task(void *pvParameters)
{
    BaseType_t xReturn = pdPASS;/* 定义一个创建信息返回值,默认为pdPASS */
	static uint32_t i=0;
	static uint32_t low_see=0;
	while(1)
    {   
        OLED_ShowString(3,0,"low_get",8,1);
			  OLED_Refresh();
		//获取二值信号量 xSemaphore,没获取到则一直等待
		xReturn = xSemaphoreTake(BinarySem_Handle,/* 二值信号量句柄 */
							  portMAX_DELAY); /* 等待时间 */
		if( xReturn == pdTRUE )
		{
			OLED_ShowString(3,0,"low_run",8,1);
			low_see++;
			OLED_ShowNum(60,0,low_see,4,8,1);
		  OLED_Refresh();
			
		}
/*****************************************************************************
此处可以占据二值信号量,导致高优先级任务无法获取二值信号量无法执行。被迫等待低优先级任务执行完毕。
而中优先级任务不需要获取二值信号量所以不受影响
*****************************************************************************/
		for(i=0;i<2000000;i++)//模拟低优先级任务占用信号量
		{
			taskYIELD();//发起任务调度
		}

		OLED_ShowString(3,0,"low_giv",8,1);
		OLED_Refresh();
		xReturn = xSemaphoreGive( BinarySem_Handle );//给出二值信号量
		LED2=!LED2;
		vTaskDelay(500);
    }
}

//中优先级任务函数
void MidPriority_Task(void *pvParameters)
{
	static uint32_t see=0;
	while(1)
    {
		see++;
		OLED_ShowNum(3,20,see,4,8,1);             // 用来证明中优先级任务没有被低优先级任务阻塞         
		OLED_Refresh();
		vTaskDelay(500);
    }
}

//高优先级任务函数
void HighPriority_Task(void *pvParameters)
{
	BaseType_t xReturn = pdTRUE;
	static uint32_t high_see=0;
	while(1)
    {   
		    OLED_ShowString(3,40,"hig_get",8,1);
			  OLED_Refresh();
		//获取二值信号量 xSemaphore,没获取到则一直等待
		xReturn = xSemaphoreTake(BinarySem_Handle,/* 二值信号量句柄 */
                              portMAX_DELAY); /* 等待时间 */
		if(pdTRUE == xReturn)
		{  
  			OLED_ShowString(3,40,"hig_run",8,1);
			  high_see++;
			  OLED_ShowNum(60,40,high_see,4,8,1);
  			OLED_Refresh();    
		}
		LED2=!LED2;
		xReturn = xSemaphoreGive( BinarySem_Handle );//给出二值信号量
		vTaskDelay(500);
    }
}

7-FreeRTOS互斥信号量实验-互斥量

/******************************2023年10月17日*************************************
此为一个互斥信号量实验,主要使用使用OLED屏幕来观察现象。
主要创建三个任务高优先级、中优先级、低优先级
模拟低优先级占用资源、低优先级任务运行时高优先级任务等待
需定义互斥信号量句柄
互斥信号量实验与优先级翻转实验的区别就是:
优先级反转实验定义的是二值信号量,只有需要获取二值信号量的任务会被影响;

互斥信号量实验定义的是互斥信号量,所有的任务都会被影响,体现资源占用互斥

需更改宏定义
//使用互斥信号量
#define configUSE_MUTEXES						    1  
*********************************************************************************/
#include "system.h"
#include "SysTick.h"
#include "led.h"
#include "key.h"
#include "oled.h"
#include "usart.h"
#include "FreeRTOS.h"
#include "task.h"
#include "queue.h"
#include "semphr.h"

//任务优先级
#define START_TASK_PRIO		1
//任务堆栈大小	
#define START_STK_SIZE 		128  
//任务句柄
TaskHandle_t StartTask_Handler;
//任务函数
void start_task(void *pvParameters);

//任务优先级
#define LED1_TASK_PRIO		3                  //这里提高LED任务优先级,防止低优先级任务阻塞了LED任务
//任务堆栈大小	(单位字)
#define LED1_STK_SIZE 		50  
//任务句柄
TaskHandle_t LED1Task_Handler;
//任务函数
void led1_task(void *pvParameters);
/*******************************************************************************/
//任务优先级
#define LowPriority_TASK_PRIO		2             //比LED优先级低
//任务堆栈大小	
#define LowPriority_STK_SIZE 		512  
//任务句柄
TaskHandle_t LowPriority_Task_Handle;
//任务函数
void LowPriority_Task(void *pvParameters);
/*******************************************************************************/
//任务优先级
#define MidPriority_TASK_PRIO		4
//任务堆栈大小	
#define MidPriority_STK_SIZE 		512  
//任务句柄
TaskHandle_t MidPriority_Task_Handle;
//任务函数
void MidPriority_Task(void *pvParameters);
/*******************************************************************************/
//任务优先级
#define HighPriority_TASK_PRIO		5
//任务堆栈大小	
#define HighPriority_STK_SIZE 		512  
//任务句柄
TaskHandle_t HighPriority_Task_Handle;
//任务函数
void HighPriority_Task(void *pvParameters);

//创建句柄
SemaphoreHandle_t MuxSem_Handle =NULL;
/*******************************************************************************
* 函 数 名         : main
* 函数功能		   : 主函数
* 输    入         : 无
* 输    出         : 无
*******************************************************************************/
int main()
{
	SysTick_Init(72);
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);//设置系统中断优先级分组4
	USART1_Init(115200);
	KEY_Init();
	LED_Init();
	OLED_Init();
	OLED_ColorTurn(0);//0正常显示,1 反色显示             
  OLED_DisplayTurn(0);
	OLED_Clear();
	//创建开始任务
    xTaskCreate((TaskFunction_t )start_task,            //任务函数
                (const char*    )"start_task",          //任务名称
                (uint16_t       )START_STK_SIZE,        //任务堆栈大小
                (void*          )NULL,                  //传递给任务函数的参数
                (UBaseType_t    )START_TASK_PRIO,       //任务优先级
                (TaskHandle_t*  )&StartTask_Handler);   //任务句柄              
    vTaskStartScheduler();          //开启任务调度
}

//开始任务任务函数
void start_task(void *pvParameters)
{   
    taskENTER_CRITICAL();           //进入临界区
   
	  /* 创建 BinarySem */
    MuxSem_Handle = xSemaphoreCreateMutex();	
    //创建LED1任务
    xTaskCreate((TaskFunction_t )led1_task,     
                (const char*    )"led1_task",   
                (uint16_t       )LED1_STK_SIZE, 
                (void*          )NULL,
                (UBaseType_t    )LED1_TASK_PRIO,
                (TaskHandle_t*  )&LED1Task_Handler); 						
		
		
		//创建低优先级任务
    xTaskCreate((TaskFunction_t )LowPriority_Task,     
                (const char*    )"LowPriority_Task",   
                (uint16_t       )LowPriority_STK_SIZE, 
                (void*          )NULL,
                (UBaseType_t    )LowPriority_TASK_PRIO,
                (TaskHandle_t*  )&LowPriority_Task_Handle);

    //创建中优先级任务
    xTaskCreate((TaskFunction_t )MidPriority_Task,     
                (const char*    )"MidPriority_Task",   
                (uint16_t       )MidPriority_STK_SIZE, 
                (void*          )NULL,
                (UBaseType_t    )MidPriority_TASK_PRIO,
                (TaskHandle_t*  )&MidPriority_Task_Handle);
								
		//创建高优先级任务
    xTaskCreate((TaskFunction_t )HighPriority_Task,     
                (const char*    )"HighPriority_Task",   
                (uint16_t       )HighPriority_STK_SIZE, 
                (void*          )NULL,
                (UBaseType_t    )HighPriority_TASK_PRIO,
                (TaskHandle_t*  )&HighPriority_Task_Handle);
								
    vTaskDelete(StartTask_Handler); //删除开始任务
    taskEXIT_CRITICAL();            //退出临界区
} 

//LED1任务函数
void led1_task(void *pvParameters)
{
    while(1)
    {
        LED1=!LED1;
        vTaskDelay(500);
    }
}


//低优先级任务函数
void LowPriority_Task(void *pvParameters)
{
    BaseType_t xReturn = pdPASS;/* 定义一个创建信息返回值,默认为pdPASS */
	static uint32_t i=0;
	static uint32_t low_see=0;
	while(1)
    {   
        OLED_ShowString(3,0,"low_get",8,1);
			  OLED_Refresh();
		//获取二值信号量 xSemaphore,没获取到则一直等待
		xReturn = xSemaphoreTake(MuxSem_Handle,/* 互斥信号量句柄 */
							  portMAX_DELAY); /* 等待时间 */
		if( xReturn == pdTRUE )
		{
			OLED_ShowString(3,0,"low_run",8,1);
			low_see++;
			OLED_ShowNum(60,0,low_see,4,8,1);
		  OLED_Refresh();
			
		}
/*****************************************************************************
		模拟低优先级任务占用资源
*****************************************************************************/
		for(i=0;i<2000000;i++)//模拟低优先级任务占用信号量
		{
			taskYIELD();//发起任务调度
		}

		OLED_ShowString(3,0,"low_giv",8,1);
		OLED_Refresh();
		xReturn = xSemaphoreGive( MuxSem_Handle );//给出互斥信号量
		LED2=!LED2;
		vTaskDelay(500);
    }
}

//中优先级任务函数
void MidPriority_Task(void *pvParameters)
{
	static uint32_t see=0;
	while(1)
    {
		see++;
		OLED_ShowNum(3,20,see,4,8,1);             // 用来证明中优先级任务没有被低优先级任务阻塞         
		OLED_Refresh();
		vTaskDelay(500);
    }
}

//高优先级任务函数
void HighPriority_Task(void *pvParameters)
{
	BaseType_t xReturn = pdTRUE;
	static uint32_t high_see=0;
	while(1)
    {   
		    OLED_ShowString(3,40,"hig_get",8,1);
			  OLED_Refresh();
		//获取互斥信号量 xSemaphore,没获取到则一直等待
		xReturn = xSemaphoreTake(MuxSem_Handle,/* 互斥信号量句柄 */
                              portMAX_DELAY); /* 等待时间 */
		if(pdTRUE == xReturn)
		{  
  			OLED_ShowString(3,40,"hig_run",8,1);
			  high_see++;
			  OLED_ShowNum(60,40,high_see,4,8,1);
  			OLED_Refresh();    
		}
		LED2=!LED2;
		xReturn = xSemaphoreGive( MuxSem_Handle );//给出互斥信号量
		vTaskDelay(500);
    }
}

8-FreeRTOS事件实验

/******************************2023年10月17日*************************************
这是一个事件实验,LED2任务需要事件触发,KEY任务可以通过按键计数创建对应的事件,
当事件满足时LED2任务才可以执行一次,执行完之后由于xEventGroupWaitBits某个参数
设置为pdTRUE,所以触发后会自动删除标志位,自动清除。这个函数返回值为事件的计算值。
*********************************************************************************/
#include "system.h"
#include "SysTick.h"
#include "led.h"
#include "key.h"
#include "oled.h"
#include "usart.h"
#include "FreeRTOS.h"
#include "task.h"
#include "queue.h"
#include "semphr.h"
#include "event_groups.h"

//任务优先级
#define START_TASK_PRIO		1
//任务堆栈大小	
#define START_STK_SIZE 		128  
//任务句柄
TaskHandle_t StartTask_Handler;
//任务函数
void start_task(void *pvParameters);

//任务优先级
#define LED1_TASK_PRIO		2
//任务堆栈大小	
#define LED1_STK_SIZE 		50  
//任务句柄
TaskHandle_t LED1Task_Handler;
//任务函数
void led1_task(void *pvParameters);

//任务优先级
#define LED2_TASK_PRIO		3
//任务堆栈大小	
#define LED2_STK_SIZE 		50  
//任务句柄
TaskHandle_t LED2Task_Handler;
//任务函数
void led2_task(void *pvParameters);

//任务优先级
#define KEY_TASK_PRIO		4
//任务堆栈大小	
#define KEY_STK_SIZE 		512  
//任务句柄
TaskHandle_t KEYTask_Handler;
//任务函数
void key_task(void *pvParameters);

//创建句柄
EventGroupHandle_t Event_Handle =NULL;

#define KEY1_EVENT  (0x01 << 0)//设置事件掩码的位0
#define KEY2_EVENT  (0x01 << 1)//设置事件掩码的位1
/*******************************************************************************
* 函 数 名         : main
* 函数功能		   : 主函数
* 输    入         : 无
* 输    出         : 无
*******************************************************************************/
int main()
{
	SysTick_Init(72);
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);//设置系统中断优先级分组4
	USART1_Init(115200);
	KEY_Init();
	LED_Init();
	OLED_Init();
	OLED_ColorTurn(0);//0正常显示,1 反色显示             
  OLED_DisplayTurn(0);
	OLED_Clear();
	//创建开始任务
    xTaskCreate((TaskFunction_t )start_task,            //任务函数
                (const char*    )"start_task",          //任务名称
                (uint16_t       )START_STK_SIZE,        //任务堆栈大小
                (void*          )NULL,                  //传递给任务函数的参数
                (UBaseType_t    )START_TASK_PRIO,       //任务优先级
                (TaskHandle_t*  )&StartTask_Handler);   //任务句柄              
    vTaskStartScheduler();          //开启任务调度
}

//开始任务任务函数
void start_task(void *pvParameters)
{   
    taskENTER_CRITICAL();           //进入临界区
   
	 	/* 创建 Event_Handle */
	 Event_Handle = xEventGroupCreate();	
	
    //创建LED1任务
    xTaskCreate((TaskFunction_t )led1_task,     
                (const char*    )"led1_task",   
                (uint16_t       )LED1_STK_SIZE, 
                (void*          )NULL,
                (UBaseType_t    )LED1_TASK_PRIO,
                (TaskHandle_t*  )&LED1Task_Handler); 
				
	//创建LED2任务
    xTaskCreate((TaskFunction_t )led2_task,     
                (const char*    )"led2_task",   
                (uint16_t       )LED2_STK_SIZE, 
                (void*          )NULL,
                (UBaseType_t    )LED2_TASK_PRIO,
                (TaskHandle_t*  )&LED2Task_Handler);
				
	//创建KEY任务
    xTaskCreate((TaskFunction_t )key_task,     
                (const char*    )"key_task",   
                (uint16_t       )KEY_STK_SIZE, 
                (void*          )NULL,
                (UBaseType_t    )KEY_TASK_PRIO,
                (TaskHandle_t*  )&KEYTask_Handler);
								
    vTaskDelete(StartTask_Handler); //删除开始任务
    taskEXIT_CRITICAL();            //退出临界区
} 

//LED1任务函数
void led1_task(void *pvParameters)
{
    while(1)
    {
        LED1=0;
        vTaskDelay(200);
        LED1=1;
        vTaskDelay(800);
    }
}

//LED2任务函数
void led2_task(void *pvParameters)
{
    EventBits_t r_event;  /* 定义一个事件接收变量 */
	
	while(1)
    {
        r_event = xEventGroupWaitBits(Event_Handle,  /* 事件对象句柄 */
                                  KEY1_EVENT|KEY2_EVENT,/* 接收线程感兴趣的事件 */
                                  pdTRUE,   /* 退出时清除事件位 */
                                  pdTRUE,   /* 满足感兴趣的所有事件 */
                                  portMAX_DELAY);/* 指定超时事件,一直等 */
                        
		if((r_event & (KEY1_EVENT|KEY2_EVENT)) == (KEY1_EVENT|KEY2_EVENT))
		{
			OLED_ShowString(3,50 ,"get!",8,1);
			LED2=!LED2;
		}
		else
			OLED_ShowString(3,50 ,"err!",8,1);
		
		OLED_Refresh();
    }
}

//KEY任务函数
void key_task(void *pvParameters)
{
   static uint32_t KEY_DOWN=0;
	
	while(1)
    {
		if(KEY==1)
		{
		  KEY_DOWN++;
		  if(KEY_DOWN%2==0) 
			{
			 xEventGroupSetBits(Event_Handle,KEY1_EVENT);         //偶数创建事件1
			 OLED_ShowString(3,0 ,"event1 created!",8,1);
			}
		  else
			{
			 xEventGroupSetBits(Event_Handle,KEY2_EVENT);         //奇数创建事件2
			 OLED_ShowString(3,20 ,"event2 created!",8,1);
		  }
			while(KEY==1);
		}
		  OLED_ShowNum(3,40,KEY_DOWN,2,8,1);
      OLED_Refresh();
		vTaskDelay(20);
    }
}

9-FreeRTOS软件定时器实验

/******************************2023年10月17日*************************************
这是一个软件定时器实验,创建了两个软件定时器,定时器1可以一直定时,定时时间1秒;
定时器2只能定时一次,定时时间5秒。通过OLED屏幕显示来观察定时情况。
1 tick为 1 ms
需要修改宏定义中
 //启用软件定时器
#define configUSE_TIMERS				            1
*********************************************************************************/
#include "system.h"
#include "SysTick.h"
#include "led.h"
#include "key.h"
#include "oled.h"
#include "usart.h"
#include "FreeRTOS.h"
#include "task.h"
#include "timers.h"

//任务优先级
#define START_TASK_PRIO		1
//任务堆栈大小	
#define START_STK_SIZE 		128  
//任务句柄
TaskHandle_t StartTask_Handler;
//任务函数
void start_task(void *pvParameters);

/**************************************************************************************/
//任务优先级
#define LED1_TASK_PRIO		2
//任务堆栈大小	
#define LED1_STK_SIZE 		50  
//任务句柄
TaskHandle_t LED1Task_Handler;
//任务函数
void led1_task(void *pvParameters);

/**************************************************************************************/
//创建句柄
TimerHandle_t Swtmr1_Handle =NULL;
TimerHandle_t Swtmr2_Handle =NULL;

static uint32_t TmrCb_Count1 = 0; /* 记录软件定时器1回调函数执行次数 */
static uint32_t TmrCb_Count2 = 0; /* 记录软件定时器2回调函数执行次数 */

//声明回调函数
static void Swtmr1_Callback(void* parameter);
static void Swtmr2_Callback(void* parameter);


/*******************************************************************************
* 函 数 名         : main
* 函数功能		   : 主函数
* 输    入         : 无
* 输    出         : 无
*******************************************************************************/
int main()
{
	SysTick_Init(72);
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);//设置系统中断优先级分组4
	USART1_Init(115200);
	KEY_Init();
	LED_Init();
	OLED_Init();
	OLED_ColorTurn(0);//0正常显示,1 反色显示             
  OLED_DisplayTurn(0);
	OLED_Clear();
	//创建开始任务
    xTaskCreate((TaskFunction_t )start_task,            //任务函数
                (const char*    )"start_task",          //任务名称
                (uint16_t       )START_STK_SIZE,        //任务堆栈大小
                (void*          )NULL,                  //传递给任务函数的参数
                (UBaseType_t    )START_TASK_PRIO,       //任务优先级
                (TaskHandle_t*  )&StartTask_Handler);   //任务句柄              
    vTaskStartScheduler();          //开启任务调度
}



//开始任务任务函数
void start_task(void *pvParameters)
{
	taskENTER_CRITICAL();           //进入临界区
    
	//创建定时器1
	Swtmr1_Handle=xTimerCreate((const char*		)"AutoReloadTimer",
                            (TickType_t			)1000,/* 定时器周期 1000(tick) */
                            (UBaseType_t		)pdTRUE,/* 周期模式 */
                            (void*				  )1,/* 为每个计时器分配一个索引的唯一ID */
                            (TimerCallbackFunction_t)Swtmr1_Callback); /*回调函数名称*/
	if(Swtmr1_Handle != NULL) 
	{
		xTimerStart(Swtmr1_Handle,0);	//开启周期定时器
	}

	//创建定时器2
	Swtmr2_Handle=xTimerCreate((const char*			)"OneShotTimer",
                             (TickType_t			)5000,/* 定时器周期 5000(tick) */
                             (UBaseType_t			)pdFALSE,/* 单次模式 */
                             (void*					  )2,/* 为每个计时器分配一个索引的唯一ID */
                             (TimerCallbackFunction_t)Swtmr2_Callback);  /*回调函数名称*/
	if(Swtmr2_Handle != NULL) 
	{
		xTimerStart(Swtmr2_Handle,0);	//开启周期定时器
	}
							 
    //创建LED1任务
    xTaskCreate((TaskFunction_t )led1_task,     
                (const char*    )"led1_task",   
                (uint16_t       )LED1_STK_SIZE, 
                (void*          )NULL,
                (UBaseType_t    )LED1_TASK_PRIO,
                (TaskHandle_t*  )&LED1Task_Handler); 
			
    vTaskDelete(StartTask_Handler); //删除开始任务
    taskEXIT_CRITICAL();            //退出临界区
} 

//LED1任务函数
void led1_task(void *pvParameters)
{
    while(1)
    {
        LED1=0;
        vTaskDelay(200);
        LED1=1;
        vTaskDelay(800);
    }
}

//定时器1回调函数
//软件定时器不要调用阻塞函数,也不要进行死循环,应快进快出
void Swtmr1_Callback(void* parameter)
{		
	TickType_t tick_num1;

	TmrCb_Count1++;						/* 每回调一次加一 */

	tick_num1 = xTaskGetTickCount();	/* 获取滴答定时器的计数值 */

	LED2=!LED2;
  
	OLED_ShowNum(3,0,tick_num1,5,8,1);        //滴答定时器值
	OLED_ShowNum(3,20,TmrCb_Count1,5,8,1);    //软件定时器1值     
	OLED_Refresh();	
}

//定时器2回调函数
//软件定时器不要调用阻塞函数,也不要进行死循环,应快进快出
void Swtmr2_Callback(void* parameter)
{		
	TickType_t tick_num2;

	TmrCb_Count2++;						/* 每回调一次加一 */

	tick_num2 = xTaskGetTickCount();	/* 获取滴答定时器的计数值 */

	OLED_ShowNum(3,40,TmrCb_Count2,5,8,1);    //软件定时器2值
	OLED_ShowNum(3,0,tick_num2,5,8,1);    //滴答定时器值
  OLED_Refresh();	
}

10-FreeRTOS任务通知代替消息队列实验

/******************************2023年10月18日*************************************
这是一个任务通知代替消息队列的实验,通过OLED与KEY观察现象。
判断KEY按下的次数来判断发送哪一个通知,奇数通知接收任务1,偶数通知接收任务2
*********************************************************************************/
#include "system.h"
#include "SysTick.h"
#include "led.h"
#include "key.h"
#include "oled.h"
#include "usart.h"
#include "FreeRTOS.h"
#include "task.h"
#include "limits.h"

//任务优先级
#define START_TASK_PRIO		1
//任务堆栈大小	
#define START_STK_SIZE 		128  
//任务句柄
TaskHandle_t StartTask_Handler;
//任务函数
void start_task(void *pvParameters);

//任务优先级
#define LED1_TASK_PRIO		2
//任务堆栈大小	
#define LED1_STK_SIZE 		50  
//任务句柄
TaskHandle_t LED1Task_Handler;
//任务函数
void led1_task(void *pvParameters);

//任务优先级
#define Receive1_TASK_PRIO		3
//任务堆栈大小	
#define Receive1_STK_SIZE 		512  
//任务句柄
TaskHandle_t Receive1Task_Handler;
//任务函数
void Receive1_task(void *pvParameters);

//任务优先级
#define Receive2_TASK_PRIO		4
//任务堆栈大小	
#define Receive2_STK_SIZE 		512  
//任务句柄
TaskHandle_t Receive2Task_Handler;
//任务函数
void Receive2_task(void *pvParameters);

//任务优先级
#define Send_TASK_PRIO		5
//任务堆栈大小	
#define Send_STK_SIZE 		512  
//任务句柄
TaskHandle_t SendTask_Handler;
//任务函数
void Send_task(void *pvParameters);

#define  USE_CHAR  0  /* 测试字符串的时候配置为 1 ,测试变量配置为 0  */

/*******************************************************************************
* 函 数 名         : main
* 函数功能		   : 主函数
* 输    入         : 无
* 输    出         : 无
*******************************************************************************/
int main()
{
	SysTick_Init(72);
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);//设置系统中断优先级分组4
	USART1_Init(115200);
	KEY_Init();
	LED_Init();
	OLED_Init();
	OLED_ColorTurn(0);//0正常显示,1 反色显示             
  OLED_DisplayTurn(0);
	OLED_Clear();
	//创建开始任务
    xTaskCreate((TaskFunction_t )start_task,            //任务函数
                (const char*    )"start_task",          //任务名称
                (uint16_t       )START_STK_SIZE,        //任务堆栈大小
                (void*          )NULL,                  //传递给任务函数的参数
                (UBaseType_t    )START_TASK_PRIO,       //任务优先级
                (TaskHandle_t*  )&StartTask_Handler);   //任务句柄              
    vTaskStartScheduler();          //开启任务调度
}



//开始任务任务函数
void start_task(void *pvParameters)
{
	taskENTER_CRITICAL();           //进入临界区
    
	//创建LED1任务
    xTaskCreate((TaskFunction_t )led1_task,     
                (const char*    )"led1_task",   
                (uint16_t       )LED1_STK_SIZE, 
                (void*          )NULL,
                (UBaseType_t    )LED1_TASK_PRIO,
                (TaskHandle_t*  )&LED1Task_Handler); 
	
	//创建Receive1任务
    xTaskCreate((TaskFunction_t )Receive1_task,     
                (const char*    )"Receive1_task",   
                (uint16_t       )Receive1_STK_SIZE, 
                (void*          )NULL,
                (UBaseType_t    )Receive1_TASK_PRIO,
                (TaskHandle_t*  )&Receive1Task_Handler);
				
	//创建Receive2任务
    xTaskCreate((TaskFunction_t )Receive2_task,     
                (const char*    )"Receive2_task",   
                (uint16_t       )Receive2_STK_SIZE, 
                (void*          )NULL,
                (UBaseType_t    )Receive2_TASK_PRIO,
                (TaskHandle_t*  )&Receive2Task_Handler);
	
	//创建Send任务
    xTaskCreate((TaskFunction_t )Send_task,     
                (const char*    )"Send_task",   
                (uint16_t       )Send_STK_SIZE, 
                (void*          )NULL,
                (UBaseType_t    )Send_TASK_PRIO,
                (TaskHandle_t*  )&SendTask_Handler);
			
    vTaskDelete(StartTask_Handler); //删除开始任务
    taskEXIT_CRITICAL();            //退出临界区
} 

//LED1任务函数
void led1_task(void *pvParameters)
{
    while(1)
    {
        LED1=0;
        vTaskDelay(200);
        LED1=1;
        vTaskDelay(800);
    }
}

//Receive1任务函数
void Receive1_task(void *pvParameters)
{
    BaseType_t xReturn = pdTRUE;
#if USE_CHAR
  char *r_char;
#else
  uint32_t r_num;
#endif
	
	while(1)
    {
		//获取任务通知 ,没获取到则一直等待
		xReturn=xTaskNotifyWait(0x0,			//进入函数的时候不清除任务bit
								ULONG_MAX,	  //退出函数的时候清除所有的bit
#if USE_CHAR
								(uint32_t *)&r_char,		  //保存任务通知值
#else
								&r_num,		  //保存任务通知值
#endif                        
								portMAX_DELAY);	//阻塞时间
		if( pdTRUE == xReturn )
#if USE_CHAR
			printf("Receive1_Task 任务通知消息为 %s \n",r_char);                      
#else
		  {
		   OLED_ShowString(3,0,"receive1:",8,1);
       OLED_ShowNum(70,0,r_num,1,8,1);	
		   OLED_Refresh();  
      }				
#endif  
		
	  }
}

//Receive2任务函数
void Receive2_task(void *pvParameters)
{
	BaseType_t xReturn = pdTRUE;
#if USE_CHAR
  char *r_char;
#else
  uint32_t r_num;
#endif
	
	while(1)
    {
		//获取任务通知 ,没获取到则一直等待
		xReturn=xTaskNotifyWait(0x0,			//进入函数的时候不清除任务bit
								ULONG_MAX,	  //退出函数的时候清除所有的bit
#if USE_CHAR
								(uint32_t *)&r_char,		  //保存任务通知值
#else
								&r_num,		  //保存任务通知值
#endif                        
								portMAX_DELAY);	//阻塞时间
		if( pdTRUE == xReturn )
#if USE_CHAR
    printf("Receive2_Task 任务通知消息为 %s \n",r_char);
#else   
    {
		 OLED_ShowString(3,20,"receive2:",8,1);
     OLED_ShowNum(70,20,r_num,1,8,1);	
		 OLED_Refresh();
    }			
#endif  
		
	}
}

//Send任务函数
void Send_task(void *pvParameters)
{
	BaseType_t xReturn = pdPASS;
	u8 PRESS=0;
#if USE_CHAR
	char test_str1[] = "this is a mail test 1";/* 邮箱消息test1 */
	char test_str2[] = "this is a mail test 2";/* 邮箱消息test2 */
#else
	uint32_t send1 = 1;
	uint32_t send2 = 2;
#endif
	
	while(1)
	{
		if(KEY==1)
		{ 
			PRESS++;
			while(KEY==1);
/**************************************奇数发送Receive1*****************************************/				
		 if(PRESS%2!=0)
		 {	xReturn = xTaskNotify(Receive1Task_Handler, /*任务句柄*/
#if USE_CHAR 
								(uint32_t)&test_str1, /* 发送的数据,最大为4字节 */
#else
								send1, /* 发送的数据,最大为4字节 */
#endif
								eSetValueWithOverwrite );/*覆盖当前通知*/
			if( xReturn == pdPASS )
			{		
			  OLED_ShowString(3,40,"receive1 send!",8,1);
		    OLED_Refresh();
			}
		}
/***************************************偶数发送Receive2**************************************/		
		else 
		{
			xReturn = xTaskNotify(Receive2Task_Handler, /*任务句柄*/
#if USE_CHAR 
								(uint32_t)&test_str2, /* 发送的数据,最大为4字节 */
#else
								send2, /* 发送的数据,最大为4字节 */
#endif
								eSetValueWithOverwrite );/*覆盖当前通知*/
			if( xReturn == pdPASS )
			{		
			  OLED_ShowString(3,40,"receive2 send!",8,1);
		    OLED_Refresh();
			}
		}
/*****************************************************************************/		
	 }
		vTaskDelay(20);
	}
}

11-FreeRTOS任务通知代替二值信号量实验

/******************************2023年10月18日*************************************
这是一个任务通知代替二值信号量的实验,通过OLED与KEY观察现象。
判断KEY按下的次数来判断发送哪一个通知,奇数通知接收任务1,偶数通知接收任务2
*********************************************************************************/
#include "system.h"
#include "SysTick.h"
#include "led.h"
#include "key.h"
#include "oled.h"
#include "usart.h"
#include "FreeRTOS.h"
#include "task.h"
#include "limits.h"

//任务优先级
#define START_TASK_PRIO		1
//任务堆栈大小	
#define START_STK_SIZE 		128  
//任务句柄
TaskHandle_t StartTask_Handler;
//任务函数
void start_task(void *pvParameters);

//任务优先级
#define LED1_TASK_PRIO		2
//任务堆栈大小	
#define LED1_STK_SIZE 		50  
//任务句柄
TaskHandle_t LED1Task_Handler;
//任务函数
void led1_task(void *pvParameters);

//任务优先级
#define Receive1_TASK_PRIO		3
//任务堆栈大小	
#define Receive1_STK_SIZE 		512  
//任务句柄
TaskHandle_t Receive1Task_Handler;
//任务函数
void Receive1_task(void *pvParameters);

//任务优先级
#define Receive2_TASK_PRIO		4
//任务堆栈大小	
#define Receive2_STK_SIZE 		512  
//任务句柄
TaskHandle_t Receive2Task_Handler;
//任务函数
void Receive2_task(void *pvParameters);

//任务优先级
#define Send_TASK_PRIO		5
//任务堆栈大小	
#define Send_STK_SIZE 		512  
//任务句柄
TaskHandle_t SendTask_Handler;
//任务函数
void Send_task(void *pvParameters);



/*******************************************************************************
* 函 数 名         : main
* 函数功能		   : 主函数
* 输    入         : 无
* 输    出         : 无
*******************************************************************************/
int main()
{
	SysTick_Init(72);
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);//设置系统中断优先级分组4
	USART1_Init(115200);
	KEY_Init();
	LED_Init();
	OLED_Init();
	OLED_ColorTurn(0);//0正常显示,1 反色显示             
  OLED_DisplayTurn(0);
	OLED_Clear();
	//创建开始任务
    xTaskCreate((TaskFunction_t )start_task,            //任务函数
                (const char*    )"start_task",          //任务名称
                (uint16_t       )START_STK_SIZE,        //任务堆栈大小
                (void*          )NULL,                  //传递给任务函数的参数
                (UBaseType_t    )START_TASK_PRIO,       //任务优先级
                (TaskHandle_t*  )&StartTask_Handler);   //任务句柄              
    vTaskStartScheduler();          //开启任务调度
}



//开始任务任务函数
void start_task(void *pvParameters)
{
	taskENTER_CRITICAL();           //进入临界区
    
	//创建LED1任务
    xTaskCreate((TaskFunction_t )led1_task,     
                (const char*    )"led1_task",   
                (uint16_t       )LED1_STK_SIZE, 
                (void*          )NULL,
                (UBaseType_t    )LED1_TASK_PRIO,
                (TaskHandle_t*  )&LED1Task_Handler); 
	
	//创建Receive1任务
    xTaskCreate((TaskFunction_t )Receive1_task,     
                (const char*    )"Receive1_task",   
                (uint16_t       )Receive1_STK_SIZE, 
                (void*          )NULL,
                (UBaseType_t    )Receive1_TASK_PRIO,
                (TaskHandle_t*  )&Receive1Task_Handler);
				
	//创建Receive2任务
    xTaskCreate((TaskFunction_t )Receive2_task,     
                (const char*    )"Receive2_task",   
                (uint16_t       )Receive2_STK_SIZE, 
                (void*          )NULL,
                (UBaseType_t    )Receive2_TASK_PRIO,
                (TaskHandle_t*  )&Receive2Task_Handler);
	
	//创建Send任务
    xTaskCreate((TaskFunction_t )Send_task,     
                (const char*    )"Send_task",   
                (uint16_t       )Send_STK_SIZE, 
                (void*          )NULL,
                (UBaseType_t    )Send_TASK_PRIO,
                (TaskHandle_t*  )&SendTask_Handler);
			
    vTaskDelete(StartTask_Handler); //删除开始任务
    taskEXIT_CRITICAL();            //退出临界区
} 

//LED1任务函数
void led1_task(void *pvParameters)
{
    while(1)
    {
        LED1=0;
        vTaskDelay(200);
        LED1=1;
        vTaskDelay(800);
    }
}

//Receive1任务函数
void Receive1_task(void *pvParameters)
{
	while(1)
    {
		//获取任务通知 ,没获取到则一直等待
		ulTaskNotifyTake(pdTRUE,portMAX_DELAY);
		OLED_ShowString(3,0,"task1 received!",8,1);
		OLED_Refresh();
	}
}

//Receive2任务函数
void Receive2_task(void *pvParameters)
{	
	while(1)
    {
		//获取任务通知 ,没获取到则一直等待
		ulTaskNotifyTake(pdTRUE,portMAX_DELAY);
		OLED_ShowString(3,20,"task2 received!",8,1);
		OLED_Refresh();
	  }
}

//Send任务函数
void Send_task(void *pvParameters)
{
	BaseType_t xReturn = pdPASS;
	u8 PRESS=0;

	while(1)
	{
		if(KEY==1)
		{ 
			PRESS++;
			while(KEY==1);
/**************************************奇数发送Receive1*****************************************/				
		 if(PRESS%2!=0)
		 {				
			  xReturn = xTaskNotifyGive(Receive1Task_Handler);
			  if( xReturn == pdTRUE )
				{
				OLED_ShowString(3,40,"task1 send!",8,1);
		    OLED_Refresh();
				}
		 }
/***************************************偶数发送Receive2**************************************/		
		else 
		{
        xReturn = xTaskNotifyGive(Receive2Task_Handler);
			  if( xReturn == pdTRUE )
				{
				OLED_ShowString(3,40,"task2 send!",8,1);
		    OLED_Refresh();
				}
		}
/*****************************************************************************/		
	 }
		vTaskDelay(20);
	}
}

12-FreeRTOS任务通知代替计数信号量实验

/******************************2023年10月18日*************************************
这是一个任务通知代替计数信号量的实验,通过OLED与KEY观察现象。
KEY按下释放信号量,长按可一直释放信号量
take任务会一直获取信号量
*********************************************************************************/
#include "system.h"
#include "SysTick.h"
#include "led.h"
#include "key.h"
#include "oled.h"
#include "usart.h"
#include "FreeRTOS.h"
#include "task.h"
#include "limits.h"

//任务优先级
#define START_TASK_PRIO		1
//任务堆栈大小	
#define START_STK_SIZE 		128  
//任务句柄
TaskHandle_t StartTask_Handler;
//任务函数
void start_task(void *pvParameters);

//任务优先级
#define LED1_TASK_PRIO		2
//任务堆栈大小	
#define LED1_STK_SIZE 		50  
//任务句柄
TaskHandle_t LED1Task_Handler;
//任务函数
void led1_task(void *pvParameters);

//任务优先级
#define Take_TASK_PRIO		3
//任务堆栈大小	
#define Take_STK_SIZE 		512  
//任务句柄
TaskHandle_t TakeTask_Handler;
//任务函数
void Take_task(void *pvParameters);

//任务优先级
#define Give_TASK_PRIO		4
//任务堆栈大小	
#define Give_STK_SIZE 		512  
//任务句柄
TaskHandle_t GiveTask_Handler;
//任务函数
void Give_task(void *pvParameters);



/*******************************************************************************
* 函 数 名         : main
* 函数功能		   : 主函数
* 输    入         : 无
* 输    出         : 无
*******************************************************************************/
int main()
{
	SysTick_Init(72);
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);//设置系统中断优先级分组4
	USART1_Init(115200);
	KEY_Init();
	LED_Init();
	OLED_Init();
	OLED_ColorTurn(0);//0正常显示,1 反色显示             
  OLED_DisplayTurn(0);
	OLED_Clear();
	//创建开始任务
    xTaskCreate((TaskFunction_t )start_task,            //任务函数
                (const char*    )"start_task",          //任务名称
                (uint16_t       )START_STK_SIZE,        //任务堆栈大小
                (void*          )NULL,                  //传递给任务函数的参数
                (UBaseType_t    )START_TASK_PRIO,       //任务优先级
                (TaskHandle_t*  )&StartTask_Handler);   //任务句柄              
    vTaskStartScheduler();          //开启任务调度
}



//开始任务任务函数
void start_task(void *pvParameters)
{
	taskENTER_CRITICAL();           //进入临界区
    
	//创建LED1任务
    xTaskCreate((TaskFunction_t )led1_task,     
                (const char*    )"led1_task",   
                (uint16_t       )LED1_STK_SIZE, 
                (void*          )NULL,
                (UBaseType_t    )LED1_TASK_PRIO,
                (TaskHandle_t*  )&LED1Task_Handler); 
	
	//创建Take任务
    xTaskCreate((TaskFunction_t )Take_task,     
                (const char*    )"Take_task",   
                (uint16_t       )Take_STK_SIZE, 
                (void*          )NULL,
                (UBaseType_t    )Take_TASK_PRIO,
                (TaskHandle_t*  )&TakeTask_Handler);
				
	//创建Give任务
    xTaskCreate((TaskFunction_t )Give_task,     
                (const char*    )"Give_task",   
                (uint16_t       )Give_STK_SIZE, 
                (void*          )NULL,
                (UBaseType_t    )Give_TASK_PRIO,
                (TaskHandle_t*  )&GiveTask_Handler);
			
    vTaskDelete(StartTask_Handler); //删除开始任务
    taskEXIT_CRITICAL();            //退出临界区
} 

//LED1任务函数
void led1_task(void *pvParameters)
{
    while(1)
    {
        LED1=0;
        vTaskDelay(200);
        LED1=1;
        vTaskDelay(800);
    }
}

//Give任务函数
void Give_task(void *pvParameters)
{	
	BaseType_t xReturn = pdPASS;

	while(1)
	{
		if(KEY==1)
		{
			xReturn=xTaskNotifyGive(TakeTask_Handler);//发送任务通知
			if ( pdPASS == xReturn ) 
			{ 
				OLED_ShowString(3,0,"release one!",8,1);
			  OLED_Refresh();
			}
		}
		vTaskDelay(20);
	}
}

//Take任务函数
void Take_task(void *pvParameters)
{
	uint32_t take_num = pdTRUE;
	
	while(1)
	{
			take_num=ulTaskNotifyTake(pdFALSE,0);
			if(take_num > 0)
			  OLED_ShowNum(3,20,take_num,4,8,1);
			else
				OLED_ShowString(3,40,"wait",8,1); 
			OLED_Refresh();
	
		vTaskDelay(20);
	}
}

13-FreeRTOS任务通知代替事件组实验

/******************************2023年10月18日*************************************
这是一个任务通知代替事件组的实验,通过OLED与KEY观察现象。
KEY按下计数,通过计数的奇偶值来判断产生哪一个事件
*********************************************************************************/
#include "system.h"
#include "SysTick.h"
#include "led.h"
#include "key.h"
#include "oled.h"
#include "usart.h"
#include "FreeRTOS.h"
#include "task.h"
#include "limits.h"

//任务优先级
#define START_TASK_PRIO		1
//任务堆栈大小	
#define START_STK_SIZE 		128  
//任务句柄
TaskHandle_t StartTask_Handler;
//任务函数
void start_task(void *pvParameters);

//任务优先级
#define LED1_TASK_PRIO		2
//任务堆栈大小	
#define LED1_STK_SIZE 		50  
//任务句柄
TaskHandle_t LED1Task_Handler;
//任务函数
void led1_task(void *pvParameters);

//任务优先级
#define LED2_TASK_PRIO		3
//任务堆栈大小	
#define LED2_STK_SIZE 		50  
//任务句柄
TaskHandle_t LED2Task_Handler;
//任务函数
void led2_task(void *pvParameters);

//任务优先级
#define KEY_TASK_PRIO		4
//任务堆栈大小	
#define KEY_STK_SIZE 		512  
//任务句柄
TaskHandle_t KEYTask_Handler;
//任务函数
void key_task(void *pvParameters);


#define KEY1_EVENT  (0x01 << 0)//设置事件掩码的位0
#define KEY2_EVENT  (0x01 << 1)//设置事件掩码的位1




/*******************************************************************************
* 函 数 名         : main
* 函数功能		   : 主函数
* 输    入         : 无
* 输    出         : 无
*******************************************************************************/
int main()
{
	SysTick_Init(72);
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);//设置系统中断优先级分组4
	USART1_Init(115200);
	KEY_Init();
	LED_Init();
	OLED_Init();
	OLED_ColorTurn(0);//0正常显示,1 反色显示             
  OLED_DisplayTurn(0);
	OLED_Clear();
	//创建开始任务
    xTaskCreate((TaskFunction_t )start_task,            //任务函数
                (const char*    )"start_task",          //任务名称
                (uint16_t       )START_STK_SIZE,        //任务堆栈大小
                (void*          )NULL,                  //传递给任务函数的参数
                (UBaseType_t    )START_TASK_PRIO,       //任务优先级
                (TaskHandle_t*  )&StartTask_Handler);   //任务句柄              
    vTaskStartScheduler();          //开启任务调度
}



//开始任务任务函数
void start_task(void *pvParameters)
{
	taskENTER_CRITICAL();           //进入临界区
    
	//创建LED1任务
    xTaskCreate((TaskFunction_t )led1_task,     
                (const char*    )"led1_task",   
                (uint16_t       )LED1_STK_SIZE, 
                (void*          )NULL,
                (UBaseType_t    )LED1_TASK_PRIO,
                (TaskHandle_t*  )&LED1Task_Handler); 
	
	//创建LED2任务
    xTaskCreate((TaskFunction_t )led2_task,     
                (const char*    )"led2_task",   
                (uint16_t       )LED2_STK_SIZE, 
                (void*          )NULL,
                (UBaseType_t    )LED2_TASK_PRIO,
                (TaskHandle_t*  )&LED2Task_Handler);
				
	//创建KEY任务
    xTaskCreate((TaskFunction_t )key_task,     
                (const char*    )"key_task",   
                (uint16_t       )KEY_STK_SIZE, 
                (void*          )NULL,
                (UBaseType_t    )KEY_TASK_PRIO,
                (TaskHandle_t*  )&KEYTask_Handler);
			
    vTaskDelete(StartTask_Handler); //删除开始任务
    taskEXIT_CRITICAL();            //退出临界区
} 

//LED1任务函数
void led1_task(void *pvParameters)
{
    while(1)
    {
        LED1=0;
        vTaskDelay(200);
        LED1=1;
        vTaskDelay(800);
    }
}

//LED2任务函数
void led2_task(void *pvParameters)
{
    BaseType_t xReturn = pdTRUE;
	uint32_t r_event = 0;  /* 定义一个事件接收变量 */
	uint32_t last_event = 0;/* 定义一个保存事件的变量 */
	
	while(1)
    {
        //获取任务通知 ,没获取到则一直等待
		xReturn = xTaskNotifyWait(0x0,			//进入函数的时候不清除任务bit
								ULONG_MAX,	  //退出函数的时候清除所有的bitR
								&r_event,		  //保存任务通知值                    
								portMAX_DELAY);	//阻塞时间
                        
		if( pdTRUE == xReturn )
		{
			last_event |= r_event;
			if(last_event == (KEY1_EVENT|KEY2_EVENT))
			{
				last_event=0;
				LED2=!LED2;
			}
			else
				last_event = r_event;
		}
    }
}

//KEY任务函数
void key_task(void *pvParameters)
{
    u8 PRESS=0;
	while(1)
    {
		if(KEY==1)
		{ 
			PRESS++;
			while(KEY==1);      
			if(PRESS%2!=0)          
			{
       OLED_ShowString(3,0,"KEY1_EVENT!",8,1);
			 /* 触发一个事件1 */
			 xTaskNotify((TaskHandle_t	)LED2Task_Handler,//接收任务通知的任务句柄
						(uint32_t		)KEY1_EVENT,//要触发的事件
						(eNotifyAction)eSetBits);//设置任务通知值中的位
			}
			else
			{
			 OLED_ShowString(3,20,"KEY2_EVENT!",8,1);
			 /* 触发一个事件2 */
			 xTaskNotify((TaskHandle_t	)LED2Task_Handler,//接收任务通知的任务句柄
						(uint32_t		)KEY2_EVENT,//要触发的事件
						(eNotifyAction)eSetBits);//设置任务通知值中的位
			}
		 }
		OLED_Refresh();
		vTaskDelay(20);
    }
}

14-FreeRTOS内存管理实验

/******************************2023年10月18日*************************************
这是一个内存管理实验,通过OLED与KEY观察现象。
KEY按下计数,通过计数的奇偶值来判断产生申请内存还是释放内存
显示申请到的内存地址,以及申请内存后的剩余空间,以及系统运行时间
*********************************************************************************/
#include "system.h"
#include "SysTick.h"
#include "led.h"
#include "key.h"
#include "oled.h"
#include "usart.h"
#include "FreeRTOS.h"
#include "task.h"
#include "limits.h"

//任务优先级
#define START_TASK_PRIO		1
//任务堆栈大小	
#define START_STK_SIZE 		128  
//任务句柄
TaskHandle_t StartTask_Handler;
//任务函数
void start_task(void *pvParameters);
/******************************************************************************/
//任务优先级
#define LED1_TASK_PRIO		2
//任务堆栈大小	
#define LED1_STK_SIZE 		50  
//任务句柄
TaskHandle_t LED1Task_Handler;
//任务函数
void led1_task(void *pvParameters);
/******************************************************************************/
//任务优先级
#define KEY_TASK_PRIO		4
//任务堆栈大小	
#define KEY_STK_SIZE 		512  
//任务句柄
TaskHandle_t KEYTask_Handler;
//任务函数
void key_task(void *pvParameters);


uint8_t *Test_Ptr = NULL;




/*******************************************************************************
* 函 数 名         : main
* 函数功能		   : 主函数
* 输    入         : 无
* 输    出         : 无
*******************************************************************************/
int main()
{
	SysTick_Init(72);
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);//设置系统中断优先级分组4
	USART1_Init(115200);
	KEY_Init();
	LED_Init();
	OLED_Init();
	OLED_ColorTurn(0);//0正常显示,1 反色显示             
  OLED_DisplayTurn(0);
	OLED_Clear();
	//创建开始任务
    xTaskCreate((TaskFunction_t )start_task,            //任务函数
                (const char*    )"start_task",          //任务名称
                (uint16_t       )START_STK_SIZE,        //任务堆栈大小
                (void*          )NULL,                  //传递给任务函数的参数
                (UBaseType_t    )START_TASK_PRIO,       //任务优先级
                (TaskHandle_t*  )&StartTask_Handler);   //任务句柄              
    vTaskStartScheduler();          //开启任务调度
}



//开始任务任务函数
void start_task(void *pvParameters)
{
	taskENTER_CRITICAL();           //进入临界区
    
	 //创建LED1任务
    xTaskCreate((TaskFunction_t )led1_task,     
                (const char*    )"led1_task",   
                (uint16_t       )LED1_STK_SIZE, 
                (void*          )NULL,
                (UBaseType_t    )LED1_TASK_PRIO,
                (TaskHandle_t*  )&LED1Task_Handler); 
	
	//创建KEY任务
    xTaskCreate((TaskFunction_t )key_task,     
                (const char*    )"key_task",   
                (uint16_t       )KEY_STK_SIZE, 
                (void*          )NULL,
                (UBaseType_t    )KEY_TASK_PRIO,
                (TaskHandle_t*  )&KEYTask_Handler);
			
    vTaskDelete(StartTask_Handler); //删除开始任务
    taskEXIT_CRITICAL();            //退出临界区
} 

//LED1任务函数
void led1_task(void *pvParameters)
{
    while(1)
    {
        LED1=0;
        vTaskDelay(200);
        LED1=1;
        vTaskDelay(800);
    }
}


//KEY任务函数
void key_task(void *pvParameters)
{
    u8 PRESS=0;
	uint32_t g_memsize;
	
	while(1)
    {
		if(KEY==1)
		{
			while(KEY==1);
			PRESS++;
			if(PRESS%2!=0)
			{
			 if(NULL == Test_Ptr)
			{
				/* 获取当前内存大小 */
				g_memsize = xPortGetFreeHeapSize();   
				OLED_ShowString(3,0,"rest ram:",8,1);
				OLED_ShowNum(60,0,g_memsize,9,8,1);
				Test_Ptr = pvPortMalloc(1024);              //申请1k内存
				if(NULL != Test_Ptr)
				{
				 OLED_ShowString(3,20,"get ram:",8,1);
	       sprintf((char*)Test_Ptr," %#x \n",Test_Ptr);     //转变为16进制数据
				 OLED_ShowString(60,20,(char*)Test_Ptr,8,1);	   //显示地址

					/* 获取当前内剩余存大小 */
				 g_memsize = xPortGetFreeHeapSize();
				 OLED_ShowString(3,40,"rest ram:",8,1);
				 OLED_ShowNum(60,40,g_memsize,9,8,1);
						  
					//向Test_Ptr中写入当数据:当前系统时间
					sprintf((char*)Test_Ptr,"TickCount = %d \n",xTaskGetTickCount());
//					printf("写入的数据是 %s \n",(char*)Test_Ptr);
					OLED_ShowString(3,50,(char*)Test_Ptr,8,1);
				}
			}
			else
				printf("请先按下KEY2释放内存再申请\n");
			}
			else
		  {
			 		if(NULL != Test_Ptr)
			{ 
				OLED_Clear();
				OLED_ShowString(3,0,"clear ram",8,1);
				vPortFree(Test_Ptr);//释放内存
				Test_Ptr=NULL;
				/* 获取当前内剩余存大小 */
				g_memsize = xPortGetFreeHeapSize();
				OLED_ShowString(3,20,"rest ram:",8,1);
				OLED_ShowNum(60,20,g_memsize,9,8,1);
			}
			else
				printf("请先按下KEY1申请内存再释放\n");
			}
		 }
	    OLED_Refresh();
		vTaskDelay(20);
    }
}

15-FreeRTOS-CPU利用率实验

/******************************2023年10月18日*************************************
这是一个CPU利用率实验,通过USART1与XCOM观察现象。
串口会不断的打印CPU利用情况
本次需要使用硬件定时器来统计CPU运行时间,频率为10000HZ
需修改配置文件如下内容

/********************************************************************
          FreeRTOS与运行时间和任务状态收集有关的配置选项   
**********************************************************************/
//启用运行时间统计功能
//#define configGENERATE_RUN_TIME_STATS	        1             
 //启用可视化跟踪调试
//#define configUSE_TRACE_FACILITY				      1    
/* 与宏configUSE_TRACE_FACILITY同时为1时会编译下面3个函数
 * prvWriteNameToBuffer()
 * vTaskList(),
 * vTaskGetRunTimeStats()
*/
//#define configUSE_STATS_FORMATTING_FUNCTIONS	1                       
//                                                                        
//     extern volatile uint32_t CPU_RunTime;

//#define portCONFIGURE_TIMER_FOR_RUN_TIME_STATS()     (CPU_RunTime = 0ul)
//#define portGET_RUN_TIME_COUNTER_VALUE()              CPU_RunTime  

*********************************************************************************/
#include "system.h"
#include "SysTick.h"
#include "led.h"
#include "key.h"
#include "oled.h"
#include "usart.h"
#include "FreeRTOS.h"
#include "task.h"
#include "limits.h"
#include "timer.h"
#include "string.h"
/************************************************************/
//任务优先级
#define START_TASK_PRIO		1
//任务堆栈大小	
#define START_STK_SIZE 		128  
//任务句柄
TaskHandle_t StartTask_Handler;
//任务函数
void start_task(void *pvParameters);
/************************************************************/
//任务优先级
#define LED1_TASK_PRIO		2
//任务堆栈大小	
#define LED1_STK_SIZE 		50  
//任务句柄
TaskHandle_t LED1Task_Handler;
//任务函数
void led1_task(void *pvParameters);
/************************************************************/
//任务优先级
#define LED2_TASK_PRIO		3
//任务堆栈大小	
#define LED2_STK_SIZE 		50  
//任务句柄
TaskHandle_t LED2Task_Handler;
//任务函数
void led2_task(void *pvParameters);
/************************************************************/

//任务优先级
#define CPU_TASK_PRIO		4
//任务堆栈大小	
#define CPU_STK_SIZE 		512  
//任务句柄
TaskHandle_t CPUTask_Handler;
//任务函数
void CPU_task(void *pvParameters);
/************************************************************/



/*******************************************************************************
* 函 数 名         : main
* 函数功能		   : 主函数
* 输    入         : 无
* 输    出         : 无
*******************************************************************************/
int main()
{
	SysTick_Init(72);
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);//设置系统中断优先级分组4
	USART1_Init(115200);
	KEY_Init();
	LED_Init();
	TIM2_Int_Init(100-1,72-1);
	printf("Freertos CPU利用率实验\r\n");
	//创建开始任务
    xTaskCreate((TaskFunction_t )start_task,            //任务函数
                (const char*    )"start_task",          //任务名称
                (uint16_t       )START_STK_SIZE,        //任务堆栈大小
                (void*          )NULL,                  //传递给任务函数的参数
                (UBaseType_t    )START_TASK_PRIO,       //任务优先级
                (TaskHandle_t*  )&StartTask_Handler);   //任务句柄              
    vTaskStartScheduler();          //开启任务调度
}



//开始任务任务函数
void start_task(void *pvParameters)
{
	taskENTER_CRITICAL();           //进入临界区
    
	  //创建LED1任务
    xTaskCreate((TaskFunction_t )led1_task,     
                (const char*    )"led1_task",   
                (uint16_t       )LED1_STK_SIZE, 
                (void*          )NULL,
                (UBaseType_t    )LED1_TASK_PRIO,
                (TaskHandle_t*  )&LED1Task_Handler);

	//创建LED2任务
    xTaskCreate((TaskFunction_t )led2_task,     
                (const char*    )"led2_task",   
                (uint16_t       )LED2_STK_SIZE, 
                (void*          )NULL,
                (UBaseType_t    )LED2_TASK_PRIO,
                (TaskHandle_t*  )&LED2Task_Handler);
	
	//创建CPU任务
    xTaskCreate((TaskFunction_t )CPU_task,     
                (const char*    )"CPU_task",   
                (uint16_t       )CPU_STK_SIZE, 
                (void*          )NULL,
                (UBaseType_t    )CPU_TASK_PRIO,
                (TaskHandle_t*  )&CPUTask_Handler);
			
    vTaskDelete(StartTask_Handler); //删除开始任务
    taskEXIT_CRITICAL();            //退出临界区
} 

//LED1任务函数
void led1_task(void *pvParameters)
{
    while(1)
    {
        LED1=0;
        vTaskDelay(200);
		printf("LED1_Task Running,LED2_ON\r\n");
        LED1=1;
        vTaskDelay(800);
		printf("LED1_Task Running,LED2_OFF\r\n");
    }
}

//LED2任务函数
void led2_task(void *pvParameters)
{
    while(1)
    {
        LED2=0;
        vTaskDelay(800);
		printf("LED2_Task Running,LED2_ON\r\n");
        LED2=1;
        vTaskDelay(200);
		printf("LED2_Task Running,LED2_OFF\r\n");
    }
}

//CPU任务函数
void CPU_task(void *pvParameters)
{
    uint8_t CPU_RunInfo[400];//保存任务运行时间信息
	
	while(1)
    {
		memset(CPU_RunInfo,0,400);//信息缓冲区清零
		vTaskList((char *)&CPU_RunInfo);  //获取任务运行时间信息
		
		printf("---------------------------------------------\r\n");
		printf("任务名      任务状态 优先级   剩余栈 任务序号\r\n");
		printf("%s", CPU_RunInfo);
		printf("---------------------------------------------\r\n");

		memset(CPU_RunInfo,0,400);				//信息缓冲区清零

		vTaskGetRunTimeStats((char *)&CPU_RunInfo);

		printf("任务名       运行计数         利用率\r\n");
		printf("%s", CPU_RunInfo);
		printf("---------------------------------------------\r\n\n");
		vTaskDelay(1000);   /* 延时1000个tick */
    }
}

16-FreeRTOS中断管理实验

/******************************2023年10月18日*************************************
这是一个中断管理实验,通过设置中断优先级来起到控制作用。
freertos中断开关管理可以管理优先级低的
中断优先级数值越小,优先级越高。
默认中断管理阈值为5,优先级数值高于或等于5的中断可以被管理
任务优先级数值小于5的中断不会被管理,因为优先级更高。
*********************************************************************************/
#include "system.h"
#include "SysTick.h"
#include "led.h"
#include "key.h"
#include "oled.h"
#include "usart.h"
#include "FreeRTOS.h"
#include "task.h"
#include "limits.h"
#include "timer.h"
#include "string.h"
/************************************************************/
//任务优先级
#define START_TASK_PRIO		1
//任务堆栈大小	
#define START_STK_SIZE 		128  
//任务句柄
TaskHandle_t StartTask_Handler;
//任务函数
void start_task(void *pvParameters);

//任务优先级
#define LED1_TASK_PRIO		2
//任务堆栈大小	
#define LED1_STK_SIZE 		512 
//任务句柄
TaskHandle_t LED1Task_Handler;
//任务函数
void led1_task(void *pvParameters);


//任务优先级
#define Interrupt_TASK_PRIO		4
//任务堆栈大小	
#define Interrupt_STK_SIZE 		512  
//任务句柄
TaskHandle_t InterruptTask_Handler;
//任务函数
void Interrupt_task(void *pvParameters);


extern volatile uint32_t TIME2_RUN;
extern volatile uint32_t TIME3_RUN;
/*******************************************************************************
* 函 数 名         : main
* 函数功能		   : 主函数
* 输    入         : 无
* 输    出         : 无
*******************************************************************************/
int main()
{
	SysTick_Init(72);
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);//设置系统中断优先级分组4
	USART1_Init(115200);
	KEY_Init();
	LED_Init();
	OLED_Init();
	OLED_ColorTurn(0);//0正常显示,1 反色显示             
  OLED_DisplayTurn(0);
	OLED_Clear();
	TIM2_Int_Init(10000-1,7200-1);     //1s中断
	TIM3_Int_Init(10000-1,7200-1);     //1s中断
	printf("Freertos CPU利用率实验\r\n");
	//创建开始任务
    xTaskCreate((TaskFunction_t )start_task,            //任务函数
                (const char*    )"start_task",          //任务名称
                (uint16_t       )START_STK_SIZE,        //任务堆栈大小
                (void*          )NULL,                  //传递给任务函数的参数
                (UBaseType_t    )START_TASK_PRIO,       //任务优先级
                (TaskHandle_t*  )&StartTask_Handler);   //任务句柄              
    vTaskStartScheduler();          //开启任务调度
}



//开始任务任务函数
void start_task(void *pvParameters)
{
	taskENTER_CRITICAL();           //进入临界区
    
	 //创建LED1任务
    xTaskCreate((TaskFunction_t )led1_task,     
                (const char*    )"led1_task",   
                (uint16_t       )LED1_STK_SIZE, 
                (void*          )NULL,
                (UBaseType_t    )LED1_TASK_PRIO,
                (TaskHandle_t*  )&LED1Task_Handler); 
	
	 //创建Interrupt任务
    xTaskCreate((TaskFunction_t )Interrupt_task,     
                (const char*    )"Interrupt_task",   
                (uint16_t       )Interrupt_STK_SIZE, 
                (void*          )NULL,
                (UBaseType_t    )Interrupt_TASK_PRIO,
                (TaskHandle_t*  )&InterruptTask_Handler);
			
    vTaskDelete(StartTask_Handler); //删除开始任务
    taskEXIT_CRITICAL();            //退出临界区
} 

//LED1任务函数
void led1_task(void *pvParameters)
{   
    while(1)
    {
			OLED_ShowNum(3,0,TIME3_RUN,4,8,1);
			OLED_ShowNum(3,20,TIME2_RUN,4,8,1);
			OLED_Refresh();
      vTaskDelay(200);
    }
}

//Interrupt任务函数
void Interrupt_task(void *pvParameters)
{
    static u32 total_num=0;
	
	while(1)
    {
		total_num+=1; 
		if(total_num==5)
		{
			printf("关闭中断.............\r\n");
			portDISABLE_INTERRUPTS(); //关闭中断
			delay_xms(6000); //延时6s,使用不影响任务调度的延时
			printf("打开中断.............\r\n"); //打开中断
			portENABLE_INTERRUPTS();
		}
		LED2=!LED2;
		vTaskDelay(1000);
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1661116.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Linux虚拟机运行“yum install gcc-c++”报错“Loading mirror speeds from cached hostfile”

目录 一、在Linux上安装Redis时&#xff0c;在终端执行命令“yum install gcc-c”时&#xff0c;报错&#xff1a; 二、然后发现linux的网络不通&#xff0c;什么网站都访问不了 三、连上网后&#xff0c;再变换yum源 四、重新运行yum install gcc 一、在Linux上安装Redis时…

QT--5

1> 将网络聊天室重新实现一遍 服务器端 #include "widget.h" #include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget) {ui->setupUi(this);ser new QTcpServer(this); }Widget::~Widget() {delete ui; }vo…

js教程(13)

一、作用域 作用域规定了变量能够被访问的范围&#xff0c;而离开变量作用域的变量则不能被访问&#xff08;有时也叫变量的生命周期&#xff09;。作用域又分为局部作用域和全局作用域。 1.局部作用域 在函数或代码块内部声明的变量只能在其内部被访问&#xff0c;在外部无法…

Docker部署Azure chatgpt样例应用

Github地址 https://github.com/microsoft/sample-app-aoai-chatGPT?tabreadme-ov-file#environment-variables 使用Amazon Linux 2 AMI 的arm 64版本镜像, t4g.medium实例。 需要安装git&#xff0c;可能需要安装 pip3等 sudo apt-get install -y python3-pip 然后从如下…

AWS Lambda 第一个例子Hello (JAVA)

什么是Serverless&#xff08;无服务器计算&#xff09; 行业通常所说的Serverless&#xff0c;主要是指“无服务器计算&#xff08;Serverless Computing&#xff09;”。无服务器计算&#xff0c;并不是真的不需要服务器&#xff0c;而是说&#xff0c;对于用户&#xff0c;…

200-500人规模工厂网络方案(中小企业网络)

一、方案概述 工厂一般有单独的弱电房&#xff0c;类似这种 里面采用的方案如下&#xff1a; 主要考虑有线、无线、财务、办公、访客等业务&#xff0c;便于维护管理和后续扩容 还需要 Wi-Fi覆盖零死角高速率&#xff0c;工作不卡顿 同时考虑AV反病毒、IPS入侵防御、用户准…

C语言实现扫雷游戏完整版

游戏介绍&#xff1a; 目录 游戏介绍&#xff1a; 游戏框架&#xff1a; 游戏具体功能实现&#xff1a; 棋盘的定义&#xff1a; 棋盘初始化&#xff1a; 棋盘打印&#xff1a; 棋盘布置雷&#xff1a; 棋盘扫雷&#xff1a; 爆炸展开一片&#xff1a; 获取周围八个…

HTML【安装HBuilder、常用标签】--学习JavaEE的day44

day44 JavaEE 学习过程&#xff1a;前端—>数据库—>服务器端 前端的VUE在框架阶段学习 JavaEE学习过程图 HTML 前端&#xff1a;展示页面、与用户交互 — HTML 后端&#xff1a;数据的交互和传递 — JavaEE/JavaWeb 1. 前端开发的工作模式 开发输出htmlcssjs 理解&am…

keil5软件安装教程(MDKv5.39)

keil5软件安装分为三部分&#xff1a; 目录 1.安装mdk 2.激活mdk 3.安装STM32芯片包 1.安装mdk 安装包链接&#xff1a;链接&#xff1a;https://pan.baidu.com/s/1PZoGhzI5Y19ROv7xe9QJKA?pwdgt3s 提取码&#xff1a;gt3s 1、下载keil5的压缩包并解压&#xff0c;鼠…

浅谈如何利用 AI 提高内容生产效率?|TodayAI

在数字化时代&#xff0c;内容的创建和分发速度变得尤为关键。人工智能&#xff08;AI&#xff09;技术提供了加速这一过程的可能性&#xff0c;不仅提升了生产效率&#xff0c;还改善了内容的质量和受众的接受度。本文深入探讨AI如何在内容生成、分发与推广&#xff0c;以及内…

Linux下GraspNet复现流程

Linux&#xff0c;Ubuntu中GraspNet复现流程 文章目录 Linux&#xff0c;Ubuntu中GraspNet复现流程1.安装cuda和cudnn2.安装pytorch3.编译graspnetAPIReference &#x1f680;非常重要的环境配置&#x1f680; ubuntu 20.04cuda 11.0.1cudnn v8.9.7python 3.8.19pytorch 1.7.0…

如何使用openEuler 22.03 配置mail.rc给邮箱发送邮件

目录 需求环境总体步骤梳理详细步骤1. 安装mailx软件包&#xff08;centos默认安装&#xff0c;openEuler不默认安装&#xff09;2. 检查是否能ping得到smtp服务器3. 在qq邮箱开启smtp设置4. 修改/etc/mail.rc文件5. 测试 可能遇到的问题 需求 希望检查每日的备份和系统运行记…

在windows下安装wsl子系统

一、安装环境 windows规格 版本Windows 10企业版版本号22H2操作系统内部版本19045.4291 二、安装过程 2.1 以管理员身份打开PowerShell&#xff08;win X快捷键&#xff09;&#xff1b; 2.2 输入命令&#xff1a;wsl --list --online&#xff08;简写&#xff1a;wsl -l …

中北大学软件学院javaweb实验二JSP应用开发实验报告

实验时间 2024年4月 25 日17时至 22 时 学时数 4 1.实验名称 实验2&#xff1a;JSP应用开发(2学时) 2.实验目的 &#xff08;1&#xff09;学会编写和运行简单的JSP页面&#xff0c;理解其运行原理&#xff1b; &#xff08;2&#xff09;学会使用JSP的声明、表达式、脚…

【全开源】Java外卖霸王餐免费吃外卖小程序+APP+公众号+H5多端霸王餐源码

一、特色功能 霸王餐活动管理&#xff1a;允许商家发布和管理霸王餐活动&#xff0c;包括设置活动时间、具体优惠、活动规则等。用户参与与浏览&#xff1a;用户可以在小程序中浏览霸王餐活动列表&#xff0c;查看活动的详情信息&#xff0c;如商品或服务的免费赠送、活动规则…

MemoryModule - exp - test

文章目录 MemoryModule - exp - test概述笔记测试环境GetModuleFileName不能正常执行GetModuleFileNameWntdll_LdrGetDllFullName猜测原因用LoadLibrary载入的DLL中功能是正常的 gLog可以正常使用内存载入DLL无法支持的功能的折中方法COM操作正常调用方代码接口代码 接口入参测…

【竞技宝】欧冠:欧洲三大赛事决赛对阵出炉

本赛季欧洲三级赛事的决赛对阵均已出炉:皇马与多特蒙德相聚欧冠决赛;勒沃库森将会和亚特兰大争夺欧联杯冠军;奥林匹亚科斯则要与佛罗伦萨争夺欧协联的冠军。在6支决赛球队中,德甲和意甲都有两支球队,而西甲的皇马则是夺冠最大热门,近几个赛季战斗力极强的英超在欧战方面彻底失败…

Day 43 1049. 最后一块石头的重量 II 494. 目标和 474.一和零

最后一块石头重量Ⅱ 有一堆石头&#xff0c;每块石头的重量都是正整数。 每一回合&#xff0c;从中选出任意两块石头&#xff0c;然后将它们一起粉碎。假设石头的重量分别为 x 和 y&#xff0c;且 x < y。那么粉碎的可能结果如下&#xff1a; 如果 x y&#xff0c;那么两…

鸿蒙OpenHarmony技术:【Docker编译环境】

Docker环境介绍 OpenHarmony为开发者提供了两种Docker环境&#xff0c;以帮助开发者快速完成复杂的开发环境准备工作。两种Docker环境及适用场景如下&#xff1a; 独立Docker环境&#xff1a;适用于直接基于Ubuntu、Windows操作系统平台进行版本编译的场景。基于HPM的Docker环…

企业合规视角下的菜鸟网络与拼多多不正当竞争案

近日&#xff0c;浙江省高院对备受瞩目的“菜鸟网络诉拼多多不正当竞争案”做出终审判决。该案件从2022年初发酵至今&#xff0c;终于以法院驳回拼多多上诉、维持一审判决而告一段落。此案不仅在法律层面引起广泛关注&#xff0c;更在企业合规方面提供了重要的案例参考。 根据判…