Compare commits

...

5 Commits
master ... dev

Author SHA1 Message Date
Frédéric Desbiens
3128f18b30 Adding maintenance log.
Signed-off-by: Frédéric Desbiens <frederic.desbiens@eclipse-foundation.org>
2025-07-17 09:18:42 -04:00
Frédéric Desbiens
b2beb17046 Merge pull request #449 from hnguyenHWI/master
Document GNU library compile flags for Linux and SMP Linux
2025-05-21 09:41:15 -04:00
Frédéric Desbiens
4fdc5dc0ae Merge pull request #447 from eclipse-threadx/implement_new_feature_424
Make queue max message size configurable
2025-04-15 08:46:53 -04:00
Huan Nguyen
20958ddcf9 Document GNU library compile flags for Linux and SMP Linux 2025-04-14 13:04:15 -06:00
Haithem Rahmani
87e5110346 Make queue max message size configurable
Summary
-------
This commit fixes the issue #424

Details
--------
- Add a the configuration option TX_QUEUE_MESSAGE_MAX_SIZE in the tx_api.h with default value
  set to TX_ULONG_16 to keep backword compatibility.
- Update the txe_queue_create() to check on TX_QUEUE_MESSAGE_MAX_SIZE rather than TX_ULONG_16
  as max message size.
- Add a new unitary test to cover the new change.
2025-04-02 16:51:36 +01:00
12 changed files with 702 additions and 7 deletions

214
CHANGELOG.md Normal file

File diff suppressed because one or more lines are too long

View File

