9 Commits

Author SHA1 Message Date
Frédéric Desbiens
c4ad279b85 Merge pull request #468 from eclipse-threadx/dev
Merge changes included in the v6.4.3.202503 release.
2025-09-28 23:22:13 +01:00
Frédéric Desbiens
8a744afc1c Updated version number and added build and hotfix. 2025-09-28 23:19:17 +01:00
Frédéric Desbiens
09751d08c5 Merge pull request #467 from eclipse-threadx/smp-test-fix
Completed the implementation of a configurable queue max size.
2025-09-28 23:07:00 +01:00
Frédéric Desbiens
b8530b59eb Added missing check for TX_QUEUE_MESSAGE_MAX_SIZE. 2025-09-28 22:53:58 +01:00
Frédéric Desbiens
1f59529034 Added missing QUEUE_MESSAGE_MAX_SIZE test for SMP. 2025-09-28 22:34:15 +01:00
Frédéric Desbiens
ea408ebe52 Merge commit from fork
Fixed pointer validation flaw and improper parameter check in syscall implementation
2025-09-28 21:23:20 +01:00
Frédéric Desbiens
372e71ffc6 Merge commit from fork
Fixed issue where thread could get a higher priority than the module's value for max priority.
2025-09-28 21:15:19 +01:00
Frédéric Desbiens
3d6b65a7d3 Merged fixes for advisories GHSA-76hh-wrj5-hr2v and GHSA-wcfg-5jpf-hhxq provided by Bill Lamie. 2025-07-14 16:58:01 -04:00
Frédéric Desbiens
da0985e748 Merged fix for advisory GHSA-w8rw-fqgj-9r49 provided by Bill Lamie. 2025-07-14 16:33:19 -04:00
9 changed files with 619 additions and 27 deletions

View File

