feat(rt/posix): Added FreeRTOS-Plus-POSIX message queues implementation

Note: The current mq_open() implementation is changed to match
      the POSIX standard.
This commit is contained in:
Jakob Hasse
2024-02-01 09:19:46 +08:00
parent 5448703663
commit bddc1e95ef
30 changed files with 2760 additions and 4 deletions

View File

@@ -0,0 +1,8 @@
# For more information about build system see
# https://docs.espressif.com/projects/esp-idf/en/latest/api-guides/build-system.html
# The following five lines of boilerplate have to be in your project's
# CMakeLists in this exact order for cmake to work correctly
cmake_minimum_required(VERSION 3.16)
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
project(posix_mqueue)

View File

@@ -0,0 +1,37 @@
| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 |
| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- | -------- | -------- |
# POSIX Message Queue Example
A simple example using a POSIX message queue. Two tasks are reading from and writing to a POSIX message queue.
## How to use example
### Hardware Required
This example should be able to run on any supported Espressif SoC development board.
### Build and Flash
Enter `idf.py -p PORT flash monitor` to build, flash and monitor the project.
(To exit the serial monitor, type ``Ctrl-]``.)
See the [Getting Started Guide](https://docs.espressif.com/projects/esp-idf/en/latest/get-started/index.html) for full steps to configure and use ESP-IDF to build projects.
## Example Output
If you see the following infinite console output, your example should be running correctly:
```
sending: 0
received: 0
sending: 1
received: 1
sending: 2
received: 2
sending: 3
received: 3
...
```

View File

@@ -0,0 +1,3 @@
idf_component_register(SRCS "posix_mqueue_example_main.c"
INCLUDE_DIRS "."
PRIV_REQUIRES rt)

View File

@@ -0,0 +1,101 @@
/*
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Unlicense OR CC0-1.0
*/
#include <stdio.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <unistd.h>
#include <stdbool.h>
#include <pthread.h>
#include <mqueue.h>
#include <string.h>
#include <errno.h>
#include <stdlib.h>
static int s_counter = 0;
const unsigned int MSG_PRIO = 0;
static void *sender_function(void * arg)
{
mqd_t *write_descr = (mqd_t*) arg;
while (true) {
printf("sending: %d\n", s_counter);
int result = mq_send(*write_descr, (const char*) &s_counter, sizeof(s_counter), MSG_PRIO);
if (result != 0) {
perror("Sending failed");
abort();
}
s_counter++;
sleep(1);
}
return NULL;
}
static void *receiver_function(void * arg)
{
mqd_t *read_descr = (mqd_t*) arg;
while (true) {
int msg;
int result = mq_receive(*read_descr, (char*) &msg, sizeof(msg), NULL);
if (result == -1) {
perror("Sending failed");
abort();
}
printf("received: %d\n", msg);
}
return NULL;
}
void app_main(void)
{
mqd_t write_descr;
mqd_t read_descr;
pthread_t sender;
pthread_t receiver;
struct mq_attr configuration = {
.mq_flags = 0, // ignored by mq_open
.mq_maxmsg = 10,
.mq_msgsize = sizeof(int),
.mq_curmsgs = 0 // ignored by mq_open
};
write_descr = mq_open("/my_queue", O_CREAT | O_WRONLY, S_IRUSR | S_IWUSR , &configuration);
if (write_descr == (mqd_t) -1) {
perror("Creating message queue failed");
abort();
}
read_descr = mq_open("/my_queue", O_RDONLY);
if (read_descr == (mqd_t) -1) {
perror("Opening message queue for reading failed");
abort();
}
int result;
result = pthread_create(&sender, NULL, sender_function, &write_descr);
if (result != 0) {
printf("Creating sender thread failed: %s", strerror(errno));
abort();
}
result = pthread_create(&receiver, NULL, receiver_function, &read_descr);
if (result != 0) {
printf("Creating receiver thread failed: %s", strerror(errno));
abort();
}
while (true) {
sleep(1000);
}
}

View File

@@ -0,0 +1,13 @@
# SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
# SPDX-License-Identifier: CC0-1.0
import pytest
from pytest_embedded import Dut
@pytest.mark.supported_targets
@pytest.mark.generic
def test_rt_mqueue_example(dut: Dut) -> None:
dut.expect_exact('sending: 0')
dut.expect_exact('received: 0')
dut.expect_exact('sending: 1')
dut.expect_exact('received: 1')