Title: Problems with xMessageBufferReceive. · feilipu/Arduino_FreeRTOS_Library · Discussion #128 · GitHub
Open Graph Title: Problems with xMessageBufferReceive. · feilipu/Arduino_FreeRTOS_Library · Discussion #128
X Title: Problems with xMessageBufferReceive. · feilipu/Arduino_FreeRTOS_Library · Discussion #128
Description: Problems with xMessageBufferReceive.
Open Graph Description: As a pedagogical exercise, I wrote an app with one task that blink a led and push some string in a Message buffer. (task1) Messages from the Message Buffer are sent over serial from another task (t...
X Description: As a pedagogical exercise, I wrote an app with one task that blink a led and push some string in a Message buffer. (task1) Messages from the Message Buffer are sent over serial from another task (t...
Opengraph URL: https://github.com/feilipu/Arduino_FreeRTOS_Library/discussions/128
X: @github
Domain: github.com
{"@context":"https://schema.org","@type":"QAPage","mainEntity":{"@type":"Question","name":"Problems with xMessageBufferReceive.","text":"\u003cp dir=\"auto\"\u003eAs a pedagogical exercise, I wrote an app with one task that blink a led and push some string in a Message buffer. (task1)\u003cbr\u003e\nMessages from the Message Buffer are sent over serial from another task (task2).\u003cbr\u003e\nI further used a binary semaphore and a mutex for regulating the access to the Message Buffer and the Serial.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eMy problem is that everything get stuck when I use xMessageBufferReceive().\u003cbr\u003e\nBelow a reproducible code, where I marked the non working part.\u003cbr\u003e\nIf you comment that section and uncomment e.g. the line above ( /* Serial.println(\"TEST\"); */) you will see that everything works.\u003cbr\u003e\nWhat I am doing wrong?\u003c/p\u003e\n\u003cdiv class=\"snippet-clipboard-content notranslate position-relative overflow-auto\" data-snippet-clipboard-copy-content=\"#include \u0026quot;FreeRTOSVariant.h\u0026quot;\n#include \u0026quot;HardwareSerial.h\u0026quot;\n#include \u0026quot;portable.h\u0026quot;\n#include \u0026quot;projdefs.h\u0026quot;\n#include \u0026lt;Arduino.h\u0026gt;\n#include \u0026lt;message_buffer.h\u0026gt;\n#include \u0026lt;semphr.h\u0026gt;\n\n// Global variables: semaphore and message buffer\n/* Create a message buffer to send data to the serial*/\nconst size_t MESSAGE_SIZE = 100;\nMessageBufferHandle_t xMessageBuffer = xMessageBufferCreate(MESSAGE_SIZE);\n\n/* Create a semaphore to control access to the message buffer */\n// TODO: do we really need static?\nstatic SemaphoreHandle_t xSemaphoreMessageBuffer = xSemaphoreCreateBinary();\nstatic SemaphoreHandle_t xSemaphoreSerialPort = xSemaphoreCreateMutex();\n\n// Task functions prototypes\nvoid task_blink(void *pVParameters);\nvoid task_serial(void *pVParameters);\n\nvoid setup() {\n\n // initialize serial communication at 9600 bits per second:\n const unsigned int BAUDRATE = 9600;\n Serial.begin(BAUDRATE);\n\n // TODO: is it really needed?\n while (!Serial) {\n ; // wait for serial port to connect. Needed for native USB, on LEONARDO,\n }\n\n // Release all the semaphore at the very beginning.\n xSemaphoreGive(xSemaphoreMessageBuffer);\n xSemaphoreGive(xSemaphoreSerialPort);\n\n // Task: Blink\n const size_t STACK_SIZE_BLINK = 128;\n const uint8_t PRIORITY_BLINK = 2;\n TaskHandle_t xTaskHandleBlink;\n\n xTaskCreate(task_blink, \u0026quot;Blink\u0026quot;, STACK_SIZE_BLINK, NULL, PRIORITY_BLINK,\n \u0026amp;xTaskHandleBlink);\n\n // Task: Serial\n const size_t STACK_SIZE_SERIAL = 128;\n const uint8_t PRIORITY_SERIAL = 2;\n TaskHandle_t xTaskHandleSerial;\n\n xTaskCreate(task_serial, \u0026quot;Serial\u0026quot;, STACK_SIZE_SERIAL, NULL, PRIORITY_SERIAL,\n \u0026amp;xTaskHandleSerial);\n}\n// Skip loop. OBS! IdleTask cannot be used!\nvoid loop() {}\n\n// Task implementation\nvoid task_blink(void *pVParameters) // This is a task.\n{\n (void)pVParameters;\n const int TASK_PERIOD = 1000;\n\n // initialize digital LED_BUILTIN on pin 13 as an output.\n pinMode(LED_BUILTIN, OUTPUT);\n static uint8_t counter = 0;\n const size_t MAX_COUNT = 2;\n\n // Condition for sending a message over the serial port\n boolean isMessageBufferSemaphoreTaken;\n boolean isMessageShortEnough;\n\n while (true) {\n static bool led_state = false;\n // send something every MAX_COUNT*TASK_PERIOD seconds.\n\n if (!led_state) {\n digitalWrite(LED_BUILTIN, HIGH);\n led_state = true;\n } else {\n digitalWrite(LED_BUILTIN, LOW);\n led_state = false;\n }\n\n char message[] = \u0026quot;dog\u0026quot;;\n if (counter == MAX_COUNT) {\n\n // Debug\n /* Serial.print(\u0026quot;Available space in message buffer: \u0026quot;); */\n /* Serial.println(xMessageBufferSpacesAvailable((xMessageBuffer))); */\n\n // Check if you can send a message\n isMessageBufferSemaphoreTaken =\n xSemaphoreTake(xSemaphoreMessageBuffer, 1000 / portTICK_PERIOD_MS) ==\n pdTRUE;\n isMessageShortEnough =\n xMessageBufferSpacesAvailable((xMessageBuffer)) \u0026gt; strlen(message);\n\n if (isMessageBufferSemaphoreTaken \u0026amp;\u0026amp; isMessageShortEnough) {\n xMessageBufferSend(xMessageBuffer, message, sizeof(message), 0);\n /* Serial.println(\u0026quot;Message sent!\u0026quot;); */\n xSemaphoreGive(xSemaphoreMessageBuffer);\n }\n counter = 0;\n } else {\n counter++;\n }\n\n // Task Schedule\n const TickType_t X_DELAY = TASK_PERIOD / portTICK_PERIOD_MS;\n vTaskDelay(X_DELAY); // one tick delay (15ms)\n }\n}\n\nvoid task_serial(void *pVParameters) // This is a task.\n{\n (void)pVParameters;\n const uint8_t TASK_PERIOD = 200;\n uint8_t received_data[MESSAGE_SIZE];\n size_t received_bytes;\n received_bytes = 0;\n\n boolean isMessageBufferSemaphoreTaken;\n boolean isSerialSemaphoreTaken;\n boolean isMessageBufferEmpty;\n\n while (true) {\n // Conditions for writing on the serial\n\n isSerialSemaphoreTaken =\n xSemaphoreTake(xSemaphoreSerialPort, 1000 / portTICK_PERIOD_MS) ==\n pdTRUE;\n isMessageBufferSemaphoreTaken =\n xSemaphoreTake(xSemaphoreMessageBuffer, 1000 / portTICK_PERIOD_MS) ==\n pdTRUE;\n isMessageBufferEmpty = xMessageBufferIsEmpty(xMessageBuffer) == pdTRUE;\n\n if (isSerialSemaphoreTaken) {\n if (isMessageBufferSemaphoreTaken) {\n if (!isMessageBufferEmpty) {\n /* Serial.println(\u0026quot;TEST\u0026quot;); */\n\n /* ------------- BEGIN NON-WORKING PART!!! -----------*/\n received_bytes = xMessageBufferReceive(xMessageBuffer, received_data,\n sizeof(received_data), 0);\n Serial.println(received_bytes);\n /* ------------- END NON-WORKING PART!!! -----------*/\n }\n xSemaphoreGive(xSemaphoreMessageBuffer);\n /* Serial.println(\u0026quot;(serial) Semaphore MessageBuffer released.\u0026quot;); */\n }\n xSemaphoreGive(xSemaphoreSerialPort);\n /* Serial.println(\u0026quot;(serial) Semaphore serial port released.\u0026quot;); */\n }\n\n // TODO: Task Schedule\n const TickType_t X_DELAY = TASK_PERIOD / portTICK_PERIOD_MS;\n vTaskDelay(X_DELAY); // one tick delay (15ms)\n }\n}\"\u003e\u003cpre class=\"notranslate\"\u003e\u003ccode class=\"notranslate\"\u003e#include \"FreeRTOSVariant.h\"\n#include \"HardwareSerial.h\"\n#include \"portable.h\"\n#include \"projdefs.h\"\n#include \u0026lt;Arduino.h\u0026gt;\n#include \u0026lt;message_buffer.h\u0026gt;\n#include \u0026lt;semphr.h\u0026gt;\n\n// Global variables: semaphore and message buffer\n/* Create a message buffer to send data to the serial*/\nconst size_t MESSAGE_SIZE = 100;\nMessageBufferHandle_t xMessageBuffer = xMessageBufferCreate(MESSAGE_SIZE);\n\n/* Create a semaphore to control access to the message buffer */\n// TODO: do we really need static?\nstatic SemaphoreHandle_t xSemaphoreMessageBuffer = xSemaphoreCreateBinary();\nstatic SemaphoreHandle_t xSemaphoreSerialPort = xSemaphoreCreateMutex();\n\n// Task functions prototypes\nvoid task_blink(void *pVParameters);\nvoid task_serial(void *pVParameters);\n\nvoid setup() {\n\n // initialize serial communication at 9600 bits per second:\n const unsigned int BAUDRATE = 9600;\n Serial.begin(BAUDRATE);\n\n // TODO: is it really needed?\n while (!Serial) {\n ; // wait for serial port to connect. Needed for native USB, on LEONARDO,\n }\n\n // Release all the semaphore at the very beginning.\n xSemaphoreGive(xSemaphoreMessageBuffer);\n xSemaphoreGive(xSemaphoreSerialPort);\n\n // Task: Blink\n const size_t STACK_SIZE_BLINK = 128;\n const uint8_t PRIORITY_BLINK = 2;\n TaskHandle_t xTaskHandleBlink;\n\n xTaskCreate(task_blink, \"Blink\", STACK_SIZE_BLINK, NULL, PRIORITY_BLINK,\n \u0026amp;xTaskHandleBlink);\n\n // Task: Serial\n const size_t STACK_SIZE_SERIAL = 128;\n const uint8_t PRIORITY_SERIAL = 2;\n TaskHandle_t xTaskHandleSerial;\n\n xTaskCreate(task_serial, \"Serial\", STACK_SIZE_SERIAL, NULL, PRIORITY_SERIAL,\n \u0026amp;xTaskHandleSerial);\n}\n// Skip loop. OBS! IdleTask cannot be used!\nvoid loop() {}\n\n// Task implementation\nvoid task_blink(void *pVParameters) // This is a task.\n{\n (void)pVParameters;\n const int TASK_PERIOD = 1000;\n\n // initialize digital LED_BUILTIN on pin 13 as an output.\n pinMode(LED_BUILTIN, OUTPUT);\n static uint8_t counter = 0;\n const size_t MAX_COUNT = 2;\n\n // Condition for sending a message over the serial port\n boolean isMessageBufferSemaphoreTaken;\n boolean isMessageShortEnough;\n\n while (true) {\n static bool led_state = false;\n // send something every MAX_COUNT*TASK_PERIOD seconds.\n\n if (!led_state) {\n digitalWrite(LED_BUILTIN, HIGH);\n led_state = true;\n } else {\n digitalWrite(LED_BUILTIN, LOW);\n led_state = false;\n }\n\n char message[] = \"dog\";\n if (counter == MAX_COUNT) {\n\n // Debug\n /* Serial.print(\"Available space in message buffer: \"); */\n /* Serial.println(xMessageBufferSpacesAvailable((xMessageBuffer))); */\n\n // Check if you can send a message\n isMessageBufferSemaphoreTaken =\n xSemaphoreTake(xSemaphoreMessageBuffer, 1000 / portTICK_PERIOD_MS) ==\n pdTRUE;\n isMessageShortEnough =\n xMessageBufferSpacesAvailable((xMessageBuffer)) \u0026gt; strlen(message);\n\n if (isMessageBufferSemaphoreTaken \u0026amp;\u0026amp; isMessageShortEnough) {\n xMessageBufferSend(xMessageBuffer, message, sizeof(message), 0);\n /* Serial.println(\"Message sent!\"); */\n xSemaphoreGive(xSemaphoreMessageBuffer);\n }\n counter = 0;\n } else {\n counter++;\n }\n\n // Task Schedule\n const TickType_t X_DELAY = TASK_PERIOD / portTICK_PERIOD_MS;\n vTaskDelay(X_DELAY); // one tick delay (15ms)\n }\n}\n\nvoid task_serial(void *pVParameters) // This is a task.\n{\n (void)pVParameters;\n const uint8_t TASK_PERIOD = 200;\n uint8_t received_data[MESSAGE_SIZE];\n size_t received_bytes;\n received_bytes = 0;\n\n boolean isMessageBufferSemaphoreTaken;\n boolean isSerialSemaphoreTaken;\n boolean isMessageBufferEmpty;\n\n while (true) {\n // Conditions for writing on the serial\n\n isSerialSemaphoreTaken =\n xSemaphoreTake(xSemaphoreSerialPort, 1000 / portTICK_PERIOD_MS) ==\n pdTRUE;\n isMessageBufferSemaphoreTaken =\n xSemaphoreTake(xSemaphoreMessageBuffer, 1000 / portTICK_PERIOD_MS) ==\n pdTRUE;\n isMessageBufferEmpty = xMessageBufferIsEmpty(xMessageBuffer) == pdTRUE;\n\n if (isSerialSemaphoreTaken) {\n if (isMessageBufferSemaphoreTaken) {\n if (!isMessageBufferEmpty) {\n /* Serial.println(\"TEST\"); */\n\n /* ------------- BEGIN NON-WORKING PART!!! -----------*/\n received_bytes = xMessageBufferReceive(xMessageBuffer, received_data,\n sizeof(received_data), 0);\n Serial.println(received_bytes);\n /* ------------- END NON-WORKING PART!!! -----------*/\n }\n xSemaphoreGive(xSemaphoreMessageBuffer);\n /* Serial.println(\"(serial) Semaphore MessageBuffer released.\"); */\n }\n xSemaphoreGive(xSemaphoreSerialPort);\n /* Serial.println(\"(serial) Semaphore serial port released.\"); */\n }\n\n // TODO: Task Schedule\n const TickType_t X_DELAY = TASK_PERIOD / portTICK_PERIOD_MS;\n vTaskDelay(X_DELAY); // one tick delay (15ms)\n }\n}\n\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e","upvoteCount":1,"answerCount":4,"acceptedAnswer":{"@type":"Answer","text":"\u003cp dir=\"auto\"\u003eWithout looking in detail, using \u003ccode class=\"notranslate\"\u003eSerial.println()\u003c/code\u003e is an Arduino C++ trap. Expect to need over 512 bytes of stack to instantiate that class of functions, IIRC, and 128 bytes is nowhere near sufficient. Check other past issues here for more details.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003ePerhaps test and report if you could, please. Then we can look in more detail.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eThere's a low level print function available as an option, IIRC.\u003c/p\u003e","upvoteCount":1,"url":"https://github.com/feilipu/Arduino_FreeRTOS_Library/discussions/128#discussioncomment-8029867"}}}
| route-pattern | /_view_fragments/Voltron::DiscussionsFragmentsController/show/:user_id/:repository/:discussion_number/discussion_layout(.:format) |
| route-controller | voltron_discussions_fragments |
| route-action | discussion_layout |
| fetch-nonce | v2:d98745b0-9aee-53e6-4067-85d27dee52b1 |
| current-catalog-service-hash | 9f0abe34da433c9b6db74bffa2466494a717b579a96b30a5d252e5090baea7be |
| request-id | C07C:33DDB5:28433A:3A11BB:6A61E217 |
| html-safe-nonce | 8e4c92918df824541da7ca7e11946bfef33f7008e679d42ba777986918c97076 |
| visitor-payload | eyJyZWZlcnJlciI6IiIsInJlcXVlc3RfaWQiOiJDMDdDOjMzRERCNToyODQzM0E6M0ExMUJCOjZBNjFFMjE3IiwidmlzaXRvcl9pZCI6IjEwMTMyNzg2NjY2NDQ0NDQzOSIsInJlZ2lvbl9lZGdlIjoiaWFkIiwicmVnaW9uX3JlbmRlciI6ImlhZCJ9 |
| visitor-hmac | 63f6df6505a4a4c3d5398b7a4493b53f37833adbfd7ec97523814ceaac266e2f |
| hovercard-subject-tag | discussion:6034443 |
| github-keyboard-shortcuts | repository,copilot |
| google-site-verification | Apib7-x98H0j5cPqHWwSMm6dNU4GmODRoqxLiDzdx9I |
| octolytics-url | https://collector.github.com/github/collect |
| analytics-location | / |
| fb:app_id | 1401488693436528 |
| apple-itunes-app | app-id=1477376905, app-argument=https://github.com/_view_fragments/Voltron::DiscussionsFragmentsController/show/feilipu/Arduino_FreeRTOS_Library/128/discussion_layout |
| twitter:image | https://opengraph.githubassets.com/6ac016d014f6829f00ba1d3f768109752bf210d934df9b624cacab47d0c6486a/feilipu/Arduino_FreeRTOS_Library/discussions/128 |
| twitter:card | summary_large_image |
| og:image | https://opengraph.githubassets.com/6ac016d014f6829f00ba1d3f768109752bf210d934df9b624cacab47d0c6486a/feilipu/Arduino_FreeRTOS_Library/discussions/128 |
| og:image:alt | As a pedagogical exercise, I wrote an app with one task that blink a led and push some string in a Message buffer. (task1) Messages from the Message Buffer are sent over serial from another task (t... |
| og:image:width | 1200 |
| og:image:height | 600 |
| og:site_name | GitHub |
| og:type | object |
| hostname | github.com |
| expected-hostname | github.com |
| None | b2de8c74e5e61e893155ba46ee41bc66170c1644cb795adefa8386d490f7781c |
| turbo-cache-control | no-preview |
| go-import | github.com/feilipu/Arduino_FreeRTOS_Library git https://github.com/feilipu/Arduino_FreeRTOS_Library.git |
| octolytics-dimension-user_id | 3955592 |
| octolytics-dimension-user_login | feilipu |
| octolytics-dimension-repository_id | 46898167 |
| octolytics-dimension-repository_nwo | feilipu/Arduino_FreeRTOS_Library |
| octolytics-dimension-repository_public | true |
| octolytics-dimension-repository_is_fork | false |
| octolytics-dimension-repository_network_root_id | 46898167 |
| octolytics-dimension-repository_network_root_nwo | feilipu/Arduino_FreeRTOS_Library |
| turbo-body-classes | logged-out env-production page-responsive |
| disable-turbo | false |
| browser-stats-url | https://api.github.com/_private/browser/stats |
| browser-errors-url | https://api.github.com/_private/browser/errors |
| release | d1866027ded575df8a15c731dd8b9986c9483ceb |
| ui-target | full |
| theme-color | #1e2327 |
| color-scheme | light dark |
Links:
Viewport: width=device-width