FreeRTOS标准库例程代码

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.mfbz.cn/a/611410.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

腾讯云coding代码托管平台配置问题公钥拉取失败提示 Permission denied(publickey)

前言 最近在学校有个课设多人开发一个游戏&#xff0c;要团队协作&#xff0c;选用了腾讯云的coding作为代码管理仓库&#xff0c;但在配置的时候遇到了一些问题&#xff0c;相比于github&#xff0c;发现腾讯的coding更难用&#xff0c;&#xff0c;&#xff0c;这里记录一下…

【进程替换】进程程序替换函数execl | 单进程程序替换原理

目录 直接看现象&#xff08;单进程&#xff09; 单进程程序替换原理 替换函数 直接看现象&#xff08;单进程&#xff09; 我们先使用execl来直接看现象man 3 execlexecute a file执行一个程序int execl(const char *path, const char *arg, ...);execl函数的返回值&#x…

使用GitLab自带的CI/CD功能在K8S集群里部署项目(四)

前置内容&#xff1a; 通过Docker Compose部署GitLab和GitLab Runner&#xff08;一&#xff09; 使用GitLab自带的CI/CD功能在本地部署项目&#xff08;二&#xff09; 使用GitLab自带的CI/CD功能在远程服务器部署项目&#xff08;三&#xff09; 一、K8S集群信息 节点名称…

Unity TileMap入门

概述 相信很多同学学习制作游戏都是从2D游戏开始制作的吧&#xff0c;瓦片地图相信大家都有接触&#xff0c;那接下来让我们学习一下这部分的内容吧&#xff01; Tilemap AnimationFrameRate:设置每帧动画的播放速率。Color:瓦片地图的颜色TileAnchor:锚点&#xff0c;&#x…

笔试强训week4

day1 Q1 难度⭐⭐ 小易的升级之路_牛客题霸_牛客网 (nowcoder.com) 题目&#xff1a; 小易经常沉迷于网络游戏.有一次,他在玩一个打怪升级的游戏,他的角色的初始能力值为 a.在接下来的一段时间内,他将会依次遇见n个怪物,每个怪物的防御力为b1,b2,b3...bn. 如果遇到的怪物防…

马斯克:脑机接口迎来首例植入者,芯片接线发生故障。

马斯克旗下的脑机接口公司Neuralink近日传出关于首例植入者诺兰阿博脑机接口芯片故障的消息。根据Neuralink发布的文章&#xff0c;诺兰阿博的脑机设备发生了故障&#xff0c;多根植入他大脑的接线已经脱落&#xff0c;导致获取数据量减少。目前该公司正在研究导致接线脱落的原…

Java进阶08 集合(续)Stream流

Java进阶08 集合&#xff08;续&#xff09;&Stream流 一、HashSet集合类&#xff08;续&#xff09; 1、JDK7(-)HashSet原理解析 1.1 底层结构 数组链表 1.2 执行过程 ①创建一个默认长度为16的数组&#xff0c;数组名为table ②根据元素的哈希值跟数组的长度求余计…

灰狼优化算法(Grey Wolf Optimizer)

注意&#xff1a;本文引用自专业人工智能社区Venus AI 更多AI知识请参考原站 &#xff08;[www.aideeplearning.cn]&#xff09; 算法引言 灰狼算法&#xff08;Grey Wolf Optimizer, GWO&#xff09;是一种受自然界灰狼行为启发的优化算法。它模拟了灰狼的社会层次和狩猎策…

JS实现初始化、动态点击切换激活样式

食用须知&#xff0c;不懂得把代码交给AI解释一下&#xff0c;明白流程就会用了&#xff0c;本文只有js与html&#xff0c;样式代码一概没有&#xff1a; 效果展示 1、点击显示的盒子代码 <div data-v-e1dd37c4"" class"news-container main-width-contain…

JAVA获取application.yml配置文件的属性值

application.yml配置参数 方式一&#xff1a;使用Value方式(常用) 语法 Value("${配置文件中的key:默认值}") Value("${配置文件中的key}")方法1&#xff1a;使用的类文件中定义变量&#xff0c;直接使用变量 import org.springframework.beans.factory.an…

