add SMP, Modules, and more processor/tools releases

This commit is contained in:
Scott Larson
2020-08-07 16:56:45 -07:00
parent 49e3c27f3f
commit 6f61053f2a
1858 changed files with 617131 additions and 4 deletions
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,188 @@
/**************************************************************************/
/* */
/* Copyright (c) Microsoft Corporation. All rights reserved. */
/* */
/* This software is licensed under the Microsoft Software License */
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
/* and in the root directory of this software. */
/* */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** ThreadX Component */
/** */
/** Module Manager */
/** */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/* */
/* COMPONENT DEFINITION RELEASE */
/* */
/* txm_module_manager_util.h PORTABLE C */
/* 6.0.1 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This file declares prototypes of utility functions used by the */
/* module manager. */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 06-30-2020 Scott Larson Initial Version 6.0.1 */
/* */
/**************************************************************************/
#ifndef TXM_MODULE_MANAGER_UTIL_H
#define TXM_MODULE_MANAGER_UTIL_H
/* Define utility macros. */
/* Define inside/outside check macros. The _INCLUSIVE/_EXCLUSIVE suffix applies only to range_end. */
#define TXM_MODULE_MANAGER_CHECK_OUTSIDE_RANGE_INCLUSIVE(range_start, range_end, obj_start, obj_size) \
((obj_start) > (ALIGN_TYPE) (range_end) || \
((obj_start) + (obj_size)) <= (ALIGN_TYPE) (range_start))
#define TXM_MODULE_MANAGER_CHECK_OUTSIDE_RANGE_EXCLUSIVE(range_start, range_end, obj_start, obj_size) \
((obj_start) >= (ALIGN_TYPE) (range_end) || \
((obj_start) + (obj_size)) <= (ALIGN_TYPE) (range_start))
#define TXM_MODULE_MANAGER_CHECK_INSIDE_RANGE_INCLUSIVE(range_start, range_end, obj_start, obj_size) \
(((obj_start) >= (ALIGN_TYPE) (range_start)) && \
(((obj_start) + (obj_size)) <= (ALIGN_TYPE) (range_end) + 1))
#define TXM_MODULE_MANAGER_CHECK_INSIDE_RANGE_INCLUSIVE_BYTE(range_start, range_end, byte_ptr) \
(((byte_ptr) >= (ALIGN_TYPE) (range_start)) && \
((byte_ptr) <= (ALIGN_TYPE) (range_end)))
#define TXM_MODULE_MANAGER_CHECK_INSIDE_RANGE_EXCLUSIVE(range_start, range_end, obj_start, obj_size) \
(((obj_start) >= (ALIGN_TYPE) (range_start)) && \
(((obj_start) + (obj_size)) <= (ALIGN_TYPE) (range_end)))
#define TXM_MODULE_MANAGER_CHECK_INSIDE_RANGE_EXCLUSIVE_BYTE(range_start, range_end, byte_ptr) \
(((byte_ptr) >= (ALIGN_TYPE) (range_start)) && \
((byte_ptr) < (ALIGN_TYPE) (range_end)))
/* Define check macros for modules. */
#define TXM_MODULE_MANAGER_CHECK_OUTSIDE_DATA(module_instance, obj_ptr, obj_size) \
TXM_MODULE_MANAGER_CHECK_OUTSIDE_RANGE_INCLUSIVE(module_instance -> txm_module_instance_data_start, \
module_instance -> txm_module_instance_data_end, \
obj_ptr, obj_size)
#define TXM_MODULE_MANAGER_CHECK_OUTSIDE_CODE(module_instance, obj_ptr, obj_size) \
TXM_MODULE_MANAGER_CHECK_OUTSIDE_RANGE_INCLUSIVE(module_instance -> txm_module_instance_code_start, \
module_instance -> txm_module_instance_code_end, \
obj_ptr, obj_size)
#define TXM_MODULE_MANAGER_CHECK_INSIDE_DATA(module_instance, obj_ptr, obj_size) \
TXM_MODULE_MANAGER_CHECK_INSIDE_RANGE_INCLUSIVE(module_instance -> txm_module_instance_data_start, \
module_instance -> txm_module_instance_data_end, \
obj_ptr, obj_size)
#define TXM_MODULE_MANAGER_CHECK_INSIDE_DATA_BYTE(module_instance, byte_ptr) \
TXM_MODULE_MANAGER_CHECK_INSIDE_RANGE_INCLUSIVE_BYTE(module_instance -> txm_module_instance_data_start, \
module_instance -> txm_module_instance_data_end, \
byte_ptr)
#define TXM_MODULE_MANAGER_CHECK_INSIDE_CODE(module_instance, obj_ptr, obj_size) \
TXM_MODULE_MANAGER_CHECK_INSIDE_RANGE_INCLUSIVE(module_instance -> txm_module_instance_code_start, \
module_instance -> txm_module_instance_code_end, \
obj_ptr, obj_size)
#define TXM_MODULE_MANAGER_CHECK_INSIDE_CODE_BYTE(module_instance, byte_ptr) \
TXM_MODULE_MANAGER_CHECK_INSIDE_RANGE_INCLUSIVE_BYTE(module_instance -> txm_module_instance_code_start, \
module_instance -> txm_module_instance_code_end, \
byte_ptr)
#define TXM_MODULE_MANAGER_CHECK_INSIDE_OBJ_POOL(module_instance, obj_ptr, obj_size) \
((_txm_module_manager_object_pool_created == TX_TRUE) && \
TXM_MODULE_MANAGER_CHECK_INSIDE_RANGE_EXCLUSIVE(_txm_module_manager_object_pool.tx_byte_pool_start, \
_txm_module_manager_object_pool.tx_byte_pool_start + _txm_module_manager_object_pool.tx_byte_pool_size, \
obj_ptr, obj_size))
/* Define macros for module. */
#define TXM_MODULE_MANAGER_ENSURE_INSIDE_MODULE(module_instance, obj_ptr, obj_size) \
(TXM_MODULE_MANAGER_CHECK_INSIDE_DATA(module_instance, obj_ptr, obj_size) || \
_txm_module_manager_shared_memory_check_inside(module_instance, (ALIGN_TYPE) obj_ptr, obj_size) || \
TXM_MODULE_MANAGER_CHECK_INSIDE_CODE(module_instance, obj_ptr, obj_size))
#define TXM_MODULE_MANAGER_ENSURE_INSIDE_MODULE_BYTE(module_instance, byte_ptr) \
(TXM_MODULE_MANAGER_CHECK_INSIDE_DATA_BYTE(module_instance, byte_ptr) || \
_txm_module_manager_shared_memory_check_inside_byte(module_instance, (ALIGN_TYPE) byte_ptr) || \
TXM_MODULE_MANAGER_CHECK_INSIDE_CODE_BYTE(module_instance, byte_ptr))
#define TXM_MODULE_MANAGER_ENSURE_INSIDE_MODULE_DATA(module_instance, obj_ptr, obj_size) \
(TXM_MODULE_MANAGER_CHECK_INSIDE_DATA(module_instance, obj_ptr, obj_size) || \
_txm_module_manager_shared_memory_check_inside(module_instance, (ALIGN_TYPE) obj_ptr, obj_size))
#define TXM_MODULE_MANAGER_ENSURE_OUTSIDE_MODULE(module_instance, obj_ptr, obj_size) \
(TXM_MODULE_MANAGER_CHECK_OUTSIDE_DATA(module_instance, obj_ptr, obj_size) && \
_txm_module_manager_shared_memory_check_outside(module_instance, (ALIGN_TYPE) obj_ptr, obj_size) && \
TXM_MODULE_MANAGER_CHECK_OUTSIDE_CODE(module_instance, obj_ptr, obj_size))
#define TXM_MODULE_MANAGER_ENSURE_INSIDE_OBJ_POOL(module_instance, obj_ptr, obj_size) \
(TXM_MODULE_MANAGER_CHECK_INSIDE_OBJ_POOL(module_instance, obj_ptr, obj_size))
/* Define macros for parameter types. */
/* Buffers we read from can be in RW/RO/Shared areas. */
#define TXM_MODULE_MANAGER_PARAM_CHECK_BUFFER_READ(module_instance, buffer_ptr, buffer_size) \
(((void *) (buffer_ptr) == TX_NULL) || \
(TXM_MODULE_MANAGER_ENSURE_INSIDE_MODULE(module_instance, buffer_ptr, buffer_size)))
/* Buffers we write to can only be in RW/Shared areas. */
#define TXM_MODULE_MANAGER_PARAM_CHECK_BUFFER_WRITE(module_instance, buffer_ptr, buffer_size) \
(((void *) (buffer_ptr) == TX_NULL) || \
(TXM_MODULE_MANAGER_ENSURE_INSIDE_MODULE_DATA(module_instance, buffer_ptr, buffer_size)))
/* 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) \
(((void *) (obj_ptr) == TX_NULL) || \
(TXM_MODULE_MANAGER_ENSURE_OUTSIDE_MODULE(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) \
(((void *) (obj_ptr) == TX_NULL) || \
(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)))
/* Strings we dereference can be in RW/RO/Shared areas. */
#define TXM_MODULE_MANAGER_PARAM_CHECK_DEREFERENCE_STRING(module_instance, string_ptr) \
(((void *) (string_ptr) == TX_NULL) || \
(TXM_MODULE_MANAGER_ENSURE_INSIDE_MODULE_BYTE(module_instance, string_ptr)))
#define TXM_MODULE_MANAGER_UTIL_MAX_VALUE_OF_TYPE_UNSIGNED(type) ((1ULL << (sizeof(type) * 8)) - 1)
#define TXM_MODULE_MANAGER_UTIL_MATH_ADD_ULONG(augend, addend, result) \
if ((ULONG)-1 - (augend) < (addend)) \
{ \
return(TXM_MODULE_MATH_OVERFLOW); \
} \
else \
{ \
(result) = (augend) + (addend); \
}
/* Define utility functions. */
UINT _txm_module_manager_object_memory_check(TXM_MODULE_INSTANCE *module_instance, ALIGN_TYPE object_ptr, ULONG object_size);
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_util_code_allocation_size_and_alignment_get(TXM_MODULE_PREAMBLE *module_preamble, ULONG *code_alignment_dest, ULONG *code_allocation_size_dest);
#endif
@@ -0,0 +1,79 @@
/**************************************************************************/
/* */
/* Copyright (c) Microsoft Corporation. All rights reserved. */
/* */
/* This software is licensed under the Microsoft Software License */
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
/* and in the root directory of this software. */
/* */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** ThreadX Component */
/** */
/** Module Manager */
/** */
/**************************************************************************/
/**************************************************************************/
/* Include necessary system files. */
#include "tx_api.h"
#include "txm_module.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _txm_module_manager_application_request PORTABLE C */
/* 6.0.1 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function processes the application-specific module request. */
/* The entire contents of the request structure is application */
/* specific and thus the processing in this file is left to the */
/* application to define. */
/* */
/* INPUT */
/* */
/* request_id Module request ID */
/* param_1 First parameter */
/* param_2 Second parameter */
/* param_3 Third parameter */
/* */
/* OUTPUT */
/* */
/* status Completion status */
/* */
/* CALLS */
/* */
/* None */
/* */
/* CALLED BY */
/* */
/* _txm_module_manager_kernel_dispatch Kernel dispatch function */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 06-30-2020 Scott Larson Initial Version 6.0.1 */
/* */
/**************************************************************************/
UINT _txm_module_manager_application_request(ULONG request_id, ALIGN_TYPE param_1, ALIGN_TYPE param_2, ALIGN_TYPE param_3)
{
/* By default, simply return the status of not available. */
return(TX_NOT_AVAILABLE);
}
@@ -0,0 +1,176 @@
/**************************************************************************/
/* */
/* Copyright (c) Microsoft Corporation. All rights reserved. */
/* */
/* This software is licensed under the Microsoft Software License */
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
/* and in the root directory of this software. */
/* */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** ThreadX Component */
/** */
/** Module Manager */
/** */
/**************************************************************************/
/**************************************************************************/
#define TX_SOURCE_CODE
#include "tx_api.h"
#include "tx_queue.h"
#include "tx_thread.h"
#include "txm_module.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _txm_module_manager_callback_request PORTABLE C */
/* 6.0.1 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function sends a notification callback function request to */
/* the associated module. */
/* */
/* INPUT */
/* */
/* module_callback_queue Module callback request queue */
/* callback_request Callback request */
/* */
/* OUTPUT */
/* */
/* None */
/* */
/* CALLS */
/* */
/* tx_queue_send Send module callback request */
/* */
/* CALLED BY */
/* */
/* ThreadX */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 06-30-2020 Scott Larson Initial Version 6.0.1 */
/* */
/**************************************************************************/
VOID _txm_module_manager_callback_request(TX_QUEUE *module_callback_queue, TXM_MODULE_CALLBACK_MESSAGE *callback_message)
{
TX_INTERRUPT_SAVE_AREA
TXM_MODULE_CALLBACK_MESSAGE *queued_message;
UINT enqueued;
UINT found;
UINT status;
/* Lockout interrupts. */
TX_DISABLE
/* Determine if the queue is valid. */
if ((module_callback_queue) && (module_callback_queue -> tx_queue_id == TX_QUEUE_ID))
{
/* Yes, the queue is valid. */
/* Pickup the current callback request in the queue. */
queued_message = (TXM_MODULE_CALLBACK_MESSAGE *) module_callback_queue -> tx_queue_read;
/* Pickup the number of items enqueued. */
enqueued = module_callback_queue -> tx_queue_enqueued;
/* Set the found flag to false. */
found = TX_FALSE;
/* Loop to look for duplicates in the queue. */
while (enqueued != 0)
{
/* Does this entry match the new callback message? */
if ((queued_message -> txm_module_callback_message_application_function == callback_message -> txm_module_callback_message_application_function) &&
(queued_message -> txm_module_callback_message_param_1 == callback_message -> txm_module_callback_message_param_1) &&
(queued_message -> txm_module_callback_message_param_2 == callback_message -> txm_module_callback_message_param_2) &&
(queued_message -> txm_module_callback_message_param_3 == callback_message -> txm_module_callback_message_param_3) &&
(queued_message -> txm_module_callback_message_param_4 == callback_message -> txm_module_callback_message_param_4) &&
(queued_message -> txm_module_callback_message_param_5 == callback_message -> txm_module_callback_message_param_5) &&
(queued_message -> txm_module_callback_message_param_6 == callback_message -> txm_module_callback_message_param_6) &&
(queued_message -> txm_module_callback_message_param_7 == callback_message -> txm_module_callback_message_param_7) &&
(queued_message -> txm_module_callback_message_param_8 == callback_message -> txm_module_callback_message_param_8) &&
(queued_message -> txm_module_callback_message_reserved1 == callback_message -> txm_module_callback_message_reserved1) &&
(queued_message -> txm_module_callback_message_reserved2 == callback_message -> txm_module_callback_message_reserved2))
{
/* Update the activation count in the queued request. */
queued_message -> txm_module_callback_message_activation_count++;
/* Set the found flag to true. */
found = TX_TRUE;
/* Get out of the loop. */
break;
}
/* Decrease the number of messages to examine. */
enqueued--;
/* Move the callback message to the next message. */
queued_message++;
/* Check for wrap? */
if (((ULONG *) queued_message) >= module_callback_queue -> tx_queue_end)
{
/* Yes, set the queued message to the beginning of the queue. */
queued_message = (TXM_MODULE_CALLBACK_MESSAGE *) module_callback_queue -> tx_queue_start;
}
}
/* Restore interrupts. */
TX_RESTORE
/* Determine if we need to send the new callback request. */
if (found == TX_FALSE)
{
/* Yes, send the message. */
status = _tx_queue_send(module_callback_queue, (VOID *) callback_message, TX_NO_WAIT);
/* Determine if an error was detected. */
if (status != TX_SUCCESS)
{
/* Error, increment the error counter and return. */
_txm_module_manager_callback_error_count++;
}
}
/* Increment the total number of callbacks. */
_txm_module_manager_callback_total_count++;
}
else
{
/* Module instance is not valid. */
/* Error, increment the error counter and return. */
_txm_module_manager_callback_error_count++;
/* Restore interrupts. */
TX_RESTORE
}
}
@@ -0,0 +1,133 @@
/**************************************************************************/
/* */
/* Copyright (c) Microsoft Corporation. All rights reserved. */
/* */
/* This software is licensed under the Microsoft Software License */
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
/* and in the root directory of this software. */
/* */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** ThreadX Component */
/** */
/** Module Manager */
/** */
/**************************************************************************/
/**************************************************************************/
#define TX_SOURCE_CODE
#include "tx_api.h"
#include "tx_event_flags.h"
#include "tx_thread.h"
#include "txm_module.h"
#ifndef TX_DISABLE_NOTIFY_CALLBACKS
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _txm_module_manager_event_flags_notify_trampoline PORTABLE C */
/* 6.0.1 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function processes the event flags set notification call from */
/* ThreadX. */
/* */
/* INPUT */
/* */
/* group_ptr Event flags group pointer */
/* */
/* OUTPUT */
/* */
/* None */
/* */
/* CALLS */
/* */
/* _txm_module_manager_callback_request Send module callback request */
/* */
/* CALLED BY */
/* */
/* ThreadX */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 06-30-2020 Scott Larson Initial Version 6.0.1 */
/* */
/**************************************************************************/
VOID _txm_module_manager_event_flags_notify_trampoline(TX_EVENT_FLAGS_GROUP *group_ptr)
{
TX_INTERRUPT_SAVE_AREA
TXM_MODULE_INSTANCE *module_instance;
TXM_MODULE_CALLBACK_MESSAGE callback_message;
TX_QUEUE *module_callback_queue;
/* We now know the callback is for a module. */
/* Disable interrupts. */
TX_DISABLE
/* Pickup the module instance pointer. */
module_instance = (TXM_MODULE_INSTANCE *) group_ptr -> tx_event_flags_group_module_instance;
/* Determine if this module is still valid. */
if ((module_instance) && (module_instance -> txm_module_instance_id == TXM_MODULE_ID) &&
(module_instance -> txm_module_instance_state == TXM_MODULE_STARTED))
{
/* Yes, the module is still valid. */
/* Pickup the module's callback message queue. */
module_callback_queue = &(module_instance -> txm_module_instance_callback_request_queue);
/* Build the queue notification message. */
callback_message.txm_module_callback_message_type = TXM_EVENTS_SET_CALLBACK;
callback_message.txm_module_callback_message_activation_count = 1;
callback_message.txm_module_callback_message_application_function = (VOID (*)(VOID)) group_ptr -> tx_event_flags_group_set_module_notify;
callback_message.txm_module_callback_message_param_1 = (ALIGN_TYPE) group_ptr;
callback_message.txm_module_callback_message_param_2 = 0;
callback_message.txm_module_callback_message_param_3 = 0;
callback_message.txm_module_callback_message_param_4 = 0;
callback_message.txm_module_callback_message_param_5 = 0;
callback_message.txm_module_callback_message_param_6 = 0;
callback_message.txm_module_callback_message_param_7 = 0;
callback_message.txm_module_callback_message_param_8 = 0;
callback_message.txm_module_callback_message_reserved1 = 0;
callback_message.txm_module_callback_message_reserved2 = 0;
/* Restore interrupts. */
TX_RESTORE
/* Call the general processing that will place the callback on the
module's callback request queue. */
_txm_module_manager_callback_request(module_callback_queue, &callback_message);
}
else
{
/* Module no longer valid. */
/* Error, increment the error counter and return. */
_txm_module_manager_callback_error_count++;
/* Restore interrupts. */
TX_RESTORE
}
}
#endif
@@ -0,0 +1,217 @@
/**************************************************************************/
/* */
/* Copyright (c) Microsoft Corporation. All rights reserved. */
/* */
/* This software is licensed under the Microsoft Software License */
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
/* and in the root directory of this software. */
/* */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** ThreadX Component */
/** */
/** Module Manager */
/** */
/**************************************************************************/
/**************************************************************************/
#ifdef FX_FILEX_PRESENT
#define TX_SOURCE_CODE
#include "tx_api.h"
#include "tx_initialize.h"
#include "tx_mutex.h"
#include "tx_thread.h"
#include "tx_byte_pool.h"
#include "fx_api.h"
#include "txm_module.h"
#include "txm_module_manager_util.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _txm_module_manager_file_load PORTABLE C */
/* 6.0.1 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function reads the module preamble, allocates memory for */
/* module code, loads the module code from the file, and calls */
/* _txm_module_manager_internal_load to load the data and prepare the */
/* module for execution. */
/* */
/* INPUT */
/* */
/* module_instance Module instance pointer */
/* module_name Name of module */
/* media_ptr FileX media pointer */
/* file_name Name of module binary file */
/* */
/* OUTPUT */
/* */
/* status Completion status */
/* */
/* CALLS */
/* */
/* fx_file_close Close file */
/* fx_file_open Open file */
/* fx_file_read File read */
/* fx_file_seek File seek */
/* _tx_byte_allocate Allocate data area */
/* _txm_module_manager_internal_load Load data and prepare module for */
/* execution */
/* */
/* CALLED BY */
/* */
/* Application code */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 06-30-2020 Scott Larson Initial Version 6.0.1 */
/* */
/**************************************************************************/
UINT _txm_module_manager_file_load(TXM_MODULE_INSTANCE *module_instance, CHAR *module_name, FX_MEDIA *media_ptr, CHAR *file_name)
{
TXM_MODULE_PREAMBLE *module_preamble;
FX_FILE module_file;
TXM_MODULE_PREAMBLE preamble;
ULONG code_start;
ULONG code_size;
ULONG code_alignment;
ULONG code_allocation_size;
CHAR *code_memory_ptr;
UCHAR *destination_ptr;
ULONG actual_size;
UINT status;
/* Attempt to open the file. */
status = fx_file_open(media_ptr, &module_file, file_name, FX_OPEN_FOR_READ);
/* Check the file open status. */
if (status == FX_SUCCESS)
{
/* Read the preamble of the module. */
status = fx_file_read(&module_file, (VOID *) &preamble, sizeof(TXM_MODULE_PREAMBLE), &actual_size);
/* Check the file read status. */
if (status == FX_SUCCESS)
{
/* Check the number of bytes read. */
if (actual_size == sizeof(TXM_MODULE_PREAMBLE))
{
/* Pickup the module's information. */
module_preamble = (TXM_MODULE_PREAMBLE *) &preamble;
/* Pickup the module code size. */
code_size = module_preamble -> txm_module_preamble_code_size;
/* Check for valid sizes. */
if (code_size != 0)
{
/* Initialize module control block to all zeros. */
TX_MEMSET(module_instance, 0, sizeof(TXM_MODULE_INSTANCE));
/* Get the amount of the bytes we need to allocate for the module's code as well as the required alignment. */
status = _txm_module_manager_util_code_allocation_size_and_alignment_get(module_preamble, &code_alignment, &code_allocation_size);
if (status == TX_SUCCESS)
{
/* Allocate code memory for the module. */
status = _tx_byte_allocate(&_txm_module_manager_byte_pool, (VOID **) &code_memory_ptr, code_allocation_size, TX_NO_WAIT);
/* Determine if the module's code memory allocation was successful. */
if (status == TX_SUCCESS)
{
/* Prepare to read the module code into memory. */
code_start = (ULONG) code_memory_ptr;
code_start = (code_start + (code_alignment - 1)) & ~(code_alignment - 1);
destination_ptr = (UCHAR *) code_start;
/* Seek back to the beginning of the file. */
status = fx_file_seek(&module_file, 0);
if (status == FX_SUCCESS)
{
/* Read the module into memory. */
status = fx_file_read(&module_file, (VOID *) destination_ptr, code_size, &actual_size);
if (status == FX_SUCCESS)
{
/* Check the actual size read. */
if (actual_size == code_size)
{
/* At this point, the module's instruction area is now in the RAM code area. */
/* Now load it in-place. */
status = _txm_module_manager_internal_load(module_instance, module_name, (VOID *) code_start,
code_size, code_memory_ptr, code_allocation_size);
if (status == TX_SUCCESS)
{
/* Close the file. */
fx_file_close(&module_file);
/* Return success. */
return(TX_SUCCESS);
}
}
else
{
/* Invalid number of bytes read. */
status = TXM_MODULE_FILEX_INVALID_BYTES_READ;
}
}
}
/* Release the memory. */
_tx_byte_release(code_memory_ptr);
}
}
}
else
{
/* Invalid module preamble. */
status = TXM_MODULE_INVALID;
}
}
else
{
/* Invalid number of bytes read. */
status = TXM_MODULE_FILEX_INVALID_BYTES_READ;
}
}
/* Close the file. */
fx_file_close(&module_file);
}
/* Return success. */
return(status);
}
#endif
@@ -0,0 +1,120 @@
/**************************************************************************/
/* */
/* Copyright (c) Microsoft Corporation. All rights reserved. */
/* */
/* This software is licensed under the Microsoft Software License */
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
/* and in the root directory of this software. */
/* */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** ThreadX Component */
/** */
/** Module Manager */
/** */
/**************************************************************************/
/**************************************************************************/
#define TX_SOURCE_CODE
#include "tx_api.h"
#include "tx_initialize.h"
#include "tx_mutex.h"
#include "tx_thread.h"
#include "tx_byte_pool.h"
#include "txm_module.h"
#include "txm_module_manager_util.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _txm_module_manager_in_place_load PORTABLE C */
/* 6.0.1 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function ensures the code-related parts of the module preamble */
/* are valid and calls _txm_module_manager_internal_load to load the */
/* data and prepare the module for execution. */
/* */
/* INPUT */
/* */
/* module_instance Module instance pointer */
/* module_name Module name pointer */
/* module_location Module code location */
/* */
/* OUTPUT */
/* */
/* status Completion status */
/* */
/* CALLS */
/* */
/* _txm_module_manager_internal_load Load data and prepare module for */
/* execution */
/* */
/* CALLED BY */
/* */
/* Application code */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 06-30-2020 Scott Larson Initial Version 6.0.1 */
/* */
/**************************************************************************/
UINT _txm_module_manager_in_place_load(TXM_MODULE_INSTANCE *module_instance, CHAR *module_name, VOID *module_location)
{
TXM_MODULE_PREAMBLE *module_preamble;
ULONG code_size;
ULONG code_alignment;
ULONG code_allocation_size_ignored;
UINT status;
/* Pickup the module's information. */
module_preamble = (TXM_MODULE_PREAMBLE *) module_location;
/* Pickup the basic module sizes. */
code_size = module_preamble -> txm_module_preamble_code_size;
/* Check for valid sizes. */
if (code_size == 0)
{
/* Invalid module preamble. */
return(TXM_MODULE_INVALID);
}
/* Get the amount of the bytes we need to allocate for the module's code
as well as the required alignment. Note that because this is an in-place
load, we only want the code alignment so we can check it. */
status = _txm_module_manager_util_code_allocation_size_and_alignment_get(module_preamble, &code_alignment, &code_allocation_size_ignored);
if (status != TX_SUCCESS)
{
/* Math overflow error occurred. */
return(status);
}
/* Since this is an in-place load, check the alignment of the module's instruction area (code). */
TXM_MODULE_MANAGER_CHECK_CODE_ALIGNMENT(module_location, code_alignment)
/* Now load the module in-place. */
status = _txm_module_manager_internal_load(module_instance, module_name, module_location,
code_size, TX_NULL, 0);
/* Return status. */
return(status);
}
@@ -0,0 +1,186 @@
/**************************************************************************/
/* */
/* Copyright (c) Microsoft Corporation. All rights reserved. */
/* */
/* This software is licensed under the Microsoft Software License */
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
/* and in the root directory of this software. */
/* */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** ThreadX Component */
/** */
/** Module Manager */
/** */
/**************************************************************************/
/**************************************************************************/
#define TX_SOURCE_CODE
#define TX_MODULE_MANAGER_INIT
#include "tx_api.h"
#include "tx_initialize.h"
#include "tx_thread.h"
#include "tx_byte_pool.h"
#include "tx_queue.h"
#include "tx_mutex.h"
#include "txm_module.h"
TXM_MODULE_MANAGER_VERSION_ID
/* Define global variables associated with the module manager. */
/* Define the module properties supported by this module manager. */
ULONG _txm_module_manager_properties_supported;
/* Define the module properties required by this module manager. */
ULONG _txm_module_manager_properties_required;
/* Define byte pool that will be used for allocating module data areas. */
TX_BYTE_POOL _txm_module_manager_byte_pool;
/* Define byte pool that will be used for allocating external memory for module objects. */
TX_BYTE_POOL _txm_module_manager_object_pool;
/* Define the flag indicating that the module manager byte pool is created. */
UINT _txm_module_manager_object_pool_created;
/* Define module manager protection mutex. */
TX_MUTEX _txm_module_manager_mutex;
/* Define the loaded modules list, which keeps track of all loaded modules. */
TXM_MODULE_INSTANCE *_txm_module_manager_loaded_list_ptr;
/* Define the count of loaded modules. */
ULONG _txm_module_manger_loaded_count;
/* Define the ready flag, which is checked by other module manager APIs
to make sure the manager has been initialized. */
UINT _txm_module_manager_ready;
/* Define the total callback activation count. This is simply incremented on every
callback activation. */
ULONG _txm_module_manager_callback_total_count;
/* Define the callback activation error count. This occurs when the available callback
structures have been exhausted. */
ULONG _txm_module_manager_callback_error_count;
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _txm_module_manager_initialize PORTABLE C */
/* 6.0.1 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function initializes the module manager. */
/* */
/* INPUT */
/* */
/* module_memory_start Start of module area */
/* module_memory_size Size in bytes of module area */
/* */
/* OUTPUT */
/* */
/* status Completion status */
/* */
/* CALLS */
/* */
/* _tx_byte_pool_create Create module memory byte pool */
/* _tx_mutex_create Create module manager */
/* protection mutex */
/* */
/* CALLED BY */
/* */
/* Application code */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 06-30-2020 Scott Larson Initial Version 6.0.1 */
/* */
/**************************************************************************/
UINT _txm_module_manager_initialize(VOID *module_memory_start, ULONG module_memory_size)
{
/* Check for interrupt call. */
if (TX_THREAD_GET_SYSTEM_STATE() != 0)
{
/* Now, make sure the call is from an interrupt and not initialization. */
if (TX_THREAD_GET_SYSTEM_STATE() < TX_INITIALIZE_IN_PROGRESS)
{
/* Invalid caller of this function, return appropriate error code. */
return(TX_CALLER_ERROR);
}
}
/* Setup the module properties supported by this module manager. */
_txm_module_manager_properties_supported = TXM_MODULE_MANAGER_SUPPORTED_OPTIONS;
/* Setup the module properties required by this module manager. */
_txm_module_manager_properties_required = TXM_MODULE_MANAGER_REQUIRED_OPTIONS;
/* Clear the module manager ready flag. */
_txm_module_manager_ready = TX_FALSE;
/* Initialize the empty module list. */
_txm_module_manager_loaded_list_ptr = TX_NULL;
/* Clear the number of loaded modules. */
_txm_module_manger_loaded_count = 0;
/* Create the module manager protection mutex. */
_tx_mutex_create(&_txm_module_manager_mutex, "Module Manager Protection Mutex", TX_NO_INHERIT);
/* Create a byte pool for allocating RAM areas for modules. */
_tx_byte_pool_create(&_txm_module_manager_byte_pool, "Module Manager Byte Pool", module_memory_start, module_memory_size);
/* Indicate the module manager object pool has not been created. */
_txm_module_manager_object_pool_created = TX_FALSE;
/* Mark the module manager as ready! */
_txm_module_manager_ready = TX_TRUE;
/* Return success. */
return(TX_SUCCESS);
}
@@ -0,0 +1,424 @@
/**************************************************************************/
/* */
/* Copyright (c) Microsoft Corporation. All rights reserved. */
/* */
/* This software is licensed under the Microsoft Software License */
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
/* and in the root directory of this software. */
/* */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** ThreadX Component */
/** */
/** Module Manager */
/** */
/**************************************************************************/
/**************************************************************************/
#define TX_SOURCE_CODE
#include "tx_api.h"
#include "tx_initialize.h"
#include "tx_mutex.h"
#include "tx_thread.h"
#include "tx_byte_pool.h"
#include "txm_module.h"
#include "txm_module_manager_util.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _txm_module_manager_internal_load PORTABLE C */
/* 6.0.1 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function allocates data memory for module and prepares the */
/* module for execution from the supplied code location. */
/* */
/* INPUT */
/* */
/* module_instance Module instance pointer */
/* module_name Module name pointer */
/* module_location Module code location */
/* code_size Module code size */
/* code_allocation_ptr Allocated code location */
/* code_allocation_size Allocated code size */
/* */
/* OUTPUT */
/* */
/* status Completion status */
/* */
/* CALLS */
/* */
/* _tx_byte_allocate Allocate data area */
/* _tx_mutex_get Get protection mutex */
/* _tx_mutex_put Release protection mutex */
/* */
/* CALLED BY */
/* */
/* Application code */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 06-30-2020 Scott Larson Initial Version 6.0.1 */
/* */
/**************************************************************************/
UINT _txm_module_manager_internal_load(TXM_MODULE_INSTANCE *module_instance, CHAR *module_name, VOID *module_location,
ULONG code_size, VOID *code_allocation_ptr, ULONG code_allocation_size)
{
TX_INTERRUPT_SAVE_AREA
TXM_MODULE_PREAMBLE *module_preamble;
TXM_MODULE_INSTANCE *next_module, *previous_module;
ULONG shell_function_adjust;
ULONG start_function_adjust;
ULONG stop_function_adjust;
ULONG callback_function_adjust;
ULONG start_stop_stack_size;
ULONG callback_stack_size;
ULONG code_size_ignored;
ULONG code_alignment_ignored;
ALIGN_TYPE data_start;
ULONG data_size;
ULONG data_alignment;
ULONG data_allocation_size;
ULONG module_properties;
CHAR *memory_ptr;
UINT status;
/* Check for interrupt call. */
if (TX_THREAD_GET_SYSTEM_STATE() != 0)
{
/* Now, make sure the call is from an interrupt and not initialization. */
if (TX_THREAD_GET_SYSTEM_STATE() < TX_INITIALIZE_IN_PROGRESS)
{
/* Invalid caller of this function, return appropriate error code. */
return(TX_CALLER_ERROR);
}
}
/* Determine if the module manager has not been initialized yet. */
if (_txm_module_manager_ready != TX_TRUE)
{
/* Module manager has not been initialized. */
return(TX_NOT_AVAILABLE);
}
/* Determine if the module is valid. */
if (module_instance == TX_NULL)
{
/* Invalid module pointer. */
return(TX_PTR_ERROR);
}
/* Get module manager protection mutex. */
_tx_mutex_get(&_txm_module_manager_mutex, TX_WAIT_FOREVER);
/* Determine if the module is already valid. */
if (module_instance -> txm_module_instance_id == TXM_MODULE_ID)
{
/* Release the protection mutex. */
_tx_mutex_put(&_txm_module_manager_mutex);
/* Module already loaded. */
return(TXM_MODULE_ALREADY_LOADED);
}
/* Pickup the module's information. */
module_preamble = (TXM_MODULE_PREAMBLE *) module_location;
/* Check to make sure there is a valid module to load. */
if (module_preamble -> txm_module_preamble_id != TXM_MODULE_ID)
{
/* Release the protection mutex. */
_tx_mutex_put(&_txm_module_manager_mutex);
/* Invalid module preamble. */
return(TXM_MODULE_INVALID);
}
/* Check the properties of this module. */
module_properties = module_preamble -> txm_module_preamble_property_flags & TXM_MODULE_OPTIONS_MASK;
if (/* Ensure the requested properties are supported. */
((module_properties & _txm_module_manager_properties_supported) != module_properties) ||
/* Ensure the required properties are there. */
((_txm_module_manager_properties_required & module_properties) != _txm_module_manager_properties_required) ||
/* If memory protection is enabled, then so must user mode. */
((module_properties & TXM_MODULE_MEMORY_PROTECTION) && !(module_properties & TXM_MODULE_USER_MODE))
)
{
/* Release the protection mutex. */
_tx_mutex_put(&_txm_module_manager_mutex);
/* Invalid properties. Return error. */
return(TXM_MODULE_INVALID_PROPERTIES);
}
/* Check for valid module entry offsets. */
if ((module_preamble -> txm_module_preamble_shell_entry_function == 0) ||
(module_preamble -> txm_module_preamble_start_function == 0))
{
/* Release the protection mutex. */
_tx_mutex_put(&_txm_module_manager_mutex);
/* Invalid module preamble. */
return(TXM_MODULE_INVALID);
}
/* Check for valid sizes. */
if ((module_preamble -> txm_module_preamble_code_size == 0) ||
(module_preamble -> txm_module_preamble_data_size == 0) ||
(module_preamble -> txm_module_preamble_start_stop_stack_size == 0) ||
(module_preamble -> txm_module_preamble_callback_stack_size == 0))
{
/* Release the protection mutex. */
_tx_mutex_put(&_txm_module_manager_mutex);
/* Invalid module preamble. */
return(TXM_MODULE_INVALID);
}
/* Initialize module control block to all zeros. */
TX_MEMSET(module_instance, 0, sizeof(TXM_MODULE_INSTANCE));
/* Pickup the basic module sizes. */
data_size = module_preamble -> txm_module_preamble_data_size;
start_stop_stack_size = module_preamble -> txm_module_preamble_start_stop_stack_size;
callback_stack_size = module_preamble -> txm_module_preamble_callback_stack_size;
/* Adjust the size of the module elements to be aligned to the default alignment. We do this
so that when we partition the allocated memory, we can simply place these regions right beside
each other without having to align their pointers. Note this only works when they all have
the same alignment. */
TXM_MODULE_MANAGER_UTIL_MATH_ADD_ULONG(data_size, TXM_MODULE_DATA_ALIGNMENT, data_size);
data_size = ((data_size - 1)/TXM_MODULE_DATA_ALIGNMENT) * TXM_MODULE_DATA_ALIGNMENT;
TXM_MODULE_MANAGER_UTIL_MATH_ADD_ULONG(start_stop_stack_size, TXM_MODULE_DATA_ALIGNMENT, start_stop_stack_size);
start_stop_stack_size = ((start_stop_stack_size - 1)/TXM_MODULE_DATA_ALIGNMENT) * TXM_MODULE_DATA_ALIGNMENT;
TXM_MODULE_MANAGER_UTIL_MATH_ADD_ULONG(callback_stack_size, TXM_MODULE_DATA_ALIGNMENT, callback_stack_size);
callback_stack_size = ((callback_stack_size - 1)/TXM_MODULE_DATA_ALIGNMENT) * TXM_MODULE_DATA_ALIGNMENT;
/* Update the data size to account for the default thread stacks. */
TXM_MODULE_MANAGER_UTIL_MATH_ADD_ULONG(data_size, start_stop_stack_size, data_size);
TXM_MODULE_MANAGER_UTIL_MATH_ADD_ULONG(data_size, callback_stack_size, data_size);
/* Setup the default code and data alignments. */
data_alignment = (ULONG) TXM_MODULE_DATA_ALIGNMENT;
/* Get the port-specific alignment for the data size. Note we only want data
so we pass values of 1 for code (to avoid any possible div by 0 errors). */
code_size_ignored = 1;
code_alignment_ignored = 1;
TXM_MODULE_MANAGER_ALIGNMENT_ADJUST(module_preamble, code_size_ignored, code_alignment_ignored, data_size, data_alignment)
/* Calculate the module's total RAM memory requirement. This entire area is allocated from the module
manager's byte pool. The general layout is defined as follows:
Lowest Address: Start of start/stop thread stack
... [note: thread entry info is embedded near end of stack areas]
End of start/stop thread stack
Start of callback thread stack
... [note: thread entry info is embedded near end of stack areas]
End of callback thread stack
Module's Data Area
...
End of Module's Data Area
Highest Address: */
/* Add an extra alignment increment so we can align the pointer after allocation. */
TXM_MODULE_MANAGER_UTIL_MATH_ADD_ULONG(data_size, data_alignment, data_allocation_size);
/* Allocate memory for the module. */
status = _tx_byte_allocate(&_txm_module_manager_byte_pool, (VOID **) &memory_ptr, data_allocation_size, TX_NO_WAIT);
/* Determine if the module memory allocation was successful. */
if (status)
{
/* Release the protection mutex. */
_tx_mutex_put(&_txm_module_manager_mutex);
/* No memory, return an error. */
return(TX_NO_MEMORY);
}
/* Clear the allocated memory. */
TX_MEMSET(memory_ptr, ((UCHAR) 0), data_allocation_size);
/* Disable interrupts. */
TX_DISABLE
/* Setup the module instance structure. */
module_instance -> txm_module_instance_id = TXM_MODULE_ID;
/* Save the module name. */
module_instance -> txm_module_instance_name = module_name;
/* Save the module properties. */
module_instance -> txm_module_instance_property_flags = module_preamble -> txm_module_preamble_property_flags;
/* Set the module data memory allocation. This is the address released
when the module is unloaded. */
module_instance -> txm_module_instance_data_allocation_ptr = (VOID *) memory_ptr;
/* Save the data allocation size. */
module_instance -> txm_module_instance_data_allocation_size = data_allocation_size;
/* Calculate the actual start of the data area. This needs to be adjusted based on the alignment. */
data_start = (ALIGN_TYPE) memory_ptr;
data_start = (data_start + (((ALIGN_TYPE)data_alignment) - 1)) & ~(((ALIGN_TYPE)data_alignment) - 1);
memory_ptr = (CHAR *) data_start;
module_instance -> txm_module_instance_data_start = (VOID *) memory_ptr;
/* Compute the end of the data memory allocation. */
module_instance -> txm_module_instance_data_end = (VOID *) (memory_ptr + (data_size - 1));
/* Save the size of the data area. */
module_instance -> txm_module_instance_data_size = data_size;
/* Set the module code memory allocation. This is the address released
when the module is unloaded. */
module_instance -> txm_module_instance_code_allocation_ptr = (VOID *) code_allocation_ptr;
/* Save the code allocation size. */
module_instance -> txm_module_instance_code_allocation_size = code_allocation_size;
/* Setup the code pointers. Since the code was loaded in-place, this is effectively just the values supplied in the API call. */
module_instance -> txm_module_instance_code_start = (VOID *) module_location;
module_instance -> txm_module_instance_code_end = (VOID *) (((CHAR *) module_location) + (code_size - 1));
/* Setup the code size. */
module_instance -> txm_module_instance_code_size = code_size;
/* Save the module's total memory usage. */
module_instance -> txm_module_instance_total_ram_usage = data_allocation_size + code_allocation_size;
/* Set the module state to started. */
module_instance -> txm_module_instance_state = TXM_MODULE_LOADED;
/* Save the preamble pointer. */
module_instance -> txm_module_instance_preamble_ptr = module_preamble;
/* Save the module application ID in the module instance. */
module_instance -> txm_module_instance_application_module_id = module_preamble -> txm_module_preamble_application_module_id;
/* Setup the module's start/stop thread stack area. */
module_instance -> txm_module_instance_start_stop_stack_start_address = (VOID *) (memory_ptr);
module_instance -> txm_module_instance_start_stop_stack_size = start_stop_stack_size;
module_instance -> txm_module_instance_start_stop_stack_end_address = (VOID *) (memory_ptr + (start_stop_stack_size - 1));
/* Move the memory pointer forward. */
memory_ptr = memory_ptr + start_stop_stack_size;
/* Save the start/stop thread priority. */
module_instance -> txm_module_instance_start_stop_priority = module_preamble -> txm_module_preamble_start_stop_priority;
/* Setup the module's callback thread stack area. */
module_instance -> txm_module_instance_callback_stack_start_address = (VOID *) (memory_ptr);
module_instance -> txm_module_instance_callback_stack_size = callback_stack_size;
module_instance -> txm_module_instance_callback_stack_end_address = (VOID *) (memory_ptr + (callback_stack_size - 1));
/* Move the memory pointer forward. */
memory_ptr = memory_ptr + callback_stack_size;
/* Save the callback thread priority. */
module_instance -> txm_module_instance_callback_priority = module_preamble -> txm_module_preamble_callback_priority;
/* Setup the start of the module data section. */
module_instance -> txm_module_instance_module_data_base_address = (VOID *) (memory_ptr);
/* Calculate the function adjustments based on the specific implementation of the module manager/module. */
TXM_MODULE_MANAGER_CALCULATE_ADJUSTMENTS(module_preamble -> txm_module_preamble_property_flags, shell_function_adjust, start_function_adjust, stop_function_adjust, callback_function_adjust)
/* Build actual addresses based on load... Setup all the function pointers. Any adjustments needed to shell entry, start function, and callback function are defined in the
module preamble. */
module_instance -> txm_module_instance_shell_entry_function = (VOID (*)(TX_THREAD *, TXM_MODULE_INSTANCE *)) (((CHAR *) module_instance -> txm_module_instance_code_start) +
(module_preamble -> txm_module_preamble_shell_entry_function) +
(shell_function_adjust));
module_instance -> txm_module_instance_start_thread_entry = (VOID (*)(ULONG)) (((CHAR *) module_instance -> txm_module_instance_code_start) +
(module_preamble -> txm_module_preamble_start_function) +
(start_function_adjust));
module_instance -> txm_module_instance_callback_request_thread_entry = (VOID (*)(ULONG)) (((CHAR *) module_instance -> txm_module_instance_code_start) +
(module_preamble -> txm_module_preamble_callback_function) +
(callback_function_adjust));
/* Determine if there is a stop function for this module. */
if (module_preamble -> txm_module_preamble_stop_function)
{
/* Yes, there is a stop function, build the address. */
module_instance -> txm_module_instance_stop_thread_entry = (VOID (*)(ULONG)) (((CHAR *) module_instance -> txm_module_instance_code_start) +
(module_preamble -> txm_module_preamble_stop_function) +
(stop_function_adjust));
}
else
{
/* No, there is no stop function. Just set the pointer to NULL. */
module_instance -> txm_module_instance_stop_thread_entry = TX_NULL;
}
/* Load the module control block with port-specific information. */
TXM_MODULE_MANAGER_MODULE_SETUP(module_instance);
/* Now add the module to the linked list of created modules. */
if (_txm_module_manger_loaded_count++ == 0)
{
/* The loaded module list is empty. Add module to empty list. */
_txm_module_manager_loaded_list_ptr = module_instance;
module_instance -> txm_module_instance_loaded_next = module_instance;
module_instance -> txm_module_instance_loaded_previous = module_instance;
}
else
{
/* This list is not NULL, add to the end of the list. */
next_module = _txm_module_manager_loaded_list_ptr;
previous_module = next_module -> txm_module_instance_loaded_previous;
/* Place the new module in the list. */
next_module -> txm_module_instance_loaded_previous = module_instance;
previous_module -> txm_module_instance_loaded_next = module_instance;
/* Setup this module's created links. */
module_instance -> txm_module_instance_loaded_previous = previous_module;
module_instance -> txm_module_instance_loaded_next = next_module;
}
/* Restore interrupts. */
TX_RESTORE
/* Release the protection mutex. */
_tx_mutex_put(&_txm_module_manager_mutex);
/* Return success. */
return(TX_SUCCESS);
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,116 @@
/**************************************************************************/
/* */
/* Copyright (c) Microsoft Corporation. All rights reserved. */
/* */
/* This software is licensed under the Microsoft Software License */
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
/* and in the root directory of this software. */
/* */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** ThreadX Component */
/** */
/** Module Manager */
/** */
/**************************************************************************/
/**************************************************************************/
#define TX_SOURCE_CODE
#include "tx_api.h"
#include "tx_mutex.h"
#include "txm_module.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _txm_module_manager_maximum_module_priority_set PORTABLE C */
/* 6.0.1 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function sets the maximum thread priority allowed in a module. */
/* */
/* INPUT */
/* */
/* module_instance Module instance pointer */
/* priority Maximum thread priority */
/* */
/* OUTPUT */
/* */
/* status Completion status */
/* */
/* CALLS */
/* */
/* _tx_mutex_get Get protection mutex */
/* _tx_mutex_put Release protection mutex */
/* */
/* CALLED BY */
/* */
/* Application code */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 06-30-2020 Scott Larson Initial Version 6.0.1 */
/* */
/**************************************************************************/
UINT _txm_module_manager_maximum_module_priority_set(TXM_MODULE_INSTANCE *module_instance, UINT priority)
{
/* Determine if the module manager has not been initialized yet. */
if (_txm_module_manager_ready != TX_TRUE)
{
/* Module manager has not been initialized. */
return(TX_NOT_AVAILABLE);
}
/* Determine if the module is valid. */
if (module_instance == TX_NULL)
{
/* Invalid module pointer. */
return(TX_PTR_ERROR);
}
/* Get module manager protection mutex. */
_tx_mutex_get(&_txm_module_manager_mutex, TX_WAIT_FOREVER);
/* Determine if the module instance is valid. */
if (module_instance -> txm_module_instance_id != TXM_MODULE_ID)
{
/* Release the protection mutex. */
_tx_mutex_put(&_txm_module_manager_mutex);
/* Invalid module pointer. */
return(TX_PTR_ERROR);
}
/* Determine if the module instance is in the loaded state. */
if ((module_instance -> txm_module_instance_state != TXM_MODULE_LOADED) && (module_instance -> txm_module_instance_state != TXM_MODULE_STOPPED))
{
/* Release the protection mutex. */
_tx_mutex_put(&_txm_module_manager_mutex);
/* Return error if the module is not ready. */
return(TX_START_ERROR);
}
/* Set module's maximum priority. */
module_instance->txm_module_instance_maximum_priority = priority;
/* Release the protection mutex. */
_tx_mutex_put(&_txm_module_manager_mutex);
return(TX_SUCCESS);
}
@@ -0,0 +1,162 @@
/**************************************************************************/
/* */
/* Copyright (c) Microsoft Corporation. All rights reserved. */
/* */
/* This software is licensed under the Microsoft Software License */
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
/* and in the root directory of this software. */
/* */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** ThreadX Component */
/** */
/** Module Manager */
/** */
/**************************************************************************/
/**************************************************************************/
#define TX_SOURCE_CODE
#include "tx_api.h"
#include "tx_initialize.h"
#include "tx_mutex.h"
#include "tx_thread.h"
#include "tx_byte_pool.h"
#include "txm_module.h"
#include "txm_module_manager_util.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _txm_module_manager_memory_load PORTABLE C */
/* 6.0.1 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function allocates memory for module code and and calls */
/* _txm_module_manager_internal_load to load the data and prepare the */
/* module for execution. */
/* */
/* INPUT */
/* */
/* module_instance Module instance pointer */
/* module_name Module name pointer */
/* module_location Module code location */
/* */
/* OUTPUT */
/* */
/* status Completion status */
/* */
/* CALLS */
/* */
/* _tx_byte_allocate Allocate data area */
/* _txm_module_manager_internal_load Load data and prepare module for */
/* execution */
/* */
/* CALLED BY */
/* */
/* Application code */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 06-30-2020 Scott Larson Initial Version 6.0.1 */
/* */
/**************************************************************************/
UINT _txm_module_manager_memory_load(TXM_MODULE_INSTANCE *module_instance, CHAR *module_name, VOID *module_location)
{
TXM_MODULE_PREAMBLE *module_preamble;
ALIGN_TYPE code_start;
ULONG code_size;
ULONG code_alignment;
ULONG code_allocation_size;
CHAR *code_memory_ptr;
UCHAR *source_ptr;
UCHAR *destination_ptr;
ULONG copy_size;
ULONG i;
UINT status;
/* Pickup the module's information. */
module_preamble = (TXM_MODULE_PREAMBLE *) module_location;
/* Pickup the basic module sizes. */
code_size = module_preamble -> txm_module_preamble_code_size;
/* Check for valid sizes. */
if (code_size == 0)
{
/* Invalid module preamble. */
return(TXM_MODULE_INVALID);
}
/* Get the amount of the bytes we need to allocate for the module's code as well as the required alignment. */
status = _txm_module_manager_util_code_allocation_size_and_alignment_get(module_preamble, &code_alignment, &code_allocation_size);
if (status != TX_SUCCESS)
{
/* Math overflow error occurred. */
return(status);
}
/* Allocate code memory for the module. */
status = _tx_byte_allocate(&_txm_module_manager_byte_pool, (VOID **) &code_memory_ptr, code_allocation_size, TX_NO_WAIT);
/* Determine if the module's code memory allocation was successful. */
if (status != TX_SUCCESS)
{
/* No memory, return an error. */
return(TX_NO_MEMORY);
}
/* Copy the module code into memory. */
source_ptr = (UCHAR *) module_location;
code_start = (ALIGN_TYPE) code_memory_ptr;
code_start = (code_start + (code_alignment - 1)) & ~(code_alignment - 1);
destination_ptr = (UCHAR *) code_start;
/* Calculate the size. */
copy_size = module_preamble -> txm_module_preamble_code_size;
/* Loop to copy the code to RAM. */
for (i = 0; i < copy_size; i++)
{
/* Copy one byte at a time. */
*destination_ptr++ = *source_ptr++;
}
/* At this point, the module's instruction area is now in the RAM code area. */
/* Now load it in-place. */
status = _txm_module_manager_internal_load(module_instance, module_name, (VOID *) code_start,
code_size, code_memory_ptr, code_allocation_size);
if (status != TX_SUCCESS)
{
/* Release code memory. */
_tx_byte_release(code_memory_ptr);
/* Return error. */
return(status);
}
/* Return success. */
return(TX_SUCCESS);
}
@@ -0,0 +1,155 @@
/**************************************************************************/
/* */
/* Copyright (c) Microsoft Corporation. All rights reserved. */
/* */
/* This software is licensed under the Microsoft Software License */
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
/* and in the root directory of this software. */
/* */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** ThreadX Component */
/** */
/** Module Manager */
/** */
/**************************************************************************/
/**************************************************************************/
#define TX_SOURCE_CODE
#include "txm_module.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _txm_module_manager_object_allocate PORTABLE C */
/* 6.0.1 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function allocates memory for an object from the memory pool */
/* supplied to txm_module_manager_initialize. */
/* */
/* INPUT */
/* */
/* object_ptr Destination of object pointer on */
/* successful allocation */
/* object_size Size in bytes of the object to be */
/* allocated */
/* module_instance The module instance that the */
/* object belongs to */
/* */
/* OUTPUT */
/* */
/* status Completion status */
/* */
/* CALLS */
/* */
/* _txe_mutex_get Get module instance mutex */
/* _txe_mutex_put Release module instance mutex */
/* _txe_byte_allocate Allocate object from pool */
/* */
/* CALLED BY */
/* */
/* Application code */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 06-30-2020 Scott Larson Initial Version 6.0.1 */
/* */
/**************************************************************************/
UINT _txm_module_manager_object_allocate(VOID **object_ptr_ptr, ULONG object_size, TXM_MODULE_INSTANCE *module_instance)
{
TXM_MODULE_ALLOCATED_OBJECT *object_ptr;
UINT return_value;
/* Ensure the object pointer pointer is valid. */
if (object_ptr_ptr == (VOID **) TX_NULL)
{
/* The object pointer pointer is invalid, return an error. */
return(TXM_MODULE_INVALID_MEMORY);
}
/* Initialize the return pointer to NULL. */
*((VOID **) object_ptr_ptr) = TX_NULL;
/* Get module manager protection mutex. */
_txe_mutex_get(&_txm_module_manager_mutex, TX_WAIT_FOREVER);
/* Determine if an object pool was created. */
if (_txm_module_manager_object_pool_created)
{
TXM_MODULE_ALLOCATED_OBJECT *next_object, *previous_object;
/* Allocate the object requested by the module - adding an extra ULONG in order to
store the module instance pointer. */
return_value = (ULONG) _txe_byte_allocate(&_txm_module_manager_object_pool, (VOID **) &object_ptr,
(ULONG) (object_size + sizeof(TXM_MODULE_ALLOCATED_OBJECT)), TX_NO_WAIT);
/* Determine if the request was successful. */
if (return_value == TX_SUCCESS)
{
/* Yes, now store the module instance in the allocated memory block. */
/* Link the allocated memory to the module instance. */
if (module_instance -> txm_module_instance_object_list_count++ == 0)
{
/* The allocated object list is empty. Add object to empty list. */
module_instance -> txm_module_instance_object_list_head = object_ptr;
object_ptr -> txm_module_allocated_object_next = object_ptr;
object_ptr -> txm_module_allocated_object_previous = object_ptr;
}
else
{
/* This list is not NULL, add to the end of the list. */
next_object = module_instance -> txm_module_instance_object_list_head;
previous_object = next_object -> txm_module_allocated_object_previous;
/* Place the new object in the list. */
next_object -> txm_module_allocated_object_previous = object_ptr;
previous_object -> txm_module_allocated_object_next = object_ptr;
/* Setup this object's allocated links. */
object_ptr -> txm_module_allocated_object_previous = previous_object;
object_ptr -> txm_module_allocated_object_next = next_object;
}
/* Setup the module instance pointer in the allocated object. */
object_ptr -> txm_module_allocated_object_module_instance = module_instance;
/* Set the object size. */
object_ptr -> txm_module_object_size = object_size;
/* Move the object pointer forward. This is what the module is given. */
object_ptr++;
/* Return this pointer to the application. */
*((VOID **) object_ptr_ptr) = object_ptr;
}
}
else
{
/* Set return value to not enabled. */
return_value = TX_NOT_AVAILABLE;
}
/* Release the protection mutex. */
_txe_mutex_put(&_txm_module_manager_mutex);
return(return_value);
}
@@ -0,0 +1,138 @@
/**************************************************************************/
/* */
/* Copyright (c) Microsoft Corporation. All rights reserved. */
/* */
/* This software is licensed under the Microsoft Software License */
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
/* and in the root directory of this software. */
/* */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** ThreadX Component */
/** */
/** Module Manager */
/** */
/**************************************************************************/
/**************************************************************************/
#define TX_SOURCE_CODE
#include "tx_api.h"
#include "tx_thread.h"
#include "txm_module.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _txm_module_manager_object_deallocate PORTABLE C */
/* 6.0.1 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function deallocates a previously allocated object. */
/* */
/* INPUT */
/* */
/* object_ptr Object pointer to deallocate */
/* */
/* OUTPUT */
/* */
/* status Completion status */
/* */
/* CALLS */
/* */
/* _txe_mutex_get Get module instance mutex */
/* _txe_mutex_put Release module instance mutex */
/* _txe_byte_release Release object back to pool */
/* */
/* */
/* CALLED BY */
/* */
/* Application code */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 06-30-2020 Scott Larson Initial Version 6.0.1 */
/* */
/**************************************************************************/
UINT _txm_module_manager_object_deallocate(VOID *object_ptr)
{
TXM_MODULE_INSTANCE *module_instance;
TXM_MODULE_ALLOCATED_OBJECT *module_allocated_object_ptr;
UINT return_value;
/* Get module manager protection mutex. */
_txe_mutex_get(&_txm_module_manager_mutex, TX_WAIT_FOREVER);
/* Determine if an object pool was created. */
if (_txm_module_manager_object_pool_created)
{
TXM_MODULE_ALLOCATED_OBJECT *next_object, *previous_object;
/* Pickup module instance pointer. */
module_instance = _tx_thread_current_ptr -> tx_thread_module_instance_ptr;
/* Setup the memory pointer. */
module_allocated_object_ptr = (TXM_MODULE_ALLOCATED_OBJECT *) object_ptr;
/* Position the object pointer backwards to position back to the module manager information. */
previous_object = module_allocated_object_ptr--;
/* Make sure the object is valid. */
if ((module_allocated_object_ptr == TX_NULL) || (module_allocated_object_ptr -> txm_module_allocated_object_module_instance != module_instance) || (module_instance -> txm_module_instance_object_list_count == 0))
{
/* Set return value to invalid pointer. */
return_value = TX_PTR_ERROR;
}
else
{
/* Unlink the node. */
if ((--module_instance -> txm_module_instance_object_list_count) == 0)
{
/* Only allocated object, just set the allocated list to NULL. */
module_instance -> txm_module_instance_object_list_head = TX_NULL;
}
else
{
/* Otherwise, not the only allocated object, link-up the neighbors. */
next_object = module_allocated_object_ptr -> txm_module_allocated_object_next;
previous_object = module_allocated_object_ptr -> txm_module_allocated_object_previous;
next_object -> txm_module_allocated_object_previous = previous_object;
previous_object -> txm_module_allocated_object_next = next_object;
/* See if we have to update the allocated object list head pointer. */
if (module_instance -> txm_module_instance_object_list_head == module_allocated_object_ptr)
{
/* Yes, move the head pointer to the next link. */
module_instance -> txm_module_instance_object_list_head = next_object;
}
}
/* Release the object memory. */
return_value = (ULONG) _txe_byte_release((VOID *) module_allocated_object_ptr);
}
}
else
{
/* Set return value to not enabled. */
return_value = TX_NOT_AVAILABLE;
}
/* Release the protection mutex. */
_txe_mutex_put(&_txm_module_manager_mutex);
return(return_value);
}
@@ -0,0 +1,91 @@
/**************************************************************************/
/* */
/* Copyright (c) Microsoft Corporation. All rights reserved. */
/* */
/* This software is licensed under the Microsoft Software License */
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
/* and in the root directory of this software. */
/* */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** ThreadX Component */
/** */
/** Module Manager */
/** */
/**************************************************************************/
/**************************************************************************/
#define TX_SOURCE_CODE
#include "txm_module.h"
#include "txm_module_manager_util.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _txm_module_manager_object_pointer_get PORTABLE C */
/* 6.0.1 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function is deprecated and calls the secure version of this */
/* function (_txm_module_manager_object_pointer_get_extended) with the */
/* maximum possible name length since none was passed. */
/* */
/* INPUT */
/* */
/* object_type Type of object, as follows: */
/* */
/* TXM_BLOCK_POOL_OBJECT */
/* TXM_BYTE_POOL_OBJECT */
/* TXM_EVENT_FLAGS_OBJECT */
/* TXM_MUTEX_OBJECT */
/* TXM_QUEUE_OBJECT */
/* TXM_SEMAPHORE_OBJECT */
/* TXM_THREAD_OBJECT */
/* TXM_TIMER_OBJECT */
/* name Name to search for */
/* object_ptr Pointer to the object */
/* */
/* OUTPUT */
/* */
/* TX_SUCCESS Successful completion */
/* TX_PTR_ERROR Invalid name or object ptr */
/* TX_OPTION_ERROR Invalid option type */
/* TX_NO_INSTANCE Object not found */
/* */
/* CALLS */
/* */
/* _txm_module_manager_object_pointer_get_extended */
/* Secure version of this function */
/* */
/* CALLED BY */
/* */
/* Application code */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 06-30-2020 Scott Larson Initial Version 6.0.1 */
/* */
/**************************************************************************/
UINT _txm_module_manager_object_pointer_get(UINT object_type, CHAR *name, VOID **object_ptr)
{
UINT status;
/* Call the secure version of this function with the maximum length
possible since none was passed. */
status = _txm_module_manager_object_pointer_get_extended(object_type, name, TXM_MODULE_MANAGER_UTIL_MAX_VALUE_OF_TYPE_UNSIGNED(UINT), object_ptr);
return(status);
}
@@ -0,0 +1,82 @@
/**************************************************************************/
/* */
/* Copyright (c) Microsoft Corporation. All rights reserved. */
/* */
/* This software is licensed under the Microsoft Software License */
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
/* and in the root directory of this software. */
/* */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** ThreadX Component */
/** */
/** Module Manager */
/** */
/**************************************************************************/
/**************************************************************************/
#define TX_SOURCE_CODE
#include "tx_api.h"
#include "txm_module.h"
#include "tx_byte_pool.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* txm_module_manager_object_pool_create PORTABLE C */
/* 6.0.1 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function creates an object pool for the module manager, */
/* which is used by modules to allocate system resources outside */
/* the memory area of the module. This is especially useful in */
/* memory protection. */
/* */
/* INPUT */
/* */
/* object_memory Object memory address */
/* object_memory_size Size in bytes of memory area */
/* */
/* OUTPUT */
/* */
/* status Completion status */
/* */
/* CALLS */
/* */
/* _tx_byte_pool_create Create module memory byte pool */
/* */
/* CALLED BY */
/* */
/* Application code */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 06-30-2020 Scott Larson Initial Version 6.0.1 */
/* */
/**************************************************************************/
UINT _txm_module_manager_object_pool_create(VOID *object_memory, ULONG object_memory_size)
{
/* Create a byte pool for allocating RAM areas for modules. */
_tx_byte_pool_create(&_txm_module_manager_object_pool, "Module Manager Object Pool", object_memory, object_memory_size);
/* Indicate the module manager object pool has been created. */
_txm_module_manager_object_pool_created = TX_TRUE;
/* Return success. */
return(TX_SUCCESS);
}
@@ -0,0 +1,106 @@
/**************************************************************************/
/* */
/* Copyright (c) Microsoft Corporation. All rights reserved. */
/* */
/* This software is licensed under the Microsoft Software License */
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
/* and in the root directory of this software. */
/* */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** ThreadX Component */
/** */
/** Module Manager */
/** */
/**************************************************************************/
/**************************************************************************/
#define TX_SOURCE_CODE
#include "txm_module.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _txm_module_manager_properties_get PORTABLE C */
/* 6.0.1 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function returns the properties of the specified module so they*/
/* may be checked before executing the module. */
/* */
/* INPUT */
/* */
/* module_instance Module instance pointer */
/* */
/* OUTPUT */
/* */
/* status Completion status */
/* */
/* CALLS */
/* */
/* None */
/* */
/* CALLED BY */
/* */
/* Application code */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 06-30-2020 Scott Larson Initial Version 6.0.1 */
/* */
/**************************************************************************/
UINT _txm_module_manager_properties_get(TXM_MODULE_INSTANCE *module_instance, ULONG *module_properties_ptr)
{
/* Determine if the module manager has not been initialized yet. */
if (_txm_module_manager_ready != TX_TRUE)
{
/* Module manager has not been initialized. */
return(TX_NOT_AVAILABLE);
}
/* Determine if the module is valid. */
if (module_instance == TX_NULL)
{
/* Invalid module pointer. */
return(TX_PTR_ERROR);
}
/* Check the module ID. */
if (module_instance -> txm_module_instance_id != TXM_MODULE_ID)
{
/* Invalid module pointer. */
return(TX_PTR_ERROR);
}
/* Check for non-null buffer. */
if (module_properties_ptr == TX_NULL)
{
/* Invalid buffer pointer. */
return(TX_PTR_ERROR);
}
/* Simply return the property bitmap. */
*module_properties_ptr = module_instance -> txm_module_instance_property_flags;
/* Return success. */
return(TX_SUCCESS);
}
@@ -0,0 +1,132 @@
/**************************************************************************/
/* */
/* Copyright (c) Microsoft Corporation. All rights reserved. */
/* */
/* This software is licensed under the Microsoft Software License */
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
/* and in the root directory of this software. */
/* */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** ThreadX Component */
/** */
/** Module Manager */
/** */
/**************************************************************************/
/**************************************************************************/
#define TX_SOURCE_CODE
#include "tx_api.h"
#include "tx_queue.h"
#include "tx_thread.h"
#include "txm_module.h"
#ifndef TX_DISABLE_NOTIFY_CALLBACKS
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _txm_module_manager_queue_notify_trampoline PORTABLE C */
/* 6.0.1 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function processes the queue notification call from ThreadX. */
/* */
/* INPUT */
/* */
/* queue_ptr Queue pointer */
/* */
/* OUTPUT */
/* */
/* None */
/* */
/* CALLS */
/* */
/* _txm_module_manager_callback_request Send module callback request */
/* */
/* CALLED BY */
/* */
/* ThreadX */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 06-30-2020 Scott Larson Initial Version 6.0.1 */
/* */
/**************************************************************************/
VOID _txm_module_manager_queue_notify_trampoline(TX_QUEUE *queue_ptr)
{
TX_INTERRUPT_SAVE_AREA
TXM_MODULE_INSTANCE *module_instance;
TXM_MODULE_CALLBACK_MESSAGE callback_message;
TX_QUEUE *module_callback_queue;
/* We now know the callback is for a module. */
/* Disable interrupts. */
TX_DISABLE
/* Pickup the module instance pointer. */
module_instance = (TXM_MODULE_INSTANCE *) queue_ptr -> tx_queue_module_instance;
/* Determine if this module is still valid. */
if ((module_instance) && (module_instance -> txm_module_instance_id == TXM_MODULE_ID) &&
(module_instance -> txm_module_instance_state == TXM_MODULE_STARTED))
{
/* Yes, the module is still valid. */
/* Pickup the module's callback message queue. */
module_callback_queue = &(module_instance -> txm_module_instance_callback_request_queue);
/* Build the queue notification message. */
callback_message.txm_module_callback_message_type = TXM_QUEUE_SEND_CALLBACK;
callback_message.txm_module_callback_message_activation_count = 1;
callback_message.txm_module_callback_message_application_function = (VOID (*)(VOID)) queue_ptr -> tx_queue_send_module_notify;
callback_message.txm_module_callback_message_param_1 = (ALIGN_TYPE) queue_ptr;
callback_message.txm_module_callback_message_param_2 = 0;
callback_message.txm_module_callback_message_param_3 = 0;
callback_message.txm_module_callback_message_param_4 = 0;
callback_message.txm_module_callback_message_param_5 = 0;
callback_message.txm_module_callback_message_param_6 = 0;
callback_message.txm_module_callback_message_param_7 = 0;
callback_message.txm_module_callback_message_param_8 = 0;
callback_message.txm_module_callback_message_reserved1 = 0;
callback_message.txm_module_callback_message_reserved2 = 0;
/* Restore interrupts. */
TX_RESTORE
/* Call the general processing that will place the callback on the
module's callback request queue. */
_txm_module_manager_callback_request(module_callback_queue, &callback_message);
}
else
{
/* Module no longer valid. */
/* Error, increment the error counter and return. */
_txm_module_manager_callback_error_count++;
/* Restore interrupts. */
TX_RESTORE
}
}
#endif
@@ -0,0 +1,131 @@
/**************************************************************************/
/* */
/* Copyright (c) Microsoft Corporation. All rights reserved. */
/* */
/* This software is licensed under the Microsoft Software License */
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
/* and in the root directory of this software. */
/* */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** ThreadX Component */
/** */
/** Module Manager */
/** */
/**************************************************************************/
/**************************************************************************/
#define TX_SOURCE_CODE
#include "tx_api.h"
#include "tx_queue.h"
#include "tx_thread.h"
#include "txm_module.h"
#ifndef TX_DISABLE_NOTIFY_CALLBACKS
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _txm_module_manager_semaphore_notify_trampoline PORTABLE C */
/* 6.0.1 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function processes the semaphore put notification call from */
/* ThreadX. */
/* */
/* INPUT */
/* */
/* semaphore_ptr Semaphore pointer */
/* */
/* OUTPUT */
/* */
/* None */
/* */
/* CALLS */
/* */
/* _txm_module_manager_callback_request Send module callback request */
/* */
/* CALLED BY */
/* */
/* ThreadX */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 06-30-2020 Scott Larson Initial Version 6.0.1 */
/* */
/**************************************************************************/
VOID _txm_module_manager_semaphore_notify_trampoline(TX_SEMAPHORE *semaphore_ptr)
{
TX_INTERRUPT_SAVE_AREA
TXM_MODULE_INSTANCE *module_instance;
TXM_MODULE_CALLBACK_MESSAGE callback_message;
TX_QUEUE *module_callback_queue;
/* We now know the callback is for a module. */
/* Disable interrupts. */
TX_DISABLE
/* Pickup the module instance pointer. */
module_instance = (TXM_MODULE_INSTANCE *) semaphore_ptr -> tx_semaphore_module_instance;
/* Determine if this module is still valid. */
if ((module_instance) && (module_instance -> txm_module_instance_id == TXM_MODULE_ID) &&
(module_instance -> txm_module_instance_state == TXM_MODULE_STARTED))
{
/* Yes, the module is still valid. */
/* Pickup the module's callback message queue. */
module_callback_queue = &(module_instance -> txm_module_instance_callback_request_queue);
/* Build the queue notification message. */
callback_message.txm_module_callback_message_type = TXM_SEMAPHORE_PUT_CALLBACK;
callback_message.txm_module_callback_message_activation_count = 1;
callback_message.txm_module_callback_message_application_function = (VOID (*)(VOID)) semaphore_ptr -> tx_semaphore_put_module_notify;
callback_message.txm_module_callback_message_param_1 = (ALIGN_TYPE) semaphore_ptr;
callback_message.txm_module_callback_message_param_2 = 0;
callback_message.txm_module_callback_message_param_3 = 0;
callback_message.txm_module_callback_message_param_4 = 0;
callback_message.txm_module_callback_message_param_5 = 0;
callback_message.txm_module_callback_message_param_6 = 0;
callback_message.txm_module_callback_message_param_7 = 0;
callback_message.txm_module_callback_message_param_8 = 0;
callback_message.txm_module_callback_message_reserved1 = 0;
callback_message.txm_module_callback_message_reserved2 = 0;
/* Restore interrupts. */
TX_RESTORE
/* Call the general processing that will place the callback on the
module's callback request queue. */
_txm_module_manager_callback_request(module_callback_queue, &callback_message);
}
else
{
/* Module no longer valid. */
/* Error, increment the error counter and return. */
_txm_module_manager_callback_error_count++;
/* Restore interrupts. */
TX_RESTORE
}
}
#endif
@@ -0,0 +1,226 @@
/**************************************************************************/
/* */
/* Copyright (c) Microsoft Corporation. All rights reserved. */
/* */
/* This software is licensed under the Microsoft Software License */
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
/* and in the root directory of this software. */
/* */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** ThreadX Component */
/** */
/** Module Manager */
/** */
/**************************************************************************/
/**************************************************************************/
#define TX_SOURCE_CODE
#include "tx_api.h"
#include "tx_mutex.h"
#include "tx_queue.h"
#include "tx_thread.h"
#include "txm_module.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _txm_module_manager_start PORTABLE C */
/* 6.0.1 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function starts execution of the specified module. */
/* */
/* INPUT */
/* */
/* module_instance Module instance pointer */
/* */
/* OUTPUT */
/* */
/* status Completion status */
/* */
/* CALLS */
/* */
/* _txm_module_manager_name_build Build module:thread name */
/* _txm_module_manager_thread_create Module thread create */
/* _tx_mutex_get Get protection mutex */
/* _tx_mutex_put Release protection mutex */
/* _tx_queue_create Create module callback queue */
/* _tx_queue_delete Delete module callback queue */
/* _tx_thread_resume Resume start thread */
/* */
/* CALLED BY */
/* */
/* Application code */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 06-30-2020 Scott Larson Initial Version 6.0.1 */
/* */
/**************************************************************************/
UINT _txm_module_manager_start(TXM_MODULE_INSTANCE *module_instance)
{
UINT status;
/* Determine if the module manager has not been initialized yet. */
if (_txm_module_manager_ready != TX_TRUE)
{
/* Module manager has not been initialized. */
return(TX_NOT_AVAILABLE);
}
/* Determine if the module is valid. */
if (module_instance == TX_NULL)
{
/* Invalid module pointer. */
return(TX_PTR_ERROR);
}
/* Get module manager protection mutex. */
_tx_mutex_get(&_txm_module_manager_mutex, TX_WAIT_FOREVER);
/* Determine if the module instance is valid. */
if (module_instance -> txm_module_instance_id != TXM_MODULE_ID)
{
/* Release the protection mutex. */
_tx_mutex_put(&_txm_module_manager_mutex);
/* Invalid module pointer. */
return(TX_PTR_ERROR);
}
/* Determine if the module instance is in the loaded state. */
if ((module_instance -> txm_module_instance_state != TXM_MODULE_LOADED) && (module_instance -> txm_module_instance_state != TXM_MODULE_STOPPED))
{
/* Release the protection mutex. */
_tx_mutex_put(&_txm_module_manager_mutex);
/* Return error if the module is not ready. */
return(TX_START_ERROR);
}
/* Check the priorities of the start/stop and callback request threads. */
if (module_instance -> txm_module_instance_start_stop_priority < module_instance -> txm_module_instance_maximum_priority ||
module_instance -> txm_module_instance_callback_priority < module_instance -> txm_module_instance_maximum_priority)
{
/* Release the protection mutex. */
_tx_mutex_put(&_txm_module_manager_mutex);
/* At least one thread has an invalid priority. */
return(TX_PRIORITY_ERROR);
}
/* Create the module's callback request queue. */
status = _tx_queue_create(&(module_instance -> txm_module_instance_callback_request_queue), "Module Callback Request Queue", (sizeof(TXM_MODULE_CALLBACK_MESSAGE)/sizeof(ULONG)),
module_instance -> txm_module_instance_callback_request_queue_area, sizeof(module_instance -> txm_module_instance_callback_request_queue_area));
/* Determine if there was an error. */
if (status)
{
/* Release the protection mutex. */
_tx_mutex_put(&_txm_module_manager_mutex);
/* Return error if the module is not ready. */
return(TX_START_ERROR);
}
/* Create the module start thread. */
status = _txm_module_manager_thread_create(&(module_instance -> txm_module_instance_start_stop_thread),
"Module Start Thread",
module_instance -> txm_module_instance_shell_entry_function,
module_instance -> txm_module_instance_start_thread_entry,
module_instance -> txm_module_instance_application_module_id,
module_instance -> txm_module_instance_start_stop_stack_start_address,
module_instance -> txm_module_instance_start_stop_stack_size,
(UINT) module_instance -> txm_module_instance_start_stop_priority,
(UINT) module_instance -> txm_module_instance_start_stop_priority,
TXM_MODULE_TIME_SLICE,
TX_DONT_START,
sizeof(TX_THREAD),
module_instance);
/* Determine if the thread create was successful. */
if (status != TX_SUCCESS)
{
/* Delete the callback notification queue. */
_tx_queue_delete(&(module_instance -> txm_module_instance_callback_request_queue));
/* Release the protection mutex. */
_tx_mutex_put(&_txm_module_manager_mutex);
/* Return the error status. */
return(status);
}
/* Create the module callback thread. */
status = _txm_module_manager_thread_create(&(module_instance -> txm_module_instance_callback_request_thread),
"Module Callback Request Thread",
module_instance -> txm_module_instance_shell_entry_function,
module_instance -> txm_module_instance_callback_request_thread_entry,
module_instance -> txm_module_instance_application_module_id,
module_instance -> txm_module_instance_callback_stack_start_address,
module_instance -> txm_module_instance_callback_stack_size,
(UINT) module_instance -> txm_module_instance_callback_priority,
(UINT) module_instance -> txm_module_instance_callback_priority,
TX_NO_TIME_SLICE,
TX_DONT_START,
sizeof(TX_THREAD),
module_instance);
/* Determine if the thread create was successful. */
if (status != TX_SUCCESS)
{
/* Terminate the start thread. */
_tx_thread_terminate(&(module_instance -> txm_module_instance_start_stop_thread));
/* Delete the start thread. */
_tx_thread_delete(&(module_instance -> txm_module_instance_start_stop_thread));
/* Delete the callback notification queue. */
_tx_queue_delete(&(module_instance -> txm_module_instance_callback_request_queue));
/* Release the protection mutex. */
_tx_mutex_put(&_txm_module_manager_mutex);
/* Return the error status. */
return(status);
}
/* Set the module state to started. */
module_instance -> txm_module_instance_state = TXM_MODULE_STARTED;
/* Release the protection mutex. */
_tx_mutex_put(&_txm_module_manager_mutex);
/* Resume the module's start thread. */
_tx_thread_resume(&(module_instance -> txm_module_instance_start_stop_thread));
/* Return success. */
return(TX_SUCCESS);
}
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,153 @@
/**************************************************************************/
/* */
/* Copyright (c) Microsoft Corporation. All rights reserved. */
/* */
/* This software is licensed under the Microsoft Software License */
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
/* and in the root directory of this software. */
/* */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** ThreadX Component */
/** */
/** Module Manager */
/** */
/**************************************************************************/
/**************************************************************************/
#define TX_SOURCE_CODE
#include "tx_api.h"
#include "tx_queue.h"
#include "tx_thread.h"
#include "txm_module.h"
#ifndef TX_DISABLE_NOTIFY_CALLBACKS
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _txm_module_manager_thread_notify_trampoline PORTABLE C */
/* 6.0.1 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function processes the thread entry/exit notification call */
/* from ThreadX. */
/* */
/* INPUT */
/* */
/* thread_ptr Thread pointer */
/* type Entry or exit type */
/* */
/* OUTPUT */
/* */
/* None */
/* */
/* CALLS */
/* */
/* _txm_module_manager_callback_request Send module callback request */
/* */
/* CALLED BY */
/* */
/* ThreadX */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 06-30-2020 Scott Larson Initial Version 6.0.1 */
/* */
/**************************************************************************/
VOID _txm_module_manager_thread_notify_trampoline(TX_THREAD *thread_ptr, UINT type)
{
TX_INTERRUPT_SAVE_AREA
TXM_MODULE_INSTANCE *module_instance;
TXM_MODULE_CALLBACK_MESSAGE callback_message;
TX_QUEUE *module_callback_queue;
TXM_MODULE_THREAD_ENTRY_INFO *thread_info;
/* We now know the callback is for a module. */
/* Disable interrupts. */
TX_DISABLE
/* Determine if the thread is valid. */
if ((thread_ptr) && (thread_ptr -> tx_thread_id == TX_THREAD_ID))
{
/* Pickup the module instance pointer. */
module_instance = (TXM_MODULE_INSTANCE *) thread_ptr -> tx_thread_module_instance_ptr;
/* Pickup the module's thread pointer. */
thread_info = (TXM_MODULE_THREAD_ENTRY_INFO *) thread_ptr -> tx_thread_module_entry_info_ptr;
/* Determine if this module is still valid. */
if ((module_instance) && (module_instance -> txm_module_instance_id == TXM_MODULE_ID) &&
(module_instance -> txm_module_instance_state == TXM_MODULE_STARTED))
{
/* Yes, the module is still valid. */
/* Pickup the module's callback message queue. */
module_callback_queue = &(module_instance -> txm_module_instance_callback_request_queue);
/* Build the queue notification message. */
callback_message.txm_module_callback_message_type = TXM_THREAD_ENTRY_EXIT_CALLBACK;
callback_message.txm_module_callback_message_activation_count = 1;
callback_message.txm_module_callback_message_application_function = (VOID (*)(VOID)) thread_info -> txm_module_thread_entry_info_exit_notify;
callback_message.txm_module_callback_message_param_1 = (ALIGN_TYPE) thread_ptr;
callback_message.txm_module_callback_message_param_2 = (ALIGN_TYPE) type;
callback_message.txm_module_callback_message_param_3 = 0;
callback_message.txm_module_callback_message_param_4 = 0;
callback_message.txm_module_callback_message_param_5 = 0;
callback_message.txm_module_callback_message_param_6 = 0;
callback_message.txm_module_callback_message_param_7 = 0;
callback_message.txm_module_callback_message_param_8 = 0;
callback_message.txm_module_callback_message_reserved1 = 0;
callback_message.txm_module_callback_message_reserved2 = 0;
/* Restore interrupts. */
TX_RESTORE
/* Call the general processing that will place the callback on the
module's callback request queue. */
_txm_module_manager_callback_request(module_callback_queue, &callback_message);
}
else
{
/* Module no longer valid. */
/* Error, increment the error counter and return. */
_txm_module_manager_callback_error_count++;
/* Restore interrupts. */
TX_RESTORE
}
}
else
{
/* Thread pointer is not valid. */
/* Error, increment the error counter and return. */
_txm_module_manager_callback_error_count++;
/* Restore interrupts. */
TX_RESTORE
}
}
#endif
@@ -0,0 +1,180 @@
/**************************************************************************/
/* */
/* Copyright (c) Microsoft Corporation. All rights reserved. */
/* */
/* This software is licensed under the Microsoft Software License */
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
/* and in the root directory of this software. */
/* */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** ThreadX Component */
/** */
/** Module Manager */
/** */
/**************************************************************************/
/**************************************************************************/
#define TX_SOURCE_CODE
#include "tx_api.h"
#include "tx_trace.h"
#include "tx_thread.h"
#include "txm_module.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _txm_module_manager_thread_reset PORTABLE C */
/* 6.0.1 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function prepares the thread to run again from the entry */
/* point specified during thread creation. The application must */
/* call tx_thread_resume after this call completes for the thread */
/* to actually run. */
/* */
/* INPUT */
/* */
/* thread_ptr Pointer to thread to reset */
/* */
/* OUTPUT */
/* */
/* status Service return status */
/* */
/* CALLS */
/* */
/* _txm_module_manager_thread_stack_build Build initial thread */
/* stack */
/* */
/* CALLED BY */
/* */
/* _txm_module_manager_kernel_dispatch Kernel dispatch function */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 06-30-2020 Scott Larson Initial Version 6.0.1 */
/* */
/**************************************************************************/
UINT _txm_module_manager_thread_reset(TX_THREAD *thread_ptr)
{
TX_INTERRUPT_SAVE_AREA
TX_THREAD *current_thread;
UINT status;
TXM_MODULE_INSTANCE *module_instance;
TXM_MODULE_THREAD_ENTRY_INFO *thread_entry_info;
/* Default a successful completion status. */
status = TX_SUCCESS;
/* Disable interrupts. */
TX_DISABLE
/* Pickup thread pointer. */
TX_THREAD_GET_CURRENT(current_thread)
/* Check for a call from the current thread, which is not allowed! */
if (current_thread == thread_ptr)
{
/* Restore interrupts. */
TX_RESTORE
/* Thread not completed or terminated - return an error! */
status = TX_NOT_DONE;
}
else
{
/* Check for proper status of this thread to reset. */
if (thread_ptr -> tx_thread_state != TX_COMPLETED)
{
/* Now check for terminated state. */
if (thread_ptr -> tx_thread_state != TX_TERMINATED)
{
/* Thread not completed or terminated - return an error! */
status = TX_NOT_DONE;
}
}
}
/* Is the request valid? */
if (status == TX_SUCCESS)
{
/* Modify the thread status to prevent additional reset calls. */
thread_ptr -> tx_thread_state = TX_NOT_DONE;
/* Get the module instance. */
module_instance = thread_ptr -> tx_thread_module_instance_ptr;
/* Execute Port-Specific completion processing. If needed, it is typically defined in txm_module_port.h. */
TXM_MODULE_MANAGER_THREAD_RESET_PORT_COMPLETION(thread_ptr, module_instance)
/* Restore interrupts. */
TX_RESTORE
#ifndef TX_DISABLE_STACK_FILLING
/* Set the thread stack to a pattern prior to creating the initial
stack frame. This pattern is used by the stack checking routines
to see how much has been used. */
TX_MEMSET(thread_ptr -> tx_thread_stack_start, ((UCHAR) TX_STACK_FILL), thread_ptr -> tx_thread_stack_size);
#endif
/* Setup pointer to the thread entry information structure, which will live at the top of each
module thread's stack. This will allow the module thread entry function to avoid direct
access to the actual thread control block. */
thread_entry_info = (TXM_MODULE_THREAD_ENTRY_INFO *) (((UCHAR *) thread_ptr -> tx_thread_stack_end) + (2*sizeof(ULONG)) + 1);
thread_entry_info = (TXM_MODULE_THREAD_ENTRY_INFO *) (((ALIGN_TYPE)(thread_entry_info)) & (~0x3));
/* Place the thread entry information pointer in the thread control block so it can be picked up
in the following stack build function. This is supplied to the module's shell entry function
to avoid direct access to the actual thread control block. Note that this is overwritten
with the actual stack pointer at the end of stack build. */
thread_ptr -> tx_thread_stack_ptr = (VOID *) thread_entry_info;
/* Call the target specific stack frame building routine to build the
thread's initial stack and to setup the actual stack pointer in the
control block. */
_txm_module_manager_thread_stack_build(thread_ptr, module_instance -> txm_module_instance_shell_entry_function);
/* Disable interrupts. */
TX_DISABLE
/* Finally, move into a suspended state to allow for the thread to be resumed. */
thread_ptr -> tx_thread_state = TX_SUSPENDED;
/* If trace is enabled, insert this event into the trace buffer. */
TX_TRACE_IN_LINE_INSERT(TX_TRACE_THREAD_RESET, thread_ptr, thread_ptr -> tx_thread_state, 0, 0, TX_TRACE_THREAD_EVENTS)
/* Log this kernel call. */
TX_EL_THREAD_RESET_INSERT
/* Log the thread status change. */
TX_EL_THREAD_STATUS_CHANGE_INSERT(thread_ptr, TX_SUSPENDED)
}
/* Restore interrupts. */
TX_RESTORE
/* Return completion status to caller. */
return(status);
}
@@ -0,0 +1,141 @@
/**************************************************************************/
/* */
/* Copyright (c) Microsoft Corporation. All rights reserved. */
/* */
/* This software is licensed under the Microsoft Software License */
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
/* and in the root directory of this software. */
/* */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** ThreadX Component */
/** */
/** Module Manager */
/** */
/**************************************************************************/
/**************************************************************************/
#define TX_SOURCE_CODE
#include "tx_api.h"
#include "tx_thread.h"
#include "tx_timer.h"
#include "txm_module.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _txm_module_manager_timer_notify_trampoline PORTABLE C */
/* 6.0.1 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function processes the timer expirations from ThreadX. */
/* */
/* INPUT */
/* */
/* id Timer ID */
/* */
/* OUTPUT */
/* */
/* None */
/* */
/* CALLS */
/* */
/* _txm_module_manager_callback_request Send module callback request */
/* */
/* CALLED BY */
/* */
/* ThreadX */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 06-30-2020 Scott Larson Initial Version 6.0.1 */
/* */
/**************************************************************************/
VOID _txm_module_manager_timer_notify_trampoline(ULONG id)
{
TX_INTERRUPT_SAVE_AREA
TXM_MODULE_INSTANCE *module_instance;
TXM_MODULE_CALLBACK_MESSAGE callback_message;
TX_QUEUE *module_callback_queue;
TX_TIMER *timer_ptr;
CHAR *internal_ptr;
/* We now know the callback is for a module. */
/* Disable interrupts. */
TX_DISABLE
/* Our expired timer pointer points to the internal timer,
* we need to get to the full timer pointer. */
/* Pickup the current internal timer pointer. */
internal_ptr = (CHAR *) _tx_timer_expired_timer_ptr;
/* Get the timer pointer from the internal pointer. */
TX_USER_TIMER_POINTER_GET((TX_TIMER_INTERNAL *) internal_ptr, timer_ptr);
/* Pickup the module instance pointer. */
module_instance = (TXM_MODULE_INSTANCE *) timer_ptr -> tx_timer_module_instance;
/* Determine if this module is still valid. */
if ((module_instance) && (module_instance -> txm_module_instance_id == TXM_MODULE_ID) &&
(module_instance -> txm_module_instance_state == TXM_MODULE_STARTED))
{
/* Yes, the module is still valid. */
/* Pickup the module's callback message queue. */
module_callback_queue = &(module_instance -> txm_module_instance_callback_request_queue);
/* Build the queue notification message. */
callback_message.txm_module_callback_message_type = TXM_TIMER_CALLBACK;
callback_message.txm_module_callback_message_activation_count = 1;
callback_message.txm_module_callback_message_application_function = (VOID (*)(VOID)) timer_ptr -> tx_timer_module_expiration_function;
callback_message.txm_module_callback_message_param_1 = (ULONG) id;
callback_message.txm_module_callback_message_param_2 = 0;
callback_message.txm_module_callback_message_param_3 = 0;
callback_message.txm_module_callback_message_param_4 = 0;
callback_message.txm_module_callback_message_param_5 = 0;
callback_message.txm_module_callback_message_param_6 = 0;
callback_message.txm_module_callback_message_param_7 = 0;
callback_message.txm_module_callback_message_param_8 = 0;
callback_message.txm_module_callback_message_reserved1 = 0;
callback_message.txm_module_callback_message_reserved2 = 0;
/* Restore interrupts. */
TX_RESTORE
/* Call the general processing that will place the callback on the
module's callback request queue. */
_txm_module_manager_callback_request(module_callback_queue, &callback_message);
}
else
{
/* Module no longer valid. */
/* Error, increment the error counter and return. */
_txm_module_manager_callback_error_count++;
/* Restore interrupts. */
TX_RESTORE
}
}
@@ -0,0 +1,197 @@
/**************************************************************************/
/* */
/* Copyright (c) Microsoft Corporation. All rights reserved. */
/* */
/* This software is licensed under the Microsoft Software License */
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
/* and in the root directory of this software. */
/* */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** ThreadX Component */
/** */
/** Module Manager */
/** */
/**************************************************************************/
/**************************************************************************/
#define TX_SOURCE_CODE
#include "tx_api.h"
#include "tx_byte_pool.h"
#include "tx_initialize.h"
#include "tx_mutex.h"
#include "tx_thread.h"
#include "txm_module.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _txm_module_manager_unload PORTABLE C */
/* 6.0.1 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function unloads a previously loaded module. */
/* */
/* INPUT */
/* */
/* module_instance Module instance pointer */
/* */
/* OUTPUT */
/* */
/* status Completion status */
/* */
/* CALLS */
/* */
/* _tx_byte_release Release data area */
/* _tx_mutex_get Get protection mutex */
/* _tx_mutex_put Release protection mutex */
/* */
/* CALLED BY */
/* */
/* Application code */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 06-30-2020 Scott Larson Initial Version 6.0.1 */
/* */
/**************************************************************************/
UINT _txm_module_manager_unload(TXM_MODULE_INSTANCE *module_instance)
{
TX_INTERRUPT_SAVE_AREA
TXM_MODULE_INSTANCE *next_module, *previous_module;
CHAR *memory_ptr;
/* Check for interrupt call. */
if (TX_THREAD_GET_SYSTEM_STATE() != 0)
{
/* Now, make sure the call is from an interrupt and not initialization. */
if (TX_THREAD_GET_SYSTEM_STATE() < TX_INITIALIZE_IN_PROGRESS)
{
/* Invalid caller of this function, return appropriate error code. */
return(TX_CALLER_ERROR);
}
}
/* Determine if the module manager has not been initialized yet. */
if (_txm_module_manager_ready != TX_TRUE)
{
/* Module manager has not been initialized. */
return(TX_NOT_AVAILABLE);
}
/* Determine if the module is valid. */
if (module_instance == TX_NULL)
{
/* Invalid module pointer. */
return(TX_PTR_ERROR);
}
/* Get module manager protection mutex. */
_tx_mutex_get(&_txm_module_manager_mutex, TX_WAIT_FOREVER);
/* Determine if the module is already valid. */
if (module_instance -> txm_module_instance_id != TXM_MODULE_ID)
{
/* Release the protection mutex. */
_tx_mutex_put(&_txm_module_manager_mutex);
/* Invalid module pointer. */
return(TX_PTR_ERROR);
}
/* Determine if the module instance is in the state. */
if ((module_instance -> txm_module_instance_state != TXM_MODULE_LOADED) && (module_instance -> txm_module_instance_state != TXM_MODULE_STOPPED))
{
/* Release the protection mutex. */
_tx_mutex_put(&_txm_module_manager_mutex);
/* Return error if the module is not ready. */
return(TX_NOT_DONE);
}
/* Pickup the module data memory allocation address. */
memory_ptr = module_instance -> txm_module_instance_data_allocation_ptr;
/* Release the module's data memory. */
_tx_byte_release(memory_ptr);
/* Determine if there was memory allocated for the code. */
if (module_instance -> txm_module_instance_code_allocation_ptr)
{
/* Yes, release the module's code memory. */
memory_ptr = module_instance -> txm_module_instance_code_allocation_ptr;
/* Release the module's data memory. */
_tx_byte_release(memory_ptr);
}
/* Temporarily disable interrupts. */
TX_DISABLE
/* Clear some of the module information. */
module_instance -> txm_module_instance_id = 0;
module_instance -> txm_module_instance_state = TXM_MODULE_UNLOADED;
/* Call port-specific unload function. */
TXM_MODULE_MANAGER_MODULE_UNLOAD(module_instance);
/* Remove the module from the linked list of loaded modules. */
/* See if the module is the only one on the list. */
if ((--_txm_module_manger_loaded_count) == 0)
{
/* Only created module, just set the created list to NULL. */
_txm_module_manager_loaded_list_ptr = TX_NULL;
}
else
{
/* Otherwise, not the only created module, link-up the neighbors. */
next_module = module_instance -> txm_module_instance_loaded_next;
previous_module = module_instance -> txm_module_instance_loaded_previous;
next_module -> txm_module_instance_loaded_previous = previous_module;
previous_module -> txm_module_instance_loaded_next = next_module;
/* See if we have to update the created list head pointer. */
if (_txm_module_manager_loaded_list_ptr == module_instance)
{
/* Yes, move the head pointer to the next link. */
_txm_module_manager_loaded_list_ptr = next_module;
}
}
/* Restore interrupts. */
TX_RESTORE
/* Release the protection mutex. */
_tx_mutex_put(&_txm_module_manager_mutex);
/* Return success. */
return(TX_SUCCESS);
}
@@ -0,0 +1,417 @@
/**************************************************************************/
/* */
/* Copyright (c) Microsoft Corporation. All rights reserved. */
/* */
/* This software is licensed under the Microsoft Software License */
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
/* and in the root directory of this software. */
/* */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** ThreadX Component */
/** */
/** Module Manager */
/** */
/**************************************************************************/
/**************************************************************************/
/* Include necessary system files. */
#define TX_SOURCE_CODE
#include "txm_module.h"
#include "txm_module_manager_util.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _txm_module_manager_object_memory_check PORTABLE C */
/* 6.0.1 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function checks if the object is inside a module's object pool */
/* or, if it's a privileged module, inside the module's data area. */
/* */
/* INPUT */
/* */
/* module_instance Module instance that the object */
/* belongs to */
/* object_ptr Pointer to object to check */
/* object_size Size of the object to check */
/* */
/* OUTPUT */
/* */
/* status Whether the object resides in a */
/* valid location */
/* */
/* CALLS */
/* */
/* None */
/* */
/* CALLED BY */
/* */
/* _txm_module_manager_kernel_dispatch Kernel dispatch function */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 06-30-2020 Scott Larson Initial Version 6.0.1 */
/* */
/**************************************************************************/
UINT _txm_module_manager_object_memory_check(TXM_MODULE_INSTANCE *module_instance, ALIGN_TYPE object_ptr, ULONG object_size)
{
/* Is the object pointer from the module manager's object pool? */
if ((_txm_module_manager_object_pool_created == TX_TRUE) &&
(object_ptr >= (ALIGN_TYPE) _txm_module_manager_object_pool.tx_byte_pool_start) &&
((object_ptr+object_size) <= (ALIGN_TYPE) (_txm_module_manager_object_pool.tx_byte_pool_start + _txm_module_manager_object_pool.tx_byte_pool_size)))
{
/* Object is from manager object pool. */
return(TX_SUCCESS);
}
/* If memory protection is not required, check if object is in module data. */
else if (!(module_instance -> txm_module_instance_property_flags & TXM_MODULE_MEMORY_PROTECTION))
{
if ((object_ptr >= (ALIGN_TYPE) module_instance -> txm_module_instance_data_start) &&
((object_ptr+object_size) <= (ALIGN_TYPE) module_instance -> txm_module_instance_data_end))
{
/* Object is from the local module memory. */
return(TX_SUCCESS);
}
}
/* Object is from invalid memory. */
return(TXM_MODULE_INVALID_MEMORY);
}
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _txm_module_manager_created_object_check PORTABLE C */
/* 6.0.1 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This functions checks if the specified object was created by the */
/* specified module */
/* */
/* INPUT */
/* */
/* module_instance The module instance to check */
/* object_ptr The object to check */
/* */
/* OUTPUT */
/* */
/* status Whether the module created the */
/* object */
/* */
/* CALLS */
/* */
/* None */
/* */
/* CALLED BY */
/* */
/* txm_module_manager*_stop Module manager stop functions */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 06-30-2020 Scott Larson Initial Version 6.0.1 */
/* */
/**************************************************************************/
UCHAR _txm_module_manager_created_object_check(TXM_MODULE_INSTANCE *module_instance, VOID *object_ptr)
{
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 current object is from the pool of dynamically allocated objects. */
if ((((UCHAR *) object_ptr) >= _txm_module_manager_object_pool.tx_byte_pool_start) &&
(((UCHAR *) object_ptr) < (_txm_module_manager_object_pool.tx_byte_pool_start + _txm_module_manager_object_pool.tx_byte_pool_size)))
{
/* Pickup object pointer. */
allocated_object_ptr = (TXM_MODULE_ALLOCATED_OBJECT *) object_ptr;
/* Move back to get the header information. */
allocated_object_ptr--;
/* Now determine if this object belongs to this module. */
if (allocated_object_ptr -> txm_module_allocated_object_module_instance == module_instance)
{
return TX_TRUE;
}
}
}
return TX_FALSE;
}
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _txm_module_manager_object_size_check PORTABLE C */
/* 6.0.1 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function checks if the specified object's size matches what is */
/* inside the object pool. */
/* */
/* INPUT */
/* */
/* object_ptr Pointer to object to check */
/* object_size Size of the object to check */
/* */
/* OUTPUT */
/* */
/* status Whether the object's size matches */
/* what's inside the object pool */
/* */
/* CALLS */
/* */
/* None */
/* */
/* CALLED BY */
/* */
/* _txm_module_manager_kernel_dispatch Kernel dispatch function */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 06-30-2020 Scott Larson Initial Version 6.0.1 */
/* */
/**************************************************************************/
UINT _txm_module_manager_object_size_check(ALIGN_TYPE object_ptr, ULONG object_size)
{
TXM_MODULE_ALLOCATED_OBJECT *module_allocated_object_ptr;
UINT return_value;
/* Pickup the allocated object pointer. */
module_allocated_object_ptr = ((TXM_MODULE_ALLOCATED_OBJECT *) object_ptr) - 1;
/* Does the allocated memory match the expected object size? */
if (module_allocated_object_ptr -> txm_module_object_size == object_size)
return_value = TX_SUCCESS;
else
return_value = TXM_MODULE_INVALID_MEMORY;
return(return_value);
}
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _txm_module_manager_name_compare PORTABLE C */
/* 6.0.1 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function compares the specified object names. */
/* */
/* INPUT */
/* */
/* search_name String pointer to the object's */
/* name being searched for */
/* search_name_length Length of search_name */
/* object_name String pointer to an object's name*/
/* to compare the search name to */
/* */
/* OUTPUT */
/* */
/* status Whether the names are equal */
/* */
/* CALLS */
/* */
/* None */
/* */
/* CALLED BY */
/* */
/* *_object_pointer_get Kernel dispatch function */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 06-30-2020 Scott Larson Initial Version 6.0.1 */
/* */
/**************************************************************************/
UINT _txm_module_manager_object_name_compare(CHAR *search_name, UINT search_name_length, CHAR *object_name)
{
CHAR search_name_char;
CHAR object_name_char;
/* Is the object name null? Note that the search name has already been checked
by the caller. */
if (object_name == TX_NULL)
{
/* The strings can't match. */
return(TX_FALSE);
}
/* Loop through the names. */
while (1)
{
/* Get the current characters from each name. */
search_name_char = *search_name;
object_name_char = *object_name;
/* Check for match. */
if (search_name_char == object_name_char)
{
/* Are they null-terminators? */
if (search_name_char == '\0')
{
/* The strings match. */
return(TX_TRUE);
}
}
else
{
/* The strings don't match. */
return(TX_FALSE);
}
/* Are we at the end of the search name? */
if (search_name_length == 0)
{
/* The strings don't match. */
return(TX_FALSE);
}
/* Move to next character. */
search_name++;
object_name++;
search_name_length--;
}
}
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _txm_module_manager_util_code_allocation_size_and_alignment_get */
/* PORTABLE C */
/* 6.0.1 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function returns the required alignment and allocation size */
/* for a module's code area. */
/* */
/* INPUT */
/* */
/* module_preamble Preamble of module to return code */
/* values for */
/* code_alignment_dest Address to return code alignment */
/* code_allocation_size_desk Address to return code allocation */
/* size */
/* */
/* OUTPUT */
/* */
/* status Success if no math overflow */
/* occurred during calculation */
/* */
/* CALLS */
/* */
/* None */
/* */
/* CALLED BY */
/* */
/* txm_module_manager_*_load Module load functions */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 06-30-2020 Scott Larson Initial Version 6.0.1 */
/* */
/**************************************************************************/
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)
{
ULONG code_size;
ULONG code_alignment;
ULONG data_size_ignored;
ULONG data_alignment_ignored;
/* Pickup the module code size. */
code_size = module_preamble -> txm_module_preamble_code_size;
/* Adjust the size of the module elements to be aligned to the default alignment. */
TXM_MODULE_MANAGER_UTIL_MATH_ADD_ULONG(code_size, TXM_MODULE_CODE_ALIGNMENT, code_size);
code_size = ((code_size - 1)/TXM_MODULE_CODE_ALIGNMENT) * TXM_MODULE_CODE_ALIGNMENT;
/* Setup the default code and data alignments. */
code_alignment = (ULONG) TXM_MODULE_CODE_ALIGNMENT;
/* Get the port-specific alignment for the code size. Note we only want code so we pass 'null' values for data. */
data_size_ignored = 1;
data_alignment_ignored = 1;
TXM_MODULE_MANAGER_ALIGNMENT_ADJUST(module_preamble, code_size, code_alignment, data_size_ignored, data_alignment_ignored)
/* Calculate the code memory allocation size. */
TXM_MODULE_MANAGER_UTIL_MATH_ADD_ULONG(code_size, code_alignment, *code_allocation_size_dest);
/* Write the alignment result into the caller's destination address. */
*code_alignment_dest = code_alignment;
/* Return success. */
return(TX_SUCCESS);
}