Task isn't running again after running for the first time

HoldMyBeer
Posts: 4
Joined: Tue Dec 14, 2021 12:37 pm

Task isn't running again after running for the first time

Postby HoldMyBeer » Wed May 11, 2022 6:49 am

I'm writing a simple program to use queues between two tasks, where one task sends data to the queue, and the other task received data from the queue. Here's the code:
  1. #include <stdio.h>
  2. #include "freertos/FreeRTOS.h"
  3. #include "freertos/task.h"
  4. #include "freertos/queue.h"
  5. #include "driver/gpio.h"
  6.  
  7. // Create a constant that restricts ESP32 to use only one core when creating tasks
  8. #if CONFIGURE_FREERTOS_UNICORE
  9. static const BaseType_t app_cpu = 0;
  10. #else
  11. static const BaseType_t app_cpu = 1;
  12. #endif
  13.  
  14. static const uint8_t queue_length = 5;  // set max length of queue
  15. static QueueHandle_t queue;             // handle for the queue
  16.  
  17. void print_messages(void *parameters) {
  18.     int item;
  19.  
  20.     while(1) {
  21.         printf("Spaces in queue :: %d\n", uxQueueSpacesAvailable(queue));
  22.         if(xQueueReceive(queue, &item, 0) == pdTRUE) {
  23.             printf("Item received :: %d\n", item);
  24.         }
  25.         else {
  26.             printf("Item not received\n");
  27.         }
  28.  
  29.         vTaskDelay(1000 / portTICK_PERIOD_MS);
  30.     }
  31. }
  32.  
  33. void send_messages(void *parameters) {
  34.     static int num = 0;
  35.  
  36.     while(1) {
  37.         printf("Sending num :: %d\n", num);
  38.         if(xQueueSend(queue, &num, 0) != pdTRUE) {
  39.             printf("Queue is full\n");
  40.         }
  41.         printf("Sent num\n");
  42.         num++;
  43.         vTaskDelay(1000 / portTICK_PERIOD_MS);
  44.     }
  45. }
  46.  
  47. void app_main(void) {
  48.     vTaskDelay(1000 / portTICK_PERIOD_MS);
  49.     queue = xQueueCreate(queue_length, sizeof(int));
  50.  
  51.     xTaskCreatePinnedToCore(
  52.         send_messages,     // function handler for the task
  53.         "Send messages",   // name of task
  54.         2048,           // stack size for the task
  55.         NULL,           // pointer to argument we'd like to pass
  56.         1,              // priority
  57.         NULL,           // task handler
  58.         app_cpu         // which core to run
  59.     );
  60.  
  61.     xTaskCreatePinnedToCore(
  62.         print_messages,     // function handler for the task
  63.         "Print messages",   // name of task
  64.         1024,           // stack size for the task
  65.         NULL,           // pointer to argument we'd like to pass
  66.         1,              // priority
  67.         NULL,           // task handler
  68.         app_cpu         // which core to run
  69.     );
  70. }
Ideally, the tasks should get scheduled in a round-robin way since their priorities are the same. So, the "Send messages" task should write data to the queue, and the "Print messages" task should receive data from the queue and print it. It works for the first time when num = 0, but after that, from the logs, it seems that the "Send messages" task doesn't get to ever run. Here is how the console looks:
  1. Sending num :: 0
  2. Sent num
  3. Spaces in queue :: 4
  4. Item received :: 0
  5. Spaces in queue :: 5
  6. Item not received
  7. Spaces in queue :: 5
  8. Item not received
  9. Spaces in queue :: 5
  10. Item not received
  11. Spaces in queue :: 5
  12. Item not received
  13. Spaces in queue :: 5
If "Send messages" runs again, then it should print "Sending num :: <value of num>". Am I missing something here? What's wrong with the code?

markkuk
Posts: 38
Joined: Wed Mar 27, 2019 11:50 am

Re: Task isn't running again after running for the first time

Postby markkuk » Wed May 11, 2022 8:36 am

The stack for "Print messages" task is too small and it breaks the other task. In my system, the program crashes after first run of print_messages():

Code: Select all

Sending num :: 0
Sent num
Spaces in queue :: 4
Item received :: 0
Guru Meditation Error: Core  0 panic'ed (LoadProhibited). Exception was unhandled.

Core  0 register dump:
PC      : 0x40086a70  PS      : 0x00060033  A0      : 0x80085452  A1      : 0x3ffb0b50
Increasing the stack size to 2048 makes the code run correctly:

Code: Select all

Sending num :: 0
Sent num
Spaces in queue :: 4
Item received :: 0
Sending num :: 1
Sent num
Spaces in queue :: 4
Item received :: 1
Sending num :: 2
Sent num
Spaces in queue :: 4
Item received :: 2
Sending num :: 3
Sent num
Spaces in queue :: 4
Item received :: 3

HoldMyBeer
Posts: 4
Joined: Tue Dec 14, 2021 12:37 pm

Re: Task isn't running again after running for the first time

Postby HoldMyBeer » Wed May 11, 2022 9:05 am

Oh I wasn't getting the error for stack overflow. Anyways, fixed the stack size and it works! Thank you! :)

User avatar
mbratch
Posts: 303
Joined: Fri Jun 11, 2021 1:51 pm

Re: Task isn't running again after running for the first time

Postby mbratch » Wed May 11, 2022 6:27 pm

A stack overflow problem may not show a message depending upon whether the code is sane enough at that point to do so. Just keep in mind when providing stack space for a task what that task is calling. Functions like `printf` require a lot of stack.

Who is online

Users browsing this forum: Baidu [Spider], Google [Bot] and 105 guests