An overview of the

Each ThreadX product distribution includes a demo system that runs on all supported microprocessors. This sample system, which can be defined in the distribution file demo_threadx.c, is designed to show how to use ThreadX in an embedded multithreaded environment. The demo includes initialization, eight threads, a byte pool, a memory block pool, a queue, a semaphore, a mutex, and an event flag group.

Note: The demo application is identical on all ThreadX supported processors, except for the stack size of the thread.

A complete list of demo_threadx.c, including the line numbers referenced in the rest of this chapter.

Application definition

Once basic ThreadX initialization is complete, the tx_Application_define function is executed. This function is responsible for setting up all initial system resources, including threads, queues, semaphores, mutex, event flags, and memory pools. The tx_application_define of the demo system (lines 60-164) creates the demo objects in the following order:

  • byte_pool_0
  • thread_0
  • thread_1
  • thread_2
  • thread_3
  • thread_4
  • thread_5
  • thread_6
  • thread_7
  • queue_0
  • semaphore_0
  • event_flags_0
  • mutex_0
  • block_pool_0

The demo system does not create any additional ThreadX objects. However, a real application might create system objects inside the thread of execution at run time.

The initial implementation

All threads are created using the TX_AUTO_START option. As a result, these threads are prima facie ready to execute. Once tx_application_define is complete, control is transferred to the thread planner and from there to the individual threads. The order in which threads execute depends on their priority and the order in which they are created. In the demo system, thread_0 is executed first because it has the highest priority (priority 1 when created). After thread_0 is suspended, thread_5 is executed, followed by thread_3, THREAD_4, thread_6, thread_7, thread_1, and finally thread_2.

Note: Even if thread_3 and THREAD_4 have the same priority (both created with priority 8), thread_3 is executed first because thread_3 is created and ready before Thread_4. Threads with the same priority execute in FIFO.

Thread 0

The function thread_0_entry marks the entry point of a thread (lines 167-190). Thread_0 is the first thread to execute in the demo system. Its handling is simple: increment its counter, sleep for 10 timer clock cycles, set an event flag to wake thread_5, and then repeat the sequence. Thread_0 is the highest priority thread in the system. When the sleep of its request expires, it preempts any other executing threads in the demo.

Thread 1

The function thread_1_entry marks the entry point of a thread (lines 193-216). Thread_1 is the penultimate thread to execute in the demo system. It does this by incrementing its counter, sending a message to Thread_2 (via Queue_0), and repeating the sequence. Notice that thread_1 hangs whenever Queue_0 is full (line 207).

Thread 2

The function thread_2_entry marks the entry point of a thread (lines 219-243). Thread_2 is the last thread to execute in the demo system. It does this by incrementing its counter, getting the message from Thread_1 (via queue_0), and repeating the sequence. Notice that thread_2 hangs whenever queue_0 is empty (line 233).

Although thread_1 and Thread_2 share the lowest priority in the demo system (priority 16), they are threads 3 and 4 and the only threads that can execute most of the time. They are also the only threads created using time slices (lines 87 and 93). Each thread can execute up to 4 timer clock cycles before executing another thread.

Threads 3 and 4

The function thread_3_AND_4_entry marks the entry point for thread_3 and THREAD_4 (lines 246-280). Both threads have priority of 8, making them the third and fourth threads to execute in the demo system. Each thread does the same: increments its counter, acquires semaphoRE_0, sleeps for two timer clock cycles, frees semaphore_0, and repeats the sequence. Note that all threads are suspended whenever semaphoRE_0 is unavailable (line 264). Meanwhile, both threads use the same function in the main processing. This doesn’t cause any problems, because they all have their own unique stack, and C is inherently reentrant. Each thread determines which thread it is by examining the thread input parameter (line 258), which can be set when the thread is created (lines 102 and 109).

Note: It is also reasonable to get the current thread point during thread execution and compare it to the address of the control block to determine the thread identity.

Thread 5

The function thread_5_entry marks the entry point of a thread (lines 283-305). Thread_5 is the second thread to execute in the demo system. This is handled by incrementing its counter, getting the event flag from thread_0 (via event_FLAGs_0), and repeating the sequence. Note that thread_5 is suspended whenever the event flag in event_FLAGs_0 is unavailable (line 298).

Threads 6 and 7

