diff --git a/.github/workflows/codeql-build.yml b/.github/workflows/codeql-cfe-build.yml similarity index 61% rename from .github/workflows/codeql-build.yml rename to .github/workflows/codeql-cfe-build.yml index 7d458fbb5..59265d882 100644 --- a/.github/workflows/codeql-build.yml +++ b/.github/workflows/codeql-cfe-build.yml @@ -1,4 +1,4 @@ -name: "CodeQL Analysis" +name: "CodeQL cFE Build Analysis" on: push: @@ -11,8 +11,23 @@ env: BUILDTYPE: release jobs: + #Checks for duplicate actions. Skips push actions if there is a matching or duplicate pull-request action. + check-for-duplicates: + runs-on: ubuntu-latest + # Map a step output to a job output + outputs: + should_skip: ${{ steps.skip_check.outputs.should_skip }} + steps: + - id: skip_check + uses: fkirc/skip-duplicate-actions@master + with: + concurrent_skipping: 'same_content' + skip_after_successful_duplicate: 'true' + do_not_skip: '["pull_request", "workflow_dispatch", "schedule"]' CodeQL-Build: + needs: check-for-duplicates + if: ${{ needs.check-for-duplicates.outputs.should_skip != 'true' }} runs-on: ubuntu-18.04 timeout-minutes: 15 diff --git a/CMakeLists.txt b/CMakeLists.txt index cad3c0324..8af13cb34 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -48,10 +48,10 @@ project(OSAL C) # part of the open source release. # CAUTION: The API between the OSAL and the low level implementation and/or BSP # is not stabilized, and may change with every OSAL release. No attempt is made -# to provide backward compatibility with to external sources. -set(OSAL_EXT_SOURCE_DIR "$ENV{OSAL_EXT_SOURCE_DIR}" +# to provide backward compatibility with to external sources. +set(OSAL_EXT_SOURCE_DIR "$ENV{OSAL_EXT_SOURCE_DIR}" CACHE PATH "External source directory to check for additional OS/BSP implementations") - + # Read the default compile-time configuration, and update with # any mission/project specific options in the OSAL_CONFIGURATION_FILE include("${OSAL_SOURCE_DIR}/default_config.cmake") @@ -170,7 +170,7 @@ if (OSAL_BSP_INCLUDE_DIRECTORIES) include_directories(${OSAL_BSP_INCLUDE_DIRECTORIES}) endif (OSAL_BSP_INCLUDE_DIRECTORIES) -set(BSP_SRCLIST +set(BSP_SRCLIST src/bsp/shared/src/osapi-bsp.c src/bsp/shared/src/bsp_default_app_run.c src/bsp/shared/src/bsp_default_app_startup.c @@ -351,6 +351,10 @@ if (HAS_PARENT) # when building code intended for coverage analysis. set(UT_COVERAGE_COMPILE_FLAGS "${UT_COVERAGE_COMPILE_FLAGS}" PARENT_SCOPE) set(UT_COVERAGE_LINK_FLAGS "${UT_COVERAGE_LINK_FLAGS}" PARENT_SCOPE) +else(HAS_PARENT) + # In a standalone build, also add the documentation target(s) + # Note that in a CFE/integrated build, it is expected this will be built separately. + add_subdirectory(doc/src doc) endif(HAS_PARENT) diff --git a/README.md b/README.md index 17f77f55c..02c4a8edd 100644 --- a/README.md +++ b/README.md @@ -11,6 +11,28 @@ The autogenerated OSAL user's guide can be viewed at and + ### Development Build: v5.1.0-rc1+dev458 - Adds Counting Semaphore Test with timeouts @@ -534,7 +556,7 @@ make make test ``` -See the [Configuration Guide](https://github.com/nasa/osal/blob/master/doc/OSAL-Configuration-guide.pdf) for more information. +See the [Configuration Guide](https://github.com/nasa/osal/blob/main/doc/OSAL-Configuration-Guide.md) for more information. See also the autogenerated user's guide: diff --git a/doc/src/CMakeLists.txt b/doc/src/CMakeLists.txt new file mode 100644 index 000000000..589da9a30 --- /dev/null +++ b/doc/src/CMakeLists.txt @@ -0,0 +1,88 @@ +######################################################## +# +# CMake Recipe to build OSAL API guide documentation +# +######################################################## + +# +# This CMake script currently defines a top-level target "apiguide" +# to build the OSAL API documentation. This may be invoked either +# from the main OSAL CMakeLists.txt as a subdirectory (useful in the +# case of a self-contained/standalone build) or by a separate script +# (useful if integrating into a larger project with a separate doc build) +# +# To invoke from a separate documentation build, the following vars +# should be defined by the caller, before adding this subdirectory: +# +# OSAL_API_INCLUDE_DIRECTORIES : +# The list of directories that have the OSAL API headers +# This should include the path to osconfig.h to avoid warnings +# about undefined references. +# +# OSALDOC_PREDEFINED : +# Not used directly, but passed through to the "osal-common.doxyfile" +# This may be used to indicate preprocessor definitions that the +# documentation generator tool should be aware of +# +# Note that OSAL_API_INCLUDE_DIRECTORIES is defined by the parent script +# in a standalone build environment. +# + +cmake_minimum_required(VERSION 3.5) +project(OSAL_DOCS NONE) + +# List of dox files to include - +# note that order is relevant here, doxygen processes in the order listed. +set(OSAL_DOCFILE_LIST + ${CMAKE_CURRENT_SOURCE_DIR}/osalmain.dox + ${CMAKE_CURRENT_SOURCE_DIR}/osal_fs.dox + ${CMAKE_CURRENT_SOURCE_DIR}/osal_timer.dox +) + +# For the generated Doxyfiles, the various paths should be in native form +set(OSAL_NATIVE_APIGUIDE_SOURCEFILES) +set(OSAL_NATIVE_INCLUDE_DIRS) +set(OSAL_DOC_DEPENDENCY_LIST) + +foreach(SRC ${OSAL_DOCFILE_LIST}) + file(TO_NATIVE_PATH "${SRC}" SRC) + string(APPEND OSAL_NATIVE_APIGUIDE_SOURCEFILES " \\\n ${SRC}") +endforeach() + +foreach(DIR ${OSAL_API_INCLUDE_DIRECTORIES}) + file(GLOB OSAL_HEADERFILE_LIST ${DIR}/*.h) + foreach(HDR ${OSAL_HEADERFILE_LIST}) + list(APPEND OSAL_DOC_DEPENDENCY_LIST ${HDR}) + file(TO_NATIVE_PATH "${HDR}" HDR) + string(APPEND OSAL_NATIVE_APIGUIDE_SOURCEFILES " \\\n ${HDR}") + endforeach() + file(TO_NATIVE_PATH "${DIR}" DIR) + string(APPEND OSAL_NATIVE_INCLUDE_DIRS " \\\n ${DIR}") +endforeach() + +file(TO_NATIVE_PATH ${CMAKE_CURRENT_BINARY_DIR}/osal-apiguide-warnings.log OSAL_NATIVE_LOGFILE) +file(TO_NATIVE_PATH ${CMAKE_CURRENT_BINARY_DIR}/osal-common.doxyfile OSAL_NATIVE_COMMON_CFGFILE) +file(TO_NATIVE_PATH ${CMAKE_CURRENT_BINARY_DIR}/osal-apiguide.doxyfile OSAL_NATIVE_APIGUIDE_CFGFILE) + +# generate the configuration files +configure_file( + ${CMAKE_CURRENT_SOURCE_DIR}/osal-common.doxyfile.in + ${CMAKE_CURRENT_BINARY_DIR}/osal-common.doxyfile + @ONLY +) +configure_file( + ${CMAKE_CURRENT_SOURCE_DIR}/osal-apiguide.doxyfile.in + ${CMAKE_CURRENT_BINARY_DIR}/osal-apiguide.doxyfile + @ONLY +) + +add_custom_command(OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/apiguide/html/index.html" + COMMAND doxygen ${OSAL_NATIVE_APIGUIDE_CFGFILE} + DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/osal-apiguide.doxyfile ${OSAL_DOCFILE_LIST} ${OSAL_DOC_DEPENDENCY_LIST} + WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}" +) + +add_custom_target(osal-apiguide + COMMAND echo "OSAL API Guide: file://${CMAKE_CURRENT_BINARY_DIR}/apiguide/html/index.html" + DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/apiguide/html/index.html" +) diff --git a/doc/src/osal-apiguide.doxyfile.in b/doc/src/osal-apiguide.doxyfile.in new file mode 100644 index 000000000..86c0de81b --- /dev/null +++ b/doc/src/osal-apiguide.doxyfile.in @@ -0,0 +1,16 @@ +#--------------------------------------------------------------------------- +# Doxygen Configuration options to generate the "OSAL API Guide" +#--------------------------------------------------------------------------- + +# Complete list of input files +INPUT += @OSAL_NATIVE_APIGUIDE_SOURCEFILES@ + + +# Common definitions, some of which are extended or overridden here. +@INCLUDE = @OSAL_NATIVE_COMMON_CFGFILE@ +PROJECT_NAME = "OSAL User's Guide" +OUTPUT_DIRECTORY = apiguide +GENERATE_LATEX = YES + +# output the warnings to a separate file +WARN_LOGFILE = @OSAL_NATIVE_LOGFILE@ diff --git a/doc/src/osal-common.doxyfile.in b/doc/src/osal-common.doxyfile.in new file mode 100644 index 000000000..39bbba061 --- /dev/null +++ b/doc/src/osal-common.doxyfile.in @@ -0,0 +1,76 @@ +#--------------------------------------------------------------------------- +# Project related configuration options, shared for all cFE doxygen outputs +#--------------------------------------------------------------------------- +@INCLUDE_PATH = @OSAL_NATIVE_INCLUDE_DIRS@ +OUTPUT_DIRECTORY = . +ABBREVIATE_BRIEF = "The $name class " \ + "The $name widget " \ + "The $name file " \ + is \ + provides \ + specifies \ + contains \ + represents \ + a \ + an \ + the +TAB_SIZE = 4 +OPTIMIZE_OUTPUT_FOR_C = YES +ALIASES += nonnull="(must not be null)" +ALIASES += nonzero="(must not be zero)" +ALIASES += covtest="(return value only verified in coverage test)" + +PREDEFINED += @OSALDOC_PREDEFINED@ + +#--------------------------------------------------------------------------- +# Build related configuration options +#--------------------------------------------------------------------------- +EXTRACT_ALL = YES +EXTRACT_PRIVATE = YES +EXTRACT_STATIC = YES +CASE_SENSE_NAMES = NO +GENERATE_TODOLIST = NO +#--------------------------------------------------------------------------- +# configuration options related to warning and progress messages +#--------------------------------------------------------------------------- +WARN_NO_PARAMDOC = YES +#--------------------------------------------------------------------------- +# configuration options related to the input files +#--------------------------------------------------------------------------- +STRIP_FROM_PATH = @OSAL_SOURCE_NATIVE_DIR@ +FILE_PATTERNS = *.c *.cpp *.cc *.C *.h *.hh *.hpp *.H *.dox *.md +RECURSIVE = YES +EXAMPLE_PATTERNS = * +#--------------------------------------------------------------------------- +# configuration options related to source browsing +#--------------------------------------------------------------------------- +SOURCE_BROWSER = YES +REFERENCED_BY_RELATION = YES +REFERENCES_RELATION = YES +#--------------------------------------------------------------------------- +# configuration options related to the LaTeX output +#--------------------------------------------------------------------------- +GENERATE_LATEX = NO +LATEX_CMD_NAME = latex +COMPACT_LATEX = YES +PAPER_TYPE = letter +#--------------------------------------------------------------------------- +# configuration options related to the RTF output +#--------------------------------------------------------------------------- +COMPACT_RTF = YES +#--------------------------------------------------------------------------- +# Configuration options related to the dot tool +#--------------------------------------------------------------------------- +CLASS_DIAGRAMS = NO +HAVE_DOT = YES +CLASS_GRAPH = NO +COLLABORATION_GRAPH = NO +INCLUDE_GRAPH = NO +INCLUDED_BY_GRAPH = NO +CALL_GRAPH = YES +GRAPHICAL_HIERARCHY = NO +MAX_DOT_GRAPH_DEPTH = 1000 +#--------------------------------------------------------------------------- +# Configuration::additions related to the search engine +#--------------------------------------------------------------------------- +SEARCHENGINE = NO diff --git a/doc/src/osal_fs.dox b/doc/src/osal_fs.dox new file mode 100644 index 000000000..6a8b8cf29 --- /dev/null +++ b/doc/src/osal_fs.dox @@ -0,0 +1,94 @@ +/** +\page osalfsovr File System Overview + + The File System API is a thin wrapper around a selection of POSIX file APIs. + In addition the File System API presents a common directory structure and + volume view regardless of the underlying system type. For example, vxWorks + uses MS-DOS style volume names and directories where a vxWorks RAM disk might + have the volume “RAM:0”. With this File System API, volumes are represented + as Unix-style paths where each volume is mounted on the root file system: + +
    +
  • RAM:0/file1.dat becomes /mnt/ram/file1.dat +
  • FL:0/file2.dat becomes /mnt/fl/file2.dat +
+ + This abstraction allows the applications to use the same paths regardless of + the implementation and it also allows file systems to be simulated on a desktop + system for testing. On a desktop Linux system, the file system abstraction can + be set up to map virtual devices to a regular directory. This is accomplished + through the OS_mkfs call, OS_mount call, and a BSP specific volume table that + maps the virtual devices to real devices or underlying file systems. + + In order to make this file system volume abstraction work, a “Volume Table” + needs to be provided in the Board Support Package of the application. The table + has the following fields: + +
    +
  • Device Name: This is the name of the virtual device that the Application + uses. Common names are “ramdisk1”, “flash1”, or “volatile1” etc. But the + name can be any unique string. +
  • Physical Device Name: This is an implementation specific field. For + vxWorks it is not needed and can be left blank. For a File system based + implementation, it is the “mount point” on the root file system where all + of the volume will be mounted. A common place for this on Linux could + be a user’s home directory, “/tmp”, or even the current working + directory “.”. In the example of “/tmp” all of the directories created + for the volumes would be under “/tmp” on the Linux file system. For a real + disk device in Linux, such as a RAM disk, this field is the device + name “/dev/ram0”. +
  • Volume Type: This field defines the type of volume. The types are: + FS_BASED which uses the existing file system, RAM_DISK which uses a + RAM_DISK device in vxWorks, RTEMS, or Linux, FLASH_DISK_FORMAT which uses + a flash disk that is to be formatted before use, FLASH_DISK_INIT which + uses a flash disk with an existing format that is just to be initialized + before it’s use, EEPROM which is for an EEPROM or PROM based system. +
  • Volatile Flag: This flag indicates that the volume or disk is a volatile + disk (RAM disk ) or a non-volatile disk, that retains its contents when + the system is rebooted. This should be set to TRUE or FALSE. +
  • Free Flag: This is an internal flag that should be set to FALSE or zero. +
  • Is Mounted Flag: This is an internal flag that should be set to FALSE + or zero. Note that a “pre-mounted” FS_BASED path can be set up by setting + this flag to one. +
  • Volume Name: This is an internal field and should be set to a space + character “ “. +
  • Mount Point Field: This is an internal field and should be set to a space + character “ “. +
  • Block Size Field: This is used to record the block size of the device and + does not need to be set by the user. +
