信号量——二值信号量
信号量简介
信号量是操作系统的重要部分,信号量一般用来进行资源管理和任务同步。FreeRTOS中信号量分为二值信号量、互斥信号量、计数信号量和递归互斥信号量,应用场景各不同。
二值信号量
二值信号量简述
二值信号量通常用于互斥访问或同步,二值信号量和互斥信号量非常相似,但互斥信号量有优先级,二值信号量没有。因此二值信号量更适合用于同步,而互斥信号量适用于简单的互斥访问。二值信号量就是只有一个队列项的队列,这个特殊队列只有两种情况满的或者空的。
二值信号量函数
二值信号量创建
二值信号量获取
二值信号量释放
二值信号量实验
要求
程序
主程序
#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "led.h"
#include "timer.h"
#include "key.h"
#include "beep.h"
#include "string.h"
#include "malloc.h"
#include "FreeRTOS.h"
#include "task.h"
#include "semphr.h"
#define START_TASK_PRIO 1
#define TASK1_TASK_PRIO 2
#define DATAPROCESS_TASK_PRIO 3
#define START_STK_SIZE 256
#define TASK1_STK_SIZE 256
#define DATAPROCESS_STK_SIZE 256
TaskHandle_t StartTask_Handler;
TaskHandle_t Task1Task_Handler;
TaskHandle_t DataProcess_Handler;
void start_task(void *pvParameters);
void task1_task(void *pvParameters);
void DataProcess_task(void *pvParameters);
SemaphoreHandle_t BinarySemaphore;
#define LED1ON 1
#define LED1OFF 2
#define BEEPON 3
#define BEEPOFF 4
#define COMMANDERR 0XFF
void LowerToCap(u8 *str,u8 len)
{
u8 i;
for(i=0;i<len;i++)
{
if((96<str[i])&&(str[i]<123))
str[i]=str[i]-32;
}
}
u8 CommandProcess(u8 *str)
{
u8 CommandValue=COMMANDERR;
if(strcmp((char*)str,"LED1ON")==0) CommandValue=LED1ON;
else if(strcmp((char*)str,"LED1OFF")==0) CommandValue=LED1OFF;
else if(strcmp((char*)str,"BEEPON")==0) CommandValue=BEEPON;
else if(strcmp((char*)str,"BEEPOFF")==0) CommandValue=BEEPOFF;
return CommandValue;
}
int main(void)
{
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);
delay_init(168);
uart_init(115200);
LED_Init();
KEY_Init();
BEEP_Init();
my_mem_init(SRAMIN);
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();
BinarySemaphore=xSemaphoreCreateBinary();
xTaskCreate((TaskFunction_t )task1_task,
(const char* )"task1_task",
(uint16_t )TASK1_STK_SIZE,
(void* )NULL,
(UBaseType_t )TASK1_TASK_PRIO,
(TaskHandle_t* )&Task1Task_Handler);
xTaskCreate((TaskFunction_t )DataProcess_task,
(const char* )"keyprocess_task",
(uint16_t )DATAPROCESS_STK_SIZE,
(void* )NULL,
(UBaseType_t )DATAPROCESS_TASK_PRIO,
(TaskHandle_t* )&DataProcess_Handler);
vTaskDelete(StartTask_Handler);
taskEXIT_CRITICAL();
}
void task1_task(void *pvParameters)
{
while(1)
{
LED0=!LED0;
vTaskDelay(500);
}
}
void DataProcess_task(void *pvParameters)
{
u8 len=0;
u8 CommandValue=COMMANDERR;
BaseType_t err=pdFALSE;
u8 *CommandStr;
while(1)
{
if(BinarySemaphore!=NULL)
{
err=xSemaphoreTake(BinarySemaphore,portMAX_DELAY);
if(err==pdTRUE)
{
len=USART_RX_STA&0x3fff;
CommandStr=mymalloc(SRAMIN,len+1);
CommandStr[len]='\0';
LowerToCap(CommandStr,len);
CommandValue=CommandProcess(CommandStr);
if(CommandValue!=COMMANDERR)
{
printf("命令:%s\r\n",CommandStr);
switch(CommandValue)
{
case LED1ON:
LED1=0;
break;
case LED1OFF:
LED1=1;
break;
case BEEPON:
BEEP=1;
break;
case BEEPOFF:
BEEP=0;
break;
}
}
else
{
printf("命令无效!!\r\n");
}
USART_RX_STA=0;
memset(USART_RX_BUF,0,USART_REC_LEN);
myfree(SRAMIN,CommandStr);
}
}
else if(err==pdFALSE)
{
vTaskDelay(10);
}
}
}
串口中断服务函数程序
```c
extern SemaphoreHandle_t BinarySemaphore;
void USART1_IRQHandler(void)
{
u8 Res;
BaseType_t xHigherPriorityTaskWoken;
if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)
{
Res =USART_ReceiveData(USART1);
if((USART_RX_STA&0x8000)==0)
{
if(USART_RX_STA&0x4000)
{
if(Res!=0x0a)USART_RX_STA=0;
else USART_RX_STA|=0x8000;
}
else
{
if(Res==0x0d)USART_RX_STA|=0x4000;
else
{
USART_RX_BUF[USART_RX_STA&0X3FFF]=Res ;
USART_RX_STA++;
if(USART_RX_STA>(USART_REC_LEN-1))USART_RX_STA=0;
}
}
}
}
if((USART_RX_STA&0x8000)&&(BinarySemaphore!=NULL))
{
xSemaphoreGiveFromISR(BinarySemaphore,&xHigherPriorityTaskWoken);
portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
}
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)