The function thread_6_AND_7_entry marks the entry point for thread_6 and thread_7 (lines 307-358). Both threads have priority of 8, making them the fifth and sixth threads to execute in the demo system. Each thread does the same: incrementing its counter, retrieving mutex_0 twice, sleeping for two timer clock cycles, releasing mutex_0 twice, and repeating the sequence. Note that all threads are suspended whenever mutex_0 is unavailable (line 325). Meanwhile, both threads use the same function in the main processing. This doesn’t cause any problems, because they all have their own unique stack, and C is inherently reentrant. Each thread determines which thread it is by examining the thread input parameter (line 319), which can be set when the thread is created (lines 126 and 133).

Watch the demo

Each demo thread increments its own unique counter. The following counters can be checked to verify the demonstrated operation:

  • thread_0_counter
  • thread_1_counter
  • thread_2_counter
  • thread_3_counter
  • thread_4_counter
  • thread_5_counter
  • thread_6_counter
  • thread_7_counter

Each counter should continue to increase during the demo execution, with thread_1_counter and Thread_2_Counter_ increasing the fastest.

Distribute file: demo_threadx.c

This section displays the complete list of demo_threadx.c, including the line numbers referenced in this chapter.

/* This is a small demo of the high-performance ThreadX kernel. It includes examples of eight
threads of different priorities, using a message queue, semaphore, mutex, event flags group,
byte pool, and block pool. */

#include "tx_api.h"

#define DEMO_STACK_SIZE 1024
#define DEMO_BYTE_POOL_SIZE 9120
#define DEMO_BLOCK_POOL_SIZE 100
#define DEMO_QUEUE_SIZE 100

/* Define the ThreadX object control blocks... * /

TX_THREAD thread_0;
TX_THREAD thread_1;
TX_THREAD thread_2;
TX_THREAD thread_3;
TX_THREAD thread_4;
TX_THREAD thread_5;
TX_THREAD thread_6;
TX_THREAD thread_7;
TX_QUEUE queue_0;/ / the queue
TX_SEMAPHORE semaphore_0;/ / semaphore
TX_MUTEX mutex_0;/ / the mutex
TX_EVENT_FLAGS_GROUP event_flags_0;// Event flag group
TX_BYTE_POOL byte_pool_0;/ / byte pool
TX_BLOCK_POOL block_pool_0;// Memory block pool

/* Define the counters used in the demo application... * /

ULONG thread_0_counter;
ULONG thread_1_counter;
ULONG thread_1_messages_sent;
ULONG thread_2_counter;
ULONG thread_2_messages_received;
ULONG thread_3_counter;
ULONG thread_4_counter;
ULONG thread_5_counter;
ULONG thread_6_counter;
ULONG thread_7_counter;

/* Define thread prototypes. */

void thread_0_entry(ULONG thread_input);
void thread_1_entry(ULONG thread_input);
void thread_2_entry(ULONG thread_input);
void thread_3_and_4_entry(ULONG thread_input);
void thread_5_entry(ULONG thread_input);
void thread_6_and_7_entry(ULONG thread_input);


/* Define main entry point. */

int main(a)
{
    /* Enter the ThreadX kernel. */
    tx_kernel_enter();
}

