二值信号量与事件组在不同任务中使用莫名奇妙获取不到二值信号量

今天在使用二值信号和事件组的时候发现获取不到二值信号量了,下面是原先的代码

/******************************************************************************************************/
/*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程序就正常了

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值