今天在使用二值信号和事件组的时候发现获取不到二值信号量了,下面是原先的代码
/******************************************************************************************************/
/*FreeRTOS配置*/
/* START_TASK 任务 配置
* 包括: 任务句柄 任务优先级 堆栈大小 创建任务
*/
#define START_TASK_PRIO 1 /* 任务优先级 */
#define START_STK_SIZE 128 /* 任务堆栈大小 */
TaskHandle_t StartTask_Handler; /* 任务句柄 */
void start_task(void *pvParameters); /* 任务函数 */
/* LV_DEMO_TASK 任务 配置
* 包括: 任务句柄 任务优先级 堆栈大小 创建任务
*/
#define LV_DEMO_TASK_PRIO 2 /* 任务优先级 */
#define LV_DEMO_STK_SIZE 1024 /* 任务堆栈大小 */
TaskHandle_t LV_DEMOTask_Handler; /* 任务句柄 */
void lv_demo_task(void *pvParameters); /* 任务函数 */
/* LED_TASK 任务 配置
* 包括: 任务句柄 任务优先级 堆栈大小 创建任务
*/
#define LED_TASK_PRIO 7 /* 任务优先级 */
#define LED_STK_SIZE 128 /* 任务堆栈大小 */
TaskHandle_t LEDTask_Handler; /* 任务句柄 */
void led_task(void *pvParameters); /* 任务函数 */
//任务优先级
#define RC522_TASK_PRIO 6
//任务堆栈大小
#define RC522_STK_SIZE 512 //如果设置成512那么所有的任务加起来刚好1024,可能内存不够所以获取不到二值信号量
//任务句柄
TaskHandle_t RC522_Task_Handler;
//任务函数
void Read_RC522_task(void *pvParameters);
//任务优先级
#define key_TASK_PRIO 2
//任务堆栈大小
#define key_STK_SIZE 128
//任务句柄
TaskHandle_t key_Task_Handler;
//任务函数
void key_free_task(void *pvParameters);
//任务优先级
#define load_scr_TASK_PRIO 4
//任务堆栈大小
#define load_scr_STK_SIZE 128
//任务句柄
TaskHandle_t load_scr_Task_Handler;
//任务函数
void load_scr_task(void *pvParameters);
//任务优先级
#define Open_lock_PRIO 4
//任务堆栈大小
#define Open_lock_STK_SIZE 128
//任务句柄
TaskHandle_t Open_lock_Handler;
//任务函数
void Open_lock_Task(void *pvParameters);
//外部变量声明
extern Root_ID_node ID_Root;
//变量定义
uint8_t RC522_Data_Buff[4]={0};//每个元素是一个一位数组且有两个第一个存放卡号,第二个存放序列号
/******************************************************************************************************/
EventGroupHandle_t EventGroup_Handle_t;
QueueHandle_t Semaphore_Handle;//二值信号量句柄,也就是一个队列指针
QueueHandle_t Open_lock_Semaphore_Handle;//开锁二值信号量句柄,也就是一个队列指针
/**
* @brief lvgl_demo入口函数
* @param 无
* @retval 无
*/
void lvgl_demo(void)
{
lv_init(); /* lvgl系统初始化 */
lv_port_disp_init(); /* lvgl显示接口初始化,放在lv_init()的后面 */
lv_port_indev_init(); /* lvgl输入接口初始化,放在lv_init()的后面 */
printf("22");
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(); /* 开启任务调度 */
}
/**
* @brief start_task
* @param pvParameters : 传入参数(未用到)
* @retval 无
*/
void start_task(void *pvParameters)
{
pvParameters = pvParameters;
//RC522事件组创建
EventGroup_Handle_t=xEventGroupCreate();
if(EventGroup_Handle_t!=NULL)
printf("创建事件组成功\r\n");
//创建开锁二值信号量
Semaphore_Handle=xSemaphoreCreateBinary();//Semaphore_Handle是一个指针类型
if(Semaphore_Handle!=NULL)
printf("二值信号量创建成功\r\n");
else
printf("二值信号量创建失败\r\n");
//创建开锁二值信号量
Open_lock_Semaphore_Handle=xSemaphoreCreateBinary();//Semaphore_Handle是一个指针类型
if(Open_lock_Semaphore_Handle!=NULL)
printf("开门二值信号量创建成功\r\n");
else
printf("开门二值信号量创建失败\r\n");
taskENTER_CRITICAL(); /* 进入临界区 */
/* 创建LVGL任务 */
xTaskCreate((TaskFunction_t )lv_demo_task,
(const char* )"lv_demo_task",
(uint16_t )LV_DEMO_STK_SIZE,
(void* )NULL,
(UBaseType_t )LV_DEMO_TASK_PRIO,
(TaskHandle_t* )&LV_DEMOTask_Handler);
/* LED测试任务 */
xTaskCreate((TaskFunction_t )led_task,
(const char* )"led_task",
(uint16_t )LED_STK_SIZE,
(void* )NULL,
(UBaseType_t )LED_TASK_PRIO,
(TaskHandle_t* )&LEDTask_Handler);
// //创建TASK1任务
xTaskCreate((TaskFunction_t )Read_RC522_task,
(const char* )"Read_RC522_task",
(uint16_t )RC522_STK_SIZE,
(void* )NULL,
(UBaseType_t )RC522_TASK_PRIO,
(TaskHandle_t* )&RC522_Task_Handler);
// //创建TASK1任务
xTaskCreate((TaskFunction_t )key_free_task,
(const char* )"key_free_task",
(uint16_t )key_STK_SIZE,
(void* )NULL,
(UBaseType_t )key_TASK_PRIO,
(TaskHandle_t* )&key_Task_Handler);
// //创建TASK1任务
xTaskCreate((TaskFunction_t )load_scr_task,
(const char* )"load_scr_task",
(uint16_t )load_scr_STK_SIZE,
(void* )NULL,
(UBaseType_t )load_scr_TASK_PRIO,
(TaskHandle_t* )&load_scr_Task_Handler);
//创建开锁任务
xTaskCreate((TaskFunction_t )Open_lock_Task,
(const char* )"Open_lock_Task",
(uint16_t )Open_lock_STK_SIZE,
(void* )NULL,
(UBaseType_t )Open_lock_PRIO,
(TaskHandle_t* )&Open_lock_Handler);
taskEXIT_CRITICAL(); /* 退出临界区 */
vTaskDelete(StartTask_Handler); /* 删除开始任务 */
}
/**
* @brief LVGL运行例程
* @param pvParameters : 传入参数(未用到)
* @retval 无
*/
void lv_demo_task(void *pvParameters)
{
pvParameters = pvParameters;
//lv_demo_stress(); /* 测试的demo */
//my_gui();
//register_Init();
printf("11");
//ID_Control_Init();
OpenDoor_Init();
while(1)
{
lv_timer_handler(); /* LVGL计时器 */
vTaskDelay(1);
}
}
/**
* @brief led_task
* @param pvParameters : 传入参数(未用到)
* @retval 无
*/
void led_task(void *pvParameters)
{
pvParameters = pvParameters;
while(1)
{
LED0_TOGGLE();
vTaskDelay(1000);
}
}
/*
RC522Task
*/
void Read_RC522_task(void *pvParameters)
{
uint8_t buff[2]={0};
uint8_t Anticoll[4]={0};//卡的序列号
EventBits_t event_bit=0;
char debug_buff[20];
while(1)
{
// vTaskList(debug_buff);
event_bit=xEventGroupWaitBits(EventGroup_Handle_t,//事件标志组句柄
1<<0,//等待事件标志组的bit0置1
pdFAIL,//成功等待事件标志位后不清除事件标志组中的bit0直到读卡成功
pdTRUE,//等待事件标志组bit0和bit1位都置1,就成立
portMAX_DELAY);//死等
printf("55\r\n");
//获取二值信号量
if(PcdRequest(0x26,buff)==0x26)//寻卡
{
//printf("333\r\n");
if(PcdAnticoll(Anticoll)==0x26)//获得卡号类型,防冲撞获得卡序列号
{
printf("0x26");
// xEventGroupClearBits(EventGroup_Handle_t,1<<0);//清除标志位,让任务挂起
ID_Inforation* ID_In=(ID_Inforation*)malloc(sizeof(ID_Inforation));//为什么要写在这里呢?因为如果写在了while(1)循环前面那么每次添加卡号都是对同一内存块进行操作那么就会导致第一个卡录进去了,后续的卡都是对该空间进行操作
ID_In->ID_type[0]=buff[0];
ID_In->ID_type[1]=buff[1];
ID_In->ID_serial_number[0]=Anticoll[0];
ID_In->ID_serial_number[1]=Anticoll[1];
ID_In->ID_serial_number[2]=Anticoll[2];
ID_In->ID_serial_number[3]=Anticoll[3];
//printf("%x%x\r\n",ID_In->ID_type[0],ID_In->ID_type[1]);
//printf("%x%x%x%x\r\n",ID_In->ID_serial_number[0],ID_In->ID_serial_number[1],ID_In->ID_serial_number[2],ID_In->ID_serial_number[3]);
//得到卡序列号后需要查找是否已在,不在添加,在不添加
if(add_ID(&ID_Root,ID_In)==0)
{
printf("添加失败\r\n");
free(ID_In);//添加失败回收空间
}
else
printf("添加成功\r\n");
xEventGroupClearBits(EventGroup_Handle_t,1<<0);//清除标志位,让任务挂起
}
}
//printf("666\r\n");
vTaskDelay(10);
}
}
void key_free_task(void *pvParameters)
{
uint8_t key=0;
uint8_t er;
while(1){
key=key_scan(0);
if(key==KEY0_PRES)//释放节点
{
printf("qewf\r\n");
er=xSemaphoreGive(Semaphore_Handle);//当任务1的优先级小于任务2的优先级,
if(er!=1)
printf("释放失败\r\n");
else
printf("释放成功\r\n");
}
vTaskDelay(10);
}
}
//load页面
void load_scr_task(void *pvParameters)
{
uint8_t er;
while(1)
{
printf("567\r\n");
er=xSemaphoreTake(Semaphore_Handle,portMAX_DELAY);//当阻塞时间设置为最大时,任务会被添加到延时列表,并切换任务,所以当只有获取到信号量才会执行下面的程序
if(er!=1)
{
printf("获取失败\r\n");
}
else
printf("获取成功\r\n");
vTaskDelay(2);
}
}
void Open_lock_Task(void *pvParameters)
{
uint8_t err;
while(1){
err=xSemaphoreTake(Open_lock_Semaphore_Handle,portMAX_DELAY);
if(err!=pdTRUE)
printf("开锁二值信号量获取失败\r\n");
else
printf("开锁二值信号量获取成功\r\n");
printf("11");
vTaskDelay(2);
}
}
这只是一部分,有些二值信号量的释放我放在了别的文件,我这个的问题是加上了void Open_lock_Task(void *pvParameters)这个任务就无法使用了,经过排查是因为我任务的内存加起来刚好就是lv_demo_task()所申请的1024个字节 (所有的任务都是在这个任务中创建的),所以可能是内存不够导致的问题,将#define RC522_STK_SIZE 512中的512改128程序就正常了