@@ -328,6 +328,12 @@ extern "C" {
#define TX_TIMER_TICKS_PER_SECOND (100UL)
#endif
/* Define the default maximum message size in a queue. The default value is TX_16_ULONG, but may
be customized in tx_user.h or as a compilation option. */
#ifndef TX_QUEUE_MESSAGE_MAX_SIZE
#define TX_QUEUE_MESSAGE_MAX_SIZE TX_16_ULONG
#endif
/* Event numbers 0 through 4095 are reserved by Azure RTOS. Specific event assignments are:

View File

@@ -117,6 +117,13 @@
#define TX_TIMER_THREAD_PRIORITY ????
*/
/* Define the maximum size of a message in the a queue. the Default value is TX_ULONG_16.
the new value must be a multiple of ULONG. */
/*
#define TX_QUEUE_MESSAGE_MAX_SIZE TX_ULONG_16
*/
/* Define the common timer tick reference for use by other middleware components. The default
value is 10ms (i.e. 100 ticks, defined in tx_api.h), but may be replaced by a port-specific
version in tx_port.h or here.

View File

@@ -178,8 +178,8 @@ TX_THREAD *thread_ptr;
status = TX_SIZE_ERROR;
}
/* Check for an invalid message size - greater than 16. */
else if (message_size > TX_16_ULONG)
/* Check for an invalid message size - greater than TX_QUEUE_MESSAGE_MAX_SIZE 16 by default. */
else if (message_size > TX_QUEUE_MESSAGE_MAX_SIZE)
{
/* Invalid message size specified. */

View File

@@ -33,6 +33,26 @@ You should observe the compilation of sample_threadx.c (which is the demonstrati
application) and linking with tx.a. The resulting file DEMO is a binary file
that can be executed.
2.1 Includes
Notice that the demonstration Makefile includes defines for _GNU_SOURCE
and TX_LINUX_MULTI_CORE. These are necessary to enable GNU/Linux-specific
compatibility for ThreadX using the Linux kernel in multi-core devices,
including the option to control processor affinity. See the GNU documentation
on CPU affinity and Feature Test Macros for more information.
TX_LINUX_MULTI_CORE is necessary to enable code that constrains ThreadX to
one core, to prevent unintended behavior when threads execute simultaneously
across multiple cores. The enabled code configures CPU affinity, requiring
the use of macros such as CPU_SET and functions such as sched_setaffinity.
Access to these macros and functions (and the underlying types for the latter)
are enabled via the definition of _GNU_SOURCE.
When building your own application, the _GNU_SOURCE and TX_LINUX_MULTI_CORE
symbols can be defined by being passed to the compiler (e.g. -D_GNU_SOURCE) or
in the optional user-defined ThreadX user define file tx_user.h. In the latter
case, ensure that the symbol TX_INCLUDE_USER_DEFINE_FILE is defined, to instruct
the tx_port.h header to include tx_user.h.
3. System Initialization

View File

@@ -33,6 +33,26 @@ You should observe the compilation of sample_threadx.c (which is the demonstrati
application) and linking with tx.a. The resulting file DEMO is a binary file
that can be executed.
2.1 Includes
Notice that the demonstration Makefile includes defines for _GNU_SOURCE
and TX_LINUX_MULTI_CORE. These are necessary to enable GNU/Linux-specific
compatibility for ThreadX using SMP with the Linux kernel in multi-core devices,
including the option to control processor affinity. See the GNU documentation
on CPU affinity and Feature Test Macros for more information.
TX_LINUX_MULTI_CORE is necessary to enable code that constrains ThreadX to
one core, to prevent unintended behavior when threads execute simultaneously
across multiple cores. The enabled code configures CPU affinity, requiring
the use of macros such as CPU_SET and functions such as sched_setaffinity.
Access to these macros and functions (and the underlying types for the latter)
are enabled via the definition of _GNU_SOURCE.
When building your own application, the _GNU_SOURCE and TX_LINUX_MULTI_CORE
symbols can be defined by being passed to the compiler (e.g. -D_GNU_SOURCE) or
in the optional user-defined ThreadX user define file tx_user.h. In the latter
case, ensure that the symbol TX_INCLUDE_USER_DEFINE_FILE is defined, to instruct
the tx_port.h header to include tx_user.h.
3. System Initialization

View File

@@ -47,6 +47,7 @@ set(regression_test_cases
${SOURCE_DIR}/threadx_queue_basic_one_word_test.c
${SOURCE_DIR}/threadx_queue_basic_sixteen_word_test.c
${SOURCE_DIR}/threadx_queue_basic_two_word_test.c
${SOURCE_DIR}/threadx_queue_basic_max_message_size_test.c
${SOURCE_DIR}/threadx_queue_empty_suspension_test.c
${SOURCE_DIR}/threadx_queue_flush_no_suspension_test.c
${SOURCE_DIR}/threadx_queue_flush_test.c

View File

@@ -185,6 +185,7 @@ void threadx_queue_basic_two_word_application_define(void *);
void threadx_queue_basic_four_word_application_define(void *);
void threadx_queue_basic_eight_word_application_define(void *);
void threadx_queue_basic_sixteen_word_application_define(void *);
void threadx_queue_basic_max_message_size_application_define(void *);
void threadx_queue_empty_suspension_application_define(void *);
void threadx_queue_full_suspension_application_define(void *);
void threadx_queue_suspension_timeout_application_define(void *);

View File

@@ -22,11 +22,11 @@ endif()
message(STATUS "Build type: ${CMAKE_BUILD_TYPE}")
message(STATUS "Using toolchain file: ${CMAKE_TOOLCHAIN_FILE}.")
set(default_build_coverage "")
set(disable_notify_callbacks_build -DTX_DISABLE_NOTIFY_CALLBACKS)
set(stack_checking_build -DTX_ENABLE_STACK_CHECKING)
set(stack_checking_rand_fill_build -DTX_ENABLE_STACK_CHECKING -DTX_ENABLE_RANDOM_NUMBER_STACK_FILLING)
set(trace_build -DTX_ENABLE_EVENT_TRACE)
set(default_build_coverage -DTX_QUEUE_MESSAGE_MAX_SIZE=32)
set(disable_notify_callbacks_build -DTX_QUEUE_MESSAGE_MAX_SIZE=32 -DTX_DISABLE_NOTIFY_CALLBACKS)
set(stack_checking_build -DTX_QUEUE_MESSAGE_MAX_SIZE=32 -DTX_ENABLE_STACK_CHECKING)
set(stack_checking_rand_fill_build -DTX_QUEUE_MESSAGE_MAX_SIZE=32 -DTX_ENABLE_STACK_CHECKING -DTX_ENABLE_RANDOM_NUMBER_STACK_FILLING)
set(trace_build -DTX_QUEUE_MESSAGE_MAX_SIZE=32 -DTX_ENABLE_EVENT_TRACE)
add_compile_options(
-m32

View File

@@ -47,6 +47,7 @@ set(regression_test_cases
${SOURCE_DIR}/threadx_queue_basic_one_word_test.c
${SOURCE_DIR}/threadx_queue_basic_sixteen_word_test.c
${SOURCE_DIR}/threadx_queue_basic_two_word_test.c
${SOURCE_DIR}/threadx_queue_basic_max_message_size_test.c
${SOURCE_DIR}/threadx_queue_empty_suspension_test.c
${SOURCE_DIR}/threadx_queue_flush_no_suspension_test.c
${SOURCE_DIR}/threadx_queue_flush_test.c

View File

@@ -171,6 +171,7 @@ void threadx_queue_basic_two_word_application_define(void *);
void threadx_queue_basic_four_word_application_define(void *);
void threadx_queue_basic_eight_word_application_define(void *);
void threadx_queue_basic_sixteen_word_application_define(void *);
void threadx_queue_basic_max_message_size_application_define(void *);
void threadx_queue_empty_suspension_application_define(void *);
void threadx_queue_full_suspension_application_define(void *);
void threadx_queue_suspension_timeout_application_define(void *);
@@ -287,6 +288,7 @@ TEST_ENTRY test_control_tests[] =
threadx_queue_basic_four_word_application_define,
threadx_queue_basic_eight_word_application_define,
threadx_queue_basic_sixteen_word_application_define,
threadx_queue_basic_max_message_size_application_define,
threadx_queue_empty_suspension_application_define,
threadx_queue_full_suspension_application_define,
threadx_queue_suspension_timeout_application_define,
@@ -1193,6 +1195,7 @@ void test_control_return(UINT status)
UINT old_posture = TX_INT_ENABLE;
printf("********** Running Queue Max Message Size Test (%u) ************** \n ", TX_QUEUE_MESSAGE_MAX_SIZE);
/* Save the status in a global. */
test_control_return_status = status;

View File

@@ -0,0 +1,422 @@
/* This test is designed to test immediate response queue services including create
and delete. This test is for queue sizes of 16 ULONG. Two queues are used one with
a capacity of 1 message and another with a capacity of 3 messages. */
#include <stdio.h>
#include "tx_api.h"
static unsigned long thread_0_counter = 0;
static TX_THREAD thread_0;
static TX_QUEUE queue_0;
static TX_QUEUE queue_1;
/* Define thread prototypes. */
static void thread_0_entry(ULONG thread_input);
/* Prototype for test control return. */
void test_control_return(UINT status);
/* Define what the initial system looks like. */
#ifdef CTEST
void test_application_define(void *first_unused_memory)
#else
void threadx_queue_basic_max_message_size_application_define(void *first_unused_memory)
#endif
{
UINT status;
CHAR *pointer;
/* Put first available memory address into a character pointer. */
pointer = (CHAR *) first_unused_memory;
/* Put system definition stuff in here, e.g. thread creates and other assorted
create information. */
status = tx_thread_create(&thread_0, "thread 0", thread_0_entry, 1,
pointer, TEST_STACK_SIZE_PRINTF,
16, 16, 100, TX_AUTO_START);
pointer = pointer + TEST_STACK_SIZE_PRINTF;
/* Check for status. */
if (status != TX_SUCCESS)
{
printf("Running Queue Max Message Size Test..................................... ERROR #1\n");
test_control_return(1);
}
/* Create the queues. */
status = tx_queue_create(&queue_0, "queue 0", TX_QUEUE_MESSAGE_MAX_SIZE, pointer, TX_QUEUE_MESSAGE_MAX_SIZE*sizeof(ULONG));
pointer = pointer + (TX_QUEUE_MESSAGE_MAX_SIZE*sizeof(ULONG));
/* Check for status. */
if (status != TX_SUCCESS)
{
printf("Running Queue Max Message Size Test..................................... ERROR #2\n");
test_control_return(1);
}
status = tx_queue_create(&queue_1, "queue 1", TX_QUEUE_MESSAGE_MAX_SIZE, pointer, TX_QUEUE_MESSAGE_MAX_SIZE*3*sizeof(ULONG));
pointer = pointer + TX_QUEUE_MESSAGE_MAX_SIZE*3*sizeof(ULONG);
/* Check for status. */
if (status != TX_SUCCESS)
{
printf("Running Queue Max Message Size Test..................................... ERROR #3\n");
test_control_return(1);
}
}
/* Define the test threads. */
static void thread_0_entry(ULONG thread_input)
{
UINT status;
ULONG source_message[TX_QUEUE_MESSAGE_MAX_SIZE];
ULONG dest_message[TX_QUEUE_MESSAGE_MAX_SIZE];
ULONG expected_message[TX_QUEUE_MESSAGE_MAX_SIZE];
/* Inform user. */
source_message[0] = 0x01234567;
source_message[TX_QUEUE_MESSAGE_MAX_SIZE -1] = 0x89ABCDEF;
/* Increment thread 0 counter. */
thread_0_counter++;
/* Place something on queue 0. */
status = tx_queue_send(&queue_0, source_message, TX_NO_WAIT);
if (status != TX_SUCCESS)
{
/* Queue error. */
printf("ERROR #4\n");
test_control_return(1);
}
/* Attempt to place something on a full queue. */
status = tx_queue_send(&queue_0, source_message, TX_NO_WAIT);
/* Should be an error. */
if (status != TX_QUEUE_FULL)
{
/* Queue error. */
printf("ERROR #5\n");
test_control_return(1);
}
/* Attempt to receive something from queue 0. */
status = tx_queue_receive(&queue_0, dest_message, TX_NO_WAIT);
/* Should be successful and dest_message should equal source. */
if ((status != TX_SUCCESS) || (source_message[0] != dest_message[0]) ||
(source_message[TX_QUEUE_MESSAGE_MAX_SIZE - 1] != dest_message[TX_QUEUE_MESSAGE_MAX_SIZE - 1]))
{
/* Queue error. */
printf("ERROR #6\n");
test_control_return(1);
}
/* Attempt to receive something from an empty queue. */
status = tx_queue_receive(&queue_0, dest_message, TX_NO_WAIT);
/* Should be an error. */
if (status != TX_QUEUE_EMPTY)
{
/* Queue error. */
printf("ERROR #7\n");
test_control_return(1);
}
/* Make sure we can do the same thing again! */
source_message[0]++;
source_message[TX_QUEUE_MESSAGE_MAX_SIZE - 1]++;
/* Place something on queue 0. */
status = tx_queue_send(&queue_0, source_message, TX_NO_WAIT);
if (status != TX_SUCCESS)
{
/* Queue error. */
printf("ERROR #8\n");
test_control_return(1);
}
/* Attempt to place something on a full queue. */
status = tx_queue_send(&queue_0, source_message, TX_NO_WAIT);
/* Should be an error. */
if (status != TX_QUEUE_FULL)
{
/* Queue error. */
printf("ERROR #9\n");
test_control_return(1);
}
/* Attempt to receive something from queue 0. */
status = tx_queue_receive(&queue_0, dest_message, TX_NO_WAIT);
/* Should be successful and dest_message should equal source. */
if ((status != TX_SUCCESS) || (source_message[0] != dest_message[0]) ||
(source_message[TX_QUEUE_MESSAGE_MAX_SIZE - 1] != dest_message[TX_QUEUE_MESSAGE_MAX_SIZE - 1]))
{
/* Queue error. */
printf("ERROR #10\n");
test_control_return(1);
}
/* Attempt to receive something from an empty queue. */
status = tx_queue_receive(&queue_0, dest_message, TX_NO_WAIT);
/* Should be an error. */
if (status != TX_QUEUE_EMPTY)
{
/* Queue error. */
printf("ERROR #11\n");
test_control_return(1);
}
/* Now we need to do the same thing with the queue with three entries. */
source_message[0]++;
source_message[TX_QUEUE_MESSAGE_MAX_SIZE - 1]++;
expected_message[0] = source_message[0];
expected_message[TX_QUEUE_MESSAGE_MAX_SIZE - 1] = source_message[TX_QUEUE_MESSAGE_MAX_SIZE - 1];
/* Place something on queue 1. */
status = tx_queue_send(&queue_1, source_message, TX_NO_WAIT);
source_message[0]++;
source_message[TX_QUEUE_MESSAGE_MAX_SIZE - 1]++;
status += tx_queue_send(&queue_1, source_message, TX_NO_WAIT);
source_message[0]++;
source_message[TX_QUEUE_MESSAGE_MAX_SIZE - 1]++;
status += tx_queue_send(&queue_1, source_message, TX_NO_WAIT);
source_message[0]++;
source_message[TX_QUEUE_MESSAGE_MAX_SIZE - 1]++;
if (status != TX_SUCCESS)
{
/* Queue error. */
printf("ERROR #12\n");
test_control_return(1);
}
/* Attempt to place something on a full queue. */
status = tx_queue_send(&queue_1, source_message, TX_NO_WAIT);
/* Should be an error. */
if (status != TX_QUEUE_FULL)
{
/* Queue error. */
printf("ERROR #13\n");
test_control_return(1);
}
/* Attempt to receive something from queue 1. */
status = tx_queue_receive(&queue_1, dest_message, TX_NO_WAIT);
/* Should be successful and dest_message should equal source. */
if ((status != TX_SUCCESS) || (expected_message[0] != dest_message[0]) ||
(expected_message[TX_QUEUE_MESSAGE_MAX_SIZE - 1] != dest_message[TX_QUEUE_MESSAGE_MAX_SIZE - 1]))
{
/* Queue error. */
printf("ERROR #14\n");
test_control_return(1);
}
expected_message[0]++;
expected_message[TX_QUEUE_MESSAGE_MAX_SIZE - 1]++;
/* Attempt to receive something from queue 1. */
status = tx_queue_receive(&queue_1, dest_message, TX_NO_WAIT);
/* Should be successful and dest_message should equal source. */
if ((status != TX_SUCCESS) || (expected_message[0] != dest_message[0]) ||
(expected_message[TX_QUEUE_MESSAGE_MAX_SIZE - 1] != dest_message[TX_QUEUE_MESSAGE_MAX_SIZE - 1]))
{
/* Queue error. */
printf("ERROR #15\n");
test_control_return(1);
}
expected_message[0]++;
expected_message[TX_QUEUE_MESSAGE_MAX_SIZE - 1]++;
/* Attempt to receive something from queue 1. */
status = tx_queue_receive(&queue_1, dest_message, TX_NO_WAIT);
/* Should be successful and dest_message should equal source. */
if ((status != TX_SUCCESS) || (expected_message[0] != dest_message[0]) ||
(expected_message[TX_QUEUE_MESSAGE_MAX_SIZE - 1] != dest_message[TX_QUEUE_MESSAGE_MAX_SIZE - 1]))
{
/* Queue error. */
printf("ERROR #16\n");
test_control_return(1);
}
expected_message[0]++;
expected_message[TX_QUEUE_MESSAGE_MAX_SIZE - 1]++;
/* Attempt to receive something from an empty queue. */
status = tx_queue_receive(&queue_1, dest_message, TX_NO_WAIT);
/* Should be an error. */
if (status != TX_QUEUE_EMPTY)
{
/* Queue error. */
printf("ERROR #17\n");
test_control_return(1);
}
/* Make sure we can do the same thing again! */
/* Place something on queue 1. */
status = tx_queue_send(&queue_1, source_message, TX_NO_WAIT);
source_message[0]++;
source_message[TX_QUEUE_MESSAGE_MAX_SIZE - 1]++;
status += tx_queue_send(&queue_1, source_message, TX_NO_WAIT);
source_message[0]++;
source_message[TX_QUEUE_MESSAGE_MAX_SIZE - 1]++;
status += tx_queue_send(&queue_1, source_message, TX_NO_WAIT);
source_message[0]++;
source_message[TX_QUEUE_MESSAGE_MAX_SIZE - 1]++;
if (status != TX_SUCCESS)
{
/* Queue error. */
printf("ERROR #18\n");
test_control_return(1);
}
/* Attempt to place something on a full queue. */
status = tx_queue_send(&queue_1, source_message, TX_NO_WAIT);
/* Should be an error. */
if (status != TX_QUEUE_FULL)
{
/* Queue error. */
printf("ERROR #19\n");
test_control_return(1);
}
/* Attempt to receive something from queue 1. */
status = tx_queue_receive(&queue_1, dest_message, TX_NO_WAIT);
/* Should be successful and dest_message should equal source. */
if ((status != TX_SUCCESS) || (expected_message[0] != dest_message[0]) ||
(expected_message[TX_QUEUE_MESSAGE_MAX_SIZE - 1] != dest_message[TX_QUEUE_MESSAGE_MAX_SIZE - 1]))
{
/* Queue error. */
printf("ERROR #20\n");
test_control_return(1);
}
expected_message[0]++;
expected_message[TX_QUEUE_MESSAGE_MAX_SIZE - 1]++;
/* Attempt to receive something from queue 1. */
status = tx_queue_receive(&queue_1, dest_message, TX_NO_WAIT);
/* Should be successful and dest_message should equal source. */
if ((status != TX_SUCCESS) || (expected_message[0] != dest_message[0]) ||
(expected_message[TX_QUEUE_MESSAGE_MAX_SIZE - 1] != dest_message[TX_QUEUE_MESSAGE_MAX_SIZE - 1]))
{
/* Queue error. */
printf("ERROR #21\n");
test_control_return(1);
}
expected_message[0]++;
expected_message[TX_QUEUE_MESSAGE_MAX_SIZE - 1]++;
/* Attempt to receive something from queue 1. */
status = tx_queue_receive(&queue_1, dest_message, TX_NO_WAIT);
/* Should be successful and dest_message should equal source. */
if ((status != TX_SUCCESS) || (expected_message[0] != dest_message[0]) ||
(expected_message[TX_QUEUE_MESSAGE_MAX_SIZE - 1] != dest_message[TX_QUEUE_MESSAGE_MAX_SIZE - 1]))
{
/* Queue error. */
printf("ERROR #22\n");
test_control_return(1);
}
expected_message[0]++;
expected_message[TX_QUEUE_MESSAGE_MAX_SIZE - 1]++;
/* Attempt to receive something from an empty queue. */
status = tx_queue_receive(&queue_1, dest_message, TX_NO_WAIT);
/* Should be an error. */
if (status != TX_QUEUE_EMPTY)
{
/* Queue error. */
printf("ERROR #23\n");
test_control_return(1);
}
/* Delete the queues. */
status = tx_queue_delete(&queue_1);
if (status != TX_SUCCESS)
{
/* Queue error. */
printf("ERROR #24\n");
test_control_return(1);
}
status = tx_queue_delete(&queue_0);
if (status != TX_SUCCESS)
{
/* Queue error. */
printf("ERROR #25\n");
test_control_return(1);
}
else
{
/* Successful test. */
printf("SUCCESS!\n");
test_control_return(0);
}
}