From 7101da006c2ecc27c9348863c97fedc06b5095f7 Mon Sep 17 00:00:00 2001 From: Joseph Hickey Date: Wed, 7 Apr 2021 09:37:44 -0400 Subject: [PATCH] Fix #944, add OS_API_Teardown This cleans up all OSAL resources as best as possible, ideally leaving the system in a state where OS_API_Init() may be invoked again. --- src/os/inc/osapi-common.h | 27 +++++++++++++++++++ src/os/shared/src/osapi-common.c | 22 +++++++++++++++ .../shared/src/coveragetest-common.c | 13 +++++++++ 3 files changed, 62 insertions(+) diff --git a/src/os/inc/osapi-common.h b/src/os/inc/osapi-common.h index ac6b1bcdc..d16372e98 100644 --- a/src/os/inc/osapi-common.h +++ b/src/os/inc/osapi-common.h @@ -138,6 +138,33 @@ void OS_Application_Run(void); */ int32 OS_API_Init(void); +/*-------------------------------------------------------------------------------------*/ +/** + * @brief Teardown/de-initialization of OSAL API + * + * This is the inverse of OS_API_Init(). It will release all OS resources and + * return the system to a state similar to what it was prior to invoking + * OS_API_Init() initially. + * + * Normally for embedded applications, the OSAL is initialized after boot and will remain + * initialized in memory until the processor is rebooted. However for testing and + * developement purposes, it is potentially useful to reset back to initial conditions. + * + * For testing purposes, this API is designed/intended to be compatible with the + * UtTest_AddTeardown() routine provided by the UT-Assert subsystem. + * + * @note This is a "best-effort" routine and it may not always be possible/guaranteed + * to recover all resources, particularly in the case of off-nominal conditions, or if + * a resource is used outside of OSAL. + * + * For example, while this will attempt to unload all dynamically-loaded modules, doing + * so may not be possible and/or may induce undefined behavior if resources are in use by + * tasks/functions outside of OSAL. + * + * @return None + */ +void OS_API_Teardown(void); + /*-------------------------------------------------------------------------------------*/ /** * @brief Background thread implementation - waits forever for events to occur. diff --git a/src/os/shared/src/osapi-common.c b/src/os/shared/src/osapi-common.c index 2543d9887..ab3f16309 100644 --- a/src/os/shared/src/osapi-common.c +++ b/src/os/shared/src/osapi-common.c @@ -219,6 +219,28 @@ int32 OS_API_Init(void) return (return_code); } /* end OS_API_Init */ +/*---------------------------------------------------------------- + * + * Function: OS_API_Teardown + * + * Purpose: Implemented per public OSAL API + * See description in API and header file for detail + * + *-----------------------------------------------------------------*/ +void OS_API_Teardown(void) +{ + /* + * This should delete any remaining user-created objects/tasks + */ + OS_DeleteAllObjects(); + + /* + * This should cause the "internal" objects (e.g. console utility task) + * to exit, and will prevent any new objects from being created. + */ + OS_ApplicationShutdown(true); +} + /*---------------------------------------------------------------- * * Function: OS_RegisterEventHandler diff --git a/src/unit-test-coverage/shared/src/coveragetest-common.c b/src/unit-test-coverage/shared/src/coveragetest-common.c index 479105e2d..f4921740b 100644 --- a/src/unit-test-coverage/shared/src/coveragetest-common.c +++ b/src/unit-test-coverage/shared/src/coveragetest-common.c @@ -128,6 +128,18 @@ void Test_OS_API_Init(void) UT_ResetState(UT_KEY(OS_TaskAPI_Init)); } +void Test_OS_API_Teardown(void) +{ + /* + * Test Case For: + * void OS_API_Teardown(void); + */ + + /* Just need to call the API for coverage; there are no conditionals + * and the internal functions are each tested separately */ + OS_API_Teardown(); +} + void Test_OS_ApplicationExit(void) { /* @@ -325,4 +337,5 @@ void UtTest_Setup(void) ADD_TEST(OS_IdleLoopAndShutdown); ADD_TEST(OS_ApplicationExit); ADD_TEST(OS_NotifyEvent); + ADD_TEST(OS_API_Teardown); }