@@ -148,7 +148,9 @@ extern "C" {
#define AZURE_RTOS_THREADX
#define THREADX_MAJOR_VERSION 6
#define THREADX_MINOR_VERSION 4
#define THREADX_PATCH_VERSION 2
#define THREADX_PATCH_VERSION 3
#define THREADX_BUILD_VERSION 202503
#define THREADX_HOTFIX_VERSION ''
/* Define the following symbol for backward compatibility */
#define EL_PRODUCT_THREADX

View File

@@ -1,5 +1,6 @@
/***************************************************************************
* Copyright (c) 2024 Microsoft Corporation
* Copyright (c) 2024 Microsoft Corporation
* Copyright (c) 2025 Eclipse ThreadX Contributors
*
* This program and the accompanying materials are made available under the
* terms of the MIT License which is available at
@@ -2389,6 +2390,11 @@ static ALIGN_TYPE _txm_module_manager_tx_thread_preemption_change_dispatch(TXM_M
ALIGN_TYPE return_value;
if (param_1 < module_instance -> txm_module_instance_maximum_priority)
{
return(TX_THRESH_ERROR);
}
if (module_instance -> txm_module_instance_property_flags & TXM_MODULE_MEMORY_PROTECTION)
{
if (!TXM_MODULE_MANAGER_PARAM_CHECK_OBJECT_FOR_USE(module_instance, param_0, sizeof(TX_THREAD)))
@@ -2418,6 +2424,11 @@ static ALIGN_TYPE _txm_module_manager_tx_thread_priority_change_dispatch(TXM_MOD
ALIGN_TYPE return_value;
if (param_1 < module_instance -> txm_module_instance_maximum_priority)
{
return(TX_PRIORITY_ERROR);
}
if (module_instance -> txm_module_instance_property_flags & TXM_MODULE_MEMORY_PROTECTION)
{
if (!TXM_MODULE_MANAGER_PARAM_CHECK_OBJECT_FOR_USE(module_instance, param_0, sizeof(TX_THREAD)))

View File

@@ -25,7 +25,7 @@
/* COMPONENT DEFINITION RELEASE */
/* */
/* txm_module_manager_util.h PORTABLE C */
/* 6.3.0 */
/* 6.4.3 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
@@ -46,6 +46,10 @@
/* 10-31-2023 Tiejun Zhou Modified comment(s) and */
/* improved object check, */
/* resulting in version 6.3.0 */
/* xx-xx-2025 William E. Lamie Modified comment(s) and */
/* improved object pointer use */
/* and creation checking, */
/* resulting in version 6.4.3 */
/* */
/**************************************************************************/
@@ -102,16 +106,11 @@
/* Kernel objects should be outside the module at the very least. */
#define TXM_MODULE_MANAGER_PARAM_CHECK_OBJECT_FOR_USE(module_instance, obj_ptr, obj_size) \
(TXM_MODULE_MANAGER_ENSURE_OUTSIDE_MODULE(module_instance, obj_ptr, obj_size) || \
(_txm_module_manager_created_object_check(module_instance, (void *)obj_ptr) == TX_FALSE) || \
((void *) (obj_ptr) == TX_NULL))
(_txm_module_manager_param_check_object_for_use(module_instance, obj_ptr, obj_size))
/* When creating an object, the object must be inside the object pool. */
#define TXM_MODULE_MANAGER_PARAM_CHECK_OBJECT_FOR_CREATION(module_instance, obj_ptr, obj_size) \
((TXM_MODULE_MANAGER_ENSURE_INSIDE_OBJ_POOL(module_instance, obj_ptr, obj_size) && \
(_txm_module_manager_object_size_check(obj_ptr, obj_size) == TX_SUCCESS)) || \
(_txm_module_manager_created_object_check(module_instance, (void *)obj_ptr) == TX_FALSE) || \
((void *) (obj_ptr) == TX_NULL))
(_txm_module_manager_param_check_object_for_creation(module_instance, obj_ptr, obj_size))
/* Strings we dereference can be in RW/RO/Shared areas. */
#define TXM_MODULE_MANAGER_PARAM_CHECK_DEREFERENCE_STRING(module_instance, string_ptr) \
@@ -136,6 +135,8 @@ UINT _txm_module_manager_object_memory_check(TXM_MODULE_INSTANCE *module_inst
UINT _txm_module_manager_object_size_check(ALIGN_TYPE object_ptr, ULONG object_size);
UINT _txm_module_manager_object_name_compare(CHAR *object_name1, UINT object_name1_length, CHAR *object_name2);
UCHAR _txm_module_manager_created_object_check(TXM_MODULE_INSTANCE *module_instance, void *object_ptr);
UINT _txm_module_manager_param_check_object_for_creation(TXM_MODULE_INSTANCE *module_instance, ALIGN_TYPE object_ptr, ULONG object_size);
UINT _txm_module_manager_param_check_object_for_use(TXM_MODULE_INSTANCE *module_instance, ALIGN_TYPE object_ptr, ULONG object_size);
UINT _txm_module_manager_util_code_allocation_size_and_alignment_get(TXM_MODULE_PREAMBLE *module_preamble, ULONG *code_alignment_dest, ULONG *code_allocation_size_dest);
#endif

View File

@@ -104,7 +104,7 @@ UINT _txm_module_manager_object_memory_check(TXM_MODULE_INSTANCE *module_instan
/* FUNCTION RELEASE */
/* */
/* _txm_module_manager_created_object_check PORTABLE C */
/* 6.1 */
/* 6.1x */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
@@ -137,6 +137,10 @@ UINT _txm_module_manager_object_memory_check(TXM_MODULE_INSTANCE *module_instan
/* DATE NAME DESCRIPTION */
/* */
/* 09-30-2020 Scott Larson Initial Version 6.1 */
/* xx-xx-2025 William E. Lamie Modified comment(s), and */
/* removed module local memory */
/* check, resulting in */
/* version 6.1x */
/* */
/**************************************************************************/
UCHAR _txm_module_manager_created_object_check(TXM_MODULE_INSTANCE *module_instance, VOID *object_ptr)
@@ -144,15 +148,9 @@ UCHAR _txm_module_manager_created_object_check(TXM_MODULE_INSTANCE *module_insta
TXM_MODULE_ALLOCATED_OBJECT *allocated_object_ptr;
/* Determine if the socket control block is inside the module. */
if ( (((CHAR *) object_ptr) >= ((CHAR *) module_instance -> txm_module_instance_data_start)) &&
(((CHAR *) object_ptr) < ((CHAR *) module_instance -> txm_module_instance_data_end)))
{
return TX_TRUE;
}
/* Determine if this object control block was allocated by this module instance. */
else if (_txm_module_manager_object_pool_created)
/* Determine if the object pool has been created. */
if (_txm_module_manager_object_pool_created)
{
/* Determine if the current object is from the pool of dynamically allocated objects. */
@@ -336,6 +334,158 @@ CHAR object_name_char;
}
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _txm_module_manager_param_check_object_for_creation PORTABLE C */
/* 6.4.3 */
/* AUTHOR */
/* */
/* William E. Lamie, RTOSX */
/* */
/* DESCRIPTION */
/* */
/* This function checks to make sure the object pointer for one of the */
/* creation APIs is valid. */
/* */
/* INPUT */
/* */
/* module_instance Requesting module instance pointer*/
/* object_ptr Address of object memory area */
/* ojbect_size Size of object memory area */
/* */
/* OUTPUT */
/* */
/* TX_TRUE Valid object pointer */
/* TX_FALSE Invalid object pointer */
/* */
/* CALLS */
/* */
/* None */
/* */
/* CALLED BY */
/* */
/* txm_module_manager_* Module manager functions */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* xx-xx-2025 William E. Lamie Initial Version 6.4.3 */
/* */
/**************************************************************************/
UINT _txm_module_manager_param_check_object_for_creation(TXM_MODULE_INSTANCE *module_instance, ALIGN_TYPE object_ptr, ULONG object_size)
{
/* Determine if the object pointer is NULL. */
if ((void *) object_ptr == TX_NULL)
{
/* Object pointer is NULL, which is invalid. */
return(TX_FALSE);
}
/* Determine if the object pointer is inside the module object pool. */
if (TXM_MODULE_MANAGER_ENSURE_INSIDE_OBJ_POOL(module_instance, object_ptr, object_size) == TX_FALSE)
{
/* Object pointer is not inside the object pool, which is invalid. */
return(TX_FALSE);
}
/* Determine if the object size is correct. */
if (_txm_module_manager_object_size_check(object_ptr, object_size) != TX_SUCCESS)
{
/* Object size is invalid. */
return(TX_FALSE);
}
/* Determine if the ojbect has already been created. */
if (_txm_module_manager_created_object_check(module_instance, (void *) object_ptr) == TX_FALSE)
{
/* Object has already been created, which is invalid. */
return(TX_FALSE);
}
/* Everything is okay with the object, return TX_TRUE. */
return(TX_TRUE);
}
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _txm_module_manager_param_check_object_for_use PORTABLE C */
/* 6.4.3 */
/* AUTHOR */
/* */
/* William E. Lamie, RTOSX */
/* */
/* DESCRIPTION */
/* */
/* This function checks to make sure the object pointer is valid. */
/* */
/* INPUT */
/* */
/* module_instance Requesting module instance pointer*/
/* object_ptr Address of object memory area */
/* ojbect_size Size of object memory area */
/* */
/* OUTPUT */
/* */
/* TX_TRUE Valid object pointer */
/* TX_FALSE Invalid object pointer */
/* */
/* CALLS */
/* */
/* None */
/* */
/* CALLED BY */
/* */
/* txm_module_manager_* Module manager functions */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* xx-xx-2025 William E. Lamie Initial Version 6.4.3 */
/* */
/**************************************************************************/
UINT _txm_module_manager_param_check_object_for_use(TXM_MODULE_INSTANCE *module_instance, ALIGN_TYPE object_ptr, ULONG object_size)
{
/* Determine if the object pointer is NULL. */
if ((void *) object_ptr == TX_NULL)
{
/* Object pointer is NULL, which is invalid. */
return(TX_FALSE);
}
/* Determine if the object pointer is inside the module object pool. */
if (TXM_MODULE_MANAGER_ENSURE_OUTSIDE_MODULE(module_instance, object_ptr, object_size) == TX_FALSE)
{
/* Object pointer is not inside the object pool, which is invalid. */
return(TX_FALSE);
}
/* Define application-specific object memory check. */
#ifdef TXM_MODULE_MANGER_APPLICATION_VALID_OBJECT_MEMORY_CHECK
/* Bring in the application-spefic objeft memory check, defined by the user. */
TXM_MODULE_MANGER_APPLICATION_VALID_OBJECT_MEMORY_CHECK
#endif /* TXM_MODULE_MANGER_APPLICATION_VALID_OBJECT_MEMORY_ENABLE */
/* Everything is okay with the object, return TX_TRUE. */
return(TX_TRUE);
}
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
@@ -414,3 +564,5 @@ ULONG data_alignment_ignored;
/* Return success. */
return(TX_SUCCESS);
}

View File

@@ -149,7 +149,10 @@ extern "C" {
#define AZURE_RTOS_THREADX
#define THREADX_MAJOR_VERSION 6
#define THREADX_MINOR_VERSION 4
#define THREADX_PATCH_VERSION 2
#define THREADX_PATCH_VERSION 3
#define THREADX_BUILD_VERSION 202503
#define THREADX_HOTFIX_VERSION ''
/* Define the following symbol for backward compatibility */
#define EL_PRODUCT_THREADX

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 sizegreater than TX_QUEUE_MESSAGE_MAX_SIZE 16 by default. */
else if (message_size > TX_QUEUE_MESSAGE_MAX_SIZE)
{
/* Invalid message size specified. */

View File

@@ -23,11 +23,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

@@ -329,6 +329,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,

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);
}
}