通义千问2.5中文能力地表最强

随着人工智能技术的不断进步&#xff0c;智能问答系统已成为人们日常生活中不可或缺的一部分。阿里巴巴集团作为全球领先的科技公司&#xff0c;一直致力于AI领域的研发和创新。最近&#xff0c;阿里巴巴发布了其最新的智能问答系统——通义千问2.5。 通义千问2.5在AI问答领域…

抖音新店怎么对接达人?对接达人秘籍流程分享,让你学会找达人

大家好&#xff0c;我是电商花花。 新手怎么对接达人带货&#xff1f;这是我们新手商家 要考虑的问题。 很多新手抱怨自己新店铺不出单&#xff0c;没有销量&#xff0c;对接达人又怕达人看不上&#xff0c;没有达人愿意帮我带货&#xff0c;在面临这样的情况下不知道该怎么办…

基于自我对弈框架的偏好优化算法SPPO

传统的从人类反馈中进行强化学习&#xff08;RLHF&#xff09;的方法仰赖如Bradley-Terry模型等参数模型,但这样的模型难以充分捕捉人类偏好中的非递移性和非理性。最新的研究进展显示,直接使用偏好机率可以更准确地反映人类偏好,从而实现更灵活、更精确的语言模型对齐。本文提…

会话劫持攻击就在我们身边,我们要如何防范

会话劫持攻击&#xff08;Session Hijacking&#xff09;是一种网络攻击方式&#xff0c;攻击者通过某种手段获取到用户的会话标识&#xff08;Session ID&#xff09;&#xff0c;然后使用这个会话标识冒充合法用户进行恶意操作。这种攻击方式允许攻击者以合法用户的身份访问受…

Go语言系统学习笔记(一):基础篇

1. 写在前面 公司的新业务开发需要用到go语言&#xff0c;虽然之前没接触过这门语言&#xff0c;但在大模型的帮助下&#xff0c;边看项目边写代码也能进行go的项目开发&#xff0c;不过&#xff0c;写了一段时间代码之后&#xff0c;总感觉对go语言本身&#xff0c;我的知识体…

Python尝试安装 pyaudio 时遇到的错误信息表示安装过程失败,原因是找不到 Python.h 头文件

环境&#xff1a; Python 3.8.10 WSL2 问题描述&#xff1a; 尝试安装 pyaudio 时遇到的错误信息表示安装过程失败&#xff0c;原因是找不到 Python.h 头文件 error: subprocess-exited-with-error Building wheel for pyaudio (pyproject.toml) did not run successfully…

【数据结构】手把手带你玩转线性表

前言&#xff1a; 哈喽大家好&#xff0c;我是野生的编程萌新&#xff0c;首先感谢大家的观看。数据结构的学习者大多有这样的想法&#xff1a;数据结构很重要&#xff0c;一定要学好&#xff0c;但数据结构比较抽象&#xff0c;有些算法理解起来很困难&#xff0c;学的很累。我…

Ubuntu 安装 samba 实现文件共享

1. samba的安装: sudo apt-get install samba sudo apt-get install smbfs2. 创建共享目录 mkdir /home/share sudo chmod -R 777 /home/share3. 创建Samba配置文件: 3.1 保存现有的配置文件 sudo cp /etc/samba/smb.conf /etc/samba/smb.conf.bak3.2 打开现有的文件 sudo…

基于小波交叉谱分析的地震波走时变化测量(MATLAB)

地震波在地球介质中传播&#xff0c;带来了丰富的地下介质物性的信息&#xff0c;为了解地球内部结构及运动变化提供了可能。地球内部地震波速度的差异是人们确定地球圈层结构和横向不均匀性的重要物理参数&#xff0c;地下介质应力的变化和积累是地震的孕育和发生的原因&#…

百面算法工程师 | 传统图像处理——OpenCV

本文给大家带来的百面算法工程师是传统图像处理的面试总结&#xff0c;文章内总结了常见的提问问题&#xff0c;旨在为广大学子模拟出更贴合实际的面试问答场景。在这篇文章中&#xff0c;我们将介绍一些集几何变换和图像平滑处理&#xff0c;并提供参考的回答及其理论基础&…
最新文章