+**/ + +/** +\page osalfsfd File Descriptors In Osal + + The OSAL uses abstracted file descriptors. This means that the file descriptors + passed back from the OS_open and OS_creat calls will only work with other OSAL OS_* + calls. The reasoning for this is as follows: + + Because the OSAL now keeps track of all file descriptors, OSAL specific information + can be associated with a specific file descriptor in an OS independent way. For +instance, the path of the file that the file descriptor points to can be easily + retrieved. Also, the OSAL task ID of the task that opened the file can also be + retrieved easily. Both of these pieces of information are very useful when trying + to determine statistics for a task, or the entire system. This information can all + be retrieved with a single API, OS_FDGetInfo. + + All of possible file system calls are not implemented. "Special" files requiring OS + specific control/operations are by nature not portable. Abstraction in this case is + is not possible, so the raw OS calls should be used (including open/close/etc). Mixing + with OSAL calls is not supported for such cases. #OS_TranslatePath is available to + support using open directly by an app and maintain abstraction on the file system. + + There are some small drawbacks with the OSAL file descriptors. Because the related + information is kept in a table, there is a define called OS_MAX_NUM_OPEN_FILES that + defines the maximum number of file descriptors available. This is a configuration +parameter, and can be changed to fit your needs. + + Also, if you open or create a file not using the OSAL calls (OS_open or OS_creat) + then none of the other OS_* calls that accept a file descriptor as a parameter will +work (the results of doing so are undefined). Therefore, if you open a file with + the underlying OS's open call, you must continue to use the OS's calls until you + close the file descriptor. Be aware that by doing this your software may no longer + be OS agnostic. +**/ diff --git a/doc/src/osal_timer.dox b/doc/src/osal_timer.dox new file mode 100644 index 000000000..793bc24c7 --- /dev/null +++ b/doc/src/osal_timer.dox @@ -0,0 +1,8 @@ +/** + \page osaltimerover Timer Overview + + The timer API is a generic interface to the OS timer facilities. It is + implemented using the POSIX timers on Linux and vxWorks and the native timer + API on RTEMS. The number of timers supported is controlled by the configuration + parameter OS_MAX_TIMERS. +**/ diff --git a/doc/src/osalmain.dox b/doc/src/osalmain.dox new file mode 100644 index 000000000..7502b6991 --- /dev/null +++ b/doc/src/osalmain.dox @@ -0,0 +1,121 @@ +/** + \mainpage Osal API Documentation + +
    +
  • General Information and Concepts +
      +
    • \subpage osalIntro +
    +
  • Core +
      +
    • \ref OSReturnCodes +
    • \ref OSObjectTypes +
    • APIs +
        +
      • \ref OSAPICore +
      • \ref OSAPIObjUtil +
      • \ref OSAPITask +
      • \ref OSAPIMsgQueue +
      • \ref OSAPIHeap +
      • \ref OSAPIError +
      • \ref OSAPISelect +
      • \ref OSAPIPrintf +
      • \ref OSAPIBsp +
      • \ref OSAPIClock +
      • \ref OSAPIShell +
      +
    • \subpage osapi-common.h "Common Reference" +
    • \subpage osapi-error.h "Return Code Reference" +
    • \subpage osapi-idmap.h "Id Map Reference" +
    • \subpage osapi-clock.h "Clock Reference" +
    • \subpage osapi-task.h "Task Reference" +
    • \subpage osapi-queue.h "Message Queue Reference" +
    • \subpage osapi-heap.h "Heap Reference" +
    • \subpage osapi-select.h "Select Reference" +
    • \subpage osapi-printf.h "Printf Reference" +
    • \subpage osapi-bsp.h "BSP Reference" +
    • \subpage osapi-shell.h "Shell Reference" +
    +
  • File System +
      +
    • \subpage osalfsovr +
    • \subpage osalfsfd +
    • \ref OSFileAccess +
    • \ref OSFileOffset +
    • APIs +
        +
      • \ref OSAPIFile +
      • \ref OSAPIDir +
      • \ref OSAPIFileSys +
      +
    • \subpage osapi-filesys.h "File System Reference" +
    • \subpage osapi-file.h "File Reference" +
    • \subpage osapi-dir.h "Directory Reference" +
    +
  • Object File Loader +
      +
    • APIs +
        +
      • \ref OSAPILoader +
      +
    • \subpage osapi-module.h "File Loader Reference" +
    +
  • Network +
      +
    • APIs +
        +
      • \ref OSALAPINetwork +
      • \ref OSAPISocketAddr +
      • \ref OSALAPISocket +
      +
    • \subpage osapi-network.h "Network Reference" +
    • \subpage osapi-sockets.h "Socket Reference" +
    +
  • Timer +
      +
    • \subpage osaltimerover +
    • APIs +
        +
      • \ref OSAPITimebase +
      • \ref OSAPITimer +
      +
    • \subpage osapi-timer.h "Timer Reference" +
    • \subpage osapi-timebase.h "Time Base Reference" +
    +
  • Semaphore and Mutex +
      +
    • \ref OSSemaphoreStates +
    • APIs +
        +
      • \ref OSAPIBinSem +
      • \ref OSAPICountSem +
      • \ref OSAPIMutex +
      +
    • \subpage osapi-binsem.h "Binary Semaphore Reference" +
    • \subpage osapi-countsem.h "Counting Semaphore Reference" +
    • \subpage osapi-mutex.h "Mutex Reference" +
    +
+**/ + +/** + \page osalIntro OSAL Introduction + + The goal of this library is to promote the creation of portable and + reusable real time embedded system software. Given the necessary OS + abstraction layer implementations, the same embedded software should + compile and run on a number of platforms ranging from spacecraft + computer systems to desktop PCs. + + The OS Application Program Interfaces (APIs) are broken up into core, + file system, loader, network, and timer APIs. See the related document + sections for full descriptions. + + @note The majority of these APIs should be called from a task running + in the context of an OSAL application and in general should not be called + from an ISR. There are a few exceptions, such as the ability to give a + binary semaphore from an ISR. +**/ + + + diff --git a/src/os/inc/osapi-binsem.h b/src/os/inc/osapi-binsem.h index 21335fc29..c36afafd6 100644 --- a/src/os/inc/osapi-binsem.h +++ b/src/os/inc/osapi-binsem.h @@ -57,8 +57,8 @@ typedef struct * sem_initial_value and name specified by sem_name. sem_id will be * returned to the caller * - * @param[out] sem_id will be set to the non-zero ID of the newly-created resource - * @param[in] sem_name the name of the new resource to create + * @param[out] sem_id will be set to the non-zero ID of the newly-created resource @nonnull + * @param[in] sem_name the name of the new resource to create @nonnull * @param[in] sem_initial_value the initial value of the binary semaphore * @param[in] options Reserved for future use, should be passed as 0. * @@ -68,7 +68,7 @@ typedef struct * @retval #OS_ERR_NAME_TOO_LONG name length including null terminator greater than #OS_MAX_API_NAME * @retval #OS_ERR_NO_FREE_IDS if all of the semaphore ids are taken * @retval #OS_ERR_NAME_TAKEN if this is already the name of a binary semaphore - * @retval #OS_SEM_FAILURE if the OS call failed + * @retval #OS_SEM_FAILURE if the OS call failed @covtest */ int32 OS_BinSemCreate(osal_id_t *sem_id, const char *sem_name, uint32 sem_initial_value, uint32 options); @@ -84,7 +84,7 @@ int32 OS_BinSemCreate(osal_id_t *sem_id, const char *sem_name, uint32 sem_initia * @return Execution status, see @ref OSReturnCodes * @retval #OS_SUCCESS @copybrief OS_SUCCESS * @retval #OS_ERR_INVALID_ID if the id passed in is not a binary semaphore - * @retval #OS_SEM_FAILURE if an unspecified failure occurs + * @retval #OS_SEM_FAILURE if an unspecified failure occurs @covtest */ int32 OS_BinSemFlush(osal_id_t sem_id); @@ -102,9 +102,8 @@ int32 OS_BinSemFlush(osal_id_t sem_id); * * @return Execution status, see @ref OSReturnCodes * @retval #OS_SUCCESS @copybrief OS_SUCCESS - * @retval #OS_SEM_FAILURE the semaphore was not previously initialized or is not - * in the array of semaphores defined by the system * @retval #OS_ERR_INVALID_ID if the id passed in is not a binary semaphore + * @retval #OS_SEM_FAILURE if an unspecified failure occurs @covtest */ int32 OS_BinSemGive(osal_id_t sem_id); @@ -123,7 +122,7 @@ int32 OS_BinSemGive(osal_id_t sem_id); * @return Execution status, see @ref OSReturnCodes * @retval #OS_SUCCESS @copybrief OS_SUCCESS * @retval #OS_ERR_INVALID_ID the Id passed in is not a valid binary semaphore - * @retval #OS_SEM_FAILURE if the OS call failed + * @retval #OS_SEM_FAILURE if an unspecified failure occurs @covtest */ int32 OS_BinSemTake(osal_id_t sem_id); @@ -142,9 +141,8 @@ int32 OS_BinSemTake(osal_id_t sem_id); * @return Execution status, see @ref OSReturnCodes * @retval #OS_SUCCESS @copybrief OS_SUCCESS * @retval #OS_SEM_TIMEOUT if semaphore was not relinquished in time - * @retval #OS_SEM_FAILURE the semaphore was not previously initialized or is not - * in the array of semaphores defined by the system * @retval #OS_ERR_INVALID_ID if the ID passed in is not a valid semaphore ID + * @retval #OS_SEM_FAILURE if an unspecified failure occurs @covtest */ int32 OS_BinSemTimedWait(osal_id_t sem_id, uint32 msecs); @@ -160,7 +158,7 @@ int32 OS_BinSemTimedWait(osal_id_t sem_id, uint32 msecs); * @return Execution status, see @ref OSReturnCodes * @retval #OS_SUCCESS @copybrief OS_SUCCESS * @retval #OS_ERR_INVALID_ID if the id passed in is not a valid binary semaphore - * @retval #OS_SEM_FAILURE the OS call failed + * @retval #OS_SEM_FAILURE if an unspecified failure occurs @covtest */ int32 OS_BinSemDelete(osal_id_t sem_id); @@ -172,7 +170,7 @@ int32 OS_BinSemDelete(osal_id_t sem_id); * The id is returned through sem_id * * @param[out] sem_id will be set to the ID of the existing resource - * @param[in] sem_name the name of the existing resource to find + * @param[in] sem_name the name of the existing resource to find @nonnull * * @return Execution status, see @ref OSReturnCodes * @retval #OS_SUCCESS @copybrief OS_SUCCESS @@ -191,7 +189,7 @@ int32 OS_BinSemGetIdByName(osal_id_t *sem_id, const char *sem_name); * semaphore. * * @param[in] sem_id The object ID to operate on - * @param[out] bin_prop The property object buffer to fill + * @param[out] bin_prop The property object buffer to fill @nonnull * * @return Execution status, see @ref OSReturnCodes * @retval #OS_SUCCESS @copybrief OS_SUCCESS diff --git a/src/os/inc/osapi-clock.h b/src/os/inc/osapi-clock.h index e620adc13..df3eab7dd 100644 --- a/src/os/inc/osapi-clock.h +++ b/src/os/inc/osapi-clock.h @@ -80,9 +80,10 @@ enum * * @note Mission time management typically uses the cFE Time Service * - * @param[out] time_struct An OS_time_t that will be set to the current time + * @param[out] time_struct An OS_time_t that will be set to the current time @nonnull * * @return Get local time status, see @ref OSReturnCodes + * @retval #OS_SUCCESS @copybrief OS_SUCCESS * @retval #OS_INVALID_POINTER if time_struct is null */ int32 OS_GetLocalTime(OS_time_t *time_struct); @@ -95,9 +96,10 @@ int32 OS_GetLocalTime(OS_time_t *time_struct); * * @note Mission time management typically uses the cFE Time Services * - * @param[in] time_struct An OS_time_t containing the current time + * @param[in] time_struct An OS_time_t containing the current time @nonnull * * @return Set local time status, see @ref OSReturnCodes + * @retval #OS_SUCCESS @copybrief OS_SUCCESS * @retval #OS_INVALID_POINTER if time_struct is null */ int32 OS_SetLocalTime(const OS_time_t *time_struct); diff --git a/src/os/inc/osapi-common.h b/src/os/inc/osapi-common.h index d81613240..4f1659d9c 100644 --- a/src/os/inc/osapi-common.h +++ b/src/os/inc/osapi-common.h @@ -136,7 +136,7 @@ void OS_Application_Run(void); * means the OSAL can not be initialized. Typical platform specific response * is to abort since additional OSAL calls will have undefined behavior. * @retval #OS_SUCCESS @copybrief OS_SUCCESS - * @retval #OS_ERROR @copybrief OS_ERROR + * @retval #OS_ERROR @copybrief OS_ERROR @covtest */ int32 OS_API_Init(void); @@ -228,10 +228,9 @@ void OS_ApplicationExit(int32 Status); * application-defined handlers for these events should not block or attempt * to access other OSAL resources. * - * @param[in] handler The application-provided event handler + * @param[in] handler The application-provided event handler @nonnull * @return Execution status, see @ref OSReturnCodes. * @retval #OS_SUCCESS @copybrief OS_SUCCESS - * @retval #OS_ERROR @copybrief OS_ERROR * @retval #OS_INVALID_POINTER if handler is NULL */ int32 OS_RegisterEventHandler(OS_EventHandler_t handler); diff --git a/src/os/inc/osapi-countsem.h b/src/os/inc/osapi-countsem.h index 8fd194a6e..d8ba2e1c5 100644 --- a/src/os/inc/osapi-countsem.h +++ b/src/os/inc/osapi-countsem.h @@ -48,10 +48,18 @@ typedef struct * * Creates a counting semaphore with initial value specified by * sem_initial_value and name specified by sem_name. sem_id will be - * returned to the caller - * - * @param[out] sem_id will be set to the non-zero ID of the newly-created resource - * @param[in] sem_name the name of the new resource to create + * returned to the caller. + * + * @note Underlying RTOS implementations may or may not impose a specific upper limit + * to the value of a counting semaphore. If the OS has a specific limit and the + * sem_initial_value exceeds this limit, then #OS_INVALID_SEM_VALUE is returned. On + * other implementations, any 32-bit integer value may be acceptable. For maximum + * portability, it is recommended to keep counting semaphore values within the + * range of a "short int" (i.e. between 0 and 32767). Many platforms do accept + * larger values, but may not be guaranteed. + * + * @param[out] sem_id will be set to the non-zero ID of the newly-created resource @nonnull + * @param[in] sem_name the name of the new resource to create @nonnull * @param[in] sem_initial_value the initial value of the counting semaphore * @param[in] options Reserved for future use, should be passed as 0. * @@ -61,8 +69,8 @@ typedef struct * @retval #OS_ERR_NAME_TOO_LONG name length including null terminator greater than #OS_MAX_API_NAME * @retval #OS_ERR_NO_FREE_IDS if all of the semaphore ids are taken * @retval #OS_ERR_NAME_TAKEN if this is already the name of a counting semaphore - * @retval #OS_SEM_FAILURE if the OS call failed - * @retval #OS_INVALID_SEM_VALUE if the semaphore value is too high + * @retval #OS_INVALID_SEM_VALUE if the semaphore value is too high @covtest + * @retval #OS_SEM_FAILURE if an unspecified implementation error occurs @covtest */ int32 OS_CountSemCreate(osal_id_t *sem_id, const char *sem_name, uint32 sem_initial_value, uint32 options); @@ -80,9 +88,8 @@ int32 OS_CountSemCreate(osal_id_t *sem_id, const char *sem_name, uint32 sem_init * * @return Execution status, see @ref OSReturnCodes * @retval #OS_SUCCESS @copybrief OS_SUCCESS - * @retval #OS_SEM_FAILURE the semaphore was not previously initialized or is not - * in the array of semaphores defined by the system * @retval #OS_ERR_INVALID_ID if the id passed in is not a counting semaphore + * @retval #OS_SEM_FAILURE if an unspecified implementation error occurs @covtest */ int32 OS_CountSemGive(osal_id_t sem_id); @@ -101,7 +108,7 @@ int32 OS_CountSemGive(osal_id_t sem_id); * @return Execution status, see @ref OSReturnCodes * @retval #OS_SUCCESS @copybrief OS_SUCCESS * @retval #OS_ERR_INVALID_ID the Id passed in is not a valid counting semaphore - * @retval #OS_SEM_FAILURE if the OS call failed + * @retval #OS_SEM_FAILURE if an unspecified implementation error occurs @covtest */ int32 OS_CountSemTake(osal_id_t sem_id); @@ -120,9 +127,8 @@ int32 OS_CountSemTake(osal_id_t sem_id); * @return Execution status, see @ref OSReturnCodes * @retval #OS_SUCCESS @copybrief OS_SUCCESS * @retval #OS_SEM_TIMEOUT if semaphore was not relinquished in time - * @retval #OS_SEM_FAILURE the semaphore was not previously initialized or is not - * in the array of semaphores defined by the system * @retval #OS_ERR_INVALID_ID if the ID passed in is not a valid semaphore ID + * @retval #OS_SEM_FAILURE if an unspecified implementation error occurs @covtest */ int32 OS_CountSemTimedWait(osal_id_t sem_id, uint32 msecs); @@ -135,7 +141,7 @@ int32 OS_CountSemTimedWait(osal_id_t sem_id, uint32 msecs); * @return Execution status, see @ref OSReturnCodes * @retval #OS_SUCCESS @copybrief OS_SUCCESS * @retval #OS_ERR_INVALID_ID if the id passed in is not a valid counting semaphore - * @retval #OS_SEM_FAILURE the OS call failed + * @retval #OS_SEM_FAILURE if an unspecified implementation error occurs @covtest */ int32 OS_CountSemDelete(osal_id_t sem_id); @@ -147,7 +153,7 @@ int32 OS_CountSemDelete(osal_id_t sem_id); * The id is returned through sem_id * * @param[out] sem_id will be set to the ID of the existing resource - * @param[in] sem_name the name of the existing resource to find + * @param[in] sem_name the name of the existing resource to find @nonnull * * @return Execution status, see @ref OSReturnCodes * @retval #OS_SUCCESS @copybrief OS_SUCCESS @@ -165,8 +171,8 @@ int32 OS_CountSemGetIdByName(osal_id_t *sem_id, const char *sem_name); * all of the relevant info( name and creator) about the specified counting * semaphore. * - * @param[in] sem_id The object ID to operate on - * @param[out] count_prop The property object buffer to fill + * @param[in] sem_id The object ID to operate on + * @param[out] count_prop The property object buffer to fill @nonnull * * @return Execution status, see @ref OSReturnCodes * @retval #OS_SUCCESS @copybrief OS_SUCCESS diff --git a/src/os/inc/osapi-dir.h b/src/os/inc/osapi-dir.h index 7b2acf0f7..c374a2581 100644 --- a/src/os/inc/osapi-dir.h +++ b/src/os/inc/osapi-dir.h @@ -53,11 +53,15 @@ typedef struct * * Prepares for reading the files within a directory * - * @param[out] dir_id The non-zero handle ID of the directory - * @param[in] path The directory to open + * @param[out] dir_id Location to store handle ID of the directory @nonnull + * @param[in] path The directory to open @nonnull * * @return Execution status, see @ref OSReturnCodes + * @retval #OS_SUCCESS @copybrief OS_SUCCESS * @retval #OS_INVALID_POINTER if dir_id or path is NULL + * @retval #OS_FS_ERR_PATH_TOO_LONG if the path argument exceeds the maximum length + * @retval #OS_FS_ERR_PATH_INVALID if the path argument is not valid + * @retval #OS_ERROR if the directory could not be opened */ int32 OS_DirectoryOpen(osal_id_t *dir_id, const char *path); @@ -70,6 +74,8 @@ int32 OS_DirectoryOpen(osal_id_t *dir_id, const char *path); * @param[in] dir_id The handle ID of the directory * * @return Execution status, see @ref OSReturnCodes + * @retval #OS_SUCCESS @copybrief OS_SUCCESS + * @retval #OS_ERR_INVALID_ID if the directory handle is invalid */ int32 OS_DirectoryClose(osal_id_t dir_id); @@ -82,6 +88,8 @@ int32 OS_DirectoryClose(osal_id_t dir_id); * @param[in] dir_id The handle ID of the directory * * @return Execution status, see @ref OSReturnCodes + * @retval #OS_SUCCESS @copybrief OS_SUCCESS + * @retval #OS_ERR_INVALID_ID if the directory handle is invalid */ int32 OS_DirectoryRewind(osal_id_t dir_id); @@ -92,10 +100,13 @@ int32 OS_DirectoryRewind(osal_id_t dir_id); * Obtains directory entry data for the next file from an open directory * * @param[in] dir_id The handle ID of the directory - * @param[out] dirent Buffer to store directory entry information + * @param[out] dirent Buffer to store directory entry information @nonnull * * @return Execution status, see @ref OSReturnCodes + * @retval #OS_SUCCESS @copybrief OS_SUCCESS * @retval #OS_INVALID_POINTER if dirent argument is NULL + * @retval #OS_ERR_INVALID_ID if the directory handle is invalid + * @retval #OS_ERROR at the end of the directory or if the OS call otherwise fails */ int32 OS_DirectoryRead(osal_id_t dir_id, os_dirent_t *dirent); @@ -105,7 +116,7 @@ int32 OS_DirectoryRead(osal_id_t dir_id, os_dirent_t *dirent); * * Makes a directory specified by path. * - * @param[in] path The new directory name + * @param[in] path The new directory name @nonnull * @param[in] access The permissions for the directory (reserved for future use) * * @note Current implementations do not utilize the "access" parameter. Applications @@ -117,7 +128,7 @@ int32 OS_DirectoryRead(osal_id_t dir_id, os_dirent_t *dirent); * @retval #OS_INVALID_POINTER if path is NULL * @retval #OS_FS_ERR_PATH_TOO_LONG if the path is too long to be stored locally * @retval #OS_FS_ERR_PATH_INVALID if path cannot be parsed - * @retval #OS_ERROR if the OS call fails + * @retval #OS_ERROR if the OS call fails @covtest */ int32 OS_mkdir(const char *path, uint32 access); @@ -135,7 +146,7 @@ int32 OS_mkdir(const char *path, uint32 access); * @retval #OS_INVALID_POINTER if path is NULL * @retval #OS_FS_ERR_PATH_INVALID if path cannot be parsed * @retval #OS_FS_ERR_PATH_TOO_LONG - * @retval #OS_ERROR if the directory remove operation failed + * @retval #OS_ERROR if the directory remove operation failed @covtest */ int32 OS_rmdir(const char *path); /**@}*/ diff --git a/src/os/inc/osapi-heap.h b/src/os/inc/osapi-heap.h index 5313bfdd3..a3763226d 100644 --- a/src/os/inc/osapi-heap.h +++ b/src/os/inc/osapi-heap.h @@ -53,6 +53,7 @@ typedef struct * @param[out] heap_prop Storage buffer for heap info * * @return Execution status, see @ref OSReturnCodes + * @retval #OS_SUCCESS @copybrief OS_SUCCESS * @retval #OS_INVALID_POINTER if the heap_prop argument is NULL */ int32 OS_HeapGetInfo(OS_heap_prop_t *heap_prop); diff --git a/src/os/inc/osapi-module.h b/src/os/inc/osapi-module.h index 25cbd14da..ed5c52c5b 100644 --- a/src/os/inc/osapi-module.h +++ b/src/os/inc/osapi-module.h @@ -133,8 +133,8 @@ typedef const struct * The static table is intended to support embedded targets that do * not have module loading capability or have it disabled. * - * @param[out] symbol_address Set to the address of the symbol - * @param[in] symbol_name Name of the symbol to look up + * @param[out] symbol_address Set to the address of the symbol @nonnull + * @param[in] symbol_name Name of the symbol to look up @nonnull * * @return Execution status, see @ref OSReturnCodes * @retval #OS_SUCCESS @copybrief OS_SUCCESS @@ -152,8 +152,8 @@ int32 OS_SymbolLookup(cpuaddr *symbol_address, const char *symbol_name); * loaded with the #OS_MODULE_FLAG_LOCAL_SYMBOLS flag. * * @param[in] module_id Module ID that should contain the symbol - * @param[out] symbol_address Set to the address of the symbol - * @param[in] symbol_name Name of the symbol to look up + * @param[out] symbol_address Set to the address of the symbol @nonnull + * @param[in] symbol_name Name of the symbol to look up @nonnull * * @return Execution status, see @ref OSReturnCodes * @retval #OS_SUCCESS @copybrief OS_SUCCESS @@ -168,14 +168,21 @@ int32 OS_ModuleSymbolLookup(osal_id_t module_id, cpuaddr *symbol_address, const * * Dumps the system symbol table to the specified filename * - * @param[in] filename File to write to + * @note Not all RTOS implementations support this API. If the underlying + * module subsystem does not provide a facility to iterate through the + * symbol table, then the #OS_ERR_NOT_IMPLEMENTED status code is returned. + * + * @param[in] filename File to write to @nonnull * @param[in] size_limit Maximum number of bytes to write * * @return Execution status, see @ref OSReturnCodes * @retval #OS_SUCCESS @copybrief OS_SUCCESS * @retval #OS_ERR_NOT_IMPLEMENTED @copybrief OS_ERR_NOT_IMPLEMENTED * @retval #OS_INVALID_POINTER if the filename argument is NULL - * @retval #OS_ERROR if the symbol table could not be read or dumped + * @retval #OS_FS_ERR_PATH_INVALID if the filename argument is not valid + * @retval #OS_ERR_NAME_TOO_LONG if any of the symbol names are too long @covtest + * @retval #OS_ERR_OUTPUT_TOO_LARGE if the size_limit was reached before completing all symbols @covtest + * @retval #OS_ERROR if an other/unspecified error occurs @covtest */ int32 OS_SymbolTableDump(const char *filename, size_t size_limit); @@ -190,17 +197,18 @@ int32 OS_SymbolTableDump(const char *filename, size_t size_limit); * and #OS_MODULE_FLAG_GLOBAL_SYMBOLS for descriptions. * * @param[out] module_id Non-zero OSAL ID corresponding to the loaded module - * @param[in] module_name Name of module - * @param[in] filename File containing the object code to load + * @param[in] module_name Name of module @nonnull + * @param[in] filename File containing the object code to load @nonnull * @param[in] flags Options for the loaded module * * @return Execution status, see @ref OSReturnCodes * @retval #OS_SUCCESS @copybrief OS_SUCCESS - * @retval #OS_ERROR if the module cannot be loaded * @retval #OS_INVALID_POINTER if one of the parameters is NULL * @retval #OS_ERR_NO_FREE_IDS if the module table is full * @retval #OS_ERR_NAME_TAKEN if the name is in use * @retval #OS_ERR_NAME_TOO_LONG if the module_name is too long + * @retval #OS_FS_ERR_PATH_INVALID if the filename argument is not valid + * @retval #OS_ERROR if an other/unspecified error occurs @covtest */ int32 OS_ModuleLoad(osal_id_t *module_id, const char *module_name, const char *filename, uint32 flags); @@ -214,7 +222,8 @@ int32 OS_ModuleLoad(osal_id_t *module_id, const char *module_name, const char *f * * @return Execution status, see @ref OSReturnCodes * @retval #OS_SUCCESS @copybrief OS_SUCCESS - * @retval #OS_ERROR if the module is invalid or cannot be unloaded + * @retval #OS_ERR_INVALID_ID if the module id invalid + * @retval #OS_ERROR if an other/unspecified error occurs @covtest */ int32 OS_ModuleUnload(osal_id_t module_id); @@ -225,12 +234,13 @@ int32 OS_ModuleUnload(osal_id_t module_id); * Returns information about the loadable module * * @param[in] module_id OSAL ID of the previously the loaded module - * @param[out] module_info Buffer to store module information + * @param[out] module_info Buffer to store module information @nonnull * * @return Execution status, see @ref OSReturnCodes * @retval #OS_SUCCESS @copybrief OS_SUCCESS * @retval #OS_ERR_INVALID_ID if the module id invalid * @retval #OS_INVALID_POINTER if the pointer to the ModuleInfo structure is invalid + * @retval #OS_ERROR if an other/unspecified error occurs @covtest */ int32 OS_ModuleInfo(osal_id_t module_id, OS_module_prop_t *module_info); /**@}*/ diff --git a/src/os/inc/osapi-mutex.h b/src/os/inc/osapi-mutex.h index b7be53b42..44c135abd 100644 --- a/src/os/inc/osapi-mutex.h +++ b/src/os/inc/osapi-mutex.h @@ -47,8 +47,8 @@ typedef struct * * Mutex semaphores are always created in the unlocked (full) state. * - * @param[out] sem_id will be set to the non-zero ID of the newly-created resource - * @param[in] sem_name the name of the new resource to create + * @param[out] sem_id will be set to the non-zero ID of the newly-created resource @nonnull + * @param[in] sem_name the name of the new resource to create @nonnull * @param[in] options reserved for future use. Should be passed as 0. * * @return Execution status, see @ref OSReturnCodes @@ -57,7 +57,7 @@ typedef struct * @retval #OS_ERR_NAME_TOO_LONG name length including null terminator greater than #OS_MAX_API_NAME * @retval #OS_ERR_NO_FREE_IDS if there are no more free mutex Ids * @retval #OS_ERR_NAME_TAKEN if there is already a mutex with the same name - * @retval #OS_SEM_FAILURE if the OS call failed + * @retval #OS_SEM_FAILURE if the OS call failed @covtest */ int32 OS_MutSemCreate(osal_id_t *sem_id, const char *sem_name, uint32 options); @@ -75,7 +75,7 @@ int32 OS_MutSemCreate(osal_id_t *sem_id, const char *sem_name, uint32 options); * @return Execution status, see @ref OSReturnCodes * @retval #OS_SUCCESS @copybrief OS_SUCCESS * @retval #OS_ERR_INVALID_ID if the id passed in is not a valid mutex - * @retval #OS_SEM_FAILURE if an unspecified error occurs + * @retval #OS_SEM_FAILURE if an unspecified error occurs @covtest */ int32 OS_MutSemGive(osal_id_t sem_id); @@ -92,9 +92,8 @@ int32 OS_MutSemGive(osal_id_t sem_id); * * @return Execution status, see @ref OSReturnCodes * @retval #OS_SUCCESS @copybrief OS_SUCCESS - * @retval #OS_SEM_FAILURE if the semaphore was not previously initialized or is - * not in the array of semaphores defined by the system * @retval #OS_ERR_INVALID_ID the id passed in is not a valid mutex + * @retval #OS_SEM_FAILURE if an unspecified error occurs @covtest */ int32 OS_MutSemTake(osal_id_t sem_id); @@ -110,7 +109,7 @@ int32 OS_MutSemTake(osal_id_t sem_id); * @return Execution status, see @ref OSReturnCodes * @retval #OS_SUCCESS @copybrief OS_SUCCESS * @retval #OS_ERR_INVALID_ID if the id passed in is not a valid mutex - * @retval #OS_SEM_FAILURE if the OS call failed + * @retval #OS_SEM_FAILURE if an unspecified error occurs @covtest */ int32 OS_MutSemDelete(osal_id_t sem_id); @@ -122,7 +121,7 @@ int32 OS_MutSemDelete(osal_id_t sem_id); * The id is returned through sem_id * * @param[out] sem_id will be set to the ID of the existing resource - * @param[in] sem_name the name of the existing resource to find + * @param[in] sem_name the name of the existing resource to find @nonnull * * @return Execution status, see @ref OSReturnCodes * @retval #OS_SUCCESS @copybrief OS_SUCCESS @@ -140,8 +139,8 @@ int32 OS_MutSemGetIdByName(osal_id_t *sem_id, const char *sem_name); * all of the relevant info( name and creator) about the specified mutex * semaphore. * - * @param[in] sem_id The object ID to operate on - * @param[out] mut_prop The property object buffer to fill + * @param[in] sem_id The object ID to operate on + * @param[out] mut_prop The property object buffer to fill @nonnull * * @return Execution status, see @ref OSReturnCodes * @retval #OS_SUCCESS @copybrief OS_SUCCESS diff --git a/src/os/inc/osapi-network.h b/src/os/inc/osapi-network.h index a805ef80b..c4339e800 100644 --- a/src/os/inc/osapi-network.h +++ b/src/os/inc/osapi-network.h @@ -65,6 +65,7 @@ int32 OS_NetworkGetID(void); * @param[in] name_len Maximum length of host name buffer * * @return Execution status, see @ref OSReturnCodes + * @retval #OS_SUCCESS @copybrief OS_SUCCESS * @retval #OS_ERR_INVALID_SIZE if the name_len is zero * @retval #OS_INVALID_POINTER if the host_name is NULL */ diff --git a/src/os/inc/osapi-queue.h b/src/os/inc/osapi-queue.h index 14f9387d4..874f368b7 100644 --- a/src/os/inc/osapi-queue.h +++ b/src/os/inc/osapi-queue.h @@ -50,10 +50,10 @@ typedef struct * the queue. Queue names must be unique; if the name already exists this * function fails. Names cannot be NULL. * - * @param[out] queue_id will be set to the non-zero ID of the newly-created resource - * @param[in] queue_name the name of the new resource to create + * @param[out] queue_id will be set to the non-zero ID of the newly-created resource @nonnull + * @param[in] queue_name the name of the new resource to create @nonnull * @param[in] queue_depth the maximum depth of the queue - * @param[in] data_size the size of each entry in the queue + * @param[in] data_size the size of each entry in the queue @nonzero * @param[in] flags options for the queue (reserved for future use, pass as 0) * * @return Execution status, see @ref OSReturnCodes @@ -84,7 +84,7 @@ int32 OS_QueueCreate(osal_id_t *queue_id, const char *queue_name, osal_blockcoun * @return Execution status, see @ref OSReturnCodes * @retval #OS_SUCCESS @copybrief OS_SUCCESS * @retval #OS_ERR_INVALID_ID if the id passed in does not exist - * @retval #OS_ERROR if the OS call to delete the queue fails + * @retval #OS_ERROR if the OS call returns an unexpected error @covtest */ int32 OS_QueueDelete(osal_id_t queue_id); @@ -96,9 +96,9 @@ int32 OS_QueueDelete(osal_id_t queue_id); * will block until a message arrives or the timeout expires. * * @param[in] queue_id The object ID to operate on - * @param[out] data The buffer to store the received message - * @param[in] size The size of the data buffer - * @param[out] size_copied Set to the actual size of the message + * @param[out] data The buffer to store the received message @nonnull + * @param[in] size The size of the data buffer @nonzero + * @param[out] size_copied Set to the actual size of the message @nonnull * @param[in] timeout The maximum amount of time to block, or OS_PEND to wait forever * * @return Execution status, see @ref OSReturnCodes @@ -108,6 +108,7 @@ int32 OS_QueueDelete(osal_id_t queue_id); * @retval #OS_QUEUE_EMPTY if the Queue has no messages on it to be recieved * @retval #OS_QUEUE_TIMEOUT if the timeout was OS_PEND and the time expired * @retval #OS_QUEUE_INVALID_SIZE if the size copied from the queue was not correct + * @retval #OS_ERROR if the OS call returns an unexpected error @covtest */ int32 OS_QueueGet(osal_id_t queue_id, void *data, size_t size, size_t *size_copied, int32 timeout); @@ -116,16 +117,17 @@ int32 OS_QueueGet(osal_id_t queue_id, void *data, size_t size, size_t *size_copi * @brief Put a message on a message queue. * * @param[in] queue_id The object ID to operate on - * @param[in] data The buffer containing the message to put - * @param[in] size The size of the data buffer + * @param[in] data The buffer containing the message to put @nonnull + * @param[in] size The size of the data buffer @nonzero * @param[in] flags Currently reserved/unused, should be passed as 0 * * @return Execution status, see @ref OSReturnCodes * @retval #OS_SUCCESS @copybrief OS_SUCCESS * @retval #OS_ERR_INVALID_ID if the queue id passed in is not a valid queue * @retval #OS_INVALID_POINTER if the data pointer is NULL + * @retval #OS_QUEUE_INVALID_SIZE if the data message is too large for the queue * @retval #OS_QUEUE_FULL if the queue cannot accept another message - * @retval #OS_ERROR if the OS call returns an error + * @retval #OS_ERROR if the OS call returns an unexpected error @covtest */ int32 OS_QueuePut(osal_id_t queue_id, const void *data, size_t size, uint32 flags); @@ -137,7 +139,7 @@ int32 OS_QueuePut(osal_id_t queue_id, const void *data, size_t size, uint32 flag * id of the queue is passed back in queue_id. * * @param[out] queue_id will be set to the ID of the existing resource - * @param[in] queue_name the name of the existing resource to find + * @param[in] queue_name the name of the existing resource to find @nonnull * * @return Execution status, see @ref OSReturnCodes * @retval #OS_SUCCESS @copybrief OS_SUCCESS @@ -155,7 +157,7 @@ int32 OS_QueueGetIdByName(osal_id_t *queue_id, const char *queue_name); * all of the relevant info (name and creator) about the specified queue. * * @param[in] queue_id The object ID to operate on - * @param[out] queue_prop The property object buffer to fill + * @param[out] queue_prop The property object buffer to fill @nonnull * * @return Execution status, see @ref OSReturnCodes * @retval #OS_SUCCESS @copybrief OS_SUCCESS diff --git a/src/os/inc/osapi-shell.h b/src/os/inc/osapi-shell.h index 613f75bc2..d01bbed9f 100644 --- a/src/os/inc/osapi-shell.h +++ b/src/os/inc/osapi-shell.h @@ -41,7 +41,7 @@ * Takes a shell command in and writes the output of that command to the specified file * The output file must be opened previously with write access (OS_WRITE_ONLY or OS_READ_WRITE). * - * @param[in] Cmd Command to pass to shell + * @param[in] Cmd Command to pass to shell @nonnull * @param[in] filedes File to send output to. * * @return Execution status, see @ref OSReturnCodes diff --git a/src/os/inc/osapi-task.h b/src/os/inc/osapi-task.h index eb9ab8301..d9ed32915 100644 --- a/src/os/inc/osapi-task.h +++ b/src/os/inc/osapi-task.h @@ -92,11 +92,11 @@ typedef osal_task((*osal_task_entry)(void)); /**< @brief For task entry point */ * the system heap. * * @param[out] task_id will be set to the non-zero ID of the newly-created resource - * @param[in] task_name the name of the new resource to create - * @param[in] function_pointer the entry point of the new task + * @param[in] task_name the name of the new resource to create @nonnull + * @param[in] function_pointer the entry point of the new task @nonnull * @param[in] stack_pointer pointer to the stack for the task, or NULL * to allocate a stack from the system memory heap - * @param[in] stack_size the size of the stack + * @param[in] stack_size the size of the stack @nonzero * @param[in] priority initial priority of the new task * @param[in] flags initial options for the new task * @@ -105,10 +105,10 @@ typedef osal_task((*osal_task_entry)(void)); /**< @brief For task entry point */ * @retval #OS_INVALID_POINTER if any of the necessary pointers are NULL * @retval #OS_ERR_INVALID_SIZE if the stack_size argument is zero * @retval #OS_ERR_NAME_TOO_LONG name length including null terminator greater than #OS_MAX_API_NAME - * @retval #OS_ERR_INVALID_PRIORITY if the priority is bad + * @retval #OS_ERR_INVALID_PRIORITY if the priority is bad @covtest * @retval #OS_ERR_NO_FREE_IDS if there can be no more tasks created * @retval #OS_ERR_NAME_TAKEN if the name specified is already used by a task - * @retval #OS_ERROR if an unspecified/other error occurs + * @retval #OS_ERROR if an unspecified/other error occurs @covtest */ int32 OS_TaskCreate(osal_id_t *task_id, const char *task_name, osal_task_entry function_pointer, osal_stackptr_t stack_pointer, size_t stack_size, osal_priority_t priority, uint32 flags); @@ -125,7 +125,7 @@ int32 OS_TaskCreate(osal_id_t *task_id, const char *task_name, osal_task_entry f * @return Execution status, see @ref OSReturnCodes * @retval #OS_SUCCESS @copybrief OS_SUCCESS * @retval #OS_ERR_INVALID_ID if the ID given to it is invalid - * @retval #OS_ERROR if the OS delete call fails + * @retval #OS_ERROR if the OS delete call fails @covtest */ int32 OS_TaskDelete(osal_id_t task_id); @@ -149,6 +149,7 @@ void OS_TaskExit(void); * @param[in] function_pointer function to be called when task exits * * @return Execution status, see @ref OSReturnCodes + * @retval #OS_ERR_INVALID_ID if the calling context is not an OSAL task */ int32 OS_TaskInstallDeleteHandler(osal_task_entry function_pointer); @@ -163,7 +164,7 @@ int32 OS_TaskInstallDeleteHandler(osal_task_entry function_pointer); * * @return Execution status, see @ref OSReturnCodes * @retval #OS_SUCCESS @copybrief OS_SUCCESS - * @retval #OS_ERROR if sleep fails or millisecond = 0 + * @retval #OS_ERROR if an unspecified/other error occurs @covtest */ int32 OS_TaskDelay(uint32 millisecond); @@ -172,14 +173,13 @@ int32 OS_TaskDelay(uint32 millisecond); * @brief Sets the given task to a new priority * * @param[in] task_id The object ID to operate on - * * @param[in] new_priority Set the new priority * * @return Execution status, see @ref OSReturnCodes * @retval #OS_SUCCESS @copybrief OS_SUCCESS * @retval #OS_ERR_INVALID_ID if the ID passed to it is invalid - * @retval #OS_ERR_INVALID_PRIORITY if the priority is greater than the max allowed - * @retval #OS_ERROR if the OS call to change the priority fails + * @retval #OS_ERR_INVALID_PRIORITY if the priority is greater than the max allowed @covtest + * @retval #OS_ERROR if an unspecified/other error occurs @covtest */ int32 OS_TaskSetPriority(osal_id_t task_id, osal_priority_t new_priority); @@ -200,7 +200,7 @@ osal_id_t OS_TaskGetId(void); * This function tries to find a task Id given the name of a task * * @param[out] task_id will be set to the ID of the existing resource - * @param[in] task_name the name of the existing resource to find + * @param[in] task_name the name of the existing resource to find @nonnull * * @return Execution status, see @ref OSReturnCodes * @retval #OS_SUCCESS @copybrief OS_SUCCESS @@ -219,7 +219,7 @@ int32 OS_TaskGetIdByName(osal_id_t *task_id, const char *task_name); * specified task. * * @param[in] task_id The object ID to operate on - * @param[out] task_prop The property object buffer to fill + * @param[out] task_prop The property object buffer to fill @nonnull * * @return Execution status, see @ref OSReturnCodes * @retval #OS_SUCCESS @copybrief OS_SUCCESS @@ -239,12 +239,12 @@ int32 OS_TaskGetInfo(osal_id_t task_id, OS_task_prop_t *task_prop); * but in some circumstances, such as exception handling, the OS may provide this information * directly to a BSP handler outside of the normal OSAL API. * - * @param[out] task_id The buffer where the task id output is stored + * @param[out] task_id The buffer where the task id output is stored @nonnull * @param[in] sysdata Pointer to the system-provided identification data * @param[in] sysdata_size Size of the system-provided identification data * * @return Execution status, see @ref OSReturnCodes - * @retval #OS_SUCCESS @copybrief OS_SUCCESS + * @retval #OS_SUCCESS @copybrief OS_SUCCESS @covtest * @retval #OS_INVALID_POINTER if a pointer argument is NULL */ int32 OS_TaskFindIdBySystemData(osal_id_t *task_id, const void *sysdata, size_t sysdata_size); diff --git a/src/os/inc/osapi-timebase.h b/src/os/inc/osapi-timebase.h index 0c5939feb..39b23e977 100644 --- a/src/os/inc/osapi-timebase.h +++ b/src/os/inc/osapi-timebase.h @@ -73,11 +73,14 @@ typedef struct * be configured to support at least (OS_MAX_TASKS + OS_MAX_TIMEBASES) threads, * to account for the helper threads associated with time base objects. * - * @param[out] timebase_id A non-zero ID corresponding to the timebase resource - * @param[in] timebase_name The name of the time base + * @param[out] timebase_id will be set to the non-zero ID of the newly-created resource @nonnull + * @param[in] timebase_name The name of the time base @nonnull * @param[in] external_sync A synchronization function for BSP hardware-based timer ticks * * @return Execution status, see @ref OSReturnCodes + * @retval #OS_SUCCESS @copybrief OS_SUCCESS + * @retval #OS_ERR_NAME_TAKEN if the name specified is already used + * @retval #OS_ERR_NO_FREE_IDS if there can be no more timebase resources created * @retval #OS_ERR_INCORRECT_OBJ_STATE if called from timer/timebase context * @retval #OS_ERR_NAME_TOO_LONG if the timebase_name is too long * @retval #OS_INVALID_POINTER if a pointer argument is NULL @@ -103,6 +106,8 @@ int32 OS_TimeBaseCreate(osal_id_t *timebase_id, const char *timebase_name, OS_Ti * @param[in] interval_time The amount of delay between ticks, in microseconds. * * @return Execution status, see @ref OSReturnCodes + * @retval #OS_SUCCESS @copybrief OS_SUCCESS + * @retval #OS_ERR_INVALID_ID if the id passed in is not a valid timebase * @retval #OS_ERR_INCORRECT_OBJ_STATE if called from timer/timebase context * @retval #OS_TIMER_ERR_INVALID_ARGS if start_time or interval_time are out of range */ @@ -118,6 +123,8 @@ int32 OS_TimeBaseSet(osal_id_t timebase_id, uint32 start_time, uint32 interval_t * @param[in] timebase_id The timebase resource to delete * * @return Execution status, see @ref OSReturnCodes + * @retval #OS_SUCCESS @copybrief OS_SUCCESS + * @retval #OS_ERR_INVALID_ID if the id passed in is not a valid timebase * @retval #OS_ERR_INCORRECT_OBJ_STATE if called from timer/timebase context */ int32 OS_TimeBaseDelete(osal_id_t timebase_id); @@ -128,8 +135,8 @@ int32 OS_TimeBaseDelete(osal_id_t timebase_id); * * Given a time base name, find and output the ID associated with it. * - * @param[out] timebase_id The timebase resource ID - * @param[in] timebase_name The name of the timebase resource to find + * @param[out] timebase_id will be set to the non-zero ID of the matching resource @nonnull + * @param[in] timebase_name The name of the timebase resource to find @nonnull * * @return Execution status, see @ref OSReturnCodes * @retval #OS_SUCCESS @copybrief OS_SUCCESS @@ -151,7 +158,7 @@ int32 OS_TimeBaseGetIdByName(osal_id_t *timebase_id, const char *timebase_name); * all of the relevant info( name and creator) about the specified timebase. * * @param[in] timebase_id The timebase resource ID - * @param[out] timebase_prop Buffer to store timebase properties + * @param[out] timebase_prop Buffer to store timebase properties @nonnull * * @return Execution status, see @ref OSReturnCodes * @retval #OS_SUCCESS @copybrief OS_SUCCESS @@ -185,7 +192,7 @@ int32 OS_TimeBaseGetInfo(osal_id_t timebase_id, OS_timebase_prop_t *timebase_pro * and calculate the difference between the consecutive samples. * * @param[in] timebase_id The timebase to operate on - * @param[out] freerun_val Buffer to store the free run counter + * @param[out] freerun_val Buffer to store the free run counter @nonnull * * @return Execution status, see @ref OSReturnCodes * @retval #OS_SUCCESS @copybrief OS_SUCCESS diff --git a/src/os/inc/osapi-timer.h b/src/os/inc/osapi-timer.h index 464e0f03c..4c10b3f4d 100644 --- a/src/os/inc/osapi-timer.h +++ b/src/os/inc/osapi-timer.h @@ -61,22 +61,20 @@ typedef struct * which is created and deleted with the timer object itself. The internal time base * is configured for an OS simulated timer tick at the same interval as the timer. * + * The callback function should be declared according to the OS_TimerCallback_t + * function pointer type. The timer_id value is passed to the callback function. + * * @note clock_accuracy comes from the underlying OS tick value. The nearest integer * microsecond value is returned, so may not be exact. * - * @warning Depending on the OS, the callback_ptr function may be similar to an - * interrupt service routine. Calls that cause the code to block or require - * an application context (like sending events) are generally not supported. + * @sa OS_TimerCallback_t * - * @param[out] timer_id The non-zero resource ID of the timer object - * @param[in] timer_name Name of the timer object + * @param[out] timer_id Will be set to the non-zero resource ID of the timer object @nonnull + * @param[in] timer_name Name of the timer object @nonnull * @param[out] clock_accuracy Expected precision of the timer, in microseconds. This * is the underlying tick value rounded to the nearest - * microsecond integer. - * @param[in] callback_ptr The function pointer of the timer callback or ISR that - * will be called by the timer. The user’s function is - * declared as follows: void timer_callback(uint32 timer_id) - * Where the timer_id is passed in to the function by the OSAL + * microsecond integer. @nonnull + * @param[in] callback_ptr The function pointer of the timer callback @nonnull. * * @return Execution status, see @ref OSReturnCodes * @retval #OS_SUCCESS @copybrief OS_SUCCESS @@ -84,8 +82,8 @@ typedef struct * @retval #OS_ERR_NAME_TOO_LONG name length including null terminator greater than #OS_MAX_API_NAME * @retval #OS_ERR_NAME_TAKEN if the name is already in use by another timer. * @retval #OS_ERR_NO_FREE_IDS if all of the timers are already allocated. - * @retval #OS_TIMER_ERR_INVALID_ARGS if the callback pointer is zero. - * @retval #OS_TIMER_ERR_UNAVAILABLE if the timer cannot be created. + * @retval #OS_ERR_INCORRECT_OBJ_STATE if invoked from a timer context + * @retval #OS_TIMER_ERR_INTERNAL if there was an error programming the OS timer @covtest */ int32 OS_TimerCreate(osal_id_t *timer_id, const char *timer_name, uint32 *clock_accuracy, OS_TimerCallback_t callback_ptr); @@ -106,17 +104,28 @@ int32 OS_TimerCreate(osal_id_t *timer_id, const char *timer_name, uint32 *clock_ * allowing a single opaque argument to be passed to the callback routine. * The OSAL implementation does not use this parameter, and may be set NULL. * - * @warning Depending on the OS, the callback_ptr function may be similar to an - * interrupt service routine. Calls that cause the code to block or require - * an application context (like sending events) are generally not supported. + * The callback function for this method should be declared according to the + * OS_ArgCallback_t function pointer type. The timer_id is passed in to the + * function by the OSAL, and the arg parameter is passed through from the + * callback_arg argument on this call. + * + * @sa OS_ArgCallback_t * - * @param[out] timer_id The non-zero resource ID of the timer object - * @param[in] timer_name Name of the timer object + * @param[out] timer_id Will be set to the non-zero resource ID of the timer object @nonnull + * @param[in] timer_name Name of the timer object @nonnull * @param[in] timebase_id The time base resource to use as a reference - * @param[in] callback_ptr Application-provided function to invoke - * @param[in] callback_arg Opaque argument to pass to callback function + * @param[in] callback_ptr Application-provided function to invoke @nonnull + * @param[in] callback_arg Opaque argument to pass to callback function, may be NULL * * @return Execution status, see @ref OSReturnCodes + * @retval #OS_SUCCESS @copybrief OS_SUCCESS + * @retval #OS_INVALID_POINTER if any parameters are NULL + * @retval #OS_ERR_INVALID_ID if the timebase_id parameter is not valid + * @retval #OS_ERR_NAME_TOO_LONG name length including null terminator greater than #OS_MAX_API_NAME + * @retval #OS_ERR_NAME_TAKEN if the name is already in use by another timer. + * @retval #OS_ERR_NO_FREE_IDS if all of the timers are already allocated. + * @retval #OS_ERR_INCORRECT_OBJ_STATE if invoked from a timer context + * @retval #OS_TIMER_ERR_INTERNAL if there was an error programming the OS timer @covtest */ int32 OS_TimerAdd(osal_id_t *timer_id, const char *timer_name, osal_id_t timebase_id, OS_ArgCallback_t callback_ptr, void *callback_arg); @@ -149,10 +158,9 @@ int32 OS_TimerAdd(osal_id_t *timer_id, const char *timer_name, osal_id_t timebas * @return Execution status, see @ref OSReturnCodes * @retval #OS_SUCCESS @copybrief OS_SUCCESS * @retval #OS_ERR_INVALID_ID if the timer_id is not valid. - * @retval #OS_TIMER_ERR_INTERNAL if there was an error programming the OS timer. - * @retval #OS_ERROR if both start time and interval time are zero. + * @retval #OS_TIMER_ERR_INTERNAL if there was an error programming the OS timer @covtest * @retval #OS_ERR_INCORRECT_OBJ_STATE if called from timer/timebase context - * @retval #OS_TIMER_ERR_INVALID_ARGS if the start_time or interval_time is out of range + * @retval #OS_TIMER_ERR_INVALID_ARGS if the start_time or interval_time is out of range, or both 0 */ int32 OS_TimerSet(osal_id_t timer_id, uint32 start_time, uint32 interval_time); @@ -168,7 +176,7 @@ int32 OS_TimerSet(osal_id_t timer_id, uint32 start_time, uint32 interval_time); * @return Execution status, see @ref OSReturnCodes * @retval #OS_SUCCESS @copybrief OS_SUCCESS * @retval #OS_ERR_INVALID_ID if the timer_id is invalid. - * @retval #OS_TIMER_ERR_INTERNAL if there was a problem deleting the timer in the host OS. + * @retval #OS_TIMER_ERR_INTERNAL if there was a problem deleting the timer in the host OS @covtest * @retval #OS_ERR_INCORRECT_OBJ_STATE if called from timer/timebase context */ int32 OS_TimerDelete(osal_id_t timer_id); @@ -179,8 +187,8 @@ int32 OS_TimerDelete(osal_id_t timer_id); * * Outputs the ID associated with the given timer, if it exists. * - * @param[out] timer_id The timer ID corresponding to the name - * @param[in] timer_name The timer name to find + * @param[out] timer_id Will be set to the timer ID corresponding to the name @nonnull + * @param[in] timer_name The timer name to find @nonnull * * @return Execution status, see @ref OSReturnCodes * @retval #OS_SUCCESS @copybrief OS_SUCCESS @@ -199,7 +207,7 @@ int32 OS_TimerGetIdByName(osal_id_t *timer_id, const char *timer_name); * information known about that timer into a structure pointer to by timer_prop. * * @param[in] timer_id The timer ID to operate on - * @param[out] timer_prop Buffer containing timer properties + * @param[out] timer_prop Buffer containing timer properties @nonnull * - creator: the OS task ID of the task that created this timer * - name: the string name of the timer * - start_time: the start time in microseconds, if any diff --git a/src/os/inc/osapi-version.h b/src/os/inc/osapi-version.h index 2ce89d3a7..b9925b89d 100644 --- a/src/os/inc/osapi-version.h +++ b/src/os/inc/osapi-version.h @@ -21,9 +21,11 @@ /** * \file * - * Provide version identifiers for cFS' Operating System Abstraction Layer - * See @ref cfsversions for version and build number and description + * Provide version identifiers for Operating System Abstraction Layer * + * @note OSAL follows the same version semantics as cFS, which in + * turn is based on the Semantic Versioning 2.0 Specification. For + * more information, see the documentation provided with cFE. */ #ifndef OSAPI_VERSION_H @@ -34,7 +36,7 @@ /* * Development Build Macro Definitions */ -#define OS_BUILD_NUMBER 458 +#define OS_BUILD_NUMBER 501 #define OS_BUILD_BASELINE "v5.1.0-rc1" /* @@ -60,7 +62,6 @@ /*! @brief Development Build Version Number. * @details Baseline git tag + Number of commits since baseline. @n - * See @ref cfsversions for format differences between development and release versions. */ #define OS_VERSION OS_BUILD_BASELINE "+dev" OS_STR(OS_BUILD_NUMBER) @@ -71,7 +72,7 @@ /*! @brief Development Build Version String. * @details Reports the current development build's baseline, number, and name. Also includes a note about the latest - * official version. @n See @ref cfsversions for format differences between development and release versions. + * official version. */ #define OS_VERSION_STRING \ " OSAL Development Build\n" \ diff --git a/src/os/shared/src/osapi-idmap.c b/src/os/shared/src/osapi-idmap.c index cd05f5f0c..f343df644 100644 --- a/src/os/shared/src/osapi-idmap.c +++ b/src/os/shared/src/osapi-idmap.c @@ -23,9 +23,8 @@ * \ingroup shared * \author joseph.p.hickey@nasa.gov * - * This file contains utility functions to interpret OSAL IDs - * in a generic/common manner. They are used internally within - * OSAL by all the various modules. + * This file contains utility functions to manipulate/interpret OSAL IDs + * in a generic/common manner. * * In order to add additional verification capabilities, each class of fundamental * objects will use its own ID space within the 32-bit integer ID value. This way @@ -35,11 +34,8 @@ * These functions provide a consistent way to validate a 32-bit OSAL ID as * well as determine its internal type and index. * - * The map/unmap functions are not part of the public API -- applications - * should be treating OSAL IDs as opaque objects. - * - * NOTE: The only exception is OS_ConvertToArrayIndex() as this is necessary to - * assist applications when storing OSAL IDs in a table. + * NOTE: This file includes local helpers, OSAL scope, and public API implementations + * as documented in the function headers */ /**************************************************************************************** @@ -1393,7 +1389,7 @@ int32 OS_ObjectIdIteratorProcessEntry(OS_object_iter_t *iter, int32 (*func)(osal *-----------------------------------------------------------------*/ int32 OS_ConvertToArrayIndex(osal_id_t object_id, osal_index_t *ArrayIndex) { - /* just pass to the generic internal conversion routine */ + /* pass to conversion routine with undefined type */ return OS_ObjectIdToArrayIndex(OS_OBJECT_TYPE_UNDEFINED, object_id, ArrayIndex); } /* end OS_ConvertToArrayIndex */ @@ -1513,15 +1509,8 @@ int32 OS_GetResourceName(osal_id_t object_id, char *buffer, size_t buffer_size) * * Function: OS_ObjectIdToArrayIndex * - * Purpose: Convert an object ID (which must be of the given type) to a number suitable - * for use as an array index. The array index will be in the range of: - * 0 <= ArrayIndex < OS_MAX_ - * - * If the passed-in ID type is OS_OBJECT_TYPE_UNDEFINED, then any type - * is allowed. - * - * returns: If the passed-in ID is not of the proper type, OS_ERROR is returned - * Otherwise OS_SUCCESS is returned. + * Purpose: Implemented per public OSAL API + * See description in API and header file for detail * *-----------------------------------------------------------------*/ int32 OS_ObjectIdToArrayIndex(osal_objtype_t idtype, osal_id_t object_id, osal_index_t *ArrayIndex) diff --git a/src/os/shared/src/osapi-time.c b/src/os/shared/src/osapi-time.c index df92e6a58..c196ec003 100644 --- a/src/os/shared/src/osapi-time.c +++ b/src/os/shared/src/osapi-time.c @@ -315,7 +315,7 @@ int32 OS_TimerSet(osal_id_t timer_id, uint32 start_time, uint32 interval_time) ARGCHECK(start_time < (UINT32_MAX / 2), OS_TIMER_ERR_INVALID_ARGS); ARGCHECK(interval_time < (UINT32_MAX / 2), OS_TIMER_ERR_INVALID_ARGS); - ARGCHECK(start_time != 0 || interval_time != 0, OS_ERROR); + ARGCHECK(start_time != 0 || interval_time != 0, OS_TIMER_ERR_INVALID_ARGS); /* * Check our context. Not allowed to use the timer API from a timer callback. diff --git a/src/tests/time-base-api-test/time-base-api-test.c b/src/tests/time-base-api-test/time-base-api-test.c index 775b5229a..e3057a778 100644 --- a/src/tests/time-base-api-test/time-base-api-test.c +++ b/src/tests/time-base-api-test/time-base-api-test.c @@ -35,8 +35,34 @@ #include "uttest.h" #include "utbsp.h" +static int32 SyncTimeBaseCreateRc = 0; +static int32 SyncTimeBaseDeleteRc = 0; +static int32 SyncTimeBaseSetRc = 0; +static int32 SyncTimeBaseGetByNameRc = 0; +static int32 SyncTimeBaseGetInfoRc = 0; + +static OS_timebase_prop_t SyncTimeBaseProp; + +static uint32 NumSyncs = 0; + static uint32 UT_TimerSync(osal_id_t timer_id) { + /* + * Calls to time base configuration from the context of a sync function + * should be rejected with OS_ERR_INCORRECT_OBJ_STATE. However because + * UtAssert is not fully thread-safe, this does not assert here, it just + * calls the various functions on the first time through and stores the + * result, which is checked/asserted in the main task. + */ + if (NumSyncs == 0) + { + SyncTimeBaseCreateRc = OS_TimeBaseCreate(&timer_id, "sync", 0); + SyncTimeBaseDeleteRc = OS_TimeBaseDelete(timer_id); + SyncTimeBaseSetRc = OS_TimeBaseSet(timer_id, 100, 100); + SyncTimeBaseGetByNameRc = OS_TimeBaseGetIdByName(&timer_id, "TimeBaseC"); + SyncTimeBaseGetInfoRc = OS_TimeBaseGetInfo(timer_id, &SyncTimeBaseProp); + } + ++NumSyncs; OS_TaskDelay(1); return 1; } @@ -47,15 +73,12 @@ void TestTimeBaseApi(void) { int32 expected; int32 actual; - int32 TimeBaseNum; - int32 tbc_results[OS_MAX_TIMEBASES]; uint32 freerun; osal_id_t objid; osal_id_t time_base_id; osal_id_t time_base_id2; osal_id_t tb_id[OS_MAX_TIMEBASES]; - char overMaxTimeBase[12]; - char TimeBaseIter[OS_MAX_TIMEBASES][12]; + char timebase_name[OS_MAX_API_NAME + 5]; OS_timebase_prop_t timebase_prop; /* @@ -63,33 +86,6 @@ void TestTimeBaseApi(void) * int32 OS_TimeBaseCreate(uint32 *timer_id, const char *timebase_name, OS_TimerSync_t external_sync) */ - /* Test for nominal inputs */ - expected = OS_SUCCESS; - - actual = OS_TimeBaseCreate(&time_base_id, "TimeBaseA", 0); - UtAssert_True(actual == expected, "OS_TimeBaseCreate() (%ld) == OS_SUCCESS", (long)actual); - - actual = OS_TimeBaseCreate(&time_base_id2, "TimeBaseB", NULL); - UtAssert_True(actual == expected, "OS_TimeBaseCreate() (%ld) == OS_SUCCESS", (long)actual); - - actual = OS_TimeBaseCreate(&time_base_id, "TimeBaseC", UT_TimerSync); - UtAssert_True(actual == expected, "OS_TimeBaseCreate() (%ld) == OS_SUCCESS", (long)actual); - - /* Test for nominal, max/min cases */ - objid = OS_OBJECT_ID_UNDEFINED; - actual = OS_TimeBaseCreate(&objid, "TimeBaseD", 0); - UtAssert_True(actual == expected, "OS_TimeBaseCreate() (%ld) == OS_SUCCESS", (long)actual); - - /* Checking for OS_MAX_TIMEBASES */ - for (int i = 0; i < OS_MAX_TIMEBASES; i++) - { - snprintf(TimeBaseIter[i], 12, "TimeBase%d", i); - tbc_results[i] = OS_TimeBaseCreate(&tb_id[i], TimeBaseIter[i], 0); - UtAssert_True(tbc_results[i] == expected, "OS_TimeBaseCreate() (%ld) == OS_SUCCESS", (long)actual); - - OS_TimeBaseDelete(tb_id[i]); - } - /* Test for invalid inputs */ expected = OS_INVALID_POINTER; actual = OS_TimeBaseCreate(NULL, NULL, NULL); @@ -103,21 +99,64 @@ void TestTimeBaseApi(void) actual = OS_TimeBaseCreate(&time_base_id, NULL, 0); UtAssert_True(actual == expected, "OS_TimeBaseCreate() (%ld) == OS_INVALID_POINTER", (long)actual); - expected = OS_ERR_NAME_TAKEN; - actual = OS_TimeBaseCreate(&time_base_id, "TimeBaseA", 0); - UtAssert_True(actual == expected, "OS_TimeBaseCreate() (%ld) == OS_ERR_NAME_TAKEN", (long)actual); + memset(timebase_name, 'x', sizeof(timebase_name)); + timebase_name[sizeof(timebase_name) - 1] = 0; + UtAssert_INT32_EQ(OS_TimeBaseCreate(&time_base_id, timebase_name, 0), OS_ERR_NAME_TOO_LONG); - /* Checking OS_MAX_TIMEBASES + 1 */ + /* Checking for OS_MAX_TIMEBASES */ for (int i = 0; i < OS_MAX_TIMEBASES; i++) { - snprintf(TimeBaseIter[i], sizeof(TimeBaseIter[i]), "TimeBase%d", i); - tbc_results[i] = OS_TimeBaseCreate(&tb_id[i], TimeBaseIter[i], 0); + /* On the final setup pass, while there is still one free slot, + * check attempting to create a duplicate name (index 0) - this + * should be rejected and _not_ consume the last empty slot */ + if (i == (OS_MAX_TIMEBASES - 1)) + { + UtAssert_INT32_EQ(OS_TimeBaseCreate(&time_base_id, "TimeBase0", 0), OS_ERR_NAME_TAKEN); + } + + snprintf(timebase_name, sizeof(timebase_name), "TimeBase%d", i); + UtAssert_INT32_EQ(OS_TimeBaseCreate(&tb_id[i], timebase_name, 0), OS_SUCCESS); } - TimeBaseNum = OS_MAX_TIMEBASES + 1; - snprintf(overMaxTimeBase, sizeof(overMaxTimeBase), "TimeBase%d", (int)TimeBaseNum); - expected = OS_ERR_NO_FREE_IDS; - actual = OS_TimeBaseCreate(&time_base_id, "overMaxTimeBase", 0); - UtAssert_True(actual == expected, "OS_TimeBaseCreate() (%ld) == OS_ERR_NO_FREE_IDS", (long)actual); + + /* Checking OS_MAX_TIMEBASES + 1 */ + UtAssert_INT32_EQ(OS_TimeBaseCreate(&time_base_id, "overMaxTimeBase", 0), OS_ERR_NO_FREE_IDS); + + /* reset test environment */ + OS_DeleteAllObjects(); + + /* Test for nominal inputs - these resources are used for the remainder of test */ + expected = OS_SUCCESS; + + actual = OS_TimeBaseCreate(&time_base_id, "TimeBaseA", 0); + UtAssert_True(actual == expected, "OS_TimeBaseCreate() (%ld) == OS_SUCCESS", (long)actual); + + actual = OS_TimeBaseCreate(&time_base_id2, "TimeBaseB", NULL); + UtAssert_True(actual == expected, "OS_TimeBaseCreate() (%ld) == OS_SUCCESS", (long)actual); + + actual = OS_TimeBaseCreate(&time_base_id, "TimeBaseC", UT_TimerSync); + UtAssert_True(actual == expected, "OS_TimeBaseCreate() (%ld) == OS_SUCCESS", (long)actual); + + /* Let the TimeBaseC accumulate at least one sync, so it will + * attempt to call timebase APIs from its own context. */ + while (NumSyncs == 0) + { + OS_TaskDelay(1); + } + + /* Check that those configuration attempts all returned OS_ERR_INCORRECT_OBJ_STATE */ + UtAssert_True(SyncTimeBaseCreateRc == OS_ERR_INCORRECT_OBJ_STATE, + "OS_TimeBaseCreate(&timer_id, \"sync\", 0) (%d) == OS_ERR_INCORRECT_OBJ_STATE", + (int)SyncTimeBaseCreateRc); + UtAssert_True(SyncTimeBaseDeleteRc == OS_ERR_INCORRECT_OBJ_STATE, + "OS_TimeBaseDelete(timer_id) (%d) == OS_ERR_INCORRECT_OBJ_STATE", (int)SyncTimeBaseDeleteRc); + UtAssert_True(SyncTimeBaseSetRc == OS_ERR_INCORRECT_OBJ_STATE, + "OS_TimeBaseSet(timer_id, 100, 100) (%d) == OS_ERR_INCORRECT_OBJ_STATE", (int)SyncTimeBaseSetRc); + UtAssert_True(SyncTimeBaseGetByNameRc == OS_ERR_INCORRECT_OBJ_STATE, + "OS_TimeBaseGetIdByName(&timer_id, \"TimeBaseC\") (%d) == OS_ERR_INCORRECT_OBJ_STATE", + (int)SyncTimeBaseGetByNameRc); + UtAssert_True(SyncTimeBaseGetInfoRc == OS_ERR_INCORRECT_OBJ_STATE, + "OS_TimeBaseGetInfo(timer_id, &SyncTimeBaseProp) (%d) == OS_ERR_INCORRECT_OBJ_STATE", + (int)SyncTimeBaseGetInfoRc); /* * Test Case For: @@ -192,9 +231,13 @@ void TestTimeBaseApi(void) UtAssert_True(!OS_ObjectIdDefined(objid), "OS_TimeBaseGetIdByName() objid (%lu) still OS_OBJECT_ID_UNDEFINED", OS_ObjectIdToInteger(objid)); - expected = OS_INVALID_POINTER; - actual = OS_TimeBaseGetIdByName(NULL, NULL); - UtAssert_True(actual == expected, "OS_TimeBaseGetIdByName() (%ld) == OS_INVALID_POINTER", (long)actual); + /* check each pointer input individually */ + UtAssert_INT32_EQ(OS_TimeBaseGetIdByName(NULL, "NF"), OS_INVALID_POINTER); + UtAssert_INT32_EQ(OS_TimeBaseGetIdByName(&objid, NULL), OS_INVALID_POINTER); + + memset(timebase_name, 'x', sizeof(timebase_name)); + timebase_name[sizeof(timebase_name) - 1] = 0; + UtAssert_INT32_EQ(OS_TimeBaseGetIdByName(&objid, timebase_name), OS_ERR_NAME_TOO_LONG); /* * Test Case For: @@ -214,7 +257,7 @@ void TestTimeBaseApi(void) UtAssert_True(!OS_ObjectIdDefined(timebase_prop.creator), "timebase_prop.creator (%lu) undefined", OS_ObjectIdToInteger(timebase_prop.creator)); - UtAssert_True(strcmp(timebase_prop.name, "TimeBaseB") == 0, "timebase_prop.name (%s) == TimeBase2", + UtAssert_True(strcmp(timebase_prop.name, "TimeBaseB") == 0, "timebase_prop.name (%s) == TimeBaseB", timebase_prop.name); UtAssert_True(timebase_prop.nominal_interval_time == 0, "timebase_prop.nominal_interval_time (%lu) == 0", (unsigned long)timebase_prop.nominal_interval_time); @@ -249,6 +292,9 @@ void TestTimeBaseApi(void) actual = OS_TimeBaseGetFreeRun(time_base_id2, &freerun); UtAssert_True(actual == expected, "OS_TimeBaseGetFreeRun() (%ld) == OS_SUCCESS", (long)actual); + UtAssert_INT32_EQ(OS_TimeBaseGetFreeRun(OS_OBJECT_ID_UNDEFINED, &freerun), OS_ERR_INVALID_ID); + UtAssert_INT32_EQ(OS_TimeBaseGetFreeRun(time_base_id2, NULL), OS_INVALID_POINTER); + /* Test for invalid inputs */ expected = OS_ERR_INVALID_ID; freerun = 0xFFFFFFFF; diff --git a/src/tests/timer-add-api-test/timer-add-api-test.c b/src/tests/timer-add-api-test/timer-add-api-test.c index 917db9e8d..d80cc5656 100644 --- a/src/tests/timer-add-api-test/timer-add-api-test.c +++ b/src/tests/timer-add-api-test/timer-add-api-test.c @@ -73,7 +73,8 @@ void TestTimerAddApi(void) osal_id_t time_base_id; int i = 0; int32 TimerStatus[NUMBER_OF_TIMERS]; - osal_id_t TimerID[NUMBER_OF_TIMERS]; + osal_id_t TimerID[OS_MAX_TIMERS]; + char temp_name[OS_MAX_API_NAME + 5]; char TimerName[NUMBER_OF_TIMERS][20] = {"TIMER1", "TIMER2", "TIMER3", "TIMER4"}; uint32 microsecs; @@ -87,11 +88,28 @@ void TestTimerAddApi(void) expected = OS_SUCCESS; UtAssert_True(tbs_ret_val == expected, "OS_TimeBaseSet() (%ld) == OS_SUCCESS", (long)tbs_ret_val); + memset(temp_name, 'x', sizeof(temp_name) - 1); + temp_name[sizeof(temp_name) - 1] = 0; + UtAssert_INT32_EQ(OS_TimerAdd(&timer_id, temp_name, time_base_id, &null_func, NULL), OS_ERR_NAME_TOO_LONG); + + for (i = 0; i < OS_MAX_TIMERS; i++) + { + snprintf(temp_name, sizeof(temp_name), "Timer%d", i); + UtAssert_INT32_EQ(OS_TimerAdd(&TimerID[i], temp_name, time_base_id, &null_func, NULL), OS_SUCCESS); + UtPrintf("Timer %d Created ID=%lx", i, OS_ObjectIdToInteger(TimerID[i])); + } + + UtAssert_INT32_EQ(OS_TimerAdd(&timer_id, "TooMany", time_base_id, &null_func, NULL), OS_ERR_NO_FREE_IDS); + for (i = 0; i < OS_MAX_TIMERS; i++) + { + UtAssert_INT32_EQ(OS_TimerDelete(TimerID[i]), OS_SUCCESS); + } + for (i = 0; i < NUMBER_OF_TIMERS; i++) { - TimerStatus[i] = OS_TimerAdd(&TimerID[i], TimerName[i], time_base_id, &counter_func, &timer_counter[i]); - UtAssert_True(TimerStatus[i] == OS_SUCCESS, "Timer %d Created RC=%d ID=%lx", i, (int)TimerStatus[i], - OS_ObjectIdToInteger(TimerID[i])); + UtAssert_INT32_EQ(OS_TimerAdd(&TimerID[i], TimerName[i], time_base_id, &counter_func, &timer_counter[i]), + OS_SUCCESS); + UtPrintf("Timer %d Created ID=%lx", i, OS_ObjectIdToInteger(TimerID[i])); } /* Sample the clock now, before starting any timer */ diff --git a/src/unit-test-coverage/shared/src/coveragetest-time.c b/src/unit-test-coverage/shared/src/coveragetest-time.c index 00c541e07..baf4c4a0d 100644 --- a/src/unit-test-coverage/shared/src/coveragetest-time.c +++ b/src/unit-test-coverage/shared/src/coveragetest-time.c @@ -170,9 +170,9 @@ void Test_OS_TimerSet(void) * Test Case For: * int32 OS_TimerSet(uint32 timer_id, uint32 start_time, uint32 interval_time) */ - int32 expected = OS_ERROR; + int32 expected = OS_TIMER_ERR_INVALID_ARGS; int32 actual = OS_TimerSet(UT_OBJID_1, 0, 0); - UtAssert_True(actual == expected, "OS_TimerSet() (%ld) == OS_ERROR", (long)actual); + UtAssert_True(actual == expected, "OS_TimerSet() (%ld) == OS_TIMER_ERR_INVALID_ARGS", (long)actual); expected = OS_SUCCESS; actual = OS_TimerSet(UT_OBJID_1, 0, 1); diff --git a/src/unit-tests/inc/ut_os_support.h b/src/unit-tests/inc/ut_os_support.h index 1b3f59e0a..02af50308 100644 --- a/src/unit-tests/inc/ut_os_support.h +++ b/src/unit-tests/inc/ut_os_support.h @@ -73,6 +73,13 @@ static inline bool UtOsalRetVal(int32 Fn, int32 Exp, bool NotImplAllowed, UtAsse return UtAssertEx(Fn == Exp, casetype, File, Line, "%s (%d) == %s (%d)", FnTxt, (int)Fn, ExpTxt, (int)Exp); } +static inline bool UtOsalNotSuccess(int32 Fn, UtAssert_CaseType_t casetype, const char *File, uint32 Line, + const char *FnTxt) +{ + /* Check result is negative to support APIs that return nonzero on success (e.g. read/write) */ + return UtAssertEx(Fn < 0, casetype, File, Line, "%s (%d) not successful", FnTxt, (int)Fn); +} + static inline bool UtManualInspectionWithStatus(int32 Fn, const char *File, uint32 Line, const char *FnTxt) { UtAssertEx(false, UTASSERT_CASETYPE_MIR, File, Line, "%s value=%d", FnTxt, (int)Fn); @@ -107,6 +114,7 @@ static inline bool UtOsalImplemented(int32 Fn, const char *File, uint32 Line) UtOsalRetVal(Fn, OS_SUCCESS, false, UTASSERT_CASETYPE_FAILURE, __FILE__, __LINE__, #Fn, "OS_SUCCESS") #define UT_NOMINAL_OR_NOTIMPL(Fn) \ UtOsalRetVal(Fn, OS_SUCCESS, true, UTASSERT_CASETYPE_FAILURE, __FILE__, __LINE__, #Fn, "OS_SUCCESS") +#define UT_NOT_SUCCESS(Fn) UtOsalNotSuccess(Fn, UTASSERT_CASETYPE_FAILURE, __FILE__, __LINE__, #Fn) #define UT_MIR_STATUS(Fn) UtManualInspectionWithStatus(Fn, __FILE__, __LINE__, #Fn) #define UT_MIR_VOID(Fn) Fn, UtAssertEx(false, UTASSERT_CASETYPE_MIR, __FILE__, __LINE__, "%s", #Fn) diff --git a/src/unit-tests/oscore-test/ut_oscore_misc_test.c b/src/unit-tests/oscore-test/ut_oscore_misc_test.c index 9bea12c08..f45994476 100644 --- a/src/unit-tests/oscore-test/ut_oscore_misc_test.c +++ b/src/unit-tests/oscore-test/ut_oscore_misc_test.c @@ -98,10 +98,17 @@ void UT_os_apiinit_test() /*-----------------------------------------------------*/ /* #1 Init-not-call-first */ - UT_RETVAL(OS_QueueCreate(&qId, "Queue A", qDepth, qSize, qFlags), OS_ERROR); - UT_RETVAL(OS_BinSemCreate(&semIds[0], "BinSem 1", semInitValue, semOptions), OS_ERROR); - UT_RETVAL(OS_CountSemCreate(&semIds[1], "CountSem 1", semInitValue, semOptions), OS_ERROR); - UT_RETVAL(OS_MutSemCreate(&semIds[2], "MutexSem 1", semOptions), OS_ERROR); + /* + * Note that OS_API_Init() is supposed to be the first function invoked, + * calling any other OSAL API before this is technically undefined behavior. + * There is code to check for errors in this regard so this just tests that + * the result is _not_ success. The specific status code if called before + * OS_API_Init is not documented. + */ + UT_NOT_SUCCESS(OS_QueueCreate(&qId, "Queue A", qDepth, qSize, qFlags)); + UT_NOT_SUCCESS(OS_BinSemCreate(&semIds[0], "BinSem 1", semInitValue, semOptions)); + UT_NOT_SUCCESS(OS_CountSemCreate(&semIds[1], "CountSem 1", semInitValue, semOptions)); + UT_NOT_SUCCESS(OS_MutSemCreate(&semIds[2], "MutexSem 1", semOptions)); /*-----------------------------------------------------*/ /* #2 Nominal */ @@ -120,6 +127,26 @@ void UT_os_apiinit_test() UT_TEARDOWN(OS_MutSemDelete(semIds[2])); } +/*--------------------------------------------------------------------------------* +** Syntax: int32 OS_RegisterEventHandler(OS_EventHandler_t handler) +** See header file for list of return values +**--------------------------------------------------------------------------------*/ +int32 UT_os_eventhandler(OS_Event_t event, osal_id_t object_id, void *data) +{ + return OS_SUCCESS; +} + +void UT_os_registereventhandler_test() +{ + /*-----------------------------------------------------*/ + /* #1 Null-pointer-arg */ + UT_RETVAL(OS_RegisterEventHandler(NULL), OS_INVALID_POINTER); + + /*-----------------------------------------------------*/ + /* #2 Nominal */ + UT_NOMINAL(OS_RegisterEventHandler(UT_os_eventhandler)); +} + /*--------------------------------------------------------------------------------* ** Syntax: void OS_printf(const char String, ...) ** Purpose: Provides a printing utility similar to printf @@ -295,7 +322,7 @@ void UT_os_setlocaltime_test() /*-----------------------------------------------------*/ /* #1 Null-pointer-arg */ - UT_RETVAL(OS_GetLocalTime(NULL), OS_INVALID_POINTER); + UT_RETVAL(OS_SetLocalTime(NULL), OS_INVALID_POINTER); /*-----------------------------------------------------*/ /* #3 Nominal */ @@ -418,23 +445,15 @@ void UT_os_heapgetinfo_test(void) { OS_heap_prop_t heapProp; - /*-----------------------------------------------------*/ - /* API not implemented */ - - if (!UT_IMPL(OS_HeapGetInfo(&heapProp))) - { - return; - } - /*-----------------------------------------------------*/ /* #1 Null-pointer-arg */ UT_RETVAL(OS_HeapGetInfo(NULL), OS_INVALID_POINTER); /*-----------------------------------------------------*/ - /* #3 Nominal */ + /* #3 Nominal (allows for not implemented) */ - UT_NOMINAL(OS_HeapGetInfo(&heapProp)); + UT_NOMINAL_OR_NOTIMPL(OS_HeapGetInfo(&heapProp)); } /*================================================================================* diff --git a/src/unit-tests/oscore-test/ut_oscore_misc_test.h b/src/unit-tests/oscore-test/ut_oscore_misc_test.h index 02864f319..71483832f 100644 --- a/src/unit-tests/oscore-test/ut_oscore_misc_test.h +++ b/src/unit-tests/oscore-test/ut_oscore_misc_test.h @@ -55,6 +55,7 @@ **--------------------------------------------------------------------------------*/ void UT_os_apiinit_test(void); +void UT_os_registereventhandler_test(void); void UT_os_printf_test(void); void UT_os_printfenable_test(void); diff --git a/src/unit-tests/oscore-test/ut_oscore_queue_test.c b/src/unit-tests/oscore-test/ut_oscore_queue_test.c index 33edadafa..f69faa716 100644 --- a/src/unit-tests/oscore-test/ut_oscore_queue_test.c +++ b/src/unit-tests/oscore-test/ut_oscore_queue_test.c @@ -87,6 +87,14 @@ void UT_os_queue_create_test() UT_RETVAL(OS_QueueCreate(&queue_id, NULL, OSAL_BLOCKCOUNT_C(10), sizeof(uint32), 0), OS_INVALID_POINTER); + /*-----------------------------------------------------*/ + + /* Invalid item size */ + UT_RETVAL(OS_QueueCreate(&queue_id, "Queue1", OSAL_BLOCKCOUNT_C(10), 0, 0), OS_ERR_INVALID_SIZE); + /* Invalid depth */ + UT_RETVAL(OS_QueueCreate(&queue_id, "Queue1", OSAL_BLOCKCOUNT_C(OS_QUEUE_MAX_DEPTH + 1), sizeof(uint32), 0), + OS_QUEUE_INVALID_SIZE); + /*-----------------------------------------------------*/ /* #3 Name-too-long */ @@ -304,6 +312,7 @@ void UT_os_queue_put_test() if (UT_SETUP(OS_QueueCreate(&queue_id, "QueuePut", OSAL_BLOCKCOUNT_C(10), sizeof(uint32), 0))) { UT_RETVAL(OS_QueuePut(queue_id, NULL, sizeof(uint32), 0), OS_INVALID_POINTER); + UT_RETVAL(OS_QueuePut(queue_id, &queue_data_out, sizeof(uint32) + 1, 0), OS_QUEUE_INVALID_SIZE); UT_TEARDOWN(OS_QueueDelete(queue_id)); } diff --git a/src/unit-tests/oscore-test/ut_oscore_task_test.c b/src/unit-tests/oscore-test/ut_oscore_task_test.c index c63e8d5d6..8f77534f0 100644 --- a/src/unit-tests/oscore-test/ut_oscore_task_test.c +++ b/src/unit-tests/oscore-test/ut_oscore_task_test.c @@ -53,6 +53,7 @@ extern char g_long_task_name[UT_OS_NAME_BUFF_SIZE]; **--------------------------------------------------------------------------------*/ uint32 g_task_result = 0; +bool g_task_handler_called; osal_id_t g_task_sync_sem; osal_id_t g_task_ids[UT_OS_TASK_LIST_LEN]; osal_id_t g_task_get_id_result; @@ -129,6 +130,13 @@ void UT_os_task_create_test() sizeof(g_task_stacks[3]), OSAL_PRIORITY_C(UT_TASK_PRIORITY), 0), OS_INVALID_POINTER); + /*-----------------------------------------------------*/ + /* Bad stack size */ + + UT_RETVAL(OS_TaskCreate(&g_task_ids[3], g_task_names[3], generic_test_task, OSAL_STACKPTR_C(&g_task_stacks[3]), 0, + OSAL_PRIORITY_C(UT_TASK_PRIORITY), 0), + OS_ERR_INVALID_SIZE); + /*-----------------------------------------------------*/ /* #4 Name-too-long */ @@ -184,15 +192,22 @@ void UT_os_task_create_test() } /*-----------------------------------------------------*/ - /* #9 Nominal */ + /* Nominal, fixed stack */ UT_NOMINAL(OS_TaskCreate(&g_task_ids[9], g_task_names[9], generic_test_task, OSAL_STACKPTR_C(&g_task_stacks[9]), sizeof(g_task_stacks[9]), OSAL_PRIORITY_C(UT_TASK_PRIORITY), 0)); + /*-----------------------------------------------------*/ + /* Nominal, dynamic stack */ + + UT_NOMINAL(OS_TaskCreate(&g_task_ids[8], g_task_names[8], generic_test_task, NULL, sizeof(g_task_stacks[8]), + OSAL_PRIORITY_C(UT_TASK_PRIORITY), 0)); + /* Delay to let child task run */ OS_TaskDelay(200); /* Reset test environment */ + UT_TEARDOWN(OS_TaskDelete(g_task_ids[8])); UT_TEARDOWN(OS_TaskDelete(g_task_ids[9])); } @@ -235,6 +250,7 @@ void UT_os_task_delete_test() void delete_handler_callback(void) { UtPrintf("Task delete callback...\n"); + g_task_handler_called = true; } /*--------------------------------------------------------------------------------*/ @@ -283,6 +299,8 @@ void UT_os_task_install_delete_handler_test(void) { OS_BinSemTake(g_task_sync_sem); + g_task_handler_called = false; + if (UT_SETUP(OS_TaskCreate(&g_task_ids[2], g_task_names[2], delete_handler_test_task, OSAL_STACKPTR_C(&g_task_stacks[2]), sizeof(g_task_stacks[2]), OSAL_PRIORITY_C(UT_TASK_PRIORITY), 0))) @@ -297,6 +315,7 @@ void UT_os_task_install_delete_handler_test(void) UtAssert_True(g_task_result == OS_SUCCESS, "OS_TaskInstallDeleteHandler() (%d) == OS_SUCCESS", (int)g_task_result); + UtAssert_True(g_task_handler_called, "OS_TaskInstallDeleteHandler() callback invoked"); } UT_TEARDOWN(OS_BinSemDelete(g_task_sync_sem)); @@ -374,10 +393,27 @@ void UT_os_task_exit_test(void) **--------------------------------------------------------------------------------*/ void UT_os_task_delay_test() { - /*-----------------------------------------------------*/ - /* #2 Nominal */ + OS_time_t before_time; + OS_time_t after_time; + int64 elapsed; + /*-----------------------------------------------------*/ + /* Nominal, 100ms delay */ + UT_SETUP(OS_GetLocalTime(&before_time)); UT_NOMINAL(OS_TaskDelay(100)); + UT_SETUP(OS_GetLocalTime(&after_time)); + + elapsed = OS_TimeGetTotalMilliseconds(OS_TimeSubtract(after_time, before_time)); + UtAssert_True(elapsed >= 100, "Elapsed time %ld msec, expected 100", (long)elapsed); + + /*-----------------------------------------------------*/ + /* Nominal, 250ms delay */ + UT_SETUP(OS_GetLocalTime(&before_time)); + UT_NOMINAL(OS_TaskDelay(250)); + UT_SETUP(OS_GetLocalTime(&after_time)); + + elapsed = OS_TimeGetTotalMilliseconds(OS_TimeSubtract(after_time, before_time)); + UtAssert_True(elapsed >= 250, "Elapsed time %ld msec, expected 250", (long)elapsed); } /*--------------------------------------------------------------------------------* @@ -554,6 +590,28 @@ void UT_os_task_get_info_test() } } +/*--------------------------------------------------------------------------------* +** Syntax: OS_TaskFindIdBySystemData +** Purpose: Finds the abstract OSAL task ID from the system ID data +**--------------------------------------------------------------------------------*/ +void UT_os_task_getid_by_sysdata_test() +{ + uint8 sysdata; + osal_id_t task_id; + + /* + * NOTE: OSAL does not provide a means to get the low level system ID data directly. + * This API is intended to aid in exception processing in a PSP/BSP, where the + * low level task information is obtained outside of OSAL in a platform-specific + * manner. + * + * As a result this cannot check for nominal conditions, only validate the error checking. + */ + UT_RETVAL(OS_TaskFindIdBySystemData(NULL, &sysdata, sizeof(sysdata)), OS_INVALID_POINTER); + UT_RETVAL(OS_TaskFindIdBySystemData(&task_id, NULL, sizeof(sysdata)), OS_INVALID_POINTER); + UT_RETVAL(OS_TaskFindIdBySystemData(&task_id, &sysdata, 0), OS_INVALID_POINTER); +} + /*================================================================================* ** End of File: ut_oscore_task_test.c **================================================================================*/ diff --git a/src/unit-tests/oscore-test/ut_oscore_task_test.h b/src/unit-tests/oscore-test/ut_oscore_task_test.h index 9ff125d66..7fb612b63 100644 --- a/src/unit-tests/oscore-test/ut_oscore_task_test.h +++ b/src/unit-tests/oscore-test/ut_oscore_task_test.h @@ -67,6 +67,7 @@ void UT_os_task_get_id_by_name_test(void); void UT_os_task_get_info_test(void); void UT_os_task_delay_test(void); void UT_os_task_get_id_test(void); +void UT_os_task_getid_by_sysdata_test(void); /*--------------------------------------------------------------------------------*/ diff --git a/src/unit-tests/oscore-test/ut_oscore_test.c b/src/unit-tests/oscore-test/ut_oscore_test.c index 3556bd074..230d99226 100644 --- a/src/unit-tests/oscore-test/ut_oscore_test.c +++ b/src/unit-tests/oscore-test/ut_oscore_test.c @@ -192,6 +192,7 @@ void UtTest_Setup(void) UtTest_AddTeardown(OS_API_Teardown, "Cleanup"); UtTest_Add(UT_os_apiinit_test, NULL, NULL, "OS_API_Init"); + UtTest_Add(UT_os_registereventhandler_test, NULL, NULL, "OS_RegisterEventHandler"); UtTest_Add(UT_os_printf_test, NULL, NULL, "OS_printf"); UtTest_Add(UT_os_printfenable_test, NULL, NULL, "OS_printf_enable"); @@ -243,6 +244,7 @@ void UtTest_Setup(void) UtTest_Add(UT_os_task_get_id_test, UT_os_init_task_get_id_test, NULL, "OS_TaskGetId"); UtTest_Add(UT_os_task_get_id_by_name_test, UT_os_init_task_get_id_by_name_test, NULL, "OS_TaskGetIdByName"); UtTest_Add(UT_os_task_get_info_test, UT_os_init_task_get_info_test, NULL, "OS_TaskGetInfo"); + UtTest_Add(UT_os_task_getid_by_sysdata_test, UT_os_task_getid_by_sysdata_test, NULL, "OS_TaskFindIdBySystemData"); UtTest_Add(UT_os_geterrorname_test, NULL, NULL, "OS_GetErrorName"); diff --git a/src/unit-tests/osfile-test/ut_osfile_dirio_test.c b/src/unit-tests/osfile-test/ut_osfile_dirio_test.c index ea7661d4c..a71fd90c8 100644 --- a/src/unit-tests/osfile-test/ut_osfile_dirio_test.c +++ b/src/unit-tests/osfile-test/ut_osfile_dirio_test.c @@ -34,7 +34,8 @@ ** Macros **--------------------------------------------------------------------------------*/ -#define UT_OS_FILE_MAX_DIRS 5 +#define UT_OS_FILE_MAX_DIRS 5 +#define UT_OS_FILE_NUM_DIR_ENTRIES 2 /*--------------------------------------------------------------------------------* ** Data types @@ -58,9 +59,14 @@ char g_dirName[UT_OS_PATH_BUFF_SIZE]; char g_fileName[UT_OS_PATH_BUFF_SIZE]; char g_subdirNames[UT_OS_FILE_MAX_DIRS][UT_OS_PATH_BUFF_SIZE]; -const char *g_tgtSubdirs[UT_OS_FILE_MAX_DIRS] = {"subdir1", "subdir2"}; +const char *g_tgtSubdirs[UT_OS_FILE_NUM_DIR_ENTRIES] = {"subdir1", "subdir2"}; -char g_dirItems[UT_OS_FILE_MAX_DIRS][UT_OS_FILE_BUFF_SIZE]; +typedef struct +{ + char DirItem[UT_OS_FILE_BUFF_SIZE]; +} UT_DirEntry_t; + +char g_dirItems[UT_OS_FILE_NUM_DIR_ENTRIES][UT_OS_FILE_BUFF_SIZE]; /*--------------------------------------------------------------------------------* ** Local function prototypes @@ -142,17 +148,16 @@ void UT_os_makedir_test() memset(g_dirName, '\0', sizeof(g_dirName)); UT_os_sprintf(g_dirName, "%s/mkdir_Nominal", g_mntName); - if (UT_SETUP(OS_mkdir(g_dirName, OS_READ_WRITE))) - { - memset(g_fileName, '\0', sizeof(g_fileName)); - UT_os_sprintf(g_fileName, "%s/mkdir_File.txt", g_dirName); - UT_NOMINAL(OS_OpenCreate(&fileDesc, g_fileName, OS_FILE_FLAG_CREATE | OS_FILE_FLAG_TRUNCATE, OS_READ_WRITE)); + UT_NOMINAL(OS_mkdir(g_dirName, OS_READ_WRITE)); - /* Reset test environment */ - UT_TEARDOWN(OS_close(fileDesc)); - UT_TEARDOWN(OS_remove(g_fileName)); - UT_TEARDOWN(OS_rmdir(g_dirName)); - } + memset(g_fileName, '\0', sizeof(g_fileName)); + UT_os_sprintf(g_fileName, "%s/mkdir_File.txt", g_dirName); + UT_NOMINAL(OS_OpenCreate(&fileDesc, g_fileName, OS_FILE_FLAG_CREATE | OS_FILE_FLAG_TRUNCATE, OS_READ_WRITE)); + + /* Reset test environment */ + UT_TEARDOWN(OS_close(fileDesc)); + UT_TEARDOWN(OS_remove(g_fileName)); + UT_TEARDOWN(OS_rmdir(g_dirName)); } /*--------------------------------------------------------------------------------* @@ -208,6 +213,7 @@ void UT_os_opendir_test() /* #1 Null-pointer-arg */ UT_RETVAL(OS_DirectoryOpen(&dirh, NULL), OS_INVALID_POINTER); + UT_RETVAL(OS_DirectoryOpen(NULL, "/drive0/test"), OS_INVALID_POINTER); /*-----------------------------------------------------*/ /* #2 Path-too-long-arg */ @@ -223,6 +229,11 @@ void UT_os_opendir_test() /* #5 Nominal */ memset(g_dirName, '\0', sizeof(g_dirName)); + + /* Non-existent directory should not succeed */ + UT_os_sprintf(g_dirName, "%s/notexist", g_mntName); + UT_RETVAL(OS_DirectoryOpen(&dirh, g_dirName), OS_ERROR); + UT_os_sprintf(g_dirName, "%s/opendir_Nominal", g_mntName); if (UT_SETUP(OS_mkdir(g_dirName, OS_READ_WRITE))) { @@ -272,6 +283,8 @@ void UT_os_closedir_test() osal_id_t dirh; os_dirent_t dirEntry; + UT_RETVAL(OS_DirectoryClose(UT_OBJID_INCORRECT), OS_ERR_INVALID_ID); + /*-----------------------------------------------------*/ /* #2 Nominal */ @@ -335,15 +348,16 @@ void UT_os_closedir_test() **--------------------------------------------------------------------------------*/ void UT_os_readdir_test() { - osal_id_t dirh = OS_OBJECT_ID_UNDEFINED; + osal_id_t dirh = OS_OBJECT_ID_UNDEFINED; + os_dirent_t dirent; strcpy(g_subdirNames[0], " "); strcpy(g_subdirNames[1], " "); /*-----------------------------------------------------*/ - /* #1 Null-pointer-arg */ + /* Invalid ID */ - UT_RETVAL(OS_DirectoryRead(OS_OBJECT_ID_UNDEFINED, NULL), OS_INVALID_POINTER); + UT_RETVAL(OS_DirectoryRead(UT_OBJID_INCORRECT, &dirent), OS_ERR_INVALID_ID); /*-----------------------------------------------------*/ /* #3 Nominal */ @@ -362,10 +376,13 @@ void UT_os_readdir_test() { if (UT_SETUP(OS_DirectoryOpen(&dirh, g_dirName))) { - UT_os_read_n_sort_dirs(dirh); + /*-----------------------------------------------------*/ + /* Null-pointer-arg */ + UT_RETVAL(OS_DirectoryRead(dirh, NULL), OS_INVALID_POINTER); - UtAssert_StrCmp(g_dirItems[2], g_tgtSubdirs[0], "%s == %s", g_dirItems[2], g_tgtSubdirs[0]); - UtAssert_StrCmp(g_dirItems[3], g_tgtSubdirs[1], "%s == %s", g_dirItems[3], g_tgtSubdirs[1]); + /*-----------------------------------------------------*/ + /* Nominal (via subfunction) */ + UT_os_read_n_sort_dirs(dirh); /* Reset test environment */ UT_TEARDOWN(OS_DirectoryClose(dirh)); @@ -428,6 +445,11 @@ void UT_os_rewinddir_test() strcpy(g_subdirNames[0], " "); strcpy(g_subdirNames[1], " "); + /*-----------------------------------------------------*/ + /* Invalid ID */ + + UT_RETVAL(OS_DirectoryRewind(UT_OBJID_INCORRECT), OS_ERR_INVALID_ID); + /*-----------------------------------------------------*/ /* #2 Nominal */ @@ -446,14 +468,10 @@ void UT_os_rewinddir_test() if (UT_SETUP(OS_DirectoryOpen(&dirh, g_dirName))) { UT_os_read_n_sort_dirs(dirh); - UtAssert_StrCmp(g_dirItems[2], g_tgtSubdirs[0], "%s == %s", g_dirItems[2], g_tgtSubdirs[0]); - UtAssert_StrCmp(g_dirItems[3], g_tgtSubdirs[1], "%s == %s", g_dirItems[3], g_tgtSubdirs[1]); UT_NOMINAL(OS_DirectoryRewind(dirh)); UT_os_read_n_sort_dirs(dirh); - UtAssert_StrCmp(g_dirItems[2], g_tgtSubdirs[0], "%s == %s", g_dirItems[2], g_tgtSubdirs[0]); - UtAssert_StrCmp(g_dirItems[3], g_tgtSubdirs[1], "%s == %s", g_dirItems[3], g_tgtSubdirs[1]); /* Reset test environment */ UT_TEARDOWN(OS_DirectoryClose(dirh)); @@ -573,23 +591,56 @@ void UT_os_removedir_test() *--------------------------------------------------------------------------------*/ void UT_os_read_n_sort_dirs(osal_id_t dirh) { - int i = 0; os_dirent_t dirEntry; + uint32 NumMatched; + uint32 NumEntries; + uint32 Check; + int32 Status; + const char *Name; + + memset(g_dirItems, 0, sizeof(g_dirItems)); - for (i = 0; i < UT_OS_FILE_MAX_DIRS; i++) - strcpy(g_dirItems[i], " "); + NumMatched = 0; + NumEntries = 0; - while (OS_DirectoryRead(dirh, &dirEntry) == OS_SUCCESS) + while (NumMatched < UT_OS_FILE_NUM_DIR_ENTRIES && NumEntries == NumMatched) { - if (strcmp(OS_DIRENTRY_NAME(dirEntry), ".") == 0) - strcpy(g_dirItems[0], "."); - else if (strcmp(OS_DIRENTRY_NAME(dirEntry), "..") == 0) - strcpy(g_dirItems[1], ".."); - else if (strcmp(OS_DIRENTRY_NAME(dirEntry), g_tgtSubdirs[0]) == 0) - strcpy(g_dirItems[2], g_tgtSubdirs[0]); - else if (strcmp(OS_DIRENTRY_NAME(dirEntry), g_tgtSubdirs[1]) == 0) - strcpy(g_dirItems[3], g_tgtSubdirs[1]); + UT_NOMINAL(OS_DirectoryRead(dirh, &dirEntry)); + + Name = OS_DIRENTRY_NAME(dirEntry); + + /* Ignore UNIX-style special entries (. and ..) */ + if (Name[0] != '.') + { + ++NumEntries; + UtPrintf("OS_DirectoryRead() name=%s\n", Name); + for (Check = 0; Check < UT_OS_FILE_NUM_DIR_ENTRIES; ++Check) + { + if (strcmp(Name, g_tgtSubdirs[Check]) == 0) + { + strcpy(g_dirItems[Check], Name); + ++NumMatched; + } + } + } } + + /* asserts that the expected number of regular entries was found */ + UtAssert_UINT32_EQ(NumMatched, UT_OS_FILE_NUM_DIR_ENTRIES); + + /* + * now continue to read to verify behavior at end of directory. + * since there is no guaranteed order in directories, also need to + * ignore the special entries here, in case they appear now. + */ + do + { + Status = OS_DirectoryRead(dirh, &dirEntry); + Name = OS_DIRENTRY_NAME(dirEntry); + } while (Status == OS_SUCCESS && Name[0] == '.'); + + /* Final return value should have been OS_ERROR, indicating end of directory */ + UtAssert_True(Status == OS_ERROR, "OS_DirectoryRead() (%d) == OS_ERROR (at end)", (int)Status); } /*================================================================================* diff --git a/src/unit-tests/osfile-test/ut_osfile_fileio_test.c b/src/unit-tests/osfile-test/ut_osfile_fileio_test.c index 0a0e51a4a..20f8f54fa 100644 --- a/src/unit-tests/osfile-test/ut_osfile_fileio_test.c +++ b/src/unit-tests/osfile-test/ut_osfile_fileio_test.c @@ -1394,11 +1394,6 @@ void UT_os_movefile_test() **--------------------------------------------------------------------------------*/ void UT_os_outputtofile_test() { - /*-----------------------------------------------------*/ - /* #1 Null-pointer-arg */ - - UT_RETVAL(OS_ShellOutputToFile(NULL, OS_OBJECT_ID_UNDEFINED), OS_INVALID_POINTER); - /*-----------------------------------------------------*/ /* #2 Invalid-file-desc-arg */ @@ -1411,7 +1406,12 @@ void UT_os_outputtofile_test() UT_os_sprintf(g_fNames[0], "%s/Output_Nominal.txt", g_mntName); if (UT_SETUP(OS_OpenCreate(&g_fDescs[0], g_fNames[0], OS_FILE_FLAG_CREATE | OS_FILE_FLAG_TRUNCATE, OS_READ_WRITE))) { - /* #4 Nominal - File-create failed */ + /*-----------------------------------------------------*/ + /* Null-pointer-arg */ + + UT_RETVAL(OS_ShellOutputToFile(NULL, g_fDescs[0]), OS_INVALID_POINTER); + + /* Nominal */ if (UT_NOMINAL_OR_NOTIMPL(OS_ShellOutputToFile("echo \"UT_os_outputtofile_test\"", g_fDescs[0]))) { UT_RETVAL(OS_lseek(g_fDescs[0], 0, OS_SEEK_SET), 0); @@ -1421,6 +1421,13 @@ void UT_os_outputtofile_test() UtAssert_True(strstr(g_readBuff, "UT_os_outputtofile_test") != NULL, "Output file contains UT_os_outputtofile_test"); } + + /* + * Executing a command name "false" should fail, either because it is not a known + * command, or if it is valid (e.g. a UNIX-like environment has /bin/false) the + * command always fails. + */ + UT_RETVAL(OS_ShellOutputToFile("false", g_fDescs[0]), OS_ERROR); } /* Reset test environment */ diff --git a/src/unit-tests/osloader-test/ut_osloader_module_test.c b/src/unit-tests/osloader-test/ut_osloader_module_test.c index f857e6078..aca22eefa 100644 --- a/src/unit-tests/osloader-test/ut_osloader_module_test.c +++ b/src/unit-tests/osloader-test/ut_osloader_module_test.c @@ -98,6 +98,22 @@ void UT_os_module_load_test() UT_RETVAL(OS_ModuleLoad(&module_id, "TestModule", 0, OS_MODULE_FLAG_LOCAL_SYMBOLS), OS_INVALID_POINTER); + /*-----------------------------------------------------*/ + /* Name too long */ + + memset(module_name, 'x', sizeof(module_name) - 1); + module_name[sizeof(module_name) - 1] = 0; + UT_RETVAL(OS_ModuleLoad(&module_id, module_name, UT_OS_GENERIC_MODULE_NAME1, OS_MODULE_FLAG_LOCAL_SYMBOLS), + OS_ERR_NAME_TOO_LONG); + + /*-----------------------------------------------------*/ + /* Path invalid */ + + memset(module_file_name, 'x', OS_MAX_PATH_LEN - 1); + module_file_name[OS_MAX_PATH_LEN - 1] = 0; + UT_RETVAL(OS_ModuleLoad(&module_id, "TestModule", module_file_name, OS_MODULE_FLAG_LOCAL_SYMBOLS), + OS_FS_ERR_PATH_INVALID); + /*-----------------------------------------------------*/ /* #4 No-free-IDs */ @@ -204,11 +220,6 @@ void UT_os_module_info_test() return; } - /*-----------------------------------------------------*/ - /* #1 Invalid-pointer-arg */ - - UT_RETVAL(OS_ModuleInfo(OS_OBJECT_ID_UNDEFINED, NULL), OS_INVALID_POINTER); - /*-----------------------------------------------------*/ /* #2 Invalid-ID-arg */ @@ -220,6 +231,10 @@ void UT_os_module_info_test() /* Setup */ if (UT_SETUP(OS_ModuleLoad(&module_id, "Good", UT_OS_GENERIC_MODULE_NAME2, OS_MODULE_FLAG_LOCAL_SYMBOLS))) { + /* Invalid-pointer-arg */ + UT_RETVAL(OS_ModuleInfo(module_id, NULL), OS_INVALID_POINTER); + + /* Nominal */ UT_NOMINAL(OS_ModuleInfo(module_id, &module_info)); UT_TEARDOWN(OS_ModuleUnload(module_id)); diff --git a/src/unit-tests/osloader-test/ut_osloader_symtable_test.c b/src/unit-tests/osloader-test/ut_osloader_symtable_test.c index c28a80ffe..b9dcad61d 100644 --- a/src/unit-tests/osloader-test/ut_osloader_symtable_test.c +++ b/src/unit-tests/osloader-test/ut_osloader_symtable_test.c @@ -187,7 +187,10 @@ void UT_os_symbol_table_dump_test() /*-----------------------------------------------------*/ /* #3 Nominal */ - UT_NOMINAL_OR_NOTIMPL(OS_SymbolTableDump(UT_OS_GENERIC_MODULE_DIR "SymbolFile.dat", 32000)); + if (UT_NOMINAL_OR_NOTIMPL(OS_SymbolTableDump(UT_OS_GENERIC_MODULE_DIR "SymbolFile.dat", 32000))) + { + UT_RETVAL(OS_SymbolTableDump(UT_OS_GENERIC_MODULE_DIR "SymbolFile.dat", 0), OS_ERR_OUTPUT_TOO_LARGE); + } } /*================================================================================* diff --git a/src/unit-tests/ostimer-test/ut_ostimer_test.c b/src/unit-tests/ostimer-test/ut_ostimer_test.c index 68e94ec89..5fb8083ac 100644 --- a/src/unit-tests/ostimer-test/ut_ostimer_test.c +++ b/src/unit-tests/ostimer-test/ut_ostimer_test.c @@ -203,6 +203,7 @@ void UtTest_Setup(void) UtTest_Add(UT_os_timergetidbyname_test, UT_os_setup_timergetidbyname_test, NULL, "OS_TimerGetIdByName"); UtTest_Add(UT_os_timergetinfo_test, UT_os_setup_timergetinfo_test, NULL, "OS_TimerGetInfo"); UtTest_Add(UT_os_timerset_test, UT_os_setup_timerset_test, NULL, "OS_TimerSet"); + UtTest_Add(UT_os_timerreconf_test, NULL, NULL, "TimerReconfig"); } /*================================================================================* diff --git a/src/unit-tests/ostimer-test/ut_ostimer_test.h b/src/unit-tests/ostimer-test/ut_ostimer_test.h index 36ca9a956..4cc2de0f9 100644 --- a/src/unit-tests/ostimer-test/ut_ostimer_test.h +++ b/src/unit-tests/ostimer-test/ut_ostimer_test.h @@ -33,12 +33,13 @@ **--------------------------------------------------------------------------------*/ #include "ut_os_support.h" -#include "ut_ostimer_timerio_test.h" /*--------------------------------------------------------------------------------* ** Macros **--------------------------------------------------------------------------------*/ +#define UT_OS_TIMER_LIST_LEN (OS_MAX_TIMERS + 10) + /*--------------------------------------------------------------------------------* ** Data types **--------------------------------------------------------------------------------*/ @@ -47,6 +48,21 @@ ** External global variables **--------------------------------------------------------------------------------*/ +extern const char *g_timerNames[UT_OS_TIMER_LIST_LEN]; +extern char g_longTimerName[UT_OS_NAME_BUFF_SIZE]; + +extern uint32 g_cbLoopCntMax; +extern uint32 g_toleranceVal; +extern uint32 g_timerFirst; +extern int32 g_status; +extern osal_id_t g_timerId; + +extern int32 TimerCreateRc; +extern int32 TimerDeleteRc; +extern int32 TimerSetRc; +extern int32 TimerGetByNameRc; +extern int32 TimerGetInfoRc; + /*--------------------------------------------------------------------------------* ** Global variables **--------------------------------------------------------------------------------*/ @@ -55,6 +71,15 @@ ** Function prototypes **--------------------------------------------------------------------------------*/ +void UT_os_timercallback(osal_id_t timerId); + +void UT_os_timercreate_test(void); +void UT_os_timerdelete_test(void); +void UT_os_timerset_test(void); +void UT_os_timerreconf_test(void); +void UT_os_timergetidbyname_test(void); +void UT_os_timergetinfo_test(void); + /*--------------------------------------------------------------------------------*/ #endif /* UT_OSTIMER_TEST_H */ diff --git a/src/unit-tests/ostimer-test/ut_ostimer_timerio_test.c b/src/unit-tests/ostimer-test/ut_ostimer_timerio_test.c index f08cb4bfb..57f5da660 100644 --- a/src/unit-tests/ostimer-test/ut_ostimer_timerio_test.c +++ b/src/unit-tests/ostimer-test/ut_ostimer_timerio_test.c @@ -28,7 +28,7 @@ ** Includes **--------------------------------------------------------------------------------*/ -#include "ut_ostimer_timerio_test.h" +#include "ut_ostimer_test.h" /*--------------------------------------------------------------------------------* ** Macros @@ -42,21 +42,10 @@ ** External global variables **--------------------------------------------------------------------------------*/ -extern char *g_timerNames[UT_OS_TIMER_LIST_LEN]; -extern char g_longTimerName[UT_OS_NAME_BUFF_SIZE]; - -extern uint32 g_cbLoopCntMax; -extern uint32 g_toleranceVal; -extern uint32 g_timerFirst; -extern int32 g_status; -extern osal_id_t g_timerId; - /*--------------------------------------------------------------------------------* ** External function prototypes **--------------------------------------------------------------------------------*/ -extern void UT_os_timercallback(osal_id_t timerId); - /*--------------------------------------------------------------------------------* ** Global variables **--------------------------------------------------------------------------------*/ @@ -64,6 +53,21 @@ extern void UT_os_timercallback(osal_id_t timerId); uint32 g_clkAccuracy = 0; osal_id_t g_timerIds[UT_OS_TIMER_LIST_LEN]; +typedef struct +{ + bool IsValid; + + int32 CreateRc; + int32 AddRc; + int32 DeleteRc; + int32 SetRc; + int32 GetByNameRc; + int32 GetInfoRc; + + OS_timer_prop_t Prop; + +} UT_reconf_status_t; + /*--------------------------------------------------------------------------------* ** Local function prototypes **--------------------------------------------------------------------------------*/ @@ -71,54 +75,31 @@ osal_id_t g_timerIds[UT_OS_TIMER_LIST_LEN]; /*--------------------------------------------------------------------------------* ** Local function definitions **--------------------------------------------------------------------------------*/ +void UT_os_othertimercallback1(osal_id_t timerId) {} +void UT_os_othertimercallback2(osal_id_t timerId, void *arg) {} -/*--------------------------------------------------------------------------------* -** Syntax: int32 OS_TimerAPIInit(void) -** Purpose: Initializes the tables that the OS timer uses to keep track of information -** about objects -** Parameters: None -** Returns: OS_ERROR on an unsuccessful inits -** OS_SUCCESS on a successful inits -** OS_ERR_NOT_IMPLEMENTED if not implemented -** ----------------------------------------------------- -** Test #0: Not-implemented condition -** 1) Call this routine -** 2) If the returned value is OS_ERR_NOT_IMPLEMENTED, then exit test -** 3) Otherwise, continue -** ----------------------------------------------------- -** Test #1: Init-not-call-first condition -** 1) Don't call this routine first -** 2) Call TBD routine(s) -** 3) Expect the returned value from those routines to be -** (a) __not__ OS_SUCCESS -*** ----------------------------------------------------- -** Test #2: Nominal condition -** 1) Call this routine -** 2) Expect the returned value to be -** (a) OS_SUCCESS (although results are not directly observable) -** 3) Call TBD routine(s) -** 4) Expect the returned value from those routines to be -** (a) OS_SUCCESS -*--------------------------------------------------------------------------------*/ -void UT_os_timerinit_test() +void UT_os_reconftimercallback(osal_id_t timerId, void *arg) { - /*-----------------------------------------------------*/ - /* #1 Init-not-call-first */ - - UT_RETVAL(OS_TimerCreate(&g_timerIds[0], "Timer #0", &g_clkAccuracy, &UT_os_timercallback), OS_ERROR); + UT_reconf_status_t *reconf = arg; - if (!UT_SETUP(OS_API_Init())) + if (!reconf->IsValid) { - return; + /* + * Calls to timer configuration from the context of a timer function + * should be rejected with OS_ERR_INCORRECT_OBJ_STATE. However because + * UtAssert is not fully thread-safe, this does not assert here, it just + * calls the various functions on the first time through and stores the + * result, which is checked/asserted in the main task. + */ + reconf->CreateRc = OS_TimerCreate(&timerId, "reconf", &g_clkAccuracy, UT_os_othertimercallback1); + reconf->AddRc = OS_TimerAdd(&timerId, "reconf", g_timerIds[1], UT_os_othertimercallback2, NULL); + reconf->DeleteRc = OS_TimerDelete(timerId); + reconf->SetRc = OS_TimerSet(timerId, 100, 100); + reconf->GetByNameRc = OS_TimerGetIdByName(&timerId, g_timerNames[7]); + reconf->GetInfoRc = OS_TimerGetInfo(timerId, &reconf->Prop); + + reconf->IsValid = true; } - - /*-----------------------------------------------------*/ - /* #2 Nominal */ - - UT_NOMINAL(OS_TimerCreate(&g_timerIds[0], "Timer #0", &g_clkAccuracy, &UT_os_timercallback)); - - /* Reset test environment */ - UT_TEARDOWN(OS_TimerDelete(g_timerIds[0])); } /*--------------------------------------------------------------------------------* @@ -270,6 +251,62 @@ void UT_os_timercreate_test() /* #8 Nominal */ UT_NOMINAL(OS_TimerCreate(&g_timerIds[7], g_timerNames[7], &g_clkAccuracy, &UT_os_timercallback)); + + /* Reset test environment */ + UT_TEARDOWN(OS_TimerDelete(g_timerIds[7])); +} + +/*--------------------------------------------------------------------------------* +** Test case to confirm that attempts to (re-)configure a timer from the context +** of a callback function should fail with OS_ERR_INCORRECT_OBJ_STATE +**--------------------------------------------------------------------------------*/ +void UT_os_timerreconf_test() +{ + UT_reconf_status_t reconf; + + memset(&reconf, 0, sizeof(reconf)); + + if (UT_SETUP(OS_TimeBaseCreate(&g_timerIds[1], "reconf", NULL))) + { + if (UT_SETUP(OS_TimeBaseSet(g_timerIds[1], 50, 50))) + { + if (UT_SETUP(OS_TimerAdd(&g_timerIds[2], "reconf", g_timerIds[1], UT_os_reconftimercallback, &reconf))) + { + if (UT_SETUP(OS_TimerSet(g_timerIds[2], 50, 50))) + { + while (!reconf.IsValid) + { + OS_TaskDelay(1); + } + } + + /* Reset test environment */ + UT_TEARDOWN(OS_TimerDelete(g_timerIds[2])); + } + } + + /* Reset test environment */ + UT_TEARDOWN(OS_TimeBaseDelete(g_timerIds[1])); + } + + /* Check that those configuration attempts all returned OS_ERR_INCORRECT_OBJ_STATE */ + UtAssert_True(reconf.CreateRc == OS_ERR_INCORRECT_OBJ_STATE, + "OS_TimerCreate(&timerId, \"reconf\", &g_clkAccuracy, UT_os_othertimercallback1) (%d) == " + "OS_ERR_INCORRECT_OBJ_STATE", + (int)reconf.CreateRc); + UtAssert_True(reconf.AddRc == OS_ERR_INCORRECT_OBJ_STATE, + "OS_TimerAdd(&timerId, \"reconf\", g_timerIds[1], UT_os_othertimercallback2, NULL) (%d) == " + "OS_ERR_INCORRECT_OBJ_STATE", + (int)reconf.AddRc); + UtAssert_True(reconf.DeleteRc == OS_ERR_INCORRECT_OBJ_STATE, + "OS_TimerDelete(timerId) (%d) == OS_ERR_INCORRECT_OBJ_STATE", (int)reconf.DeleteRc); + UtAssert_True(reconf.SetRc == OS_ERR_INCORRECT_OBJ_STATE, + "OS_TimerSet(timerId, 100, 100) (%d) == OS_ERR_INCORRECT_OBJ_STATE", (int)reconf.SetRc); + UtAssert_True(reconf.GetByNameRc == OS_ERR_INCORRECT_OBJ_STATE, + "OS_TimerGetIdByName(&timerId, g_timerNames[7]) (%d) == OS_ERR_INCORRECT_OBJ_STATE", + (int)reconf.GetByNameRc); + UtAssert_True(reconf.GetInfoRc == OS_ERR_INCORRECT_OBJ_STATE, + "OS_TimerGetInfo(timerId, &TimerProp) (%d) == OS_ERR_INCORRECT_OBJ_STATE", (int)reconf.GetInfoRc); } /*--------------------------------------------------------------------------------* @@ -406,6 +443,8 @@ void UT_os_timerset_test() if (UT_SETUP(OS_TimerCreate(&g_timerIds[3], g_timerNames[3], &g_clkAccuracy, &UT_os_timercallback))) { + UT_RETVAL(OS_TimerSet(g_timerIds[3], 0, 0), OS_TIMER_ERR_INVALID_ARGS); + g_status = 0; g_timerId = g_timerIds[3]; g_timerFirst = 1; diff --git a/src/unit-tests/ostimer-test/ut_ostimer_timerio_test.h b/src/unit-tests/ostimer-test/ut_ostimer_timerio_test.h deleted file mode 100644 index d4be070b3..000000000 --- a/src/unit-tests/ostimer-test/ut_ostimer_timerio_test.h +++ /dev/null @@ -1,68 +0,0 @@ -/* - * NASA Docket No. GSC-18,370-1, and identified as "Operating System Abstraction Layer" - * - * Copyright (c) 2019 United States Government as represented by - * the Administrator of the National Aeronautics and Space Administration. - * All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * \file - * - * Owner: Tam Ngo - * Date: April 2013 - */ - -#ifndef UT_OSTIMER_TIMERIO_TEST_H -#define UT_OSTIMER_TIMERIO_TEST_H - -/*--------------------------------------------------------------------------------* -** Includes -**--------------------------------------------------------------------------------*/ - -#include "ut_os_support.h" - -/*--------------------------------------------------------------------------------* -** Macros -**--------------------------------------------------------------------------------*/ - -#define UT_OS_TIMER_LIST_LEN (OS_MAX_TIMERS + 10) - -/*--------------------------------------------------------------------------------* -** Data types -**--------------------------------------------------------------------------------*/ - -/*--------------------------------------------------------------------------------* -** External global variables -**--------------------------------------------------------------------------------*/ - -/*--------------------------------------------------------------------------------* -** Global variables -**--------------------------------------------------------------------------------*/ - -/*--------------------------------------------------------------------------------* -** Function prototypes -**--------------------------------------------------------------------------------*/ - -void UT_os_timerinit_test(void); -void UT_os_timercreate_test(void); -void UT_os_timerdelete_test(void); -void UT_os_timerset_test(void); -void UT_os_timergetidbyname_test(void); -void UT_os_timergetinfo_test(void); - -/*--------------------------------------------------------------------------------*/ - -#endif /* UT_OSTIMER_TIMERIO_TEST_H */ diff --git a/src/ut-stubs/osapi-timebase-stubs.c b/src/ut-stubs/osapi-timebase-stubs.c index c1e3439dc..cf5163ab2 100644 --- a/src/ut-stubs/osapi-timebase-stubs.c +++ b/src/ut-stubs/osapi-timebase-stubs.c @@ -38,13 +38,13 @@ extern void UT_DefaultHandler_OS_TimeBaseGetInfo(void *, UT_EntryKey_t, const UT * Generated stub function for OS_TimeBaseCreate() * ---------------------------------------------------- */ -int32 OS_TimeBaseCreate(osal_id_t *timebase_id, const char *timebase_name, OS_TimerSync_t al_sync) +int32 OS_TimeBaseCreate(osal_id_t *timebase_id, const char *timebase_name, OS_TimerSync_t external_sync) { UT_GenStub_SetupReturnBuffer(OS_TimeBaseCreate, int32); UT_GenStub_AddParam(OS_TimeBaseCreate, osal_id_t *, timebase_id); UT_GenStub_AddParam(OS_TimeBaseCreate, const char *, timebase_name); - UT_GenStub_AddParam(OS_TimeBaseCreate, OS_TimerSync_t, al_sync); + UT_GenStub_AddParam(OS_TimeBaseCreate, OS_TimerSync_t, external_sync); UT_GenStub_Execute(OS_TimeBaseCreate, Basic, UT_DefaultHandler_OS_TimeBaseCreate); diff --git a/ut_assert/scripts/generate_stubs.pl b/ut_assert/scripts/generate_stubs.pl index fefa2623f..9dff1e610 100755 --- a/ut_assert/scripts/generate_stubs.pl +++ b/ut_assert/scripts/generate_stubs.pl @@ -129,6 +129,12 @@ } close(HDR); + foreach (@lines) + { + # Truncate each line at C++-style comment + s/\/\/.*$//; + } + # combine all content into a single string # this eases processing of multi-line constructs $file = join('', @lines); @@ -155,20 +161,20 @@ # Now Find function prototypes foreach (@lines) { - next if (/typedef/); # ignore typedefs - next if (/static inline/); # ignore + next if (/\btypedef\b/); # ignore typedefs + next if (/\bstatic inline\b/); # ignore # discard "extern" qualifier # (but other qualifiers like "const" are OK and should be preserved, as # it is part of return type). - s/extern//; + s/\bextern\b//; # The following macros are defined in OSAL common_types.h as function attributes # They may appear on other function declarations, and should be ignored here. - s/_EXTENSION_//; - s/OS_USED//; - s/OS_PRINTF\(.*?\)//; + s/\b_EXTENSION_\b//; + s/\bOS_USED\b//; + s/\bOS_PRINTF\(.*?\)//; # scrub whitespace for consistency - multiple spaces become single space # and trim leading/trailing spaces again