/* Define what the initial system looks like. */
void tx_application_define(void *first_unused_memory)
{

    CHAR *pointer;

    /* Create a byte memory pool from which to allocate the thread stacks. */
    tx_byte_pool_create(&byte_pool_0,        // Pointer to memory pool control block;
                        "byte pool 0".// a pointer to the memory pool name;
                        first_unused_memory, // Start address of the memory pool;
                        DEMO_BYTE_POOL_SIZE);// The total number of bytes available in the memory pool, in this case 9120;

    /* Put system definition stuff in here, e.g., thread creates and other assorted create information. */

    /* Allocate the stack for thread 0. */
    tx_byte_allocate(&byte_pool_0,       // pointer to the memory pool created earlier;
                        &pointer,        // A pointer to the target memory;
                        DEMO_STACK_SIZE, // The number of bytes requested;
                        TX_NO_WAIT);     // Define how to behave when there is not enough memory available (set to return immediately);

    /* Create the main thread. */
    tx_thread_create(&thread_0,          // A pointer to the thread control block;
                    "thread 0".// a pointer to the thread name;
                    thread_0_entry,      // Specifies the initial C function executed by the thread;
                    0.// The value of the entry function passed to the thread on the first execution is available for free use;
                    pointer,             // The starting address of the memory area of the stack;
                    DEMO_STACK_SIZE,     // The number of bytes in the stack memory area;
                    1.// Priority;
                    1.// Disable the highest preemption priority;
                    TX_NO_TIME_SLICE,    // The number of cycles that this thread is allowed to run before other threads of the same priority are ready;
                    TX_AUTO_START);      // Indicates whether the thread is started immediately or suspended;

    /* Allocate the stack for thread 1. */
    tx_byte_allocate(&byte_pool_0, &pointer, DEMO_STACK_SIZE, TX_NO_WAIT);

    /* Create threads 1 and 2. These threads pass information through a ThreadX message queue. It is also interesting to note that these threads have a time slice. Note the use of time slicing */
    tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1,
        pointer, DEMO_STACK_SIZE,
        16.16.4, TX_AUTO_START);

    /* Allocate the stack for thread 2. */
    tx_byte_allocate(&byte_pool_0, &pointer, DEMO_STACK_SIZE, TX_NO_WAIT);
        tx_thread_create(&thread_2, "thread 2", thread_2_entry, 2,
        pointer, DEMO_STACK_SIZE,
        16.16.4, TX_AUTO_START);

    /* Allocate the stack for thread 3. */
    tx_byte_allocate(&byte_pool_0, &pointer, DEMO_STACK_SIZE, TX_NO_WAIT);

    /* Create threads 3 and 4. These threads compete for a ThreadX counting semaphore. An interesting thing here is that both threads share the same instruction area. */
    tx_thread_create(&thread_3, "thread 3", thread_3_and_4_entry, 3,
        pointer, DEMO_STACK_SIZE,
        8.8, TX_NO_TIME_SLICE, TX_AUTO_START);

    /* Allocate the stack for thread 4. */
    tx_byte_allocate(&byte_pool_0, &pointer, DEMO_STACK_SIZE, TX_NO_WAIT);

    tx_thread_create(&thread_4, "thread 4", thread_3_and_4_entry, 4,
        pointer, DEMO_STACK_SIZE,
        8.8, TX_NO_TIME_SLICE, TX_AUTO_START);

    /* Allocate the stack for thread 5. */
    tx_byte_allocate(&byte_pool_0, &pointer, DEMO_STACK_SIZE, TX_NO_WAIT);

    /* Create thread 5. This thread simply pends on an event flag, which will be set by thread_0. This thread is controlled by thread_0 with an event flag */
    tx_thread_create(&thread_5, "thread 5", thread_5_entry, 5,
        pointer, DEMO_STACK_SIZE,
        4.4, TX_NO_TIME_SLICE, TX_AUTO_START);

    /* Allocate the stack for thread 6. */
    tx_byte_allocate(&byte_pool_0, &pointer, DEMO_STACK_SIZE, TX_NO_WAIT);

    /* Create threads 6 and 7. These threads compete for a ThreadX mutex. The mutex * /
    tx_thread_create(&thread_6, "thread 6", thread_6_and_7_entry, 6,
        pointer, DEMO_STACK_SIZE,
        8.8, TX_NO_TIME_SLICE, TX_AUTO_START);

    /* Allocate the stack for thread 7. */
    tx_byte_allocate(&byte_pool_0, &pointer, DEMO_STACK_SIZE, TX_NO_WAIT);

    tx_thread_create(&thread_7, "thread 7", thread_6_and_7_entry, 7,
        pointer, DEMO_STACK_SIZE,
        8.8, TX_NO_TIME_SLICE, TX_AUTO_START);

    /* Allocate the message queue. */
    tx_byte_allocate(&byte_pool_0, &pointer, DEMO_QUEUE_SIZE*sizeof(ULONG), TX_NO_WAIT);

    /* Create the message queue shared by threads 1 and 2. Queue * /
    tx_queue_create(&queue_0,                      // A pointer to the message queue;
                    "queue 0".// A pointer to the information queue name;
                    TX_1_ULONG,                    // Specify the size of each message in the information queue;
                    pointer,                       // Start address of the message queue;
                    DEMO_QUEUE_SIZE*sizeof(ULONG));// Total number of bytes available for the information queue;

    /* Create the semaphore used by threads 3 and 4. Semaphore * /
    tx_semaphore_create(&semaphore_0,       // A pointer to the semaphore control block;
                        "semaphore 0".// Pointer to semaphore name;
                        1);                 // Specify the initial count value of this semaphore;

    /* Create the event flags group used by threads 1 and 5. Event tag group */
    tx_event_flags_create(&event_flags_0,     // A pointer to the event flag group control block;
                            "event flags 0"); // A pointer to the event flag group name;

    /* Create the mutex used by thread 6 and 7 without priority inheritance. The mutex * /
    tx_mutex_create(&mutex_0,                 // A pointer to the mutex control block;
                    "mutex 0".// A pointer to the mutex name;
                    TX_NO_INHERIT);           // Specifies whether this semaphore supports priority inheritance.

    /* Allocate the memory for a small block pool. */
    tx_byte_allocate(&byte_pool_0, &pointer, DEMO_BLOCK_POOL_SIZE, TX_NO_WAIT);

    /* Create a block memory pool to allocate a message buffer from. */
    tx_block_pool_create(&block_pool_0, "block pool 0".sizeof(ULONG), pointer,
        DEMO_BLOCK_POOL_SIZE);

    /* Allocate a block and release the block memory. */
    tx_block_allocate(&block_pool_0, &pointer, TX_NO_WAIT);

    /* Release the block back to the pool. */
    tx_block_release(pointer);
}

