最近在学习freeRTOS,学习到信号量的时候,发现了参数挺有意思的,所以用来记录一下;
BaseType_t xQueueSemaphoreTake( QueueHandle_t xQueue,TickType_t xTicksToWait );
参数:xTicksToWait;范围:0-portMAX_DELAY;
当值为0时,表示不需要阻塞等待;当值为portMAX_DELAY时,则表示一直处于阻塞等待中;
在同一个任务中,同时去接收两个信号量,计数信号量CountSemaph以及二值信号量BinarySemaph;代码如下:
if(TIM_GetITStatus(TIM9,TIM_IT_Update)==SET) //Òç³öÖжÏ
{
tick++;
if((tick%30) == 0)
{ //计数信号量
xHigherPriorityTaskWoken = pdFALSE;
xSemaphoreGiveFromISR(CountSemaph,&xHigherPriorityTaskWoken);
portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
}
if(tick >= 100)
{ //二值信号量
tick = 0;
xHigherPriorityTaskWoken = pdFALSE;
xSemaphoreGiveFromISR(BinarySemaph,&xHigherPriorityTaskWoken);
portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
}
TIM_ClearITPendingBit(TIM9,TIM_IT_Update); //清中断
}
/*--------------------------------------------------------------------------*/
/* LED0 */
void LED0_Task(void *pvParameters)
{
BaseType_t err=pdFALSE;
char *Sempr_Test = "¶þÖµÐźÅÁ¿½ÓÊÕ\r\n";
char *SemprC_Test = "¼ÆÊýÐźÅÁ¿½ÓÊÕ\r\n";
while(1)
{
err = xSemaphoreTake(BinarySemaph,10);
if(err==pdTRUE)
{
USART1_SendStr((uint8_t *)&Sempr_Test[0],strlen(Sempr_Test));
rLED_Toggle();
}
err = xSemaphoreTake(CountSemaph,10);
if(err==pdTRUE)
{
USART1_SendStr((uint8_t *)&SemprC_Test[0],strlen(SemprC_Test));
}
}
}
/*--------------------------------------------------------------------------*/
按照代码预期设定的值,定时器中断时间为10ms,计数100次,则二值信号量每1000ms发送一次值,计数信号量在1000ms的时间内,分别在300ms,600ms,900ms的时候发送一次值;
所以串口预期的结果是,每接收3次计数信号量后,接收一次二值信号量;
(1)当xTicksToWait = 10时,接收正常,每接收三次计数信号量,则接收一次二值信号量;
(2)当第一个xTicksToWait设置为portMAX_DELAY时,仅当二值信号量正常接收后,计数信号量才能正常读取之前缓存(900ms时)好的值;
如果二值信号量的频率拉长后,那么第二个信号量的接收也将受到影响;
所以,同一个任务接收多个信号量时,考虑到各个信号量的发送频率时间,我们也需要考虑信号量接收函数中的阻塞时间,避免阻塞时间为portMAX_DELAY,导致其他信号量接收受影响;
#记第一次写文章,所以不知道描述是否有所错误,大家多多包涵#