Отправка строки через очередь во Freertos

#c #stm32 #freertos

#c #stm32 #freertos

Вопрос:

Я хочу создать задачу с помощью кнопки, и задача отправляет строку в очередь и создает другую задачу (это также может быть отдельная задача с более низким приоритетом), которая считывает очередь и мигает светодиодом, если его переменная совпадает со строкой в очереди. В противном случае система должна оставаться в режиме ожидания. Я совсем новичок в freertos, и индикатор не мигает с приведенными ниже кодами, хотя ошибки компиляции нет. Я также хочу заменить тип данных с char на string, если это возможно. (select и zyRxBuff поступают из разных источников, для простоты это написано как показано ниже)

 #include "main.h"
#include "FreeRTOS.h"
#include "task.h"
#include "timers.h"
#include "queue.h"
    
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
  

Обработчики ;

 QueueHandle_t myQueue = NULL;
TaskHandle_t QTASK1 = NULL;
TaskHandle_t QTASK2 = NULL;
  

Прототипы ;

 void Qsender(void* p);
void Qreceiver(void* p);
  

Основной блок;

 int main(void)
{

 HAL_Init();
 SystemClock_Config();
 MX_GPIO_Init();

if (HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_13) == GPIO_PIN_SET)
{
     xTaskCreate(Qsender, "SendingTask", 200, NULL, 1, amp;QTASK1);
     vTaskStartScheduler();
}
 while (1) {};
}
  

Функция отправителя;

 void Qsender(void* p)
{
  char select[10]= "BlinkLed";
    myQueue = xQueueCreate(1, sizeof(select));
    xQueueSend(myQueue, (void*) amp;select, (TickType_t)10);

    if (myQueue != 0)
    {
        xTaskCreate(Qreceiver, "ReceivingTask", 200, NULL, 1, amp;QTASK2);
    }

}
  

Функция получателя;

 void Qreceiver(void* p)
{
    char myRxBuff[10];
    char zyRxBuff[10]="BlinkLed";
    xQueueReceive(myQueue, amp;myRxBuff, (TickType_t)50);

    if ( myRxBuff == zyRxBuff)
    {
            HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_0);
            HAL_Delay(500);
    }
}
  

Функция ожидания;

 void vApplicationIdleHook(void){__WFI();};
  

Комментарии:

1. Что вы используете, C или C . Отредактируйте сообщение, чтобы сохранить только используемый вами тег. А вы компилировали и видели предупреждения или ошибки? Если это так, опубликуйте их, указав, где в коде они появились.

Ответ №1:

Ничего не происходит, потому что программа, вероятно, выполняется слишком быстро, чтобы что-то работало. Когда ваша программа запускается, она инициализирует все за долю секунды, и если кнопка не нажата, ничего не происходит. Тогда ваш основной цикл ничего не делает. Как минимум, вы должны поместить кнопку просмотра в задачу, и эта задача должна иметь while for цикл or, который не заканчивается.

Сначала создайте более простую систему, например, две задачи, считыватель кнопок и излучатель света. Задача чтения кнопок просто проверяет, нажата ли кнопка, и вставляет элемент в очередь. Источник света проверяет, есть ли что-то в очереди.

Следует также отметить, что всем ОСРВ действительно не нравится постоянно создавать и завершать задачи. Если вы собираетесь это сделать, вам следует прочитать о том, как создаются и уничтожаются задачи. (https://www.freertos.org/a00125.html ) Выход задачи из контекста не приводит к ее автоматической очистке, вам нужно использовать vTaskDelete — С вашими текущими функциями вам нужно будет очистить QReceiver с помощью вашей QSender задачи, что является нарушением принципов SOLID. Кроме того, вам QReceiver нужно будет отправить ответное сообщение о том, что это сделано. Если вы сможете сначала заставить их статически работать, будет намного проще заставить их работать динамически позже.

Я также заметил, что вы сравниваете строки по адресу, а не по содержимому. Qsender отправляет BlinkLed

 void Qsender(void* p){
    char select[10]= "BlinkLed";
    myQueue = xQueueCreate(1, sizeof(select));
    xQueueSend(myQueue, (void*) amp;select, (TickType_t)10);

    if (myQueue){
        xTaskCreate(Qreceiver, "ReceivingTask", 200, NULL, 1, amp;QTASK2);
    }
}
  

Однако в Qreceiver вы сравниваете адрес myRxBuff и zyRxBuff , когда вы должны выполнять сравнение строк

 void Qreceiver(void* p){
    char myRxBuff[10];
    char zyRxBuff[10]="BlinkLed";
    xQueueReceive(myQueue, amp;myRxBuff, (TickType_t)50);
    if ( myRxBuff == zyRxBuff){ // Offending Line
            HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_0);
            HAL_Delay(500);
    }
}

void Qreceiver(void* p){
    char myRxBuff[10];
    char zyRxBuff[10]="BlinkLed";
    xQueueReceive(myQueue, amp;myRxBuff, (TickType_t)50);
    if ( strcmp(myRxBuff, zyRxBuff) == 0){ // Should compare content now
            HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_0);
            HAL_Delay(500);
    }
}
  

Комментарии:

1. «Ничего не происходит, потому что программа, вероятно, выполняется слишком быстро, чтобы что-то работало. Когда ваша программа запускается, она инициализирует все за доли секунды, и если кнопка не нажата, ничего не происходит » обычно это то, что я хочу. Эти две задачи должны выполнить свои задачи, а затем система вернется в режим ожидания. Время их выполнения изменится, но они не будут находиться в бесконечном цикле. Может быть, я смогу создать новую задачу, которая будет управлять этими двумя задачами в качестве своих подзадач в цикле while.

2. Когда я отлаживаю текущий код, я увидел, что создано two task, но оно не входит в оператор if, это похоже на ошибку в xQueueReceive из-за неправильного использования назначений указателя / адреса.

3. К вашему первому пункту — если вы не удерживаете кнопку при включении платы, оператор if не будет выполнен, и первая задача не будет создана. Что касается вашего второго пункта — попробуйте использовать strcmp(a,b)=0 вместо == in QReceiver . Вы сравниваете адрес двух строк вместо фактического содержимого двух строк.

4. да, он мигает 🙂