250 likes | 393 Views
Chapter 12. Thread Communication with Message Queue. Outline. Brief Introduction to Message Queue Look into Message Queue Control Block Investigate Message Queue Service 4 Public Resources vs. ThreadX Applications. Brief Introduction to Message Queue.
E N D
Chapter 12 Thread Communication with Message Queue
Outline • Brief Introduction to Message Queue • Look into Message Queue Control Block • Investigate Message Queue Service • 4 Public Resources vs. ThreadX Applications
Brief Introduction to Message Queue • Message queues are the primary means of inter-thread communication in ThreadX. • TX_QUEUE data type is used to declare a message queue, a Queue Control Block (QCB) is created and added to a doubly linked circular list, in which the first QCB is pointed to by a pointer named tx_queue_created_ptr.
Brief Introduction to Message Queue (cont.) • Messages reside in a FIFO discipline, the only exception occurs when a thread is suspended on a message from an empty queue. In this case, message will bypass the queue and go directly to the thread for system performance enhancement. • A message is copied to the rear or front of the queue and is removed from the front of the queue.
Brief Introduction to Message Queue (cont.) • Message size must be specified as the queue is created, it’s 1, 2, 4, 8 or 16 32-bit words. • A pointer can be used instead in the queue for message which are lager than 16 words.
Brief Introduction to Message Queue (Cont.) • Number of messages calculationQUEUE_TOTAL_SIZE / MESSAGE_SIZE [no overhead]Example:QUEUE_TOTAL_SIZE = 100 bytes, MESSAGE_SIZE = TX_1_ULONGQueue Capacity = 100 / 4 = 25 • The memory area of a message queue can be located anywhere in the target’s HW address • Threads can suspend while attempting either to receive a message from an empty queue or send a message to a full queue. • The resume sequence of threads which are all suspended on the same queue : FIFO, tx_queue_prioritize service call could change that order.
Message Queue Control BlockNew created queue: 100 * TX_1_ULONG
Message Queue Service (Cont.) • tx_queue_createUINT tx_queue_create(TX_QUEUE *queue_ptr, CHAR *name_ptr, UINT message_size, VOID *queue_start, ULONG queue_total_size_in_bytes) • tx_queue_sendUINT tx_queue_send(TX_QUEUE *queue_ptr, VOID *source_ptr, ULONG wait_option)Note: (1) This service copies the message to the back of the queue. (2) application timer, initialization routine and ISR call this service with only TX_NO_WAIT wait option allowed, or TX_WAIT_ERROR(0x04) returns at runtime and fails send operation.
Message Queue Service (Cont.) • tx_queue_receiveUINT tx_queue_receive(TX_QUEUE *queue_ptr, VOID * destination_ptr, ULONG wait_option)Note: (1) This service move the retrieved message from the front of the queue. (2) Destination memory area must be large enough to avoid memory corruption. (3) application timer, initialization routine and ISR call this service with only TX_NO_WAIT wait option allowed, or TX_WAIT_ERROR(0x04) returns at runtime and fails receive operation.
Example to Verify Previous Statement void tx_application_define(void *first_unused_memory) { UINT status; tx_thread_create(&speedy_thread, "speedy_thread", speedy_thread_entry, 0, stack_speedy, STACK_SIZE, 5, 5, TX_NO_TIME_SLICE, TX_AUTO_START); tx_thread_create(&slow_thread, "slow_thread", slow_thread_entry, 1, stack_slow, STACK_SIZE, 15, 15, TX_NO_TIME_SLICE, TX_AUTO_START); tx_queue_create (&my_queue, "my_queue", QUEUE_MSG_SIZE, queue_storage, QUEUE_TOTAL_SIZE); msg_arr[QUEUE_MSG_SIZE-1] = 1; status = tx_queue_send(&my_queue, msg_arr, TX_WAIT_FOREVER); printf("the status is %d\n", status); tx_timer_create (&stats_timer, "stats_timer", print_stats, 0x1234, 500, 500, TX_AUTO_ACTIVATE); }
Message Queue Service (Cont.) • tx_queue_deleteUINT tx_queue_delete(TX_QUEUE *queue_ptr)Note: (1)All threads that are suspended on a message from the deleted queue are resumed with TX_DELETED status. (2)ThreadX won’t manage the memory area associated with the deleted queue. • tx_queue_flushUINT tx_queue_flush(TX_QUEUE *queue_ptr)Note: (1)Delete or discard all messages either in the queue or in suspended threads which are waiting to send messages to the specified full queue.
Message Queue Service (Cont.) • tx_queue_front_sendUINT tx_queue_front_send(TX_QUEUE *queue_ptr, VOID * source_ptr, ULONG wait_option)Note: This service copies the message to the front of the queue.Example: Send two 1-word messages to an 100 capacity array queue, one is sent by calling the tx_queue_send service and the other is sent by calling the tx_queue_front_send service.
Message Queue Service (Cont.) Insert one message at rear QUEUE_TOTAL_SIZE = (tx_queue_end) – (tx_queue_start)0x426f10 – 0x426d80 = 0x190 (400 bytes)
Message Queue Service (Cont.) Insert one message at front tx_queue_read becomes 0x426f0c, which is 4 bytes in front of tx_queue_end.
Message Queue Service (Cont.) Remove one message tx_queue_read is back to tx_queue_start
Message Queue Service (Cont.) • tx_queue_info_getUINT tx_queue_info_get( TX_QUEUE *queue_ptr, CHAR **name, ULONG *enqueued, ULONG *available_storage, TX_THREAD ** first_suspended, ULONG *suspended_count, TX_QUEUE ** next_queue) • tx_queue_prioritizeUINT tx_queue_prioritize(TX_QUEUE *queue_ptr)Note: All threads but the highest priority one remain in the same FIFO order in which they were suspended.
Sample Systems using a Message Queue for Inter-Thread Communicationand Event Notification Source Code 1 Link
Execution Result Result is the same as the counting semaphore for event notification application (producer-consumer) at p.158
Sample Systems using a Message Queue for Thread Synchronization Source Code 2 Link
Execution Result Totally the same as using Event Flags Group at p.178
Sample Systems using a Message Queue for Mutual Exclusion (trial) • Key section of this program// Initial message with value 1 and send to the queue at application definition sectionmsg_arr[QUEUE_MSG_SIZE-1] = 1;tx_queue_send(&my_queue, msg_arr, TX_NO_WAIT);/* Get a message from the queue before entering its critical section, hold the message during sleeping and send the message back to the queue at last */tx_queue_receive(&my_queue, msg_arr, TX_WAIT_FOREVER);tx_thread_sleep(5);tx_queue_send(&my_queue, msg_arr, TX_WAIT_FOREVER); Source Code 3 Link
Execution Result • Compare this result with that of using a binary semaphore for mutual exclusion at p.150