/* Define the test threads. */
void thread_0_entry(ULONG thread_input)
{
    UINT status;


    /* This thread simply sits in while-forever-sleep loop. */
    while(1)
    {

        /* Increment the thread counter. */
        thread_0_counter++;

        /* Sleep for 10 ticks. */
        tx_thread_sleep(10);

        /* Set event flag 0 to wakeup thread 5. */
        status = tx_event_flags_set(&event_flags_0, 0x1, TX_OR);

        /* Check status. */
        if(status ! = TX_SUCCESS)break; }}void thread_1_entry(ULONG thread_input)
{
    UINT status;


    /* This thread simply sends messages to a queue shared by thread 2. */
    while(1)
    {
        /* Increment the thread counter. */
        thread_1_counter++;

        /* Send message to queue 0. */
        status = tx_queue_send(&queue_0, &thread_1_messages_sent, TX_WAIT_FOREVER);

        /* Check completion status. */
        if(status ! = TX_SUCCESS)break;

        /* Increment the message sent. */thread_1_messages_sent++; }}void thread_2_entry(ULONG thread_input)
{
    ULONG received_message;
    UINT status;

    /* This thread retrieves messages placed on the queue by thread 1. */
    while(1)
    {
        /* Increment the thread counter. */
        thread_2_counter++;

        /* Retrieve a message from the queue. */
        status = tx_queue_receive(&queue_0, &received_message, TX_WAIT_FOREVER);

        /* Check completion status and make sure the message is what we expected. */
        if((status ! = TX_SUCCESS) || (received_message ! = thread_2_messages_received))break;

        /* Otherwise, all is okay. Increment the received message count. */thread_2_messages_received++; }}void thread_3_and_4_entry(ULONG thread_input)
{
    UINT status;


    /* This function is executed from thread 3 and thread 4. As the loop below shows, these function compete for ownership of semaphore_0. */
    while(1)
    {
        /* Increment the thread counter. */
        if (thread_input == 3)
            thread_3_counter++;
        else
            thread_4_counter++;

        /* Get the semaphore with suspension. */
        status = tx_semaphore_get(&semaphore_0, TX_WAIT_FOREVER);

        /* Check status. */
        if(status ! = TX_SUCCESS)break;

        /* Sleep for 2 ticks to hold the semaphore. */
        tx_thread_sleep(2);

        /* Release the semaphore. */
        status = tx_semaphore_put(&semaphore_0);

        /* Check status. */
        if(status ! = TX_SUCCESS)break; }}void thread_5_entry(ULONG thread_input)
{
    UINT status;
    ULONG actual_flags;


    /* This thread simply waits for an event in a forever loop. */
    while(1)
    {
        /* Increment the thread counter. */
        thread_5_counter++;

        /* Wait for event flag 0. */
        status = tx_event_flags_get(&event_flags_0, 0x1, TX_OR_CLEAR,
            &actual_flags, TX_WAIT_FOREVER);

        /* Check status. */
        if((status ! = TX_SUCCESS) || (actual_flags ! =0x1))
            break; }}void thread_6_and_7_entry(ULONG thread_input)
{
    UINT status;

    /* This function is executed from thread 6 and thread 7. As the loop
        below shows, these function compete for ownership of mutex_0.互斥量 */
    while(1)
    {
        /* Increment the thread counter. */
        if (thread_input == 6)
            thread_6_counter++;
        else
            thread_7_counter++;

        /* Get the mutex with suspension. */
        status = tx_mutex_get(&mutex_0, TX_WAIT_FOREVER);

        /* Check status. */
        if(status ! = TX_SUCCESS)break;

        /* Get the mutex again with suspension. This shows that an owning thread may retrieve the mutex it owns multiple times. * /
        status = tx_mutex_get(&mutex_0, TX_WAIT_FOREVER);

        /* Check status. */
        if(status ! = TX_SUCCESS)break;

        /* Sleep for 2 ticks to hold the mutex. */
        tx_thread_sleep(2);

        /* Release the mutex. */
        status = tx_mutex_put(&mutex_0);

        /* Check status. */
        if(status ! = TX_SUCCESS)break;

        /* Release the mutex again. This will actually release ownership since it was obtained twice. */
        status = tx_mutex_put(&mutex_0);

        /* Check status. */
        if(status ! = TX_SUCCESS)break; }}Copy the code

Function description in the sample code:

tx_byte_pool_create

Create a memory byte pool

The prototype

UINT tx_byte_pool_create( TX_BYTE_POOL *pool_ptr, CHAR *name_ptr, VOID *pool_start, ULONG pool_size);         
Copy the code

instructions

This service creates a memory byte pool in the specified region. Initially, the pool basically consisted of only one very large available block. However, over time, the pool is divided into smaller chunks.

parameter

  • Pool_ptr: pointer to the memory pool control block.
  • Name_ptr: pointer to the memory pool name.
  • Pool_start: specifies the start address of the memory pool. The start address must be the same size as the ULONG data type.
  • Pool_size: specifies the total number of bytes available in the memory pool.

The return value

  • TX_SUCCESS :(0X00) memory pool created successfully.
  • TX_POOL_ERROR :(0x02) memory pool pointer is invalid. Pointer to NULL or pool created.
  • TX_PTR_ERROR :(0x03) the start address of the pool is invalid.
  • TX_SIZE_ERROR :(0x05) the pool size is invalid.
  • NX_CALLER_ERROR :(0x13) the caller of this service is invalid.

Allowed from

Initialization and threading

You can take

no

tx_byte_allocate

Bytes allocated for memory

The prototype

UINT tx_byte_allocate( TX_BYTE_POOL *pool_ptr, VOID **memory_ptr, ULONG memory_size, ULONG wait_option);
Copy the code

instructions

This service allocates the specified number of bytes from the specified memory byte pool.

Important: Be sure that application code is not written outside the allocated block of memory. If this happens, it corrupts its adjacent memory blocks (usually the ones that follow). The results are unpredictable and often severe!

Note: The performance of this service is a function of block size and the amount of fragmentation in the pool. Therefore, this service should not be used during execution of time-critical threads.

parameter

  • Pool_ptr: pointer to the previously created memory block pool.
  • Memory_ptr: a pointer to a target memory pointer. When the allocation succeeds, the address of the allocated memory region is at the location indicated by this parameter.
  • Memory_size: Number of bytes requested.
  • Wait_option: defines how this service behaves when there is not enough memory available. The wait option is defined as follows:
    • TX_NO_WAIT (0x00000000) – If TX_NO_WAIT is selected, this service will be returned immediately regardless of whether it was successful or not. This is the only valid option if the service is called from initialization.
    • TX_WAIT_FOREVER (0xFFFFFFFF) – Selecting TX_WAIT_FOREVER causes the calling thread to hang indefinitely until enough memory is available.
    • Timeout value (0x00000001 to 0xFFFFFFFE) – If you select a value (1 to 0xFFFFFFFE), it specifies the maximum number of timer clock cycles that the calling thread can hold pending while waiting for memory.

The return value

  • TX_SUCCESS :(0x00) memory allocated successfully.
  • TX_DELETED :(0x01) the memory pool was deleted when the thread was suspended.
  • TX_NO_MEMORY :(0X10) the service was unable to allocate memory during the specified wait time.
  • TX_WAIT_ABORTED (0x1A) The pending state is terminated by another thread, timer, or ISR.
  • TX_POOL_ERROR :(0x02) memory pool pointer is invalid.
  • TX_PTR_ERROR :(0x03) pointer to target pointer is invalid.
  • TX_SIZE_ERROR :(0X05) the requested size is zero or exceeds the pool size.
  • TX_WAIT_ERROR :(0x04) specifies wait options other than TX_NO_WAIT when called from a non-thread.
  • NX_CALLER_ERROR :(0x13) the caller of this service is invalid.

Allowed from

Initialization and threading

You can take

is

tx_thread_create

Create application threads

The prototype

UINT tx_thread_create( TX_THREAD *thread_ptr, CHAR *name_ptr, VOID (*entry_function)(ULONG), ULONG entry_input, VOID *stack_start, ULONG stack_size, UINT priority, UINT preempt_threshold, ULONG time_slice, UINT auto_start);
Copy the code

instructions

This service creates an application thread that starts execution at the specified task entry function. Stack, priority, preemption threshold, and time slice are all properties specified by the input parameter. In addition, the initial execution state of the thread is specified.

parameter

  • Thread_ptr: Pointer to a thread control block.
  • Name_ptr: pointer to the thread name.
  • Entry_function: Specifies the initial C function to be executed by the thread. When a thread returns from this entry function, it is in the finished state and suspended indefinitely.
  • Entry_input: 32-bit value of the entry function passed to the thread on first execution. The purpose of this input is entirely up to the application.
  • Stack_start: The starting address of the memory area of the stack.
  • Stack_size: The number of bytes in the stack memory area. The stack area of the thread must be large enough to handle worst-case nesting of function calls and local variable use.
  • Priority: indicates the priority of a thread. The legal values range from 0 to (tx_max_priorites-1), where 0 indicates the highest priority.
  • Preempt_threshold: disables the highest preemption priority (0 to (TX_MAX_PRIORITIES-1)). Only priorities higher than this level are allowed to preempt this thread. The value must be less than or equal to the specified priority. If a value is equal to thread priority, the preemption threshold is disabled.
  • Time_slice: The number of timer clock cycles that this thread is allowed to run before other ready threads with the same priority have a chance to run. Note that using preemption thresholds will disable time slices. Valid time slice values range from 1 to 0xFFFFFFFF (inclusive). A value of TX_NO_TIME_SLICE (0) disables the time slice for this thread.

Remarks Using time chips incurs a small amount of system overhead. Since a time slice only works when multiple threads have the same priority, a thread with a unique priority should not be assigned a time slice.

Auto_start: specifies whether the thread is started immediately or suspended. The valid options are TX_AUTO_START (0x01) and TX_DONT_START (0x00). If TX_DONT_START is specified, the application must then call tx_thread_resume in order for the thread to run.

The return value

  • TX_SUCCESS :(0X00) thread created successfully.
  • TX_THREAD_ERROR :(0x0E) thread control pointer is invalid. Pointer is NULL or a thread has been created.
  • TX_PTR_ERROR :(0x03) the starting address of the entry point is invalid or the stack area is invalid (usually NULL).
  • TX_SIZE_ERROR :(0x05) stack area size is invalid. Threads must have at least TX_MINIMUM_STACK bytes to execute.
  • TX_PRIORITY_ERROR :(0x0F) thread priority is invalid. This value is out of range (0 to (TX_MAX_PRIORITIES-1)).
  • TX_THRESH_ERROR :(0x18) the specified preemption threshold is invalid. This value must be a valid priority less than or equal to the thread’s initial priority.
  • TX_START_ERROR :(0x10) the auto start selection is invalid.
  • NX_CALLER_ERROR :(0x13) the caller of this service is invalid.

Allowed from

Initialization and threading

You can take

is

tx_queue_create

Creating a message queue

The prototype

UINT tx_queue_create( TX_QUEUE *queue_ptr, CHAR *name_ptr, UINT message_size, VOID *queue_start, ULONG queue_size);
Copy the code

instructions

This service creates message queues that are typically used for communication between threads. The total number of messages is calculated based on the specified message size and the total number of bytes in the queue.

Note: If the total number of bytes specified in the queue memory region is not divisible by the specified message size, the remaining bytes in the memory region are not used.

parameter

  • Queue_ptr: Pointer to the message queue control block.
  • Name_ptr: pointer to the message queue name.
  • Message_size: Specifies the size of each message in the queue. Message sizes range from 1 32-bit word to 16 32-bit words. Valid message size options range from 1 to 16 inclusive.
  • Queue_start: start address of the message queue. The start address must be the same size as the ULONG data type.
  • Queue_size: Total number of bytes available for message queues.

The return value

  • TX_SUCCESS :(0X00) message queue was successfully created.
  • TX_QUEUE_ERROR :(0X09) message queue pointer is invalid. Pointer is NULL or a queue has been created.
  • TX_PTR_ERROR :(0x03) message queue start address is invalid.
  • TX_SIZE_ERROR :(0x05) message queue size is invalid.
  • NX_CALLER_ERROR :(0x13) the caller of this service is invalid.

Allowed from

Initialization and threading

You can take

no

tx_semaphore_create

Create count semaphore

The prototype

UINT tx_semaphore_create( TX_SEMAPHORE *semaphore_ptr, CHAR *name_ptr, ULONG initial_count);
Copy the code

instructions

This service creates semaphores for synchronization between threads. The initial semaphore count is specified as an input parameter.

parameter

  • Semaphore_ptr: Pointer to the semaphore control block.
  • Name_ptr: pointer to the semaphore name.
  • Initial_count: Specifies the initial count value for this semaphore. Valid values range from 0x00000000 to 0xFFFFFFFF.

The return value

  • TX_SUCCESS :(0X00) semaphore created successfully.
  • TX_SEMAPHORE_ERROR :(0x0C) the semaphore pointer is invalid. Pointer to NULL or semaphore created.
  • NX_CALLER_ERROR :(0x13) the caller of this service is invalid.

Allowed from

Initialization and threading

You can take

no

tx_event_flags_create

Create an event flag group

The prototype

UINT tx_event_flags_create( TX_EVENT_FLAGS_GROUP *group_ptr, CHAR *name_ptr);
Copy the code

instructions

This service creates a set of 32 event flags. All 32 event flags in this group are initialized to zero. Each event flag is represented by a bit.

parameter

  • Group_ptr: pointer to the event flag group control block.
  • Name_ptr: pointer to the event flag group name.

The return value

  • TX_SUCCESS :(0X00) event group created successfully.
  • TX_GROUP_ERROR :(0x06) the event group pointer is invalid. Pointer is NULL or the event group has been created.
  • NX_CALLER_ERROR :(0x13) the caller of this service is invalid.

Allowed from

Initialization and threading

You can take

no

tx_mutex_create

Create mutex semaphore

The prototype

UINT tx_mutex_create( TX_MUTEX *mutex_ptr, CHAR *name_ptr, UINT priority_inherit);
Copy the code

instructions

This service creates a mutex semaphore for interthread mutex to protect resources.

parameter

  • Mutex_ptr: pointer to the mutex control block.
  • Name_ptr: pointer to the mutex semaphore name.
  • Priority_inherit: Specifies whether this mutex semaphore supports priority inheritance. If this value is TX_INHERIT, priority inheritance is supported. However, if TX_NO_INHERIT is specified, the mutex does not support priority inheritance.

The return value

  • TX_SUCCESS :(0X00) mutex successfully created.
  • TX_MUTEX_ERROR :(0X1C) the mutex pointer is invalid. Pointer is NULL or a mutex has been created.
  • NX_CALLER_ERROR :(0x13) the caller of this service is invalid.
  • TX_INHERIT_ERROR :(0x1F) the priority inheritance parameter is invalid.

Allowed from

Initialization and threading

You can take

no

tx_block_release

Frees a fixed-size memory block

The prototype

UINT tx_block_release(VOID *block_ptr);
Copy the code

instructions

This service frees previously allocated blocks back to their associated memory pool. If one or more threads are suspended and waiting for a memory block in this pool, the first suspended thread is supplied with the memory block and the thread is restored.

important

Applications should block the use of a memory block area once it has been released back into the pool.

parameter

  • Block_ptr: pointer to the previously allocated memory block.

The return value

  • TX_SUCCESS :(0x00) successfully freed the memory block.
  • TX_PTR_ERROR :(0x03) pointer to memory block is invalid.

Allowed from

Initialization, thread, timer, and ISR

You can take

is