diff options
Diffstat (limited to '')
55 files changed, 3256 insertions, 3583 deletions
diff --git a/cpukit/include/dev/can/can-msg.h b/cpukit/include/dev/can/can-msg.h deleted file mode 100644 index 9863e14d84..0000000000 --- a/cpukit/include/dev/can/can-msg.h +++ /dev/null @@ -1,105 +0,0 @@ -/* SPDX-License-Identifier: BSD-2-Clause */ - -/** - * @file - * - * @ingroup CANBus - * - * @brief Controller Area Network (CAN) Bus Implementation - * - */ - -/* - * Copyright (C) 2022 Prashanth S <fishesprashanth@gmail.com> - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef _DEV_CAN_CAN_MSG_H -#define _DEV_CAN_CAN_MSG_H - -/** - * @defgroup Controller Area Network (CAN) Driver - * - * @ingroup RTEMSDeviceDrivers - * - * @brief Controller Area Network (CAN) bus and device driver support. - * - * @{ - */ - -/** - * @defgroup CANBus CAN Bus Driver - * - * @ingroup CAN - * - * @{ - */ - -/** - * @brief CAN message size - */ -#define CAN_MSG_MAX_SIZE (8u) - -/** - * @brief Number of CAN tx buffers - */ -#define CAN_TX_BUF_COUNT (10u) - -/** - * @brief Number of CAN rx buffers - */ -#define CAN_RX_BUF_COUNT (2u) - -#define CAN_MSGLEN(msg) (sizeof(struct can_msg) - (CAN_MSG_MAX_SIZE - msg->len)) - -/** - * @brief CAN message structure. - */ -struct can_msg { - /** - * @brief CAN message id. - */ - uint32_t id; - /** - * @brief CAN message timestamp. - */ - uint32_t timestamp; - /** - * @brief CAN message flags RTR | BRS | EXT. - */ - uint16_t flags; - /** - * @brief CAN message length. - */ - uint16_t len; - /** - * @brief CAN message. - */ - uint8_t data[CAN_MSG_MAX_SIZE]; -}; - -/** @} */ /* end of CAN message */ - -/** @} */ - -#endif /* _DEV_CAN_CAN_MSG_H */ diff --git a/cpukit/include/dev/can/can.h b/cpukit/include/dev/can/can.h deleted file mode 100644 index 9e55395039..0000000000 --- a/cpukit/include/dev/can/can.h +++ /dev/null @@ -1,284 +0,0 @@ -/* SPDX-License-Identifier: BSD-2-Clause */ - -/** - * @file - * - * @ingroup CANBus - * - * @brief Controller Area Network (CAN) Bus Implementation - * - */ - -/* - * Copyright (C) 2022 Prashanth S (fishesprashanth@gmail.com) - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef _DEV_CAN_CAN_H -#define _DEV_CAN_CAN_H - -#include <rtems/imfs.h> -#include <rtems/thread.h> -#include <semaphore.h> - -#include <string.h> -#include <stdlib.h> -#include <stdio.h> - -#include <dev/can/can-msg.h> - -#define DEBUG(str, ...) \ - do { \ - printf("CAN: %s:%d ID: %08X ", __FILE__, __LINE__, rtems_task_self()); \ - printf(str, ##__VA_ARGS__); \ - } while (false); - -#define CAN_DEBUG(str, ...) DEBUG(str, ##__VA_ARGS__) -#define CAN_DEBUG_BUF(str, ...) CAN_DEBUG(str, ##__VA_ARGS__) -#define CAN_DEBUG_ISR(str, ...) CAN_DEBUG(str, ##__VA_ARGS__) -#define CAN_DEBUG_LOCK(str, ...) CAN_DEBUG(str, ##__VA_ARGS__) -#define CAN_DEBUG_RX(str, ...) CAN_DEBUG(str, ##__VA_ARGS__) -#define CAN_DEBUG_TX(str, ...) CAN_DEBUG(str, ##__VA_ARGS__) -#define CAN_DEBUG_REG(str, ...) //CAN_DEBUG(str, ##__VA_ARGS__) -#define CAN_ERR(str, ...) DEBUG(str, ##__VA_ARGS__) - -#define CAN_MSG_LEN(msg) ((char *)(&((struct can_msg *)msg)->data[(uint16_t)((struct can_msg *)msg)->len]) - (char *)(msg)) - -/* Maximum Bus Reg (255) */ -#define CAN_BUS_REG_MAX (255) - -/** - * @defgroup Controller Area Network (CAN) Driver - * - * @ingroup RTEMSDeviceDrivers - * - * @brief Controller Area Network (CAN) bus and device driver support. - * - * @{ - */ - -/** - * @defgroup CANBus CAN Bus Driver - * - * @ingroup CAN - * - * @{ - */ - -/** - * @brief CAN tx fifo data structure. - */ -struct ring_buf { - /** - * @brief Pointer to array of can_msg structure. - */ - struct can_msg *pbuf; - /** - * @brief Index of the next free buffer. - */ - uint32_t head; - /** - * @brief Index of the produced buffer. - */ - uint32_t tail; - /** - * @brief Number of empty buffers. - */ - uint32_t empty_count; -}; - -/** - * @brief CAN Controller device specific operations. - * These function pointers are initialized by the CAN device driver while - * registering (can_bus_register). - */ -typedef struct can_dev_ops { - /** - * @brief Transfers CAN messages to device fifo. - * - * @param[in] priv device control structure. - * @param[in] msg can_msg message structure. - * - * @retval 0 Successful operation. - * @retval >0 error number in case of an error. - */ - int32_t (*dev_tx)(void *priv, struct can_msg *msg); - /** - * @brief Check device is ready to transfer a CAN message - * - * @param[in] priv device control structure. - * - * @retval true device ready. - * @retval false device not ready. - */ - bool (*dev_tx_ready)(void *priv); - /** - * @brief Enable/Disable CAN interrupts. - * - * @param[in] priv device control structure. - * @param[in] flag true/false to Enable/Disable CAN interrupts. - * - */ - void (*dev_int)(void *priv, bool flag); - /** - * @brief CAN device specific I/O controls. - * - * @param[in] priv device control structure. - * @param[in] buffer This depends on the cmd. - * @param[in] cmd Device specific I/O commands. - * - * @retval 0 Depends on the cmd. - */ - int32_t (*dev_ioctl)(void *priv, void *buffer, size_t cmd); -} can_dev_ops; - -/** - * @name CAN bus control - * - * @{ - */ - -/** - * @brief Obtains the bus. - * - * This command has no argument. - */ -typedef struct can_bus { - /** - * @brief Device specific control. - */ - void *priv; - /** - * @brief Device controller index. - */ - uint8_t index; - /** - * @brief Device specific operations. - */ - struct can_dev_ops *can_dev_ops; - /** - * @brief tx fifo. - */ - struct ring_buf tx_fifo; - /** - * @brief Counting semaphore id (for fifo sync). - */ - rtems_id tx_fifo_sem_id; - - /* FIXME: Using only one CAN msg buffer, Should create a ring buffer */ - /** - * @brief rx fifo. - */ - struct can_msg can_rx_msg; - /** - * @brief Mutex to handle bus concurrency. - */ - rtems_mutex mutex; - /** - * @brief Destroys the bus. - * - * @param[in] bus control structure. - */ - void (*destroy)(struct can_bus *bus); -#ifdef CAN_DEBUG_LOCK - - /** - * @brief For debugging semaphore obtain/release. - */ - int sem_count; - -#endif /* CAN_DEBUG_LOCK */ - -} can_bus; - -/** @} */ - -/** - * @brief Register a CAN node with the CAN bus driver. - * - * @param[in] bus bus control structure. - * @param[in] bus_path path of device node. - * - * @retval >=0 rtems status. - */ -rtems_status_code can_bus_register(can_bus *bus, const char *bus_path); - -/** - * @brief Allocate and initilaize bus control structure. - * - * @param[in] size Size of the bus control structure. - * - * @retval NULL No memory available. - * @retval Address Pointer to the allocated bus control structure. - */ -can_bus *can_bus_alloc_and_init(size_t size); - -/** - * @brief initilaize bus control structure. - * - * @param[in] bus bus control structure. - * - * @retval 0 success. - * @retval >0 error number. - */ -int can_bus_init(can_bus *bus); - -/** - * @brief Initiates CAN message transfer. - * - * Should be called with CAN interrupt disabled. - * - * @param[in] bus Bus control structure. - * - * @retval 0 success. - * @retval >0 error number. - */ -int can_tx_done(struct can_bus *bus); - -/** - * @brief Sends the received CAN message to the application. - * - * Should be called by the device when CAN message should be sent to applicaiton. - * Should be called only with CAN interrupts disabled. - * - * @param[in] bus bus control structure. - * @param[in] msg can_msg structure. - * - * @retval 0 success. - * @retval >0 error number. - */ -int can_receive(struct can_bus *bus, struct can_msg *msg); - -/** - * @brief Prints the can_msg values pointed by msg. - * - * @param[in] msg can_msg structure. - * - */ -void can_print_msg(struct can_msg const *msg); - -/** @} */ /* end of CAN device driver */ - -/** @} */ - -#endif /* _DEV_CAN_CAN_H */ diff --git a/cpukit/include/dev/can/canqueueimpl.h b/cpukit/include/dev/can/canqueueimpl.h deleted file mode 100644 index ef0d56fe31..0000000000 --- a/cpukit/include/dev/can/canqueueimpl.h +++ /dev/null @@ -1,231 +0,0 @@ -/* SPDX-License-Identifier: BSD-2-Clause */ - -/** - * @file - * - * @ingroup CANBus - * - * @brief Controller Area Network (CAN) Bus Implementation - * - */ - -/* - * Copyright (C) 2022 Prashanth S <fishesprashanth@gmail.com> - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef _DEV_CAN_CAN_QUEUE_H -#define _DEV_CAN_CAN_QUEUE_H - -#include <rtems/imfs.h> -#include <rtems/thread.h> - -#include <string.h> -#include <stdlib.h> -#include <stdio.h> - -#include <dev/can/can-msg.h> -#include <dev/can/can.h> - -/** - * @defgroup Controller Area Network (CAN) Driver - * - * @ingroup RTEMSDeviceDrivers - * - * @brief Controller Area Network (CAN) bus and device driver support. - * - * @{ - */ - -/** - * @defgroup CANBus CAN Bus Driver - * - * @ingroup CAN - * - * @{ - */ - -/** - * @brief Create CAN tx buffers. - * - * @param[in] bus Bus control structure. - * - * @retval 0 Successful operation. - * @retval >0 error number in case of an error. - */ -static rtems_status_code can_bus_create_tx_buffers(struct can_bus *bus); - -/** - * @brief Free CAN tx buffers. - * - * @param[in] bus Bus control structure. - * - */ -static void can_bus_free_tx_buffers(struct can_bus *bus); - -/** - * @brief Check for atleast one empty CAN tx buffer. - * - * @param[in] bus Bus control structure. - * - * @retval true If atleast one CAN buffer is empty. - * @retval false If no CAN buffer is empty. - */ -static bool can_bus_tx_buf_is_empty(struct can_bus *bus); - -/** - * @brief Get a produced tx buffer to transmit from the tx fifo. - * - * @param[in] bus Bus control structure. - * - * @retval can_msg Pointer to can_msg structure buffer. - * @retval NULL If no can_msg buffer. - */ -static struct can_msg *can_bus_tx_get_data_buf(struct can_bus *bus); - -/** - * @brief Get a empty tx buffer. - * - * @param[in] bus Bus control structure. - * - * @retval can_msg Pointer to can_msg structure buffer. - * @retval NULL If no empty can_msg buffer. - */ -static struct can_msg *can_bus_tx_get_empty_buf(struct can_bus *bus); - -/** - * @brief Creates tx buffers for the CAN bus driver. - * - * @param[in] bus Bus control structure. - * - * @retval rtems_status_code - */ -static rtems_status_code can_bus_create_tx_buffers(struct can_bus *bus) -{ - bus->tx_fifo.pbuf = (struct can_msg *)malloc(CAN_TX_BUF_COUNT * - sizeof(struct can_msg)); - if (bus->tx_fifo.pbuf == NULL) { - CAN_ERR("can_create_tx_buffers: malloc failed\n"); - return RTEMS_NO_MEMORY; - } - - bus->tx_fifo.empty_count = CAN_TX_BUF_COUNT; - - return RTEMS_SUCCESSFUL; -} - -/** - * @brief Free tx buffers for the CAN bus driver. - * - * @param[in] bus Bus control structure. - * - */ -static void can_bus_free_tx_buffers(struct can_bus *bus) -{ - free(bus->tx_fifo.pbuf); -} - -/** - * @brief Check if there is atleast one tx buffer in the CAN - * bus driver. - * - * @param[in] bus Bus control structure. - * - * @retval true - If there is at least one free tx buffer. - * false - If there is no free tx buffer. - */ -static bool can_bus_tx_buf_is_empty(struct can_bus *bus) -{ - if (bus->tx_fifo.empty_count == 0) { - return false; - } - - return true; -} - -/** - * @brief To get a can_msg tx buf which contains valid data to send in - * in the CAN bus. - * - * Note: freeing the returned data buf is done in the same function, - * So the returned buffer should be sent before releasing the - * lock acquired while calling this function. - * - * @param[in] bus Bus control structure. - * - * @retval *can_msg - If there is atleast one tx buffer to send in the CAN bus. - * NULL - If there is no valid tx buffer. - */ -static struct can_msg *can_bus_tx_get_data_buf(struct can_bus *bus) -{ - struct can_msg *msg = NULL; - - if (bus->tx_fifo.empty_count == CAN_TX_BUF_COUNT || - bus->tx_fifo.tail >= CAN_TX_BUF_COUNT) { - CAN_DEBUG_BUF("can_bus_tx_get_data_buf: All buffers are empty\n"); - return NULL; - } - - msg = &bus->tx_fifo.pbuf[bus->tx_fifo.tail]; - bus->tx_fifo.empty_count++; - bus->tx_fifo.tail = (bus->tx_fifo.tail + 1) % CAN_TX_BUF_COUNT; - - return msg; -} - -/** - * @brief To get a can_msg tx buf which is empty (contains no valid data). - * - * Note: marking the returned buf valid is done in the same function - * So a valid CAN message should be copied to the returned buffer before - * releasing the lock acquired while calling this function. - * - * @param[in] bus Bus control structure. - * - * @retval *can_msg - If there is atleast one empty tx buffer. - * NULL - If there is no empty tx buffer. - */ -static struct can_msg *can_bus_tx_get_empty_buf(struct can_bus *bus) -{ - struct can_msg *msg = NULL; - - /* Check whether there is a empty CAN msg buffer */ - if (can_bus_tx_buf_is_empty(bus) == false) { - CAN_DEBUG_BUF("can_bus_tx_get_empty_buf: No empty buffer\n"); - return NULL; - } - - bus->tx_fifo.empty_count--; - - /* tx_fifo.head always points to a empty buffer if there is atleast one */ - msg = &bus->tx_fifo.pbuf[bus->tx_fifo.head]; - bus->tx_fifo.head = (bus->tx_fifo.head + 1) % CAN_TX_BUF_COUNT; - - return msg; -} - -/** @} */ /* end of CAN device driver */ - -/** @} */ - -#endif /*_DEV_CAN_CAN_QUEUE_H */ diff --git a/cpukit/include/dev/flash/flashdev.h b/cpukit/include/dev/flash/flashdev.h index d1dc08a5c4..6759357206 100644 --- a/cpukit/include/dev/flash/flashdev.h +++ b/cpukit/include/dev/flash/flashdev.h @@ -39,6 +39,11 @@ #include <rtems/thread.h> #include <sys/types.h> +#ifdef __cplusplus +extern "C" { +#endif + + typedef struct rtems_flashdev rtems_flashdev; /** @@ -454,6 +459,10 @@ void rtems_flashdev_destroy_and_free( rtems_flashdev *flash ); +#ifdef __cplusplus +} +#endif + /** @} */ #endif /* _DEV_FLASHDEV_H */ diff --git a/cpukit/include/machine/_timecounter.h b/cpukit/include/machine/_timecounter.h index 127e5f6fd3..e20e051f84 100644 --- a/cpukit/include/machine/_timecounter.h +++ b/cpukit/include/machine/_timecounter.h @@ -3,6 +3,8 @@ /** * @file * + * @ingroup RTEMSScoreTimecounter + * * @brief This header file provides timecounter definitions for the kernel space * (_KERNEL is defined before including <sys/time.h>) and RTEMS. */ diff --git a/cpukit/include/pci/irq.h b/cpukit/include/pci/irq.h index 4069f1ffa8..8617dd1680 100644 --- a/cpukit/include/pci/irq.h +++ b/cpukit/include/pci/irq.h @@ -38,18 +38,9 @@ #ifndef __PCI_IRQ_H__ #define __PCI_IRQ_H__ -#include <rtems/irq-extension.h> +#include <rtems/rtems/intr.h> #include <rtems/score/basedefs.h> -/* - * FIXME: This should be available via the IRQ extensions API. - * - * https://devel.rtems.org/ticket/3269 - */ -void BSP_shared_interrupt_clear(int irq); -void BSP_shared_interrupt_unmask(int irq); -void BSP_shared_interrupt_mask(int irq); - /* PCI Handler (ISR) called when IRQ is generated by any of the PCI devices * connected to the same PCI IRQ Pin. This has been defined the same way as * rtems_interrupt_handler in order for BSPs to "direct-map" the register @@ -106,7 +97,7 @@ static inline int pci_interrupt_unregister(int irq, pci_isr isr, */ static inline void pci_interrupt_unmask(int irq) { - BSP_shared_interrupt_unmask(irq); + (void)rtems_interrupt_vector_enable((rtems_vector_number)irq); } /* Disable shared PCI IRQ handler. This function will mask the interrupt @@ -122,7 +113,7 @@ static inline void pci_interrupt_unmask(int irq) */ static inline void pci_interrupt_mask(int irq) { - BSP_shared_interrupt_mask(irq); + (void)rtems_interrupt_vector_disable((rtems_vector_number)irq); } /* Acknowledge the interrupt controller by writing to the interrupt controller. @@ -136,7 +127,7 @@ static inline void pci_interrupt_mask(int irq) */ static inline void pci_interrupt_clear(int irq) { - BSP_shared_interrupt_clear(irq); + (void)rtems_interrupt_clear((rtems_vector_number)irq); } #endif /* !__PCI_IRQ_H__ */ diff --git a/cpukit/include/rtems/score/io.h b/cpukit/include/rtems/base64.h index 9cd401eb1d..58e48a8c33 100644 --- a/cpukit/include/rtems/score/io.h +++ b/cpukit/include/rtems/base64.h @@ -3,14 +3,14 @@ /** * @file * - * @ingroup RTEMSScoreIO + * @ingroup RTEMSImplBase64 * * @brief This header file provides the interfaces of the - * @ref RTEMSScoreIO. + * @ref RTEMSImplBase64. */ /* - * Copyright (c) 2017 embedded brains GmbH & Co. KG + * Copyright (C) 2020, 2024 embedded brains GmbH & Co. KG * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -34,42 +34,35 @@ * POSSIBILITY OF SUCH DAMAGE. */ -#ifndef _RTEMS_SCORE_IO_H -#define _RTEMS_SCORE_IO_H +#ifndef _RTEMS_BASE64_H +#define _RTEMS_BASE64_H -#include <rtems/score/basedefs.h> - -#include <stdarg.h> +#include <rtems/dev/io.h> #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ /** - * @defgroup RTEMSScoreIO IO Handler + * @defgroup RTEMSImplBase64 Base64 Encoding and Decoding * - * @ingroup RTEMSScore + * @ingroup RTEMSImpl * - * @brief This group contains the IO Handler implementation. + * @brief This group contains support functions for base64 and base64url + * encoding and decoding. * * @{ */ -typedef void ( *IO_Put_char )( int c, void *arg ); - -int _IO_Printf( - IO_Put_char put_char, - void *arg, - char const *fmt, - ... -) RTEMS_PRINTFLIKE( 3, 4 ); +/** + * @brief Maps a 6-bit integer to the corresponding base64 encoding. + */ +extern const uint8_t _Base64_Encoding[ 64 ]; -int _IO_Vprintf( - IO_Put_char put_char, - void *arg, - char const *fmt, - va_list ap -); +/** + * @brief Maps a 6-bit integer to the corresponding base64url encoding. + */ +extern const uint8_t _Base64url_Encoding[ 64 ]; /** * @brief Outputs the source buffer in base64 encoding. @@ -93,7 +86,7 @@ int _IO_Vprintf( * * @return Returns the count of output characters. */ -int _IO_Base64( +int _Base64_Encode( IO_Put_char put_char, void *arg, const void *src, @@ -124,7 +117,7 @@ int _IO_Base64( * * @return Returns the count of output characters. */ -int _IO_Base64url( +int _Base64url_Encode( IO_Put_char put_char, void *arg, const void *src, @@ -134,17 +127,72 @@ int _IO_Base64url( ); /** - * @brief Issues a couple of no-operation instructions. + * @brief Represents the base64 and base64url decoder state. + */ +typedef enum { + BASE64_DECODE_STATE_0, + BASE64_DECODE_STATE_1, + BASE64_DECODE_STATE_2, + BASE64_DECODE_STATE_3 +} Base64_Decode_state; + +/** + * @brief Contains the base64 and base64url decoder control. + */ +typedef struct { + Base64_Decode_state state; + uint8_t *target; + const uint8_t *target_end; +} Base64_Decode_control; + +/** + * @brief Maps a 7-bit character to the associated 6-bit integer as defined by + * the base64 or base64url encoding or a special value. + */ +extern const uint8_t _Base64_Decoding[ 128 ]; + +/** + * @brief Initializes the base64 decoder. + * + * @param[out] self is the base64 decoder control to initialize. + * + * @param[out] target is the base address of the target area for decoding. + * + * @param target_size is the size in bytes of the target area for decoding. + */ +void _Base64_Decode_initialize( + Base64_Decode_control *self, + uint8_t *target, + size_t target_size +); + +/** + * @brief Represents the base64 and base64url decoder status. + */ +typedef enum { + BASE64_DECODE_SUCCESS, + BASE64_DECODE_OVERFLOW, + BASE64_DECODE_INVALID_INPUT +} Base64_Decode_status; + +/** + * @brief Decodes the character. + * + * The decoder accepts base64 and base64url encodings. White space is ignored. * - * This function may be used to burn a couple of processor cycles with minimum - * impact on the system bus. It may be used in busy wait loops. + * @param[in, out] self is the base64 decoder control. + * + * @param ch is the character to decode. */ -void _IO_Relax( void ); +Base64_Decode_status _Base64_Decode( + Base64_Decode_control *self, + char ch +); -/** @} */ +/** @} */ #ifdef __cplusplus } #endif /* __cplusplus */ -#endif /* _RTEMS_SCORE_IO_H */ +#endif /* _RTEMS_BASE64_H */ diff --git a/cpukit/include/rtems/confdefs/clock.h b/cpukit/include/rtems/confdefs/clock.h index 26519cc70b..e57daa899b 100644 --- a/cpukit/include/rtems/confdefs/clock.h +++ b/cpukit/include/rtems/confdefs/clock.h @@ -70,6 +70,11 @@ #warning "The clock ticks per second is not an integer" #endif +#if defined(CONFIGURE_TICKS_PER_TIMESLICE) \ + && CONFIGURE_TICKS_PER_TIMESLICE <= 0 + #error "CONFIGURE_TICKS_PER_TIMESLICE shall be greater than zero" +#endif + #if CONFIGURE_MICROSECONDS_PER_TICK <= 0 #error "CONFIGURE_MICROSECONDS_PER_TICK must be positive" #endif diff --git a/cpukit/include/rtems/config.h b/cpukit/include/rtems/config.h index 40d703d61a..a19d809cf9 100644 --- a/cpukit/include/rtems/config.h +++ b/cpukit/include/rtems/config.h @@ -438,7 +438,7 @@ const char *rtems_get_version_string( void ); * @endparblock */ #define rtems_configuration_get_interrupt_stack_size() \ - ((size_t) _ISR_Stack_size) + ((size_t) _ISR_Stack_size_object) /* Generated from spec:/rtems/config/if/get-maximum-extensions */ diff --git a/cpukit/include/rtems/crc.h b/cpukit/include/rtems/crc.h new file mode 100644 index 0000000000..1158dbcd7b --- /dev/null +++ b/cpukit/include/rtems/crc.h @@ -0,0 +1,106 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ + +/** + * @file + * + * @ingroup RTEMSImplCRC + * + * @brief This header file provides the interfaces of the + * @ref RTEMSImplCRC. + */ + +/* + * Copyright (C) 2024 embedded brains GmbH & Co. KG + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _RTEMS_CRC_H +#define _RTEMS_CRC_H + +#include <stddef.h> +#include <stdint.h> + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/** + * @defgroup RTEMSImplCRC Cyclic Redundancy Check (CRC) Support + * + * @ingroup RTEMSImpl + * + * @brief This group contains functions to calculate + * Cyclic Redundancy Check (CRC) values. + * + * @{ + */ + + +/** + * @brief This constant represents the default CRC-24Q seed state. + */ +#define CRC24Q_SEED 0U + +/** + * @brief This constant provides a mask to get a valid CRC-24Q value from the + * integers returned by _CRC24Q_Update() and _CRC24Q_Sequence_update(). + */ +#define CRC24Q_MASK 0xffffffU + +/** + * @brief Updates the CRC-24Q state using a byte. + * + * @param crc is the input CRC-24Q state. + * + * @param byte is the byte updating the input CRC-24Q state. + * + * @return Returns the updated CRC-24Q state. Use the #CRC24Q_MASK to get a + * valid CRC-24Q value. + */ +uint32_t _CRC24Q_Update( uint32_t crc, uint8_t byte ); + +/** + * @brief Updates the CRC-24Q state using a sequence of bytes. + * + * @param crc is the input CRC-24Q state. + * + * @param bytes[in] is the sequence of bytes updating the input CRC-24Q state. + * + * @param size_in_bytes is the size in bytes of the byte sequence. + * + * @return Returns the updated CRC-24Q state. Use the #CRC24Q_MASK to get a + * valid CRC-24Q value. + */ +uint32_t _CRC24Q_Sequence_update( + uint32_t crc, + const void *bytes, + size_t size_in_bytes +); + +/** @} */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* _RTEMS_CRC_H */ diff --git a/cpukit/include/rtems/dev/io.h b/cpukit/include/rtems/dev/io.h new file mode 100644 index 0000000000..b8bcde7af4 --- /dev/null +++ b/cpukit/include/rtems/dev/io.h @@ -0,0 +1,123 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ + +/** + * @file + * + * @ingroup RTEMSDeviceIO + * + * @brief This header file provides the interfaces of the + * @ref RTEMSDeviceIO. + */ + +/* + * Copyright (C) 2017, 2023 embedded brains GmbH & Co. KG + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _RTEMS_DEV_IO_H +#define _RTEMS_DEV_IO_H + +#include <rtems/score/basedefs.h> + +#include <stdarg.h> + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/** + * @defgroup RTEMSDeviceIO Device I/O Support + * + * @ingroup RTEMSDeviceDrivers + * + * @brief This group contains the Device I/O Support API and implementation. + * + * @{ + */ + +/** + * @brief This type defines the put character handler. + * + * @param c is the character to put. + * + * @param arg is the user-provided argument. + */ +typedef void ( *IO_Put_char )( int c, void *arg ); + +/** + * @brief Prints characters using the put character handler according to the + * format string. + * + * @param put_char is the put character handler. + * + * @param arg is the user-provided argument for the put character handler. + * + * @param fmt is the printf()-style format string. + * + * @param ... is the list of parameters required by the format string. + * + * @return Returns the count of put characters. + */ +int _IO_Printf( + IO_Put_char put_char, + void *arg, + char const *fmt, + ... +) RTEMS_PRINTFLIKE( 3, 4 ); + +/** + * @brief Prints characters using the put character handler according to the + * format string. + * + * @param put_char is the put character handler. + * + * @param arg is the user-provided argument for the put character handler. + * + * @param fmt is the printf()-style format string. + * + * @param ap is the argument list required by the format string. + * + * @return Returns the count of put characters. + */ +int _IO_Vprintf( + IO_Put_char put_char, + void *arg, + char const *fmt, + va_list ap +); + +/** + * @brief Issues a couple of no-operation instructions. + * + * This function may be used to burn a couple of processor cycles with minimum + * impact on the system bus. It may be used in busy wait loops. + */ +void _IO_Relax( void ); + +/** @} */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* _RTEMS_DEV_IO_H */ diff --git a/cpukit/include/rtems/imfs.h b/cpukit/include/rtems/imfs.h index 7db9b4e462..405f489ab3 100644 --- a/cpukit/include/rtems/imfs.h +++ b/cpukit/include/rtems/imfs.h @@ -477,7 +477,7 @@ extern void IMFS_fsunmount( */ extern int rtems_tarfs_load( const char *mountpoint, - uint8_t *tar_image, + const void *tar_image, size_t tar_size ); diff --git a/cpukit/include/rtems/libio.h b/cpukit/include/rtems/libio.h index cb0e6879a9..5424a2a03c 100644 --- a/cpukit/include/rtems/libio.h +++ b/cpukit/include/rtems/libio.h @@ -56,6 +56,7 @@ #include <rtems/fs.h> #include <rtems/chain.h> #include <rtems/score/atomic.h> +#include <rtems/termiosdevice.h> #ifdef __cplusplus extern "C" { @@ -1360,7 +1361,7 @@ typedef struct { /** * @brief Parameter block for open/close. */ -typedef struct { +typedef struct rtems_libio_open_close_args { rtems_libio_t *iop; uint32_t flags; uint32_t mode; @@ -1902,7 +1903,7 @@ typedef struct rtems_termios_callbacks { int (*setAttributes)(int minor, const struct termios *t); int (*stopRemoteTx)(int minor); int (*startRemoteTx)(int minor); - int outputUsesInterrupts; + rtems_termios_device_mode outputUsesInterrupts; } rtems_termios_callbacks; static inline void rtems_termios_initialize( void ) diff --git a/cpukit/include/rtems/linkersets.h b/cpukit/include/rtems/linkersets.h index ef1b0d38d4..a5d7b1b037 100644 --- a/cpukit/include/rtems/linkersets.h +++ b/cpukit/include/rtems/linkersets.h @@ -1,5 +1,13 @@ /* SPDX-License-Identifier: BSD-2-Clause */ +/** + * @file + * + * @ingroup RTEMSAPILinkerSets + * + * @brief This header file provides the linker sets API. + */ + /* * Copyright (C) 2015, 2020 embedded brains GmbH & Co. KG * @@ -34,6 +42,36 @@ extern "C" { #endif /* __cplusplus */ +/** + * @ingroup RTEMSImpl + * + * @brief Obfuscates a pointer to prevent compiler optimizations. + * + * @param ptr is the pointer to obfuscate. + * + * @return Returns the unsigned integer representation of the obfuscated + * pointer. + */ +static inline uintptr_t _Linker_set_Obfuscate( const void *ptr ) +{ + uintptr_t addr; + + addr = (uintptr_t) ptr; + RTEMS_OBFUSCATE_VARIABLE( addr ); + + return addr; +} + +/** + * @defgroup RTEMSAPILinkerSets Linker Sets + * + * @ingroup RTEMSAPI + * + * @brief This group contains the linker sets API. + * + * @{ + */ + #define RTEMS_LINKER_SET_BEGIN( set ) \ _Linker_set_##set##_begin @@ -129,16 +167,6 @@ extern "C" { decl \ RTEMS_SECTION( ".rtemsrwset." #set ".content" ) -static inline uintptr_t _Linker_set_Obfuscate( const void *ptr ) -{ - uintptr_t addr; - - addr = (uintptr_t) ptr; - RTEMS_OBFUSCATE_VARIABLE( addr ); - - return addr; -} - #define RTEMS_LINKER_SET_SIZE( set ) \ ( _Linker_set_Obfuscate( RTEMS_LINKER_SET_END( set ) ) \ - _Linker_set_Obfuscate( RTEMS_LINKER_SET_BEGIN( set ) ) ) @@ -157,6 +185,8 @@ static inline uintptr_t _Linker_set_Obfuscate( const void *ptr ) ++item \ ) +/** @} */ + #ifdef __cplusplus } #endif /* __cplusplus */ diff --git a/cpukit/include/rtems/posix/posixapi.h b/cpukit/include/rtems/posix/posixapi.h index 24c1dc51e0..5d78573ef7 100644 --- a/cpukit/include/rtems/posix/posixapi.h +++ b/cpukit/include/rtems/posix/posixapi.h @@ -3,10 +3,10 @@ /** * @file * - * @brief POSIX API Implementation + * @ingroup POSIXAPI * - * This include file defines the top level interface to the POSIX API - * implementation in RTEMS. + * @brief This header file provides interfaces used by the POSIX API + * implementation. */ /* diff --git a/cpukit/include/rtems/posix/spinlockimpl.h b/cpukit/include/rtems/posix/spinlockimpl.h index 855e57cc14..10424f1961 100644 --- a/cpukit/include/rtems/posix/spinlockimpl.h +++ b/cpukit/include/rtems/posix/spinlockimpl.h @@ -2,11 +2,11 @@ /** * @file - * - * @brief Inlined Routines from the POSIX Spinlock Manager * - * This file contains the static inlin implementation of the inlined - * routines from the POSIX Spinlock Manager. + * @ingroup POSIXAPI + * + * @brief This header file provides interfaces used by the POSIX Spinlock + * implementation. */ /* diff --git a/cpukit/include/rtems/regulator.h b/cpukit/include/rtems/regulator.h new file mode 100644 index 0000000000..442040a180 --- /dev/null +++ b/cpukit/include/rtems/regulator.h @@ -0,0 +1,502 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ + +/** + * @file + * + * @ingroup RegulatorAPI + * + * @brief This header file defines the Regulator API. + * + */ + +/* + * Copyright (C) 2023 On-Line Applications Research Corporation (OAR) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * @defgroup RegulatorAPI Regulator API + * + * @brief Regulator APIs + * + * The Regulator provides a set of APIs to manage input sources which + * produces bursts of message traffic. + * + * The regulator is designed to sit logically between two entities -- a + * source and a destination, where it limits the traffic sent to the + * destination to prevent it from being flooded with messages from the + * source. This can be used to accommodate bursts of input from a source + * and meter it out to a destination. The maximum number of messages + * which can be buffered in the regulator is specified by the + * @a maximum_messages field in the @a rtems_regulator_attributes + * structure passed as an argument to @a rtems_regulator_create(). + * + * The regulator library accepts an input stream of messages from a + * source and delivers them to a destination. The regulator assumes that the + * input stream from the source contains sporadic bursts of data which can + * exceed the acceptable rate of the destination. By limiting the message rate, + * the regulator prevents an overflow of messages. + * + * The regulator can be configured for the input buffering required to manage + * the maximum burst and for the metering rate for the output. The output rate + * is in messages per second. If the sender produces data too fast, the + * regulator will buffer the configured number of messages. + * + * A configuration capability is provided to allow for adaptation to different + * message streams. The regulator can also support running multiple instances, + * which could be used on independent message streams. + * + * The regulator provides a simple interface to the application for avoiding + * bursts of input from a fast source overflowing a slower destination. + * + * It is assumed that the application has a design limit on the number of + * messages which may be buffered. All messages accepted by the regulator, + * assuming no overflow on input, will eventually be output by the Delivery + * thread. + * + * A regulator instance is used as follows from the producer/source side: + * + * @code + * while (1) + * use rtems_regulator_obtain_buffer to obtain a buffer + * input operation to fetch data into the buffer + * rtems_regulator_send(buffer, size of message) + * @endcode + * + * The delivery of message buffers to the Destination and subsequent + * release is performed in the context of the delivery thread by either + * the delivery function or delivery thread. Details are below. + * + * The sequence diagram below shows the interaction between a message Source, + * a Regulator instance, and RTEMS, given the usage described in the above + * paragraphs. + * + * \startuml "Regulator Application Input Source Usage" + * Source -> Regulator : rtems_regulator_obtain_buffer(regulator, buffer) + * Regulator -> RTEMS : rtems_partition_get_buffer(id, buffer) + * RTEMS --> Regulator : rtems_status_code + * Regulator --> Source : rtems_status_code + * Source -> Regulator : rtems_regulator_send(regulator, message, length) + * Regulator -> RTEMS : rtems_message_queue_send(id, message, size) + * RTEMS --> Regulator : rtems_status_code + * Regulator --> Source : rtems_status_code + * \enduml + * + * As illustrated in the sequence diagram, the Source usually corresponds + * to application software reading a system input. The Source obtains a + * buffer from the Regulator instance and fills it with incoming data. + * The application explicitly obtaining a buffer and filling it in allows + * for zero copy operations on the Source side. + * + * The Source then sends the buffer to the Regulator instance. The Regulator + * the sends the buffer via a message queue which to the Delivery thread. + * The Delivery thread executes periodically at a rate specified at + * Regulation creation. At each period, the Delivery thread attempts to + * receive up to a configured number of buffers and invoke the Delivery + * function to deliver them to the Destination. + * + * The Delivery function is provided by the application for this + * specific Regulator instance. Depending on the Destination, it may use + * a function which copies the buffer contents (e.g., write()) or which + * operates directly on the buffer contents (e.g. DMA from buffer). In + * the case of a Destination which copies the buffer contents, the buffer + * can be released via @a rtems_regulator_release_buffer() as soon as the + * function or copying completes. In the case where the delivery uses the + * buffer and returns, the call to @a rtems_regulator_release_buffer() + * will occur when the use of the buffer is complete (e.g. completion + * of DMA transfer). This explicit and deliberate exposure of buffering + * provides the application with the ability to avoid copying the contents. + * + * After the Source has sent the message to the Regulator instance, + * the Source is free to process another input and the Regulator + * instance will ensure that the buffer is delivered to the Delivery + * function and Destination. + * + * The Regulator implementation uses the RTEMS Classic API Partition Manager + * to manage the buffer pool and the RTEMS Classic API Message Queue + * Manager to send the buffer to the Delivery thread. + */ + +#ifndef REGULATOR_H +#define REGULATOR_H + +#include <stdlib.h> + +#include <rtems.h> + +/** + * @ingroup RegulatorAPI + * + * @brief Regulator Delivery Function Type + * + * The user provides a function which is invoked to deliver a message + * to the output. It is invoked by the Delivery thread created as part + * of @a rtems_regulator_create(). The priority and stack size of the + * Delivery thread are specified in the regulator attribute set. + * + * It takes three parameters: + * + * @param[in] context is an untyped pointer to a user context + * @param[in] message points to the message + * @param[in] length is the message size + * + * The following is an example deliverer function. It assumes that the + * application has defined the my_context_t structure and it has at least + * the socket field. The @a message passed in originated with an + * application source which obtained the @a message buffer using + * @a rtems_regulator_obtain_buffer(), filled it in with source data, + * and used @a rtems_regulator_send() to hand to the regulator instance + * for later delivery. + * + * @code + * bool my_deliverer( + * void *context, + * void *message, + * size_t length + * ) + * { + * my_context_t *my_context; + * + * my_context = (my_context_t *)context; + * + * write(my_context->socket, message, length); + * rtems_regulator_release_buffer(message); + * // return false to indicate we released the buffer + * return false; + * } + * @endcode + * + * The delivery function returns true to indicate that the delivery thread + * should release the buffer or false to indicate that it released the + * buffer. If the delivery function invokes a function like @a write() + * to deliver the message to the destination, then the buffer can be + * released immediately after the call. If the delivery function does + * something like setting up a DMA transfer of the buffer, it cannot be + * released until after the DMA is complete. + * + * The following sequence diagram shows the behavior of the Delivery thread + * body and its interaction with the user-supplied deliverer() function. + * + * \startuml "Regulator Delivery Thread Body" + * loop while (1) + * "Delivery Thread" -> RTEMS : rtems_rate_monotonic_period(id, delivery_thread_period) + * loop for 0 : maximum_to_dequeue_per_period + * "Delivery Thread" -> RTEMS : rtems_message_queue_receive(id, message, size, wait, 0) + * RTEMS --> "Delivery Thread" : rtems_status_code + * group if [rtems_status_code != RTEMS_SUCCESSFUL] + * RTEMS -> "Delivery Thread" : break + * end + * "Delivery Thread" -> Application : deliverer(context, buffer, length) + * "Delivery Thread" -> RTEMS : rtems_partition_return_buffer(id, buffer) + * RTEMS --> "Delivery Thread" : rtems_status_code + * end + * end + * \enduml + * + * In the above sequence diagram, the key points are: + * + * -# The Delivery Thread Body is periodically executed. + * -# During each period, up to the instance configuration parameter + * @a maximum_to_dequeue_per_period may be dequeued and + * passed the application's delivery function for processing. + * + * Note that the application explicitly obtains buffers from the + * regulator instance but that the release may be done by Delivery + * Thread, the Delivery function, or later when the buffer contents + * are transferred. + */ +typedef bool (*rtems_regulator_deliverer)( + void *context, + void *message, + size_t length +); + +/** + * @ingroup RegulatorAPI + * + * @brief Attributes for Regulator Instance + * + * An instance of this structure must be populated by the application + * before creating an instance of the regulator. These settings tailor + * the behavior of the regulator instance. + */ +typedef struct { + /** Application function to invoke to output a message to the destination*/ + rtems_regulator_deliverer deliverer; + + /** Context pointer to pass to deliver function */ + void *deliverer_context; + + /** Maximum size message to process */ + size_t maximum_message_size; + + /** Maximum number of messages to be able to buffer */ + size_t maximum_messages; + + /** Priority of Delivery thread */ + rtems_task_priority delivery_thread_priority; + + /** Stack size of Delivery thread */ + size_t delivery_thread_stack_size; + + /** Period (in ticks) of Delivery thread */ + rtems_interval delivery_thread_period; + + /** Maximum messages to dequeue per period */ + size_t maximum_to_dequeue_per_period; + +} rtems_regulator_attributes; + +/** + * @ingroup RegulatorAPI + * + * @brief Statistics for Regulator Instance + * + * An instance of this structure is provided to the directive + * @a rtems_regulator_get_statistics and is filled in by that service. + */ +typedef struct { + /** Number of successfully obtained buffers. */ + size_t obtained; + + /** Number of successfully released buffers. */ + size_t released; + + /** Number of successfully delivered buffers. */ + size_t delivered; + + /** Rate Monotonic Period statistics for Delivery Thread */ + rtems_rate_monotonic_period_statistics period_statistics; + +} rtems_regulator_statistics; + +/** + * @ingroup RegulatorAPI + * + * @brief Regulator Internal Structure + */ +struct _Regulator_Control; + +/** + * @ingroup RegulatorAPI + * + * @brief Regulator Instance + * + * This is used by the application as the handle to a Regulator instance. + */ +typedef struct _Regulator_Control *rtems_regulator_instance; + +/** + * @ingroup RegulatorAPI + * + * @brief Create a regulator + * + * This function creates an instance of a regulator. It uses the provided + * @a attributes to create the instance return in @a regulator. This instance + * will allocate the buffers associated with the regulator instance as well + * as the Delivery thread. + * + * The @a attributes structure defines the priority and stack size of + * the Delivery thread dedicated to this regulator instance. It also + * defines the period of the Delivery thread and the maximum number of + * messages that may be delivered per period via invocation of the + * delivery function. + * + * For each regulator instance, the following resources are allocated: + * + * - A memory area for the regulator control block using @a malloc(). + * - A RTEMS Classic API Message Queue is constructed with message + * buffer memory allocated using @a malloc(). Each message consists + * of a pointer and a length. + * - A RTEMS Classic API Partition. + * - A RTEMS Classic API Rate Monotonic Period. + * + * @param[in] attributes specify the regulator instance attributes + * @param[inout] regulator will point to the regulator instance + * + * @return an RTEMS status code indicating success or failure. + * + * @note This function allocates memory for the buffers holding messages, + * an Delivery thread and an RTEMS partition. When it executes, the + * Delivery thread will create an RTEMS rate monotonic period. + */ +rtems_status_code rtems_regulator_create( + rtems_regulator_attributes *attributes, + rtems_regulator_instance **regulator +); + +/** + * @ingroup RegulatorAPI + * + * @brief Delete a regulator + * + * This function is used to delete the specified @a regulator instance. + * + * It is the responsibility of the user to ensure that any resources + * such as sockets or open file descriptors used by the delivery + * function are also deleted. It is likely safer to delete those + * delivery resources after deleting the regulator instance rather than + * before. + * + * @param[in] regulator is the instance to delete + * @param[in] ticks is the maximum number of ticks to wait for + * the delivery thread to shutdown. + * + * @return an RTEMS status code indicating success or failure. + * + * @note This function deallocates the resources allocated during + * @a rtems_regulator_create(). + */ +rtems_status_code rtems_regulator_delete( + rtems_regulator_instance *regulator, + rtems_interval ticks +); + +/** + * @ingroup RegulatorAPI + * + * @brief Obtain Buffer from Regulator + * + * This function is used to obtain a buffer from the regulator's pool. The + * @a buffer returned is assumed to be filled in with contents and used + * in a subsequent call to @a rtems_regulator_send(). When the @a buffer is + * delivered, it is expected to be released. If the @a buffer is not + * successfully accepted by this function, then it should be returned + * using @a rtems_regulator_release_buffer() or used to send another message. + * + * The @a buffer is of the maximum_message_size specified in the attributes + * passed in to @a rtems_regulator_create(). + * + * @param[in] regulator is the regulator instance to operate upon + * @param[out] buffer will point to the allocated buffer + * + * @return an RTEMS status code indicating success or failure. + * + * @note This function does not perform dynamic allocation. It obtains a + * buffer from the pool allocated during @a rtems_regulator_create(). + * + * @note Any attempt to write outside the buffer area is undefined. + */ +rtems_status_code rtems_regulator_obtain_buffer( + rtems_regulator_instance *regulator, + void **buffer +); + +/** + * @ingroup RegulatorAPI + * + * @brief Release Previously Obtained Regulator Buffer + * + * This function is used to release a buffer to the regulator's pool. It is + * assumed that the @a buffer returned will not be used by the application + * anymore. The @a buffer must have previously been allocated by + * @a rtems_regulator_obtain_buffer() and NOT passed to + * @a rtems_regulator_send(). + * + * If a subsequent @a rtems_regulator_send() using this @a buffer is + * successful, the @a buffer will eventually be processed by the delivery + * thread and released. + * + * @param[in] regulator is the regulator instance to operate upon + * @param[out] buffer will point to the buffer to release + * + * @return an RTEMS status code indicating success or failure. + * + * @note This function does not perform dynamic deallocation. It releases a + * buffer to the pool allocated during @a rtems_regulator_create(). + */ +rtems_status_code rtems_regulator_release_buffer( + rtems_regulator_instance *regulator, + void *buffer +); + +/** + * @ingroup RegulatorAPI + * + * @brief Send to regulator instance + * + * This function is used by the producer to send a @a message to the + * @a regulator for later delivery by the Delivery thread. The message is + * contained in the memory pointed to by @a message and is @a length + * bytes in length. + * + * It is required that the @a message buffer was obtained via + * @a rtems_regulator_obtain_buffer(). + * + * It is assumed that the @a message buffer has been filled in with + * application content to deliver. + * + * If the @a rtems_regulator_send() is successful, the buffer is enqueued + * inside the regulator instance for subsequent delivery. After the + * @a message is delivered, it may be released by either delivery + * function or the application code depending on the implementation. + * + * The status @a RTEMS_TOO_MANY is returned if the regulator's + * internal queue is full. This indicates that the configured + * maximum number of messages was insufficient. It is the + * responsibility of the caller to decide whether to hold messages, + * drop them, or print a message that the maximum number of messages + * should be increased. + * + * If @a rtems_regulator_send() is unsuccessful, it is the application's + * responsibility to release the buffer. If it is successfully sent, + * then it becomes the responsibility of the delivery function to + * release it. + * + * @param[in] regulator is the regulator instance to operate upon + * @param[out] message points to the message to deliver + * @param[out] length is the size of the message in bytes + * + * @return an RTEMS status code indicating success or failure. + * + */ +rtems_status_code rtems_regulator_send( + rtems_regulator_instance *regulator, + void *message, + size_t length +); + +/** + * @ingroup RegulatorAPI + * + * @brief Obtain statistics for regulator instance + * + * This function is used by the application to obtain statistics + * information about the regulator instance. + * + * If the @a obtained and @a released fields in the returned + * @a statistics structure are equal, then there are no buffers + * outstanding from this regulator instance. + * + * @param[in] regulator is the regulator instance to operate upon + * @param[inout] statistics points to the statistics structure to fill in + * + * @return an RTEMS status code indicating success or failure. + * + */ +rtems_status_code rtems_regulator_get_statistics( + rtems_regulator_instance *regulator, + rtems_regulator_statistics *statistics +); + +#endif /* REGULATOR_H */ diff --git a/cpukit/include/rtems/regulatorimpl.h b/cpukit/include/rtems/regulatorimpl.h new file mode 100644 index 0000000000..a5652a764d --- /dev/null +++ b/cpukit/include/rtems/regulatorimpl.h @@ -0,0 +1,135 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ + +/** + * @file + * + * @ingroup RegulatorInternalAPI + * + * @brief Regulator Library Implementation Support + */ + +/* + * Copyright (C) 2023 On-Line Applications Research Corporation (OAR) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * @defgroup RegulatorInternalAPI Regulator API Internals + * + * @brief Regulator Internal Information + * + * This concerns implementation information about the Regulator. + */ + +#ifndef RTEMS_REGULATORIMPL_H +#define RTEMS_REGULATORIMPL_H + +#include <stdatomic.h> + +#include <rtems/chain.h> + + +/** + * @ingroup RegulatorInternalAPI + * + * This constant is used to indicate the regulator instance is initialized. + */ +#define REGULATOR_INITIALIZED 0xDeadF00d + +/** + * @ingroup RegulatorInternalAPI + * + * @brief Regulator Message Instance Management Structure + */ +typedef struct { + /** This points to the message contents. */ + void *buffer; + /** This is the length of the message. */ + size_t length; +} _Regulator_Message_t; + +/** + * @ingroup RegulatorInternalAPI + * + * @brief Regulator Statistics Private Structure + * + * An instance of this structure is allocated per regulator instance. + */ +typedef struct { + /** Number of successfully obtained buffers. */ + atomic_size_t obtained; + + /** Number of successfully released buffers. */ + atomic_size_t released; + + /** Number of successfully delivered buffers. */ + atomic_size_t delivered; +} _Regulator_Statistics; + +/** + * @ingroup RegulatorInternalAPI + * + * @brief Regulator Instance Private Structure + * + * An instance of this structure is allocated per regulator instance. + */ +typedef struct { + /** Has magic value when instance is usable */ + uint32_t initialized; + + /** Attributes for this instance -- copied from user */ + rtems_regulator_attributes Attributes; + + /** Pointer to allocated message memory */ + void *message_memory; + + /** Pointer to allocated memory for RTEMS Message Queue for pending buffers*/ + void *message_queue_storage; + + /** RTEMS Message Queue of pending outgoing messages */ + rtems_id queue_id; + + /** RTEMS Partition for pool of unused messages */ + rtems_id messages_partition_id; + + /** RTEMS Task for performing output */ + rtems_id delivery_thread_id; + + /** Id of period used by output thread */ + rtems_id delivery_thread_period_id; + + /** Indicates Delivery thread is running */ + bool delivery_thread_is_running; + + /** Indicates Delivery thread has been requested to exit */ + bool delivery_thread_request_exit; + + /** Indicates Delivery thread has exited */ + bool delivery_thread_has_exited; + + /** Internal Statistics */ + _Regulator_Statistics Statistics; + +} _Regulator_Control; + +#endif /* RTEMS_REGULATORIMPL_H */ diff --git a/cpukit/include/rtems/rtems/cache.h b/cpukit/include/rtems/rtems/cache.h index 20c630a3eb..d59a3fddca 100644 --- a/cpukit/include/rtems/rtems/cache.h +++ b/cpukit/include/rtems/rtems/cache.h @@ -59,6 +59,7 @@ #include <stddef.h> #include <stdint.h> +#include <rtems/rtems/status.h> #ifdef __cplusplus extern "C" { @@ -89,6 +90,10 @@ extern "C" { * * @param size is the size in bytes of the cache coherent memory area to add. * + * @retval ::RTEMS_SUCCESSFUL The requested operation was successful. + * + * @retval ::RTEMS_UNSATISFIED The requested operation was not successful. + * * @par Constraints * @parblock * The following constraints apply to this directive: @@ -102,7 +107,7 @@ extern "C" { * cause the calling task to be preempted. * @endparblock */ -void rtems_cache_coherent_add_area( void *begin, uintptr_t size ); +rtems_status_code rtems_cache_coherent_add_area( void *begin, uintptr_t size ); /* Generated from spec:/rtems/cache/if/coherent-allocate */ diff --git a/cpukit/include/rtems/rtems/mainpage.h b/cpukit/include/rtems/rtems/mainpage.h deleted file mode 100644 index f168cc3395..0000000000 --- a/cpukit/include/rtems/rtems/mainpage.h +++ /dev/null @@ -1,951 +0,0 @@ -/* SPDX-License-Identifier: BSD-2-Clause */ - -/** - * @file - * - * @ingroup RTEMSImplDoxygen - * - * @brief This file exists to provide a top level description of RTEMS for - * Doxygen. - */ - -/* - * COPYRIGHT (c) 1989-2014. - * On-Line Applications Research Corporation (OAR). - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * @mainpage - * - * The RTEMS real-time operating systems is a layered system with each of the - * public APIs implemented in terms of a common foundation layer called the - * SuperCore. This is the Doxygen generated documentation for the RTEMS CPU - * Kit including the Classic API, POSIX API and SuperCore. - */ - -/** - * @page RTEMSPreface RTEMS History and Introduction - * - * In recent years, the cost required to develop a software product has - * increased significantly while the target hardware costs have decreased. Now - * a larger portion of money is expended in developing, using, and maintaining - * software. The trend in computing costs is the complete dominance of software - * over hardware costs. Because of this, it is necessary that formal - * disciplines be established to increase the probability that software is - * characterized by a high degree of correctness, maintainability, and - * portability. In addition, these disciplines must promote practices that aid - * in the consistent and orderly development of a software system within - * schedule and budgetary constraints. To be effective, these disciplines must - * adopt standards which channel individual software efforts toward a common - * goal. - * - * The push for standards in the software development field has been met with - * various degrees of success. The Microprocessor Operating Systems Interfaces - * (MOSI) effort has experienced only limited success. As popular as the UNIX - * operating system has grown, the attempt to develop a standard interface - * definition to allow portable application development has only recently begun - * to produce the results needed in this area. Unfortunately, very little - * effort has been expended to provide standards addressing the needs of the - * real-time community. Several organizations have addressed this need during - * recent years. - * - * The Real Time Executive Interface Definition (RTEID) was developed by - * Motorola with technical input from Software Components Group. RTEID was - * adopted by the VMEbus International Trade Association (VITA) as a baseline - * draft for their proposed standard multiprocessor, real-time executive - * interface, Open Real-Time Kernel Interface Definition (ORKID). These two - * groups are currently working together with the IEEE P1003.4 committee to - * insure that the functionality of their proposed standards is adopted as the - * real-time extensions to POSIX. - * - * This emerging standard defines an interface for the development of real-time - * software to ease the writing of real-time application programs that are - * directly portable across multiple real-time executive implementations. This - * interface includes both the source code interfaces and run-time behavior as - * seen by a real-time application. It does not include the details of how a - * kernel implements these functions. The standard's goal is to serve as a - * complete definition of external interfaces so that application code that - * conforms to these interfaces will execute properly in all real-time - * executive environments. With the use of a standards compliant executive, - * routines that acquire memory blocks, create and manage message queues, - * establish and use semaphores, and send and receive signals need not be - * redeveloped for a different real-time environment as long as the new - * environment is compliant with the standard. Software developers need only - * concentrate on the hardware dependencies of the real-time system. - * Furthermore, most hardware dependencies for real-time applications can be - * localized to the device drivers. - * - * A compliant executive provides simple and flexible real-time - * multiprocessing. It easily lends itself to both tightly-coupled and - * loosely-coupled configurations (depending on the system hardware - * configuration). Objects such as tasks, queues, events, signals, semaphores, - * and memory blocks can be designated as global objects and accessed by any - * task regardless of which processor the object and the accessing task reside. - * - * The acceptance of a standard for real-time executives will produce the same - * advantages enjoyed from the push for UNIX standardization by AT&T's System V - * Interface Definition and IEEE's POSIX efforts. A compliant multiprocessing - * executive will allow close coupling between UNIX systems and real-time - * executives to provide the many benefits of the UNIX development environment - * to be applied to real-time software development. Together they provide the - * necessary laboratory environment to implement real-time, distributed, - * embedded systems using a wide variety of computer architectures. - * - * A study was completed in 1988, within the Research, Development, and - * Engineering Center, U.S. Army Missile Command, which compared the various - * aspects of the Ada programming language as they related to the application - * of Ada code in distributed and/or multiple processing systems. Several - * critical conclusions were derived from the study. These conclusions have a - * major impact on the way the Army develops application software for embedded - * applications. These impacts apply to both in-house software development and - * contractor developed software. - * - * A conclusion of the analysis, which has been previously recognized by other - * agencies attempting to utilize Ada in a distributed or multiprocessing - * environment, is that the Ada programming language does not adequately - * support multiprocessing. Ada does provide a mechanism for multi-tasking, - * however, this capability exists only for a single processor system. The - * language also does not have inherent capabilities to access global named - * variables, flags or program code. These critical features are essential in - * order for data to be shared between processors. However, these drawbacks do - * have workarounds which are sometimes awkward and defeat the intent of - * software maintainability and portability goals. - * - * Another conclusion drawn from the analysis, was that the run time executives - * being delivered with the Ada compilers were too slow and inefficient to be - * used in modern missile systems. A run time executive is the core part of the - * run time system code, or operating system code, that controls task - * scheduling, input/output management and memory management. Traditionally, - * whenever efficient executive (also known as kernel) code was required by the - * application, the user developed in-house software. This software was usually - * written in assembly language for optimization. - * - * Because of this shortcoming in the Ada programming language, software - * developers in research and development and contractors for project managed - * systems, are mandated by technology to purchase and utilize off-the-shelf - * third party kernel code. The contractor, and eventually the Government, must - * pay a licensing fee for every copy of the kernel code used in an embedded - * system. - * - * The main drawback to this development environment is that the Government - * does not own, nor has the right to modify code contained within the kernel. - * V&V techniques in this situation are more difficult than if the complete - * source code were available. Responsibility for system failures due to faulty - * software is yet another area to be resolved under this environment. - * - * The Guidance and Control Directorate began a software development effort to - * address these problems. A project to develop an experimental run time kernel - * was begun that will eliminate the major drawbacks of the Ada programming - * language mentioned above. The Real Time Executive for Multiprocessor Systems - * (RTEMS) provides full capabilities for management of tasks, interrupts, - * time, and multiple processors in addition to those features typical of - * generic operating systems. The code is Government owned, so no licensing - * fees are necessary. RTEMS has been implemented in both the Ada and C - * programming languages. It has been ported to the following processor - * families: - * - * - Altera NIOS II - * - Analog Devices Blackfin - * - ARM - * - Freescale (formerly Motorola) MC68xxx - * - Freescale (formerly Motorola) MC683xx - * - Freescale (formerly Motorola) ColdFire - * - Intel i386 and above - * - Lattice Semiconductor LM32 - * - MIPS - * - PowerPC - * - Renesas (formerly Hitachi) SuperH - * - Renesas (formerly Hitachi) H8/300 - * - SPARC - * - Texas Instruments C3x/C4x - * - UNIX - * - * Support for other processor families, including RISC, CISC, and DSP, is - * planned. Since almost all of RTEMS is written in a high level language, - * ports to additional processor families require minimal effort. - * - * RTEMS multiprocessor support is capable of handling either homogeneous or - * heterogeneous systems. The kernel automatically compensates for - * architectural differences (byte swapping, etc.) between processors. This - * allows a much easier transition from one processor family to another without - * a major system redesign. - * - * Since the proposed standards are still in draft form, RTEMS cannot and does - * not claim compliance. However, the status of the standard is being carefully - * monitored to guarantee that RTEMS provides the functionality specified in - * the standard. Once approved, RTEMS will be made compliant. - */ - -/** - * @page RTEMSOverview RTEMS Overview - * - * @section RTEMSOverviewSecIntroduction Introduction - * - * RTEMS, Real-Time Executive for Multiprocessor Systems, is a real-time - * executive (kernel) which provides a high performance environment for - * embedded military applications including the following features: - * - * - multitasking capabilities - * - homogeneous and heterogeneous multiprocessor systems - * - event-driven, priority-based, preemptive scheduling - * - optional rate monotonic scheduling - * - intertask communication and synchronization - * - priority inheritance - * - responsive interrupt management - * - dynamic memory allocation - * - high level of user configurability - * - * This manual describes the usage of RTEMS for applications written in the C - * programming language. Those implementation details that are processor - * dependent are provided in the Applications Supplement documents. A - * supplement document which addresses specific architectural issues that - * affect RTEMS is provided for each processor type that is supported. - * - * @section RTEMSOverviewSecRealtimeApplicationSystems Real-time Application Systems - * - * Real-time application systems are a special class of computer applications. - * They have a complex set of characteristics that distinguish them from other - * software problems. Generally, they must adhere to more rigorous - * requirements. The correctness of the system depends not only on the results - * of computations, but also on the time at which the results are produced. The - * most important and complex characteristic of real-time application systems - * is that they must receive and respond to a set of external stimuli within - * rigid and critical time constraints referred to as deadlines. Systems can be - * buried by an avalanche of interdependent, asynchronous or cyclical event - * streams. - * - * Deadlines can be further characterized as either hard or soft based upon the - * value of the results when produced after the deadline has passed. A deadline - * is hard if the results have no value or if their use will result in a - * catastrophic event. In contrast, results which are produced after a soft - * deadline may have some value. - * - * Another distinguishing requirement of real-time application systems is the - * ability to coordinate or manage a large number of concurrent activities. - * Since software is a synchronous entity, this presents special problems. One - * instruction follows another in a repeating synchronous cycle. Even though - * mechanisms have been developed to allow for the processing of external - * asynchronous events, the software design efforts required to process and - * manage these events and tasks are growing more complicated. - * - * The design process is complicated further by spreading this activity over a - * set of processors instead of a single processor. The challenges associated - * with designing and building real-time application systems become very - * complex when multiple processors are involved. New requirements such as - * interprocessor communication channels and global resources that must be - * shared between competing processors are introduced. The ramifications of - * multiple processors complicate each and every characteristic of a real-time - * system. - * - * @section RTEMSOverviewSecRealtimeExecutive Real-time Executive - * - * Fortunately, real-time operating systems or real-time executives serve as a - * cornerstone on which to build the application system. A real-time - * multitasking executive allows an application to be cast into a set of - * logical, autonomous processes or tasks which become quite manageable. Each - * task is internally synchronous, but different tasks execute independently, - * resulting in an asynchronous processing stream. Tasks can be dynamically - * paused for many reasons resulting in a different task being allowed to - * execute for a period of time. The executive also provides an interface to - * other system components such as interrupt handlers and device drivers. - * System components may request the executive to allocate and coordinate - * resources, and to wait for and trigger synchronizing conditions. The - * executive system calls effectively extend the CPU instruction set to support - * efficient multitasking. By causing tasks to travel through well-defined - * state transitions, system calls permit an application to demand-switch - * between tasks in response to real-time events. - * - * By proper grouping of responses to stimuli into separate tasks, a system can - * now asynchronously switch between independent streams of execution, directly - * responding to external stimuli as they occur. This allows the system design - * to meet critical performance specifications which are typically measured by - * guaranteed response time and transaction throughput. The multiprocessor - * extensions of RTEMS provide the features necessary to manage the extra - * requirements introduced by a system distributed across several processors. - * It removes the physical barriers of processor boundaries from the world of - * the system designer, enabling more critical aspects of the system to receive - * the required attention. Such a system, based on an efficient real-time, - * multiprocessor executive, is a more realistic model of the outside world or - * environment for which it is designed. As a result, the system will always be - * more logical, efficient, and reliable. - * - * By using the directives provided by RTEMS, the real-time applications - * developer is freed from the problem of controlling and synchronizing - * multiple tasks and processors. In addition, one need not develop, test, - * debug, and document routines to manage memory, pass messages, or provide - * mutual exclusion. The developer is then able to concentrate solely on the - * application. By using standard software components, the time and cost - * required to develop sophisticated real-time applications is significantly - * reduced. - * - * @section RTEMSOverviewSecApplicationArchitecture RTEMS Application Architecture - * - * One important design goal of RTEMS was to provide a bridge between two - * critical layers of typical real-time systems. As shown in the following - * figure, RTEMS serves as a buffer between the project dependent application - * code and the target hardware. Most hardware dependencies for real-time - * applications can be localized to the low level device drivers. - * - * @todo Image RTEMS Application Architecture - * - * The RTEMS I/O interface manager provides an efficient tool for incorporating - * these hardware dependencies into the system while simultaneously providing a - * general mechanism to the application code that accesses them. A well - * designed real-time system can benefit from this architecture by building a - * rich library of standard application components which can be used repeatedly - * in other real-time projects. - * - * @section RTEMSOverviewSecInternalArchitecture RTEMS Internal Architecture - * - * RTEMS can be viewed as a set of layered components that work in harmony to - * provide a set of services to a real-time application system. The executive - * interface presented to the application is formed by grouping directives into - * logical sets called resource managers. Functions utilized by multiple - * managers such as scheduling, dispatching, and object management are provided - * in the executive core. The executive core depends on a small set of CPU - * dependent routines. Together these components provide a powerful run time - * environment that promotes the development of efficient real-time application - * systems. The following figure illustrates this organization: - * - * @todo Image RTEMS Architecture - * - * Subsequent chapters present a detailed description of the capabilities - * provided by each of the following RTEMS managers: - * - * - initialization - * - task - * - interrupt - * - clock - * - timer - * - semaphore - * - message - * - event - * - signal - * - partition - * - region - * - dual ported memory - * - I/O - * - fatal error - * - rate monotonic - * - user extensions - * - multiprocessing - * - * @section RTEMSOverviewSecUserCustomization User Customization and Extensibility - * - * As 32-bit microprocessors have decreased in cost, they have become - * increasingly common in a variety of embedded systems. A wide range of custom - * and general-purpose processor boards are based on various 32-bit - * processors. RTEMS was designed to make no assumptions concerning the - * characteristics of individual microprocessor families or of specific support - * hardware. In addition, RTEMS allows the system developer a high degree of - * freedom in customizing and extending its features. - * - * RTEMS assumes the existence of a supported microprocessor and sufficient - * memory for both RTEMS and the real-time application. Board dependent - * components such as clocks, interrupt controllers, or I/O devices can be - * easily integrated with RTEMS. The customization and extensibility features - * allow RTEMS to efficiently support as many environments as possible. - * - * @section RTEMSOverviewSecPortability Portability - * - * The issue of portability was the major factor in the creation of RTEMS. - * Since RTEMS is designed to isolate the hardware dependencies in the specific - * board support packages, the real-time application should be easily ported to - * any other processor. The use of RTEMS allows the development of real-time - * applications which can be completely independent of a particular - * microprocessor architecture. - * - * @section RTEMSOverviewSecMemoryRequirements Memory Requirements - * - * Since memory is a critical resource in many real-time embedded systems, - * RTEMS was specifically designed to automatically leave out all services that - * are not required from the run-time environment. Features such as networking, - * various filesystems, and many other features are completely optional. This - * allows the application designer the flexibility to tailor RTEMS to most - * efficiently meet system requirements while still satisfying even the most - * stringent memory constraints. As a result, the size of the RTEMS executive - * is application dependent. - * - * RTEMS requires RAM to manage each instance of an RTEMS object that is - * created. Thus the more RTEMS objects an application needs, the more memory - * that must be reserved. See Configuring a System Determining Memory - * Requirements for more details. - * - * @todo Link to Configuring a SystemDetermining Memory Requirements - * - * RTEMS utilizes memory for both code and data space. Although RTEMS' data - * space must be in RAM, its code space can be located in either ROM or RAM. - * - * @section RTEMSOverviewSecAudience Audience - * - * This manual was written for experienced real-time software developers. - * Although some background is provided, it is assumed that the reader is - * familiar with the concepts of task management as well as intertask - * communication and synchronization. Since directives, user related data - * structures, and examples are presented in C, a basic understanding of the C - * programming language is required to fully understand the material presented. - * However, because of the similarity of the Ada and C RTEMS implementations, - * users will find that the use and behavior of the two implementations is very - * similar. A working knowledge of the target processor is helpful in - * understanding some of RTEMS' features. A thorough understanding of the - * executive cannot be obtained without studying the entire manual because many - * of RTEMS' concepts and features are interrelated. Experienced RTEMS users - * will find that the manual organization facilitates its use as a reference - * document. - */ - -/** - * @addtogroup RTEMSAPIClassic - * - * The facilities provided by RTEMS are built upon a foundation of very - * powerful concepts. These concepts must be understood before the application - * developer can efficiently utilize RTEMS. The purpose of this chapter is to - * familiarize one with these concepts. - * - * @section ClassicRTEMSSecObjects Objects - * - * RTEMS provides directives which can be used to dynamically create, delete, - * and manipulate a set of predefined object types. These types include tasks, - * message queues, semaphores, memory regions, memory partitions, timers, - * ports, and rate monotonic periods. The object-oriented nature of RTEMS - * encourages the creation of modular applications built upon re-usable - * "building block" routines. - * - * All objects are created on the local node as required by the application and - * have an RTEMS assigned ID. All objects have a user-assigned name. Although a - * relationship exists between an object's name and its RTEMS assigned ID, the - * name and ID are not identical. Object names are completely arbitrary and - * selected by the user as a meaningful "tag" which may commonly reflect the - * object's use in the application. Conversely, object IDs are designed to - * facilitate efficient object manipulation by the executive. - * - * @subsection ClassicRTEMSSubSecObjectNames Object Names - * - * An object name is an unsigned 32-bit entity associated with the - * object by the user. The data type @ref rtems_name is used to store object names. - * - * Although not required by RTEMS, object names are often composed of four - * ASCII characters which help identify that object. For example, a task which - * causes a light to blink might be called "LITE". The rtems_build_name() - * routine is provided to build an object name from four ASCII characters. The - * following example illustrates this: - * - * @code - * rtems_name my_name = rtems_build_name('L', 'I', 'T', 'E'); - * @endcode - * - * However, it is not required that the application use ASCII characters to - * build object names. For example, if an application requires one-hundred - * tasks, it would be difficult to assign meaningful ASCII names to each task. - * A more convenient approach would be to name them the binary values one - * through one-hundred, respectively. - * - * RTEMS provides a helper routine, rtems_object_get_name(), which can be used to - * obtain the name of any RTEMS object using just its ID. This routine attempts - * to convert the name into a printable string. - * - * @subsection ClassicRTEMSSubSecObjectIdentifiers Object Identifiers - * - * An object ID is a unique unsigned integer value which uniquely identifies an - * object instance. Object IDs are passed as arguments to many directives in - * RTEMS and RTEMS translates the ID to an internal object pointer. The - * efficient manipulation of object IDs is critical to the performance of RTEMS - * services. Because of this, there are two object ID formats defined. Each - * target architecture specifies which format it will use. There is a 32-bit - * format which is used for most of the supported architectures and supports - * multiprocessor configurations. There is also a simpler 16-bit format which - * is appropriate for smaller target architectures and does not support - * multiprocessor configurations. - * - * @subsubsection ClassicRTEMSSubSec32BitObjectIdentifierFormat 32-Bit Object Identifier Format - * - * The 32-bit format for an object ID is composed of four parts: API, - * object class, node, and index. The data type @ref rtems_id is used to store - * object IDs. - * - * <table> - * <tr> - * <th>Bits</th> - * <td>31</td><td>30</td><td>29</td><td>28</td><td>27</td><td>26</td><td>25</td><td>24</td> - * <td>23</td><td>22</td><td>21</td><td>20</td><td>19</td><td>18</td><td>17</td><td>16</td> - * <td>15</td><td>14</td><td>13</td><td>12</td><td>11</td><td>10</td><td>09</td><td>08</td> - * <td>07</td><td>06</td><td>05</td><td>04</td><td>03</td><td>02</td><td>01</td><td>00</td> - * </tr> - * <tr> - * <th>Contents</th> - * <td colspan=5>Class</td><td colspan=3>API</td><td colspan=8>Node</td><td colspan=16>Object Index</td> - * </tr> - * </table> - * - * The most significant five bits are the object class. The next three bits - * indicate the API to which the object class belongs. The next eight bits - * (16 .. 23) are the number of the node on which this object was created. The - * node number is always one (1) in a single processor system. The least - * significant 16-bits form an identifier within a particular object type. - * This identifier, called the object index, ranges in value from one to the - * maximum number of objects configured for this object type. - * - * @subsubsection ClassicRTEMSSubSec16BitObjectIdentifierFormat 16-Bit Object Identifier Format - * - * The 16-bit format for an object ID is composed of three parts: API, object - * class, and index. The data type @ref rtems_id is used to store object IDs. - * - * <table> - * <tr> - * <th>Bits</th> - * <td>15</td><td>14</td><td>13</td><td>12</td><td>11</td><td>10</td><td>09</td><td>08</td> - * <td>07</td><td>06</td><td>05</td><td>04</td><td>03</td><td>02</td><td>01</td><td>00</td> - * </tr> - * <tr> - * <th>Contents</th> - * <td colspan=5>Class</td><td colspan=3>API</td><td colspan=8>Object Index</td> - * </tr> - * </table> - * - * The 16-bit format is designed to be as similar as possible to the 32-bit - * format. The differences are limited to the elimination of the node field - * and reduction of the index field from 16-bits to 8-bits. Thus the 16-bit - * format only supports up to 255 object instances per API/Class combination - * and single processor systems. As this format is typically utilized by 16-bit - * processors with limited address space, this is more than enough object - * instances. - * - * @subsection ClassicRTEMSSubSecObjectIdentiferDescription Object Identifer Description - * - * The components of an object ID make it possible to quickly locate any object - * in even the most complicated multiprocessor system. Object ID's are - * associated with an object by RTEMS when the object is created and the - * corresponding ID is returned by the appropriate object create directive. The - * object ID is required as input to all directives involving objects, except - * those which create an object or obtain the ID of an object. - * - * The object identification directives can be used to dynamically obtain a - * particular object's ID given its name. This mapping is accomplished by - * searching the name table associated with this object type. If the name is - * non-unique, then the ID associated with the first occurrence of the name - * will be returned to the application. Since object IDs are returned when the - * object is created, the object identification directives are not necessary in - * a properly designed single processor application. - * - * In addition, services are provided to portably examine the subcomponents of - * an RTEMS ID. These services are described in detail later in this manual but - * are prototyped as follows: - * - * - rtems_object_id_get_api() - * - rtems_object_id_get_class() - * - rtems_object_id_get_node() - * - rtems_object_id_get_index() - * - * An object control block is a data structure defined by RTEMS which contains - * the information necessary to manage a particular object type. For efficiency - * reasons, the format of each object type's control block is different. - * However, many of the fields are similar in function. The number of each type - * of control block is application dependent and determined by the values - * specified in the user's Configuration Table. An object control block is - * allocated at object create time and freed when the object is deleted. With - * the exception of user extension routines, object control blocks are not - * directly manipulated by user applications. - * - * @section ClassicRTEMSSecComSync Communication and Synchronization - * - * In real-time multitasking applications, the ability for cooperating - * execution threads to communicate and synchronize with each other is - * imperative. A real-time executive should provide an application with the - * following capabilities - * - * - data transfer between cooperating tasks, - * - data transfer between tasks and ISRs, - * - synchronization of cooperating tasks, and - * - synchronization of tasks and ISRs. - * - * Most RTEMS managers can be used to provide some form of communication and/or - * synchronization. However, managers dedicated specifically to communication - * and synchronization provide well established mechanisms which directly map - * to the application's varying needs. This level of flexibility allows the - * application designer to match the features of a particular manager with the - * complexity of communication and synchronization required. The following - * managers were specifically designed for communication and synchronization: - * - * - @ref ClassicSem - * - @ref ClassicMessageQueue - * - @ref ClassicEvent - * - @ref ClassicSignal - * - * The semaphore manager supports mutual exclusion involving the - * synchronization of access to one or more shared user resources. Binary - * semaphores may utilize the optional priority inheritance algorithm to avoid - * the problem of priority inversion. The message manager supports both - * communication and synchronization, while the event manager primarily - * provides a high performance synchronization mechanism. The signal manager - * supports only asynchronous communication and is typically used for exception - * handling. - * - * @section ClassicRTEMSSecTime Time - * - * The development of responsive real-time applications requires an - * understanding of how RTEMS maintains and supports time-related operations. - * The basic unit of time in RTEMS is known as a tick. The frequency of clock - * ticks is completely application dependent and determines the granularity and - * accuracy of all interval and calendar time operations. - * - * By tracking time in units of ticks, RTEMS is capable of supporting interval - * timing functions such as task delays, timeouts, timeslicing, the delayed - * execution of timer service routines, and the rate monotonic scheduling of - * tasks. An interval is defined as a number of ticks relative to the current - * time. For example, when a task delays for an interval of ten ticks, it is - * implied that the task will not execute until ten clock ticks have occurred. - * All intervals are specified using data type @ref rtems_interval. - * - * A characteristic of interval timing is that the actual interval period may - * be a fraction of a tick less than the interval requested. This occurs - * because the time at which the delay timer is set up occurs at some time - * between two clock ticks. Therefore, the first countdown tick occurs in less - * than the complete time interval for a tick. This can be a problem if the - * clock granularity is large. - * - * The rate monotonic scheduling algorithm is a hard real-time scheduling - * methodology. This methodology provides rules which allows one to guarantee - * that a set of independent periodic tasks will always meet their deadlines -- - * even under transient overload conditions. The rate monotonic manager - * provides directives built upon the Clock Manager's interval timer support - * routines. - * - * Interval timing is not sufficient for the many applications which require - * that time be kept in wall time or true calendar form. Consequently, RTEMS - * maintains the current date and time. This allows selected time operations to - * be scheduled at an actual calendar date and time. For example, a task could - * request to delay until midnight on New Year's Eve before lowering the ball - * at Times Square. The data type @ref rtems_time_of_day is used to specify - * calendar time in RTEMS services. See Clock Manager Time and Date Data - * Structures. - * - * @todo Link to Clock Manager Time and Date Data Structures - * - * Obviously, the directives which use intervals or wall time cannot operate - * without some external mechanism which provides a periodic clock tick. This - * clock tick is typically provided by a real time clock or counter/timer - * device. - * - * @section ClassicRTEMSSecMemoryManagement Memory Management - * - * RTEMS memory management facilities can be grouped into two classes: dynamic - * memory allocation and address translation. Dynamic memory allocation is - * required by applications whose memory requirements vary through the - * application's course of execution. Address translation is needed by - * applications which share memory with another CPU or an intelligent - * Input/Output processor. The following RTEMS managers provide facilities to - * manage memory: - * - * - @ref ClassicRegion - * - @ref ClassicPart - * - @ref ClassicDPMEM - * - * RTEMS memory management features allow an application to create simple - * memory pools of fixed size buffers and/or more complex memory pools of - * variable size segments. The partition manager provides directives to manage - * and maintain pools of fixed size entities such as resource control blocks. - * Alternatively, the region manager provides a more general purpose memory - * allocation scheme that supports variable size blocks of memory which are - * dynamically obtained and freed by the application. The dual-ported memory - * manager provides executive support for address translation between internal - * and external dual-ported RAM address space. - */ - -/** - * @addtogroup RTEMSAPIClassicTasks - * - * @section ClassicTasksSecTaskDefinition Task Definition - * - * Many definitions of a task have been proposed in computer literature. - * Unfortunately, none of these definitions encompasses all facets of the - * concept in a manner which is operating system independent. Several of the - * more common definitions are provided to enable each user to select a - * definition which best matches their own experience and understanding of the - * task concept: - * - * - a "dispatchable" unit. - * - an entity to which the processor is allocated. - * - an atomic unit of a real-time, multiprocessor system. - * - single threads of execution which concurrently compete for resources. - * - a sequence of closely related computations which can execute concurrently - * with other computational sequences. - * - * From RTEMS' perspective, a task is the smallest thread of execution which - * can compete on its own for system resources. A task is manifested by the - * existence of a task control block (TCB). - * - * @section ClassicTasksSecTaskControlBlock Task Control Block - * - * The Task Control Block (TCB) is an RTEMS defined data structure which - * contains all the information that is pertinent to the execution of a task. - * During system initialization, RTEMS reserves a TCB for each task configured. - * A TCB is allocated upon creation of the task and is returned to the TCB free - * list upon deletion of the task. - * - * The TCB's elements are modified as a result of system calls made by the - * application in response to external and internal stimuli. TCBs are the only - * RTEMS internal data structure that can be accessed by an application via - * user extension routines. The TCB contains a task's name, ID, current - * priority, current and starting states, execution mode, TCB user extension - * pointer, scheduling control structures, as well as data required by a - * blocked task. - * - * A task's context is stored in the TCB when a task switch occurs. When the - * task regains control of the processor, its context is restored from the TCB. - * When a task is restarted, the initial state of the task is restored from the - * starting context area in the task's TCB. - * - * @section ClassicTasksSecTaskStates Task States - * - * A task may exist in one of the following five states: - * - * - executing - Currently scheduled to the CPU - * - ready - May be scheduled to the CPU - * - blocked - Unable to be scheduled to the CPU - * - dormant - Created task that is not started - * - non-existent - Uncreated or deleted task - * - * An active task may occupy the executing, ready, blocked or dormant state, - * otherwise the task is considered non-existent. One or more tasks may be - * active in the system simultaneously. Multiple tasks communicate, - * synchronize, and compete for system resources with each other via system - * calls. The multiple tasks appear to execute in parallel, but actually each - * is dispatched to the CPU for periods of time determined by the RTEMS - * scheduling algorithm. The scheduling of a task is based on its current state - * and priority. - * - * @section ClassicTasksSecTaskPriority Task Priority - * - * A task's priority determines its importance in relation to the other tasks - * executing on the same processor. RTEMS supports 255 levels of priority - * ranging from 1 to 255. The data type rtems_task_priority() is used to store - * task priorities. - * - * Tasks of numerically smaller priority values are more important tasks than - * tasks of numerically larger priority values. For example, a task at priority - * level 5 is of higher privilege than a task at priority level 10. There is no - * limit to the number of tasks assigned to the same priority. - * - * Each task has a priority associated with it at all times. The initial value - * of this priority is assigned at task creation time. The priority of a task - * may be changed at any subsequent time. - * - * Priorities are used by the scheduler to determine which ready task will be - * allowed to execute. In general, the higher the logical priority of a task, - * the more likely it is to receive processor execution time. - * - * @section ClassicTasksSecTaskMode Task Mode - * - * A task's execution mode is a combination of the following four components: - * - * - preemption - * - ASR processing - * - timeslicing - * - interrupt level - * - * It is used to modify RTEMS' scheduling process and to alter the execution - * environment of the task. The data type rtems_task_mode() is used to manage - * the task execution mode. - * - * The preemption component allows a task to determine when control of the - * processor is relinquished. If preemption is disabled (@c - * RTEMS_NO_PREEMPT), the task will retain control of the - * processor as long as it is in the executing state -- even if a higher - * priority task is made ready. If preemption is enabled (@c RTEMS_PREEMPT) - * and a higher priority task is made ready, then the processor will be - * taken away from the current task immediately and given to the higher - * priority task. - * - * The timeslicing component is used by the RTEMS scheduler to determine how - * the processor is allocated to tasks of equal priority. If timeslicing is - * enabled (@c RTEMS_TIMESLICE), then RTEMS will limit the amount of time the - * task can execute before the processor is allocated to another ready task of - * equal priority. The length of the timeslice is application dependent and - * specified in the Configuration Table. If timeslicing is disabled (@c - * RTEMS_NO_TIMESLICE), then the task will be allowed to - * execute until a task of higher priority is made ready. If @c - * RTEMS_NO_PREEMPT is selected, then the timeslicing component is ignored by - * the scheduler. - * - * The asynchronous signal processing component is used to determine when - * received signals are to be processed by the task. If signal processing is - * enabled (@c RTEMS_ASR), then signals sent to the task will be processed - * the next time the task executes. If signal processing is disabled (@c - * RTEMS_NO_ASR), then all signals received by the task will - * remain posted until signal processing is enabled. This component affects - * only tasks which have established a routine to process asynchronous signals. - * - * The interrupt level component is used to determine which interrupts will be - * enabled when the task is executing. @c RTEMS_INTERRUPT_LEVEL(n) specifies - * that the task will execute at interrupt level n. - * - * - @ref RTEMS_PREEMPT - enable preemption (default) - * - @ref RTEMS_NO_PREEMPT - disable preemption - * - @ref RTEMS_NO_TIMESLICE - disable timeslicing (default) - * - @ref RTEMS_TIMESLICE - enable timeslicing - * - @ref RTEMS_ASR - enable ASR processing (default) - * - @ref RTEMS_NO_ASR - disable ASR processing - * - @ref RTEMS_INTERRUPT_LEVEL(0) - enable all interrupts (default) - * - @ref RTEMS_INTERRUPT_LEVEL(n) - execute at interrupt level n - * - * The set of default modes may be selected by specifying the @ref - * RTEMS_DEFAULT_MODES constant. - * - * @section ClassicTasksSecAccessingTaskArguments Accessing Task Arguments - * - * All RTEMS tasks are invoked with a single argument which is specified when - * they are started or restarted. The argument is commonly used to communicate - * startup information to the task. The simplest manner in which to define a - * task which accesses it argument is: - * - * @code - * rtems_task user_task( - * rtems_task_argument argument - * ); - * @endcode - * - * Application tasks requiring more information may view this single argument - * as an index into an array of parameter blocks. - * - * @section ClassicTasksSecFloatingPointConsiderations Floating Point Considerations - * - * Creating a task with the @ref RTEMS_FLOATING_POINT attribute flag results in - * additional memory being allocated for the TCB to store the state of the - * numeric coprocessor during task switches. This additional memory is NOT - * allocated for @ref RTEMS_NO_FLOATING_POINT tasks. Saving and restoring the - * context of a @c RTEMS_FLOATING_POINT task takes longer than that of a @c - * RTEMS_NO_FLOATING_POINT task because of the relatively large amount of time - * required for the numeric coprocessor to save or restore its computational - * state. - * - * Since RTEMS was designed specifically for embedded military applications - * which are floating point intensive, the executive is optimized to avoid - * unnecessarily saving and restoring the state of the numeric coprocessor. The - * state of the numeric coprocessor is only saved when a @c - * RTEMS_FLOATING_POINT task is dispatched and that task was not the last task - * to utilize the coprocessor. In a system with only one @c - * RTEMS_FLOATING_POINT task, the state of the numeric coprocessor will never - * be saved or restored. - * - * Although the overhead imposed by @c RTEMS_FLOATING_POINT tasks is minimal, - * some applications may wish to completely avoid the overhead associated with - * @c RTEMS_FLOATING_POINT tasks and still utilize a numeric coprocessor. By - * preventing a task from being preempted while performing a sequence of - * floating point operations, a @c RTEMS_NO_FLOATING_POINT task can utilize - * the numeric coprocessor without incurring the overhead of a @c - * RTEMS_FLOATING_POINT context switch. This approach also avoids the - * allocation of a floating point context area. However, if this approach is - * taken by the application designer, NO tasks should be created as @c - * RTEMS_FLOATING_POINT tasks. Otherwise, the floating point context will not - * be correctly maintained because RTEMS assumes that the state of the numeric - * coprocessor will not be altered by @c RTEMS_NO_FLOATING_POINT tasks. - * - * If the supported processor type does not have hardware floating capabilities - * or a standard numeric coprocessor, RTEMS will not provide built-in support - * for hardware floating point on that processor. In this case, all tasks are - * considered @c RTEMS_NO_FLOATING_POINT whether created as @c - * RTEMS_FLOATING_POINT or @c RTEMS_NO_FLOATING_POINT tasks. A floating point - * emulation software library must be utilized for floating point operations. - * - * On some processors, it is possible to disable the floating point unit - * dynamically. If this capability is supported by the target processor, then - * RTEMS will utilize this capability to enable the floating point unit only - * for tasks which are created with the @c RTEMS_FLOATING_POINT attribute. - * The consequence of a @c RTEMS_NO_FLOATING_POINT task attempting to access - * the floating point unit is CPU dependent but will generally result in an - * exception condition. - * - * @section ClassicTasksSecPerTaskVariables Per Task Variables - * - * Per task variables are no longer available. In particular the - * rtems_task_variable_add(), rtems_task_variable_get() and - * rtems_task_variable_delete() functions are neither declared nor defined - * anymore. Use thread local storage or POSIX Keys instead. - * - * @section ClassicTasksSecBuildingTaskAttributeSet Building a Task Attribute Set - * - * In general, an attribute set is built by a bitwise OR of the desired - * components. The set of valid task attribute components is listed below: - * - * - @ref RTEMS_NO_FLOATING_POINT - does not use coprocessor (default) - * - @ref RTEMS_FLOATING_POINT - uses numeric coprocessor - * - @ref RTEMS_LOCAL - local task (default) - * - @ref RTEMS_GLOBAL - global task - * - * Attribute values are specifically designed to be mutually exclusive, - * therefore bitwise OR and addition operations are equivalent as long as each - * attribute appears exactly once in the component list. A component listed as - * a default is not required to appear in the component list, although it is a - * good programming practice to specify default components. If all defaults are - * desired, then @ref RTEMS_DEFAULT_ATTRIBUTES should be used. This example - * demonstrates the attribute_set parameter needed to create a local task which - * utilizes the numeric coprocessor. The attribute_set parameter could be @c - * RTEMS_FLOATING_POINT or @c RTEMS_LOCAL | @c RTEMS_FLOATING_POINT. The - * attribute_set parameter can be set to @c RTEMS_FLOATING_POINT because @c - * RTEMS_LOCAL is the default for all created tasks. If the task were global - * and used the numeric coprocessor, then the attribute_set parameter would be - * @c RTEMS_GLOBAL | @c RTEMS_FLOATING_POINT. - * - * @section ClassicTasksSecBuildingModeAndMask Building a Mode and Mask - * - * In general, a mode and its corresponding mask is built by a bitwise OR of - * the desired components. The set of valid mode constants and each mode's - * corresponding mask constant is listed below: - * - * <table> - * <tr><th>Mode Constant</th><th>Mask Constant</th><th>Description</th></tr> - * <tr><td>@ref RTEMS_PREEMPT</td><td>@ref RTEMS_PREEMPT_MASK</td><td>enables preemption</td></tr> - * <tr><td>@ref RTEMS_NO_PREEMPT</td><td>@ref RTEMS_PREEMPT_MASK</td><td>disables preemption</td></tr> - * <tr><td>@ref RTEMS_NO_TIMESLICE</td><td>@ref RTEMS_TIMESLICE_MASK</td><td>disables timeslicing</td></tr> - * <tr><td>@ref RTEMS_TIMESLICE</td><td>@ref RTEMS_TIMESLICE_MASK</td><td>enables timeslicing</td></tr> - * <tr><td>@ref RTEMS_ASR</td><td>@ref RTEMS_ASR_MASK</td><td>enables ASR processing</td></tr> - * <tr><td>@ref RTEMS_NO_ASR</td><td>@ref RTEMS_ASR_MASK</td><td>disables ASR processing</td></tr> - * <tr><td>@ref RTEMS_INTERRUPT_LEVEL(0)</td><td>@ref RTEMS_INTERRUPT_MASK</td><td>enables all interrupts</td></tr> - * <tr><td>@ref RTEMS_INTERRUPT_LEVEL(n)</td><td>@ref RTEMS_INTERRUPT_MASK</td><td>sets interrupts level n</td></tr> - * </table> - * - * Mode values are specifically designed to be mutually exclusive, therefore - * bitwise OR and addition operations are equivalent as long as each mode - * appears exactly once in the component list. A mode component listed as a - * default is not required to appear in the mode component list, although it is - * a good programming practice to specify default components. If all defaults - * are desired, the mode @ref RTEMS_DEFAULT_MODES and the mask @ref - * RTEMS_ALL_MODE_MASKS should be used. - * - * The following example demonstrates the mode and mask parameters used with - * the rtems_task_mode() directive to place a task at interrupt level 3 and - * make it non-preemptible. The mode should be set to @c - * RTEMS_INTERRUPT_LEVEL(3) | @c RTEMS_NO_PREEMPT to indicate the desired - * preemption mode and interrupt level, while the mask parameter should be set - * to @c RTEMS_INTERRUPT_MASK | @c RTEMS_PREEMPT_MASK to indicate that - * the calling task's interrupt level and preemption mode are being altered. - */ - - /** - * @defgroup LocalPackages Local Packages - * - * @ingroup RTEMSAPIClassic - * - * @brief Local packages. - */ diff --git a/cpukit/include/rtems/rtems/partdata.h b/cpukit/include/rtems/rtems/partdata.h index 864c47294e..6df4af81c5 100644 --- a/cpukit/include/rtems/rtems/partdata.h +++ b/cpukit/include/rtems/rtems/partdata.h @@ -116,6 +116,8 @@ typedef struct { extern Objects_Information _Partition_Information; #if defined(RTEMS_MULTIPROCESSING) +struct _Thread_Control; + /** * @brief Sends the extract proxy request. * @@ -126,8 +128,8 @@ extern Objects_Information _Partition_Information; * @param id is the partition identifier. */ void _Partition_MP_Send_extract_proxy ( - Thread_Control *the_thread, - Objects_Id id + struct _Thread_Control *the_thread, + Objects_Id id ); #endif diff --git a/cpukit/include/rtems/rtems/tasks.h b/cpukit/include/rtems/rtems/tasks.h index 45be8a8730..84dd646fe7 100644 --- a/cpukit/include/rtems/rtems/tasks.h +++ b/cpukit/include/rtems/rtems/tasks.h @@ -10,7 +10,7 @@ /* * Copyright (C) 2020, 2021 embedded brains GmbH & Co. KG - * Copyright (C) 1988, 2017 On-Line Applications Research Corporation (OAR) + * Copyright (C) 1988, 2023 On-Line Applications Research Corporation (OAR) * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -234,7 +234,7 @@ typedef void rtems_task; /** * @ingroup RTEMSAPIClassicTasks * - * @brief This type defines the entry point of an RTEMS task. + * @brief This type defines the task entry point of an RTEMS task. */ typedef rtems_task ( *rtems_task_entry )( rtems_task_argument ); @@ -897,8 +897,8 @@ rtems_id rtems_task_self( void ); * * This directive readies the task, specified by ``id``, for execution based on * the priority and execution mode specified when the task was created. The - * entry point of the task is given in ``entry_point``. The task's entry point - * argument is contained in ``argument``. + * task entry point of the task is given in ``entry_point``. The task's entry + * point argument is contained in ``argument``. * * @retval ::RTEMS_SUCCESSFUL The requested operation was successful. * @@ -1544,15 +1544,16 @@ rtems_status_code rtems_task_mode( /** * @ingroup RTEMSAPIClassicTasks * - * @brief Wakes up after an interval in clock ticks or yields the processor. + * @brief Wakes up after a count of clock ticks have occurred or yields the + * processor. * - * @param ticks is the interval in clock ticks to delay the task or + * @param ticks is the count of clock ticks to delay the task or * #RTEMS_YIELD_PROCESSOR to yield the processor. * - * This directive blocks the calling task for the specified ``ticks`` of clock - * ticks if the value is not equal to #RTEMS_YIELD_PROCESSOR. When the - * requested interval has elapsed, the task is made ready. The clock tick - * directives automatically updates the delay period. The calling task may + * This directive blocks the calling task for the specified ``ticks`` count of + * clock ticks if the value is not equal to #RTEMS_YIELD_PROCESSOR. When the + * requested count of ticks have occurred, the task is made ready. The clock + * tick directives automatically update the delay period. The calling task may * give up the processor and remain in the ready state by specifying a value of * #RTEMS_YIELD_PROCESSOR in ``ticks``. * @@ -1561,7 +1562,11 @@ rtems_status_code rtems_task_mode( * @par Notes * Setting the system date and time with the rtems_clock_set() directive and * similar directives which set CLOCK_REALTIME have no effect on a - * rtems_task_wake_after() blocked task. + * rtems_task_wake_after() blocked task. The delay until first clock tick will + * never be a whole clock tick interval since this directive will never execute + * exactly on a clock tick. Applications requiring use of a clock + * (CLOCK_REALTIME or CLOCK_MONOTONIC) instead of clock ticks should make use + * of clock_nanosleep(). * * @par Constraints * @parblock diff --git a/cpukit/include/rtems/rtl/rtl-allocator.h b/cpukit/include/rtems/rtl/rtl-allocator.h index 8ffaf58c3c..7d291c65f4 100644 --- a/cpukit/include/rtems/rtl/rtl-allocator.h +++ b/cpukit/include/rtems/rtl/rtl-allocator.h @@ -1,7 +1,7 @@ /* SPDX-License-Identifier: BSD-2-Clause */ /* - * COPYRIGHT (c) 2012, 2018 Chris Johns <chrisj@rtems.org> + * COPYRIGHT (c) 2012, 2018, 2023 Chris Johns <chrisj@rtems.org> * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -69,6 +69,7 @@ typedef enum rtems_rtl_alloc_tags rtems_rtl_alloc_tag; enum rtems_rtl_alloc_cmd { RTEMS_RTL_ALLOC_NEW, /**< Allocate new memory. */ RTEMS_RTL_ALLOC_DEL, /**< Delete allocated memory. */ + RTEMS_RTL_ALLOC_RESIZE, /**< Resize allocated memory. */ RTEMS_RTL_ALLOC_LOCK, /**< Lock the allocator. */ RTEMS_RTL_ALLOC_UNLOCK, /**< Unlock the allocator. */ RTEMS_RTL_ALLOC_WR_ENABLE, /**< Enable writes to the memory. */ @@ -143,6 +144,25 @@ void* rtems_rtl_alloc_new (rtems_rtl_alloc_tag tag, size_t size, bool zero); void rtems_rtl_alloc_del (rtems_rtl_alloc_tag tag, void* address); /** + * The Runtime Loader allocator resize resizes allocated memory. + * + * This call resizes a previously allocated block of memory. If the + * provided address cannot be resized it is deleted and a new block is + * allocated and the contents of the existing memory is copied. + * + * + * @param tag The type of allocation request. + * @param address The memory address to resize. A NULL is ignored. + * @param size The size of the allocation. + * @param zero If true the memory is cleared. + * @return void* The memory address or NULL is not memory available. + */ +void* rtems_rtl_alloc_resize (rtems_rtl_alloc_tag tag, + void* address, + size_t size, + bool zero); + +/** * The Runtime Loader allocator lock. An allocator that depends on a * separate allocation process, for example the heap, may need to be * locked during loading of an object file to make sure the locality @@ -267,6 +287,30 @@ bool rtems_rtl_alloc_module_new (void** text_base, size_t text_size, void** bss_base, size_t bss_size); /** + * Resize the allocated memory for a module given the new size of the text, + * const, data and bss sections. If any part of the allocation fails the + * allocated is deleted. + * + * @param text_base Pointer to the text base pointer. + * @param text_size The size of the read/exec section. + * @param const_base Pointer to the const base pointer. + * @param const_size The size of the read only section. + * @param eh_base Pointer to the eh base pointer. + * @param eh_size The size of the eh section. + * @param data_base Pointer to the data base pointer. + * @param data_size The size of the read/write secton. + * @param bss_base Pointer to the bss base pointer. + * @param bss_size The size of the read/write. + * @retval true The memory has been allocated. + * @retval false The allocation of memory has failed. + */ +bool rtems_rtl_alloc_module_resize (void** text_base, size_t text_size, + void** const_base, size_t const_size, + void** eh_base, size_t eh_size, + void** data_base, size_t data_size, + void** bss_base, size_t bss_size); + +/** * Free the memory allocated to a module. * * @param text_base Pointer to the text base pointer. diff --git a/cpukit/include/rtems/rtl/rtl-obj.h b/cpukit/include/rtems/rtl/rtl-obj.h index 6b47eb1205..3523958bfd 100644 --- a/cpukit/include/rtems/rtl/rtl-obj.h +++ b/cpukit/include/rtems/rtl/rtl-obj.h @@ -198,65 +198,66 @@ typedef bool (*rtems_rtl_obj_depends_iterator) (rtems_rtl_obj* obj, */ struct rtems_rtl_obj { - rtems_chain_node link; /**< The node's link in the chain. */ - uint32_t flags; /**< The status of the object file. */ - size_t users; /**< Users of this object file, number of loads. */ - size_t refs; /**< References to the object file. */ - int format; /**< The format of the object file. */ - const char* fname; /**< The file name for the object. */ - const char* oname; /**< The object file name. Can be - * relative. */ - const char* aname; /**< The archive name containing the - * object. NULL means the object is not - * in a lib */ - off_t ooffset; /**< The object offset in the archive. */ - size_t fsize; /**< Size of the object file. */ - rtems_chain_control sections; /**< The sections of interest in the object - * file. */ - rtems_chain_control dependents; /**< The dependent object files. */ - rtems_rtl_obj_sym* local_table; /**< Local symbol table. */ - size_t local_syms; /**< Local symbol count. */ - size_t local_size; /**< Local symbol memory usage. */ - rtems_rtl_obj_sym* global_table; /**< Global symbol table. */ - size_t global_syms; /**< Global symbol count. */ - size_t global_size; /**< Global symbol memory usage. */ - size_t unresolved; /**< The number of unresolved relocations. */ - void* text_base; /**< The base address of the text section - * in memory. */ - size_t text_size; /**< The size of the text section. */ - void* const_base; /**< The base address of the const section - * in memory. */ - size_t const_size; /**< The size of the const section. */ - void* eh_base; /**< The base address of the eh section in - * memory. */ - size_t eh_size; /**< The size of the eh section. */ - void* data_base; /**< The base address of the data section - * in memory. */ - size_t data_size; /**< The size of the data section. */ - void* bss_base; /**< The base address of the bss section in - * memory. */ - size_t bss_size; /**< The size of the bss section. */ - size_t exec_size; /**< The amount of executable memory - * allocated */ - void* entry; /**< The entry point of the module. */ - uint32_t checksum; /**< The checksum of the text sections. A - * zero means do not checksum. */ - uint32_t* sec_num; /**< The sec nums of each obj. */ - uint32_t obj_num; /**< The count of elf files in an rtl - * obj. */ - void* trampoline; /**< Trampoline memory. Used for fixups or - * veneers */ - size_t tramp_size; /**< Size of a tramopline slot. */ - size_t tramps_size; /**< Size of the trampoline memory. */ - void* tramp_brk; /**< Trampoline memory allocator. MD - * relocators can take memory from the - * break up to the size. */ - size_t tramp_relocs; /**< Number of slots reserved for - * relocs. The remainder are for - * unresolved symbols. */ - struct link_map* linkmap; /**< For GDB. */ - void* loader; /**< The file details specific to a - * loader. */ + rtems_chain_node link; /**< The node's link in the chain. */ + uint32_t flags; /**< The status of the object file. */ + size_t users; /**< Users of this object file, number of loads. */ + size_t refs; /**< References to the object file. */ + int format; /**< The format of the object file. */ + const char* fname; /**< The file name for the object. */ + const char* oname; /**< The object file name. Can be + * relative. */ + const char* aname; /**< The archive name containing the + * object. NULL means the object is not + * in a lib */ + off_t ooffset; /**< The object offset in the archive. */ + size_t fsize; /**< Size of the object file. */ + rtems_chain_control sections; /**< The sections of interest in the object + * file. */ + rtems_chain_control dependents; /**< The dependent object files. */ + rtems_rtl_obj_sym* local_table; /**< Local symbol table. */ + size_t local_syms; /**< Local symbol count. */ + size_t local_size; /**< Local symbol memory usage. */ + rtems_rtl_obj_sym* global_table; /**< Global symbol table. */ + size_t global_syms; /**< Global symbol count. */ + size_t global_size; /**< Global symbol memory usage. */ + size_t unresolved; /**< The number of unresolved relocations. */ + void* text_base; /**< The base address of the text section + * in memory. */ + size_t text_size; /**< The size of the text section. */ + void* const_base; /**< The base address of the const section + * in memory. */ + size_t const_size; /**< The size of the const section. */ + void* eh_base; /**< The base address of the eh section in + * memory. */ + size_t eh_size; /**< The size of the eh section. */ + void* data_base; /**< The base address of the data section + * in memory. */ + size_t data_size; /**< The size of the data section. */ + void* bss_base; /**< The base address of the bss section in + * memory. */ + size_t bss_size; /**< The size of the bss section. */ + size_t exec_size; /**< The amount of executable memory + * allocated */ + void* entry; /**< The entry point of the module. */ + uint32_t checksum; /**< The checksum of the text sections. A + * zero means do not checksum. */ + uint32_t* sec_num; /**< The sec nums of each obj. */ + uint32_t obj_num; /**< The count of elf files in an rtl + * obj. */ + void* tramp_base; /**< Trampoline memory. Used for fixups or + * veneers */ + size_t tramp_size; /**< Size of a trampoline memory. */ + size_t tramp_slots; /**< The number of tampoline slots. */ + size_t tramp_slot_size; /**< The number of tampoline slots. */ + void* tramp_brk; /**< Trampoline memory allocator. MD + * relocators can take memory from the + * break up to the size. */ + size_t tramp_relocs; /**< Number of slots reserved for + * relocs. The remainder are for + * unresolved symbols. */ + struct link_map* linkmap; /**< For GDB. */ + void* loader; /**< The file details specific to a + * loader. */ }; /** @@ -387,6 +388,17 @@ static inline bool rtems_rtl_obj_has_symbol (const rtems_rtl_obj* obj, } /** + * Does the object file have any trampolines? + * + * @param obj The object file's descriptor to check for available space. + * @retval bool Returns @true if the object file has trampolines + */ +static inline size_t rtems_rtl_obj_has_trampolines (const rtems_rtl_obj* obj) +{ + return obj->tramp_slot_size != 0 && obj->tramp_slots != 0; +} + +/** * Is there space in the trampoline memory for a trapoline. * * @param obj The object file's descriptor to check for available space. @@ -395,7 +407,7 @@ static inline bool rtems_rtl_obj_has_symbol (const rtems_rtl_obj* obj, */ static inline size_t rtems_rtl_obj_tramp_avail_space (const rtems_rtl_obj* obj) { - return (char*) obj->tramp_brk - (char*) obj->trampoline; + return (char*) obj->tramp_brk - (char*) obj->tramp_base; } /** @@ -408,8 +420,8 @@ static inline size_t rtems_rtl_obj_tramp_avail_space (const rtems_rtl_obj* obj) static inline bool rtems_rtl_obj_has_tramp_space (const rtems_rtl_obj* obj, const size_t size) { - return (obj->trampoline != NULL && - (rtems_rtl_obj_tramp_avail_space (obj) + size) <= obj->tramps_size); + return (obj->tramp_base != NULL && + (rtems_rtl_obj_tramp_avail_space (obj) + size) <= obj->tramp_size); } /** @@ -420,20 +432,19 @@ static inline bool rtems_rtl_obj_has_tramp_space (const rtems_rtl_obj* obj, */ static inline size_t rtems_rtl_obj_trampoline_slots (const rtems_rtl_obj* obj) { - return obj->trampoline == NULL || obj->tramp_size == 0 ? - 0 : obj->tramps_size / obj->tramp_size; + return obj->tramp_slots; } /** - * Number of trampolines. + * Number of trampoline slot available. * * @param obj The object file's descriptor. - * @retval size_t The number of trampolines. + * @retval size_t The number of trampoline slots available. */ static inline size_t rtems_rtl_obj_trampolines (const rtems_rtl_obj* obj) { - return obj->trampoline == NULL || obj->tramp_size == 0 ? - 0 : rtems_rtl_obj_tramp_avail_space (obj) / obj->tramp_size; + return obj->tramp_base == NULL || obj->tramp_slots == 0 ? + 0 : rtems_rtl_obj_tramp_avail_space (obj) / obj->tramp_slot_size; } /** @@ -572,22 +583,6 @@ rtems_rtl_obj_sect* rtems_rtl_obj_find_section_by_mask (const rtems_rtl_obj* obj uint32_t mask); /** - * Allocate a table for trampoline fixup calls. - * - * @param obj The object file's descriptor. - * @retval true The table was allocated. - * @retval false The alloction failed. - */ -bool rtems_rtl_obj_alloc_trampoline (rtems_rtl_obj* obj); - -/** - * Erase the object file descriptor's trampoline table.. - * - * @param obj The object file's descriptor. - */ -void rtems_rtl_obj_erase_trampoline (rtems_rtl_obj* obj); - -/** * Allocate a table for dependent objects. * * @param obj The object file's descriptor. @@ -750,6 +745,24 @@ size_t rtems_rtl_obj_bss_size (const rtems_rtl_obj* obj); uint32_t rtems_rtl_obj_bss_alignment (const rtems_rtl_obj* obj); /** + * The trampoline size. + * + * @param obj The object file's descriptor. + * @return size_t The size of the trampoline memory of the object file. + */ +size_t rtems_rtl_obj_tramp_size (const rtems_rtl_obj* obj); + +/** + * The trampolinme alignment for the architecture. + * + * This is implemented and set in the architecture backend. + * + * @param obj The object file's descriptor. + * @return uint32_t The alignment. Can be 0 or 1 for not aligned or the alignment. + */ +uint32_t rtems_rtl_obj_tramp_alignment (const rtems_rtl_obj* obj); + +/** * Relocate the object file. The object file's section are parsed for any * relocation type sections. * @@ -810,11 +823,19 @@ bool rtems_rtl_obj_load_symbols (rtems_rtl_obj* obj, * @retval true The object has been sucessfully loaded. * @retval false The load failed. The RTL error has been set. */ -bool -rtems_rtl_obj_alloc_sections (rtems_rtl_obj* obj, - int fd, - rtems_rtl_obj_sect_handler handler, - void* data); +bool rtems_rtl_obj_alloc_sections (rtems_rtl_obj* obj, + int fd, + rtems_rtl_obj_sect_handler handler, + void* data); + +/** + * Resize the sections. + * + * @param obj The object file's descriptor. + * @retval true The object has been sucessfully loaded. + * @retval false The load failed. The RTL error has been set. + */ +bool rtems_rtl_obj_resize_sections (rtems_rtl_obj* obj); /** * Load the sections that have been allocated memory in the target. The bss diff --git a/cpukit/include/rtems/rtl/rtl-sym.h b/cpukit/include/rtems/rtl/rtl-sym.h index 0d29a6ae40..3502b303b8 100644 --- a/cpukit/include/rtems/rtl/rtl-sym.h +++ b/cpukit/include/rtems/rtl/rtl-sym.h @@ -63,6 +63,22 @@ typedef struct rtems_rtl_symbols } rtems_rtl_symbols; /** + * A TLS variable offset call. There is one per base image TLS + * variable. + */ +typedef size_t (*rtems_rtl_tls_offset_func)(void); + +/** + * A TLS symbol offset entry. It is used with an exported symbol table + * to find a TSL table offset for a variable at runtime. + */ +typedef struct rtems_rtl_tls_offset +{ + size_t index; /** exported symbol table index */ + rtems_rtl_tls_offset_func offset; /** TLS offset function */ +} rtems_rtl_tls_offset; + +/** * Open a symbol table with the specified number of buckets. * * @param symbols The symbol table to open. @@ -101,10 +117,14 @@ void rtems_rtl_symbol_table_close (rtems_rtl_symbols* symbols); * @param obj The object table the symbols are for. * @param esyms The exported symbol table. * @param size The size of the table in bytes. + * @param tls_offsets The TLS offsets table. If NULL none provided. + * @param tls_size The number TLS offset entries in the table. */ -bool rtems_rtl_symbol_global_add (rtems_rtl_obj* obj, - const unsigned char* esyms, - unsigned int size); +bool rtems_rtl_symbol_global_add (rtems_rtl_obj* obj, + const unsigned char* esyms, + unsigned int size, + rtems_rtl_tls_offset* tls_offsets, + unsigned int tls_size); /** * Find a symbol given the symbol label in the global symbol table. diff --git a/cpukit/include/rtems/rtl/rtl.h b/cpukit/include/rtems/rtl/rtl.h index 0fd4e74cdf..bd3dce588a 100644 --- a/cpukit/include/rtems/rtl/rtl.h +++ b/cpukit/include/rtems/rtl/rtl.h @@ -393,9 +393,13 @@ bool rtems_rtl_path_prepend (const char* path); * * @param esyms The exported symbol table. * @param count The size of the exported symbol table. + * @param tls_offsets The TLS offsets table. If NULL none provided. + * @param tls_size The number TLS offset entries in the table. */ -void rtems_rtl_base_sym_global_add (const unsigned char* esyms, - unsigned int count); +void rtems_rtl_base_sym_global_add (const unsigned char* esyms, + unsigned int count, + rtems_rtl_tls_offset* tls_offsets, + unsigned int tls_size); /** * Return the object file descriptor for the base image. The object file diff --git a/cpukit/include/rtems/score/atomic.h b/cpukit/include/rtems/score/atomic.h index 161b0ec03e..9ef1779e60 100644 --- a/cpukit/include/rtems/score/atomic.h +++ b/cpukit/include/rtems/score/atomic.h @@ -10,6 +10,7 @@ */ /* + * Copyright (C) 2015 embedded brains GmbH & Co. KG * COPYRIGHT (c) 2012-2013 Deng Hengyi. * * Redistribution and use in source and binary forms, with or without @@ -37,7 +38,7 @@ #ifndef _RTEMS_SCORE_ATOMIC_H #define _RTEMS_SCORE_ATOMIC_H -#include <rtems/score/cpuatomic.h> +#include <rtems/score/basedefs.h> /** * @defgroup RTEMSScoreAtomic Atomic Operations @@ -54,122 +55,935 @@ * @{ */ -typedef CPU_atomic_Uint Atomic_Uint; +#ifdef RTEMS_SMP + #if defined(__cplusplus) \ + && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 9)) + /* + * The GCC 4.9 ships its own <stdatomic.h> which is not C++ compatible. The + * suggested solution was to include <atomic> in case C++ is used. This works + * at least with GCC 4.9. See also: + * + * http://gcc.gnu.org/bugzilla/show_bug.cgi?id=60932 + * http://gcc.gnu.org/bugzilla/show_bug.cgi?id=60940 + */ + #include <atomic> + #define _RTEMS_SCORE_ATOMIC_USE_ATOMIC + #else + #include <stdatomic.h> + #define _RTEMS_SCORE_ATOMIC_USE_STDATOMIC + #endif +#else + #include <rtems/score/isrlevel.h> +#endif -typedef CPU_atomic_Ulong Atomic_Ulong; +#if defined(_RTEMS_SCORE_ATOMIC_USE_ATOMIC) -typedef CPU_atomic_Uintptr Atomic_Uintptr; +typedef std::atomic_uint Atomic_Uint; -typedef CPU_atomic_Flag Atomic_Flag; +typedef std::atomic_ulong Atomic_Ulong; -typedef CPU_atomic_Order Atomic_Order; +typedef std::atomic_uintptr_t Atomic_Uintptr; -#define ATOMIC_ORDER_RELAXED CPU_ATOMIC_ORDER_RELAXED +typedef std::atomic_flag Atomic_Flag; -#define ATOMIC_ORDER_ACQUIRE CPU_ATOMIC_ORDER_ACQUIRE +typedef std::memory_order Atomic_Order; -#define ATOMIC_ORDER_RELEASE CPU_ATOMIC_ORDER_RELEASE +#define ATOMIC_ORDER_RELAXED std::memory_order_relaxed -#define ATOMIC_ORDER_ACQ_REL CPU_ATOMIC_ORDER_ACQ_REL +#define ATOMIC_ORDER_ACQUIRE std::memory_order_acquire -#define ATOMIC_ORDER_SEQ_CST CPU_ATOMIC_ORDER_SEQ_CST +#define ATOMIC_ORDER_RELEASE std::memory_order_release -#define ATOMIC_INITIALIZER_UINT( value ) CPU_ATOMIC_INITIALIZER_UINT( value ) +#define ATOMIC_ORDER_ACQ_REL std::memory_order_acq_rel -#define ATOMIC_INITIALIZER_ULONG( value ) CPU_ATOMIC_INITIALIZER_ULONG( value ) +#define ATOMIC_ORDER_SEQ_CST std::memory_order_seq_cst -#define ATOMIC_INITIALIZER_UINTPTR( value ) CPU_ATOMIC_INITIALIZER_UINTPTR( value ) +#define ATOMIC_INITIALIZER_UINT( value ) ATOMIC_VAR_INIT( value ) -#define ATOMIC_INITIALIZER_FLAG CPU_ATOMIC_INITIALIZER_FLAG +#define ATOMIC_INITIALIZER_ULONG( value ) ATOMIC_VAR_INIT( value ) -#define _Atomic_Fence( order ) _CPU_atomic_Fence( order ) +#define ATOMIC_INITIALIZER_UINTPTR( value ) ATOMIC_VAR_INIT( value ) -#define _Atomic_Init_uint( obj, desired ) \ - _CPU_atomic_Init_uint( obj, desired ) +#define ATOMIC_INITIALIZER_FLAG ATOMIC_FLAG_INIT -#define _Atomic_Init_ulong( obj, desired ) \ - _CPU_atomic_Init_ulong( obj, desired ) +#elif defined(_RTEMS_SCORE_ATOMIC_USE_STDATOMIC) -#define _Atomic_Init_uintptr( obj, desired ) \ - _CPU_atomic_Init_uintptr( obj, desired ) +typedef atomic_uint Atomic_Uint; -#define _Atomic_Load_uint( obj, order ) \ - _CPU_atomic_Load_uint( obj, order ) +typedef atomic_ulong Atomic_Ulong; -#define _Atomic_Load_ulong( obj, order ) \ - _CPU_atomic_Load_ulong( obj, order ) +typedef atomic_uintptr_t Atomic_Uintptr; -#define _Atomic_Load_uintptr( obj, order ) \ - _CPU_atomic_Load_uintptr( obj, order ) +typedef atomic_flag Atomic_Flag; -#define _Atomic_Store_uint( obj, desr, order ) \ - _CPU_atomic_Store_uint( obj, desr, order ) +typedef memory_order Atomic_Order; -#define _Atomic_Store_ulong( obj, desr, order ) \ - _CPU_atomic_Store_ulong( obj, desr, order ) +#define ATOMIC_ORDER_RELAXED memory_order_relaxed -#define _Atomic_Store_uintptr( obj, desr, order ) \ - _CPU_atomic_Store_uintptr( obj, desr, order ) +#define ATOMIC_ORDER_ACQUIRE memory_order_acquire -#define _Atomic_Fetch_add_uint( obj, arg, order ) \ - _CPU_atomic_Fetch_add_uint( obj, arg, order ) +#define ATOMIC_ORDER_RELEASE memory_order_release -#define _Atomic_Fetch_add_ulong( obj, arg, order ) \ - _CPU_atomic_Fetch_add_ulong( obj, arg, order ) +#define ATOMIC_ORDER_ACQ_REL memory_order_acq_rel -#define _Atomic_Fetch_add_uintptr( obj, arg, order ) \ - _CPU_atomic_Fetch_add_uintptr( obj, arg, order ) +#define ATOMIC_ORDER_SEQ_CST memory_order_seq_cst -#define _Atomic_Fetch_sub_uint( obj, arg, order ) \ - _CPU_atomic_Fetch_sub_uint( obj, arg, order ) +#define ATOMIC_INITIALIZER_UINT( value ) ATOMIC_VAR_INIT( value ) -#define _Atomic_Fetch_sub_ulong( obj, arg, order ) \ - _CPU_atomic_Fetch_sub_ulong( obj, arg, order ) +#define ATOMIC_INITIALIZER_ULONG( value ) ATOMIC_VAR_INIT( value ) -#define _Atomic_Fetch_sub_uintptr( obj, arg, order ) \ - _CPU_atomic_Fetch_sub_uintptr( obj, arg, order ) +#define ATOMIC_INITIALIZER_UINTPTR( value ) ATOMIC_VAR_INIT( value ) -#define _Atomic_Fetch_or_uint( obj, arg, order ) \ - _CPU_atomic_Fetch_or_uint( obj, arg, order ) +#define ATOMIC_INITIALIZER_FLAG ATOMIC_FLAG_INIT -#define _Atomic_Fetch_or_ulong( obj, arg, order ) \ - _CPU_atomic_Fetch_or_ulong( obj, arg, order ) +#else -#define _Atomic_Fetch_or_uintptr( obj, arg, order ) \ - _CPU_atomic_Fetch_or_uintptr( obj, arg, order ) +typedef unsigned int Atomic_Uint; -#define _Atomic_Fetch_and_uint( obj, arg, order ) \ - _CPU_atomic_Fetch_and_uint( obj, arg, order ) +typedef unsigned long Atomic_Ulong; -#define _Atomic_Fetch_and_ulong( obj, arg, order ) \ - _CPU_atomic_Fetch_and_ulong( obj, arg, order ) +typedef uintptr_t Atomic_Uintptr; -#define _Atomic_Fetch_and_uintptr( obj, arg, order ) \ - _CPU_atomic_Fetch_and_uintptr( obj, arg, order ) +typedef bool Atomic_Flag; -#define _Atomic_Exchange_uint( obj, desr, order ) \ - _CPU_atomic_Exchange_uint( obj, desr, order ) +typedef int Atomic_Order; -#define _Atomic_Exchange_ulong( obj, desr, order ) \ - _CPU_atomic_Exchange_ulong( obj, desr, order ) +#define ATOMIC_ORDER_RELAXED 0 -#define _Atomic_Exchange_uintptr( obj, desr, order ) \ - _CPU_atomic_Exchange_uintptr( obj, desr, order ) +#define ATOMIC_ORDER_ACQUIRE 2 -#define _Atomic_Compare_exchange_uint( obj, expected, desired, succ, fail ) \ - _CPU_atomic_Compare_exchange_uint( obj, expected, desired, succ, fail ) +#define ATOMIC_ORDER_RELEASE 3 -#define _Atomic_Compare_exchange_ulong( obj, expected, desired, succ, fail ) \ - _CPU_atomic_Compare_exchange_ulong( obj, expected, desired, succ, fail ) +#define ATOMIC_ORDER_ACQ_REL 4 -#define _Atomic_Compare_exchange_uintptr( obj, expected, desired, succ, fail ) \ - _CPU_atomic_Compare_exchange_uintptr( obj, expected, desired, succ, fail ) +#define ATOMIC_ORDER_SEQ_CST 5 -#define _Atomic_Flag_clear( obj, order ) \ - _CPU_atomic_Flag_clear( obj, order ) +#define ATOMIC_INITIALIZER_UINT( value ) ( value ) -#define _Atomic_Flag_test_and_set( obj, order ) \ - _CPU_atomic_Flag_test_and_set( obj, order ) +#define ATOMIC_INITIALIZER_ULONG( value ) ( value ) + +#define ATOMIC_INITIALIZER_UINTPTR( value ) ( value ) + +#define ATOMIC_INITIALIZER_FLAG false + +#endif + +/** + * @brief Sets up a cpu fence. + * + * @param[out] order The order for the fence. + */ +static inline void _Atomic_Fence( Atomic_Order order ) +{ +#if defined(_RTEMS_SCORE_ATOMIC_USE_ATOMIC) + std::atomic_thread_fence( order ); +#elif defined(_RTEMS_SCORE_ATOMIC_USE_STDATOMIC) + atomic_thread_fence( order ); +#else + (void) order; + RTEMS_COMPILER_MEMORY_BARRIER(); +#endif +} + +/** + * @brief Initializes Uint. + * + * @param[out] obj The CPU atomic Uint to initialize. + * @param desired The desired value for @a obj. + */ +static inline void _Atomic_Init_uint( Atomic_Uint *obj, unsigned int desired ) +{ +#if defined(_RTEMS_SCORE_ATOMIC_USE_ATOMIC) + obj->store( desired ); +#elif defined(_RTEMS_SCORE_ATOMIC_USE_STDATOMIC) + atomic_init( obj, desired ); +#else + *obj = desired; +#endif +} + +/** + * @brief Initializes Ulong. + * + * @param[out] obj The CPU atomic Ulong to initialize. + * @param desired The desired value for @a obj. + */ +static inline void _Atomic_Init_ulong( Atomic_Ulong *obj, unsigned long desired ) +{ +#if defined(_RTEMS_SCORE_ATOMIC_USE_ATOMIC) + obj->store( desired ); +#elif defined(_RTEMS_SCORE_ATOMIC_USE_STDATOMIC) + atomic_init( obj, desired ); +#else + *obj = desired; +#endif +} + +/** + * @brief Initializes Uintptr. + * + * @param[out] obj The CPU atomic Uintptr to initialize. + * @param desired The desired value for @a obj. + */ +static inline void _Atomic_Init_uintptr( Atomic_Uintptr *obj, uintptr_t desired ) +{ +#if defined(_RTEMS_SCORE_ATOMIC_USE_ATOMIC) + obj->store( desired ); +#elif defined(_RTEMS_SCORE_ATOMIC_USE_STDATOMIC) + atomic_init( obj, desired ); +#else + *obj = desired; +#endif +} + +/** + * @brief Loads value of Uint considering the order. + * + * @param obj The CPU atomic Uint to get the value from. + * @param order The atomic order for getting the value. + * + * @return The value of @a obj considering the @a order. + */ +static inline unsigned int _Atomic_Load_uint( const Atomic_Uint *obj, Atomic_Order order ) +{ +#if defined(_RTEMS_SCORE_ATOMIC_USE_ATOMIC) + return obj->load( order ); +#elif defined(_RTEMS_SCORE_ATOMIC_USE_STDATOMIC) + return atomic_load_explicit( obj, order ); +#else + unsigned int val; + + (void) order; + val = *obj; + RTEMS_COMPILER_MEMORY_BARRIER(); + + return val; +#endif +} + +/** + * @brief Loads value of Ulong considering the order. + * + * @param obj The CPU atomic Ulong to get the value from. + * @param order The atomic order for getting the value. + * + * @return The value of @a obj considering the @a order. + */ +static inline unsigned long _Atomic_Load_ulong( const Atomic_Ulong *obj, Atomic_Order order ) +{ +#if defined(_RTEMS_SCORE_ATOMIC_USE_ATOMIC) + return obj->load( order ); +#elif defined(_RTEMS_SCORE_ATOMIC_USE_STDATOMIC) + return atomic_load_explicit( obj, order ); +#else + unsigned long val; + + (void) order; + val = *obj; + RTEMS_COMPILER_MEMORY_BARRIER(); + + return val; +#endif +} + +/** + * @brief Loads value of Uintptr considering the order. + * + * @param obj The CPU atomic Uintptr to get the value from. + * @param order The atomic order for getting the value. + * + * @return The value of @a obj considering the @a order. + */ +static inline uintptr_t _Atomic_Load_uintptr( const Atomic_Uintptr *obj, Atomic_Order order ) +{ +#if defined(_RTEMS_SCORE_ATOMIC_USE_ATOMIC) + return obj->load( order ); +#elif defined(_RTEMS_SCORE_ATOMIC_USE_STDATOMIC) + return atomic_load_explicit( obj, order ); +#else + uintptr_t val; + + (void) order; + val = *obj; + RTEMS_COMPILER_MEMORY_BARRIER(); + + return val; +#endif +} + +/** + * @brief Stores a value to Uint considering the order. + * + * @param[out] obj The CPU atomic Uint to store a value in. + * @param desired The desired value for @a obj. + * @param order The atomic order for storing the value. + */ +static inline void _Atomic_Store_uint( Atomic_Uint *obj, unsigned int desired, Atomic_Order order ) +{ +#if defined(_RTEMS_SCORE_ATOMIC_USE_ATOMIC) + obj->store( desired, order ); +#elif defined(_RTEMS_SCORE_ATOMIC_USE_STDATOMIC) + atomic_store_explicit( obj, desired, order ); +#else + (void) order; + RTEMS_COMPILER_MEMORY_BARRIER(); + *obj = desired; +#endif +} + +/** + * @brief Stores a value to Ulong considering the order. + * + * @param[out] obj The CPU atomic Ulong to store a value in. + * @param desired The desired value for @a obj. + * @param order The atomic order for storing the value. + */ +static inline void _Atomic_Store_ulong( Atomic_Ulong *obj, unsigned long desired, Atomic_Order order ) +{ +#if defined(_RTEMS_SCORE_ATOMIC_USE_ATOMIC) + obj->store( desired, order ); +#elif defined(_RTEMS_SCORE_ATOMIC_USE_STDATOMIC) + atomic_store_explicit( obj, desired, order ); +#else + (void) order; + RTEMS_COMPILER_MEMORY_BARRIER(); + *obj = desired; +#endif +} + +/** + * @brief Stores a value to Uintptr considering the order. + * + * @param[out] obj The CPU atomic Uintptr to store a value in. + * @param desired The desired value for @a obj. + * @param order The atomic order for storing the value. + */ +static inline void _Atomic_Store_uintptr( Atomic_Uintptr *obj, uintptr_t desired, Atomic_Order order ) +{ +#if defined(_RTEMS_SCORE_ATOMIC_USE_ATOMIC) + obj->store( desired, order ); +#elif defined(_RTEMS_SCORE_ATOMIC_USE_STDATOMIC) + atomic_store_explicit( obj, desired, order ); +#else + (void) order; + RTEMS_COMPILER_MEMORY_BARRIER(); + *obj = desired; +#endif +} + +/** + * @brief Fetches current value of Uint and adds a value to the stored value. + * + * @param[in, out] obj The CPU atomic Uint to get the value from and add @a arg to. + * @param arg The value to add to @a obj. + * @param order The atomic order for the operation. + * + * @return The value of @a obj prior to the addition of @a arg. + */ +static inline unsigned int _Atomic_Fetch_add_uint( Atomic_Uint *obj, unsigned int arg, Atomic_Order order ) +{ +#if defined(_RTEMS_SCORE_ATOMIC_USE_ATOMIC) + return obj->fetch_add( arg, order ); +#elif defined(_RTEMS_SCORE_ATOMIC_USE_STDATOMIC) + return atomic_fetch_add_explicit( obj, arg, order ); +#else + unsigned int val; + ISR_Level level; + + (void) order; + _ISR_Local_disable( level ); + val = *obj; + *obj = val + arg; + _ISR_Local_enable( level ); + + return val; +#endif +} + +/** + * @brief Fetches current value of Ulong and adds a value to the stored value. + * + * @param[in, out] obj The CPU atomic Ulong to get the value from and add @a arg to. + * @param arg The value to add to @a obj. + * @param order The atomic order for the operation. + * + * @return The value of @a obj prior to the addition of @a arg. + */ +static inline unsigned long _Atomic_Fetch_add_ulong( Atomic_Ulong *obj, unsigned long arg, Atomic_Order order ) +{ +#if defined(_RTEMS_SCORE_ATOMIC_USE_ATOMIC) + return obj->fetch_add( arg, order ); +#elif defined(_RTEMS_SCORE_ATOMIC_USE_STDATOMIC) + return atomic_fetch_add_explicit( obj, arg, order ); +#else + unsigned long val; + ISR_Level level; + + (void) order; + _ISR_Local_disable( level ); + val = *obj; + *obj = val + arg; + _ISR_Local_enable( level ); + + return val; +#endif +} + +/** + * @brief Fetches current value of Uintptr and adds a value to the stored value. + * + * @param[in, out] obj The CPU atomic Uintptr to get the value from and add @a arg to. + * @param arg The value to add to @a obj. + * @param order The atomic order for the operation. + * + * @return The value of @a obj prior to the addition of @a arg. + */ +static inline uintptr_t _Atomic_Fetch_add_uintptr( Atomic_Uintptr *obj, uintptr_t arg, Atomic_Order order ) +{ +#if defined(_RTEMS_SCORE_ATOMIC_USE_ATOMIC) + return obj->fetch_add( arg, order ); +#elif defined(_RTEMS_SCORE_ATOMIC_USE_STDATOMIC) + return atomic_fetch_add_explicit( obj, arg, order ); +#else + uintptr_t val; + ISR_Level level; + + (void) order; + _ISR_Local_disable( level ); + val = *obj; + *obj = val + arg; + _ISR_Local_enable( level ); + + return val; +#endif +} + +/** + * @brief Fetches current value of Uint and subtracts a value from the stored value. + * + * @param[in, out] obj The CPU atomic Uint to get the value from and subtract @a arg from. + * @param arg The value to subtract from @a obj. + * @param order The atomic order for the operation. + * + * @return The value of @a obj prior to the subtraction of @a arg. + */ +static inline unsigned int _Atomic_Fetch_sub_uint( Atomic_Uint *obj, unsigned int arg, Atomic_Order order ) +{ +#if defined(_RTEMS_SCORE_ATOMIC_USE_ATOMIC) + return obj->fetch_sub( arg, order ); +#elif defined(_RTEMS_SCORE_ATOMIC_USE_STDATOMIC) + return atomic_fetch_sub_explicit( obj, arg, order ); +#else + unsigned int val; + ISR_Level level; + + (void) order; + _ISR_Local_disable( level ); + val = *obj; + *obj = val - arg; + _ISR_Local_enable( level ); + + return val; +#endif +} + +/** + * @brief Fetches current value of Ulong and subtracts a value from the stored value. + * + * @param[in, out] obj The CPU atomic Ulong to get the value from and subtract @a arg from. + * @param arg The value to subtract from @a obj. + * @param order The atomic order for the operation. + * + * @return The value of @a obj prior to the subtraction of @a arg. + */ +static inline unsigned long _Atomic_Fetch_sub_ulong( Atomic_Ulong *obj, unsigned long arg, Atomic_Order order ) +{ +#if defined(_RTEMS_SCORE_ATOMIC_USE_ATOMIC) + return obj->fetch_sub( arg, order ); +#elif defined(_RTEMS_SCORE_ATOMIC_USE_STDATOMIC) + return atomic_fetch_sub_explicit( obj, arg, order ); +#else + unsigned long val; + ISR_Level level; + + (void) order; + _ISR_Local_disable( level ); + val = *obj; + *obj = val - arg; + _ISR_Local_enable( level ); + + return val; +#endif +} + +/** + * @brief Fetches current value of Uintptr and subtracts a value from the stored value. + * + * @param[in, out] obj The CPU atomic Uintptr to get the value from and subtract @a arg from. + * @param arg The value to subtract from @a obj. + * @param order The atomic order for the operation. + * + * @return The value of @a obj prior to the subtraction of @a arg. + */ +static inline uintptr_t _Atomic_Fetch_sub_uintptr( Atomic_Uintptr *obj, uintptr_t arg, Atomic_Order order ) +{ +#if defined(_RTEMS_SCORE_ATOMIC_USE_ATOMIC) + return obj->fetch_sub( arg, order ); +#elif defined(_RTEMS_SCORE_ATOMIC_USE_STDATOMIC) + return atomic_fetch_sub_explicit( obj, arg, order ); +#else + uintptr_t val; + ISR_Level level; + + (void) order; + _ISR_Local_disable( level ); + val = *obj; + *obj = val - arg; + _ISR_Local_enable( level ); + + return val; +#endif +} + +/** + * @brief Fetches current value of Uint and ORs a value with the stored value. + * + * @param[in, out] obj The CPU atomic Uint to get the value from and OR @a arg to. + * @param arg The value to OR with @a obj. + * @param order The atomic order for the operation. + * + * @return The value of @a obj prior to the OR operation with @a arg. + */ +static inline unsigned int _Atomic_Fetch_or_uint( Atomic_Uint *obj, unsigned int arg, Atomic_Order order ) +{ +#if defined(_RTEMS_SCORE_ATOMIC_USE_ATOMIC) + return obj->fetch_or( arg, order ); +#elif defined(_RTEMS_SCORE_ATOMIC_USE_STDATOMIC) + return atomic_fetch_or_explicit( obj, arg, order ); +#else + unsigned int val; + ISR_Level level; + + (void) order; + _ISR_Local_disable( level ); + val = *obj; + *obj = val | arg; + _ISR_Local_enable( level ); + + return val; +#endif +} + +/** + * @brief Fetches current value of Ulong and ORs a value with the stored value. + * + * @param[in, out] obj The CPU atomic Ulong to get the value from and OR @a arg to. + * @param arg The value to OR with @a obj. + * @param order The atomic order for the operation. + * + * @return The value of @a obj prior to the OR operation with @a arg. + */ +static inline unsigned long _Atomic_Fetch_or_ulong( Atomic_Ulong *obj, unsigned long arg, Atomic_Order order ) +{ +#if defined(_RTEMS_SCORE_ATOMIC_USE_ATOMIC) + return obj->fetch_or( arg, order ); +#elif defined(_RTEMS_SCORE_ATOMIC_USE_STDATOMIC) + return atomic_fetch_or_explicit( obj, arg, order ); +#else + unsigned long val; + ISR_Level level; + + (void) order; + _ISR_Local_disable( level ); + val = *obj; + *obj = val | arg; + _ISR_Local_enable( level ); + + return val; +#endif +} + +/** + * @brief Fetches current value of Uintptr and ORs a value with the stored value. + * + * @param[in, out] obj The CPU atomic Uintptr to get the value from and OR @a arg to. + * @param arg The value to OR with @a obj. + * @param order The atomic order for the operation. + * + * @return The value of @a obj prior to the OR operation with @a arg. + */ +static inline uintptr_t _Atomic_Fetch_or_uintptr( Atomic_Uintptr *obj, uintptr_t arg, Atomic_Order order ) +{ +#if defined(_RTEMS_SCORE_ATOMIC_USE_ATOMIC) + return obj->fetch_or( arg, order ); +#elif defined(_RTEMS_SCORE_ATOMIC_USE_STDATOMIC) + return atomic_fetch_or_explicit( obj, arg, order ); +#else + uintptr_t val; + ISR_Level level; + + (void) order; + _ISR_Local_disable( level ); + val = *obj; + *obj = val | arg; + _ISR_Local_enable( level ); + + return val; +#endif +} + +/** + * @brief Fetches current value of Uint and ANDs a value with the stored value. + * + * @param[in, out] obj The CPU atomic Uint to get the value from and AND @a arg to. + * @param arg The value to AND with @a obj. + * @param order The atomic order for the operation. + * + * @return The value of @a obj prior to the AND operation with @a arg. + */ +static inline unsigned int _Atomic_Fetch_and_uint( Atomic_Uint *obj, unsigned int arg, Atomic_Order order ) +{ +#if defined(_RTEMS_SCORE_ATOMIC_USE_ATOMIC) + return obj->fetch_and( arg, order ); +#elif defined(_RTEMS_SCORE_ATOMIC_USE_STDATOMIC) + return atomic_fetch_and_explicit( obj, arg, order ); +#else + unsigned int val; + ISR_Level level; + + (void) order; + _ISR_Local_disable( level ); + val = *obj; + *obj = val & arg; + _ISR_Local_enable( level ); + + return val; +#endif +} + +/** + * @brief Fetches current value of Ulong and ANDs a value with the stored value. + * + * @param[in, out] obj The CPU atomic Ulong to get the value from and AND @a arg to. + * @param arg The value to AND with @a obj. + * @param order The atomic order for the operation. + * + * @return The value of @a obj prior to the AND operation with @a arg. + */ +static inline unsigned long _Atomic_Fetch_and_ulong( Atomic_Ulong *obj, unsigned long arg, Atomic_Order order ) +{ +#if defined(_RTEMS_SCORE_ATOMIC_USE_ATOMIC) + return obj->fetch_and( arg, order ); +#elif defined(_RTEMS_SCORE_ATOMIC_USE_STDATOMIC) + return atomic_fetch_and_explicit( obj, arg, order ); +#else + unsigned long val; + ISR_Level level; + + (void) order; + _ISR_Local_disable( level ); + val = *obj; + *obj = val & arg; + _ISR_Local_enable( level ); + + return val; +#endif +} + +/** + * @brief Fetches current value of Uintptr and ANDs a value with the stored value. + * + * @param[in, out] obj The CPU atomic Uintptr to get the value from and AND @a arg to. + * @param arg The value to AND with @a obj. + * @param order The atomic order for the operation. + * + * @return The value of @a obj prior to the AND operation with @a arg. + */ +static inline uintptr_t _Atomic_Fetch_and_uintptr( Atomic_Uintptr *obj, uintptr_t arg, Atomic_Order order ) +{ +#if defined(_RTEMS_SCORE_ATOMIC_USE_ATOMIC) + return obj->fetch_and( arg, order ); +#elif defined(_RTEMS_SCORE_ATOMIC_USE_STDATOMIC) + return atomic_fetch_and_explicit( obj, arg, order ); +#else + uintptr_t val; + ISR_Level level; + + (void) order; + _ISR_Local_disable( level ); + val = *obj; + *obj = val & arg; + _ISR_Local_enable( level ); + + return val; +#endif +} + +/** + * @brief Fetches current value of Uint and sets its value. + * + * @param[in, out] obj The CPU atomic Uint to get the value from and set the value to @a desired. + * @param arg The value to set for @a obj. + * @param order The atomic order for the operation. + * + * @return The value of @a obj prior to the exchange with @a desired. + */ +static inline unsigned int _Atomic_Exchange_uint( Atomic_Uint *obj, unsigned int desired, Atomic_Order order ) +{ +#if defined(_RTEMS_SCORE_ATOMIC_USE_ATOMIC) + return obj->exchange( desired, order ); +#elif defined(_RTEMS_SCORE_ATOMIC_USE_STDATOMIC) + return atomic_exchange_explicit( obj, desired, order ); +#else + unsigned int val; + ISR_Level level; + + (void) order; + _ISR_Local_disable( level ); + val = *obj; + *obj = desired; + _ISR_Local_enable( level ); + + return val; +#endif +} + +/** + * @brief Fetches current value of Ulong and sets its value. + * + * @param[in, out] obj The CPU atomic Ulong to get the value from and set the value to @a desired. + * @param arg The value to set for @a obj. + * @param order The atomic order for the operation. + * + * @return The value of @a obj prior to the exchange with @a desired. + */ +static inline unsigned long _Atomic_Exchange_ulong( Atomic_Ulong *obj, unsigned long desired, Atomic_Order order ) +{ +#if defined(_RTEMS_SCORE_ATOMIC_USE_ATOMIC) + return obj->exchange( desired, order ); +#elif defined(_RTEMS_SCORE_ATOMIC_USE_STDATOMIC) + return atomic_exchange_explicit( obj, desired, order ); +#else + unsigned long val; + ISR_Level level; + + (void) order; + _ISR_Local_disable( level ); + val = *obj; + *obj = desired; + _ISR_Local_enable( level ); + + return val; +#endif +} + +/** + * @brief Fetches current value of Uintptr and sets its value. + * + * @param[in, out] obj The CPU atomic Uintptr to get the value from and set the value to @a desired. + * @param arg The value to set for @a obj. + * @param order The atomic order for the operation. + * + * @return The value of @a obj prior to the exchange with @a desired. + */ +static inline uintptr_t _Atomic_Exchange_uintptr( Atomic_Uintptr *obj, uintptr_t desired, Atomic_Order order ) +{ +#if defined(_RTEMS_SCORE_ATOMIC_USE_ATOMIC) + return obj->exchange( desired, order ); +#elif defined(_RTEMS_SCORE_ATOMIC_USE_STDATOMIC) + return atomic_exchange_explicit( obj, desired, order ); +#else + uintptr_t val; + ISR_Level level; + + (void) order; + _ISR_Local_disable( level ); + val = *obj; + *obj = desired; + _ISR_Local_enable( level ); + + return val; +#endif +} + +/** + * @brief Checks if value of Uint is as expected. + * + * This method checks if the value of @a obj is equal to the value of @a expected. If + * this is the case, the value of @a obj is changed to @a desired. Otherwise, the value + * of @a obj is changed to @a expected. + * + * @param[in, out] obj The CPU atomic Uint to operate upon. + * @param[in, out] expected The expected value of @a obj. If @a obj has a different + * value, @a expected is changed to the actual value of @a obj. + * @param desired The new value of @a obj if the old value of @a obj was as expected. + * @param succ The order if it is successful. + * @param fail The order if it fails. + * + * @retval true The old value of @a obj was as expected. + * @retval false The old value of @a obj was not as expected. + */ +static inline bool _Atomic_Compare_exchange_uint( Atomic_Uint *obj, unsigned int *expected, unsigned int desired, Atomic_Order succ, Atomic_Order fail ) +{ +#if defined(_RTEMS_SCORE_ATOMIC_USE_ATOMIC) + return obj->compare_exchange_strong( *expected, desired, succ, fail ); +#elif defined(_RTEMS_SCORE_ATOMIC_USE_STDATOMIC) + return atomic_compare_exchange_strong_explicit( obj, expected, desired, succ, fail ); +#else + bool success; + ISR_Level level; + unsigned int actual; + + (void) succ; + (void) fail; + _ISR_Local_disable( level ); + actual = *obj; + success = ( actual == *expected ); + if ( success ) { + *obj = desired; + } else { + *expected = actual; + } + _ISR_Local_enable( level ); + + return success; +#endif +} + +/** + * @brief Checks if value of Ulong is as expected. + * + * This method checks if the value of @a obj is equal to the value of @a expected. If + * this is the case, the value of @a obj is changed to @a desired. Otherwise, the value + * of @a obj is changed to @a expected. + * + * @param[in, out] obj The CPU atomic Ulong to operate upon. + * @param[in, out] expected The expected value of @a obj. If @a obj has a different + * value, @a expected is changed to the actual value of @a obj. + * @param desired The new value of @a obj if the old value of @a obj was as expected. + * @param succ The order if it is successful. + * @param fail The order if it fails. + * + * @retval true The old value of @a obj was as expected. + * @retval false The old value of @a obj was not as expected. + */ +static inline bool _Atomic_Compare_exchange_ulong( Atomic_Ulong *obj, unsigned long *expected, unsigned long desired, Atomic_Order succ, Atomic_Order fail ) +{ +#if defined(_RTEMS_SCORE_ATOMIC_USE_ATOMIC) + return obj->compare_exchange_strong( *expected, desired, succ, fail ); +#elif defined(_RTEMS_SCORE_ATOMIC_USE_STDATOMIC) + return atomic_compare_exchange_strong_explicit( obj, expected, desired, succ, fail ); +#else + bool success; + ISR_Level level; + unsigned long actual; + + (void) succ; + (void) fail; + _ISR_Local_disable( level ); + actual = *obj; + success = ( actual == *expected ); + if ( success ) { + *obj = desired; + } else { + *expected = actual; + } + _ISR_Local_enable( level ); + + return success; +#endif +} + +/** + * @brief Checks if value of Uintptr is as expected. + * + * This method checks if the value of @a obj is equal to the value of @a expected. If + * this is the case, the value of @a obj is changed to @a desired. Otherwise, the value + * of @a obj is changed to @a expected. + * + * @param[in, out] obj The CPU atomic Uintptr to operate upon. + * @param[in, out] expected The expected value of @a obj. If @a obj has a different + * value, @a expected is changed to the actual value of @a obj. + * @param desired The new value of @a obj if the old value of @a obj was as expected. + * @param succ The order if it is successful. + * @param fail The order if it fails. + * + * @retval true The old value of @a obj was as expected. + * @retval false The old value of @a obj was not as expected. + */ +static inline bool _Atomic_Compare_exchange_uintptr( Atomic_Uintptr *obj, uintptr_t *expected, uintptr_t desired, Atomic_Order succ, Atomic_Order fail ) +{ +#if defined(_RTEMS_SCORE_ATOMIC_USE_ATOMIC) + return obj->compare_exchange_strong( *expected, desired, succ, fail ); +#elif defined(_RTEMS_SCORE_ATOMIC_USE_STDATOMIC) + return atomic_compare_exchange_strong_explicit( obj, expected, desired, succ, fail ); +#else + bool success; + ISR_Level level; + uintptr_t actual; + + (void) succ; + (void) fail; + _ISR_Local_disable( level ); + actual = *obj; + success = ( actual == *expected ); + if ( success ) { + *obj = desired; + } else { + *expected = actual; + } + _ISR_Local_enable( level ); + + return success; +#endif +} + +/** + * @brief Clears the atomic flag. + * + * @param[out] obj The atomic flag to be cleared. + * @param order The atomic order for the operation. + */ +static inline void _Atomic_Flag_clear( Atomic_Flag *obj, Atomic_Order order ) +{ +#if defined(_RTEMS_SCORE_ATOMIC_USE_ATOMIC) + obj->clear( order ); +#elif defined(_RTEMS_SCORE_ATOMIC_USE_STDATOMIC) + atomic_flag_clear_explicit( obj, order ); +#else + (void) order; + *obj = false; +#endif +} + +/** + * @brief Returns current flag state and sets it. + * + * @param[in, out] obj The atomic flag to be set. + * @param order The atomic order for the operation. + * + * @retval true @a obj was set prior to this operation. + * @retval false @a obj was not set prior to this operation. + */ +static inline bool _Atomic_Flag_test_and_set( Atomic_Flag *obj, Atomic_Order order ) +{ +#if defined(_RTEMS_SCORE_ATOMIC_USE_ATOMIC) + return obj->test_and_set( order ); +#elif defined(_RTEMS_SCORE_ATOMIC_USE_STDATOMIC) + return atomic_flag_test_and_set_explicit( obj, order ); +#else + bool flag; + ISR_Level level; + + (void) order; + _ISR_Local_disable( level ); + flag = *obj; + *obj = true; + _ISR_Local_enable( level ); + + return flag; +#endif +} /** @} */ diff --git a/cpukit/include/rtems/score/basedefs.h b/cpukit/include/rtems/score/basedefs.h index 99fda67e8c..010728d795 100644 --- a/cpukit/include/rtems/score/basedefs.h +++ b/cpukit/include/rtems/score/basedefs.h @@ -10,7 +10,7 @@ */ /* - * Copyright (C) 2014 Paval Pisa + * Copyright (C) 2014 Pavel Pisa * Copyright (C) 2011, 2013 On-Line Applications Research Corporation (OAR) * Copyright (C) 2009, 2023 embedded brains GmbH & Co. KG * @@ -168,9 +168,9 @@ extern "C" { * * @return Returns the alignment requirement of the type. */ -#if __cplusplus >= 201103L +#if defined( __cplusplus ) && __cplusplus >= 201103L #define RTEMS_ALIGNOF( _type_name ) alignof( _type_name ) -#elif __STDC_VERSION__ >= 201112L +#elif defined( __STDC_VERSION__ ) && __STDC_VERSION__ >= 201112L #define RTEMS_ALIGNOF( _type_name ) _Alignof( _type_name ) #else #define RTEMS_ALIGNOF( _type_name ) sizeof( _type_name ) @@ -376,9 +376,9 @@ extern "C" { * @brief Tells the compiler in a function declaration that this function does * not return. */ -#if __cplusplus >= 201103L +#if defined( __cplusplus ) && __cplusplus >= 201103L #define RTEMS_NO_RETURN [[noreturn]] -#elif __STDC_VERSION__ >= 201112L +#elif defined( __STDC_VERSION__ ) && __STDC_VERSION__ >= 201112L #define RTEMS_NO_RETURN _Noreturn #elif defined(__GNUC__) #define RTEMS_NO_RETURN __attribute__(( __noreturn__ )) @@ -833,9 +833,9 @@ extern "C" { * * @param _msg is the error message in case the static assertion fails. */ -#if __cplusplus >= 201103L +#if defined( __cplusplus ) && __cplusplus >= 201103L #define RTEMS_STATIC_ASSERT( _cond, _msg ) static_assert( _cond, # _msg ) -#elif __STDC_VERSION__ >= 201112L +#elif defined( __STDC_VERSION__ ) && __STDC_VERSION__ >= 201112L #define RTEMS_STATIC_ASSERT( _cond, _msg ) _Static_assert( _cond, # _msg ) #else #define RTEMS_STATIC_ASSERT( _cond, _msg ) \ @@ -999,11 +999,12 @@ extern "C" { * * @param _value is the value of the symbol. On the value a macro expansion is * performed and afterwards it is stringified. It shall expand to an integer - * expression understood by the assembler. + * expression understood by the assembler. The value shall be representable + * in the code model of the target architecture. * * This macro shall be placed at file scope. */ -#if defined(__USER_LABEL_PREFIX__) +#if defined(__GNUC__) #define RTEMS_DEFINE_GLOBAL_SYMBOL( _name, _value ) \ __asm__( \ "\t.globl " RTEMS_XSTRING( RTEMS_SYMBOL_NAME( _name ) ) \ diff --git a/cpukit/include/rtems/score/cpustdatomic.h b/cpukit/include/rtems/score/cpustdatomic.h deleted file mode 100644 index f1afa6bec2..0000000000 --- a/cpukit/include/rtems/score/cpustdatomic.h +++ /dev/null @@ -1,986 +0,0 @@ -/* SPDX-License-Identifier: BSD-2-Clause */ - -/** - * @file - * - * @ingroup RTEMSScoreAtomicCPU - * - * @brief This header file provides the interfaces of the - * @ref RTEMSScoreAtomicCPU. - */ - -/* - * COPYRIGHT (c) 2013 Deng Hengyi. - * Copyright (c) 2015 embedded brains GmbH & Co. KG - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef _RTEMS_SCORE_CPUSTDATOMIC_H -#define _RTEMS_SCORE_CPUSTDATOMIC_H - -#include <rtems/score/basedefs.h> - -/** - * @defgroup RTEMSScoreAtomicCPU C11/C++11 Atomic Operations - * - * @ingroup RTEMSScoreAtomic - * - * @brief This group contains the atomic operations implementation using - * functions provided by the C11/C++11. - * - * @{ - */ - -#ifdef RTEMS_SMP - #if defined(__cplusplus) \ - && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 9)) - /* - * The GCC 4.9 ships its own <stdatomic.h> which is not C++ compatible. The - * suggested solution was to include <atomic> in case C++ is used. This works - * at least with GCC 4.9. See also: - * - * http://gcc.gnu.org/bugzilla/show_bug.cgi?id=60932 - * http://gcc.gnu.org/bugzilla/show_bug.cgi?id=60940 - */ - #include <atomic> - #define _RTEMS_SCORE_CPUSTDATOMIC_USE_ATOMIC - #else - #include <stdatomic.h> - #define _RTEMS_SCORE_CPUSTDATOMIC_USE_STDATOMIC - #endif -#else - #include <rtems/score/isrlevel.h> -#endif - -#if defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_ATOMIC) - -typedef std::atomic_uint CPU_atomic_Uint; - -typedef std::atomic_ulong CPU_atomic_Ulong; - -typedef std::atomic_uintptr_t CPU_atomic_Uintptr; - -typedef std::atomic_flag CPU_atomic_Flag; - -typedef std::memory_order CPU_atomic_Order; - -#define CPU_ATOMIC_ORDER_RELAXED std::memory_order_relaxed - -#define CPU_ATOMIC_ORDER_ACQUIRE std::memory_order_acquire - -#define CPU_ATOMIC_ORDER_RELEASE std::memory_order_release - -#define CPU_ATOMIC_ORDER_ACQ_REL std::memory_order_acq_rel - -#define CPU_ATOMIC_ORDER_SEQ_CST std::memory_order_seq_cst - -#define CPU_ATOMIC_INITIALIZER_UINT( value ) ATOMIC_VAR_INIT( value ) - -#define CPU_ATOMIC_INITIALIZER_ULONG( value ) ATOMIC_VAR_INIT( value ) - -#define CPU_ATOMIC_INITIALIZER_UINTPTR( value ) ATOMIC_VAR_INIT( value ) - -#define CPU_ATOMIC_INITIALIZER_FLAG ATOMIC_FLAG_INIT - -#elif defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_STDATOMIC) - -typedef atomic_uint CPU_atomic_Uint; - -typedef atomic_ulong CPU_atomic_Ulong; - -typedef atomic_uintptr_t CPU_atomic_Uintptr; - -typedef atomic_flag CPU_atomic_Flag; - -typedef memory_order CPU_atomic_Order; - -#define CPU_ATOMIC_ORDER_RELAXED memory_order_relaxed - -#define CPU_ATOMIC_ORDER_ACQUIRE memory_order_acquire - -#define CPU_ATOMIC_ORDER_RELEASE memory_order_release - -#define CPU_ATOMIC_ORDER_ACQ_REL memory_order_acq_rel - -#define CPU_ATOMIC_ORDER_SEQ_CST memory_order_seq_cst - -#define CPU_ATOMIC_INITIALIZER_UINT( value ) ATOMIC_VAR_INIT( value ) - -#define CPU_ATOMIC_INITIALIZER_ULONG( value ) ATOMIC_VAR_INIT( value ) - -#define CPU_ATOMIC_INITIALIZER_UINTPTR( value ) ATOMIC_VAR_INIT( value ) - -#define CPU_ATOMIC_INITIALIZER_FLAG ATOMIC_FLAG_INIT - -#else - -typedef unsigned int CPU_atomic_Uint; - -typedef unsigned long CPU_atomic_Ulong; - -typedef uintptr_t CPU_atomic_Uintptr; - -typedef bool CPU_atomic_Flag; - -typedef int CPU_atomic_Order; - -#define CPU_ATOMIC_ORDER_RELAXED 0 - -#define CPU_ATOMIC_ORDER_ACQUIRE 2 - -#define CPU_ATOMIC_ORDER_RELEASE 3 - -#define CPU_ATOMIC_ORDER_ACQ_REL 4 - -#define CPU_ATOMIC_ORDER_SEQ_CST 5 - -#define CPU_ATOMIC_INITIALIZER_UINT( value ) ( value ) - -#define CPU_ATOMIC_INITIALIZER_ULONG( value ) ( value ) - -#define CPU_ATOMIC_INITIALIZER_UINTPTR( value ) ( value ) - -#define CPU_ATOMIC_INITIALIZER_FLAG false - -#endif - -/** - * @brief Sets up a cpu fence. - * - * @param[out] order The order for the fence. - */ -static inline void _CPU_atomic_Fence( CPU_atomic_Order order ) -{ -#if defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_ATOMIC) - std::atomic_thread_fence( order ); -#elif defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_STDATOMIC) - atomic_thread_fence( order ); -#else - (void) order; - RTEMS_COMPILER_MEMORY_BARRIER(); -#endif -} - -/** - * @brief Initializes Uint. - * - * @param[out] obj The CPU atomic Uint to initialize. - * @param desired The desired value for @a obj. - */ -static inline void _CPU_atomic_Init_uint( CPU_atomic_Uint *obj, unsigned int desired ) -{ -#if defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_ATOMIC) - obj->store( desired ); -#elif defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_STDATOMIC) - atomic_init( obj, desired ); -#else - *obj = desired; -#endif -} - -/** - * @brief Initializes Ulong. - * - * @param[out] obj The CPU atomic Ulong to initialize. - * @param desired The desired value for @a obj. - */ -static inline void _CPU_atomic_Init_ulong( CPU_atomic_Ulong *obj, unsigned long desired ) -{ -#if defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_ATOMIC) - obj->store( desired ); -#elif defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_STDATOMIC) - atomic_init( obj, desired ); -#else - *obj = desired; -#endif -} - -/** - * @brief Initializes Uintptr. - * - * @param[out] obj The CPU atomic Uintptr to initialize. - * @param desired The desired value for @a obj. - */ -static inline void _CPU_atomic_Init_uintptr( CPU_atomic_Uintptr *obj, uintptr_t desired ) -{ -#if defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_ATOMIC) - obj->store( desired ); -#elif defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_STDATOMIC) - atomic_init( obj, desired ); -#else - *obj = desired; -#endif -} - -/** - * @brief Loads value of Uint considering the order. - * - * @param obj The CPU atomic Uint to get the value from. - * @param order The atomic order for getting the value. - * - * @return The value of @a obj considering the @a order. - */ -static inline unsigned int _CPU_atomic_Load_uint( const CPU_atomic_Uint *obj, CPU_atomic_Order order ) -{ -#if defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_ATOMIC) - return obj->load( order ); -#elif defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_STDATOMIC) - return atomic_load_explicit( obj, order ); -#else - unsigned int val; - - (void) order; - val = *obj; - RTEMS_COMPILER_MEMORY_BARRIER(); - - return val; -#endif -} - -/** - * @brief Loads value of Ulong considering the order. - * - * @param obj The CPU atomic Ulong to get the value from. - * @param order The atomic order for getting the value. - * - * @return The value of @a obj considering the @a order. - */ -static inline unsigned long _CPU_atomic_Load_ulong( const CPU_atomic_Ulong *obj, CPU_atomic_Order order ) -{ -#if defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_ATOMIC) - return obj->load( order ); -#elif defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_STDATOMIC) - return atomic_load_explicit( obj, order ); -#else - unsigned long val; - - (void) order; - val = *obj; - RTEMS_COMPILER_MEMORY_BARRIER(); - - return val; -#endif -} - -/** - * @brief Loads value of Uintptr considering the order. - * - * @param obj The CPU atomic Uintptr to get the value from. - * @param order The atomic order for getting the value. - * - * @return The value of @a obj considering the @a order. - */ -static inline uintptr_t _CPU_atomic_Load_uintptr( const CPU_atomic_Uintptr *obj, CPU_atomic_Order order ) -{ -#if defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_ATOMIC) - return obj->load( order ); -#elif defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_STDATOMIC) - return atomic_load_explicit( obj, order ); -#else - uintptr_t val; - - (void) order; - val = *obj; - RTEMS_COMPILER_MEMORY_BARRIER(); - - return val; -#endif -} - -/** - * @brief Stores a value to Uint considering the order. - * - * @param[out] obj The CPU atomic Uint to store a value in. - * @param desired The desired value for @a obj. - * @param order The atomic order for storing the value. - */ -static inline void _CPU_atomic_Store_uint( CPU_atomic_Uint *obj, unsigned int desired, CPU_atomic_Order order ) -{ -#if defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_ATOMIC) - obj->store( desired, order ); -#elif defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_STDATOMIC) - atomic_store_explicit( obj, desired, order ); -#else - (void) order; - RTEMS_COMPILER_MEMORY_BARRIER(); - *obj = desired; -#endif -} - -/** - * @brief Stores a value to Ulong considering the order. - * - * @param[out] obj The CPU atomic Ulong to store a value in. - * @param desired The desired value for @a obj. - * @param order The atomic order for storing the value. - */ -static inline void _CPU_atomic_Store_ulong( CPU_atomic_Ulong *obj, unsigned long desired, CPU_atomic_Order order ) -{ -#if defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_ATOMIC) - obj->store( desired, order ); -#elif defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_STDATOMIC) - atomic_store_explicit( obj, desired, order ); -#else - (void) order; - RTEMS_COMPILER_MEMORY_BARRIER(); - *obj = desired; -#endif -} - -/** - * @brief Stores a value to Uintptr considering the order. - * - * @param[out] obj The CPU atomic Uintptr to store a value in. - * @param desired The desired value for @a obj. - * @param order The atomic order for storing the value. - */ -static inline void _CPU_atomic_Store_uintptr( CPU_atomic_Uintptr *obj, uintptr_t desired, CPU_atomic_Order order ) -{ -#if defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_ATOMIC) - obj->store( desired, order ); -#elif defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_STDATOMIC) - atomic_store_explicit( obj, desired, order ); -#else - (void) order; - RTEMS_COMPILER_MEMORY_BARRIER(); - *obj = desired; -#endif -} - -/** - * @brief Fetches current value of Uint and adds a value to the stored value. - * - * @param[in, out] obj The CPU atomic Uint to get the value from and add @a arg to. - * @param arg The value to add to @a obj. - * @param order The atomic order for the operation. - * - * @return The value of @a obj prior to the addition of @a arg. - */ -static inline unsigned int _CPU_atomic_Fetch_add_uint( CPU_atomic_Uint *obj, unsigned int arg, CPU_atomic_Order order ) -{ -#if defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_ATOMIC) - return obj->fetch_add( arg, order ); -#elif defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_STDATOMIC) - return atomic_fetch_add_explicit( obj, arg, order ); -#else - unsigned int val; - ISR_Level level; - - (void) order; - _ISR_Local_disable( level ); - val = *obj; - *obj = val + arg; - _ISR_Local_enable( level ); - - return val; -#endif -} - -/** - * @brief Fetches current value of Ulong and adds a value to the stored value. - * - * @param[in, out] obj The CPU atomic Ulong to get the value from and add @a arg to. - * @param arg The value to add to @a obj. - * @param order The atomic order for the operation. - * - * @return The value of @a obj prior to the addition of @a arg. - */ -static inline unsigned long _CPU_atomic_Fetch_add_ulong( CPU_atomic_Ulong *obj, unsigned long arg, CPU_atomic_Order order ) -{ -#if defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_ATOMIC) - return obj->fetch_add( arg, order ); -#elif defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_STDATOMIC) - return atomic_fetch_add_explicit( obj, arg, order ); -#else - unsigned long val; - ISR_Level level; - - (void) order; - _ISR_Local_disable( level ); - val = *obj; - *obj = val + arg; - _ISR_Local_enable( level ); - - return val; -#endif -} - -/** - * @brief Fetches current value of Uintptr and adds a value to the stored value. - * - * @param[in, out] obj The CPU atomic Uintptr to get the value from and add @a arg to. - * @param arg The value to add to @a obj. - * @param order The atomic order for the operation. - * - * @return The value of @a obj prior to the addition of @a arg. - */ -static inline uintptr_t _CPU_atomic_Fetch_add_uintptr( CPU_atomic_Uintptr *obj, uintptr_t arg, CPU_atomic_Order order ) -{ -#if defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_ATOMIC) - return obj->fetch_add( arg, order ); -#elif defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_STDATOMIC) - return atomic_fetch_add_explicit( obj, arg, order ); -#else - uintptr_t val; - ISR_Level level; - - (void) order; - _ISR_Local_disable( level ); - val = *obj; - *obj = val + arg; - _ISR_Local_enable( level ); - - return val; -#endif -} - -/** - * @brief Fetches current value of Uint and subtracts a value from the stored value. - * - * @param[in, out] obj The CPU atomic Uint to get the value from and subtract @a arg from. - * @param arg The value to subtract from @a obj. - * @param order The atomic order for the operation. - * - * @return The value of @a obj prior to the subtraction of @a arg. - */ -static inline unsigned int _CPU_atomic_Fetch_sub_uint( CPU_atomic_Uint *obj, unsigned int arg, CPU_atomic_Order order ) -{ -#if defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_ATOMIC) - return obj->fetch_sub( arg, order ); -#elif defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_STDATOMIC) - return atomic_fetch_sub_explicit( obj, arg, order ); -#else - unsigned int val; - ISR_Level level; - - (void) order; - _ISR_Local_disable( level ); - val = *obj; - *obj = val - arg; - _ISR_Local_enable( level ); - - return val; -#endif -} - -/** - * @brief Fetches current value of Ulong and subtracts a value from the stored value. - * - * @param[in, out] obj The CPU atomic Ulong to get the value from and subtract @a arg from. - * @param arg The value to subtract from @a obj. - * @param order The atomic order for the operation. - * - * @return The value of @a obj prior to the subtraction of @a arg. - */ -static inline unsigned long _CPU_atomic_Fetch_sub_ulong( CPU_atomic_Ulong *obj, unsigned long arg, CPU_atomic_Order order ) -{ -#if defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_ATOMIC) - return obj->fetch_sub( arg, order ); -#elif defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_STDATOMIC) - return atomic_fetch_sub_explicit( obj, arg, order ); -#else - unsigned long val; - ISR_Level level; - - (void) order; - _ISR_Local_disable( level ); - val = *obj; - *obj = val - arg; - _ISR_Local_enable( level ); - - return val; -#endif -} - -/** - * @brief Fetches current value of Uintptr and subtracts a value from the stored value. - * - * @param[in, out] obj The CPU atomic Uintptr to get the value from and subtract @a arg from. - * @param arg The value to subtract from @a obj. - * @param order The atomic order for the operation. - * - * @return The value of @a obj prior to the subtraction of @a arg. - */ -static inline uintptr_t _CPU_atomic_Fetch_sub_uintptr( CPU_atomic_Uintptr *obj, uintptr_t arg, CPU_atomic_Order order ) -{ -#if defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_ATOMIC) - return obj->fetch_sub( arg, order ); -#elif defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_STDATOMIC) - return atomic_fetch_sub_explicit( obj, arg, order ); -#else - uintptr_t val; - ISR_Level level; - - (void) order; - _ISR_Local_disable( level ); - val = *obj; - *obj = val - arg; - _ISR_Local_enable( level ); - - return val; -#endif -} - -/** - * @brief Fetches current value of Uint and ORs a value with the stored value. - * - * @param[in, out] obj The CPU atomic Uint to get the value from and OR @a arg to. - * @param arg The value to OR with @a obj. - * @param order The atomic order for the operation. - * - * @return The value of @a obj prior to the OR operation with @a arg. - */ -static inline unsigned int _CPU_atomic_Fetch_or_uint( CPU_atomic_Uint *obj, unsigned int arg, CPU_atomic_Order order ) -{ -#if defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_ATOMIC) - return obj->fetch_or( arg, order ); -#elif defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_STDATOMIC) - return atomic_fetch_or_explicit( obj, arg, order ); -#else - unsigned int val; - ISR_Level level; - - (void) order; - _ISR_Local_disable( level ); - val = *obj; - *obj = val | arg; - _ISR_Local_enable( level ); - - return val; -#endif -} - -/** - * @brief Fetches current value of Ulong and ORs a value with the stored value. - * - * @param[in, out] obj The CPU atomic Ulong to get the value from and OR @a arg to. - * @param arg The value to OR with @a obj. - * @param order The atomic order for the operation. - * - * @return The value of @a obj prior to the OR operation with @a arg. - */ -static inline unsigned long _CPU_atomic_Fetch_or_ulong( CPU_atomic_Ulong *obj, unsigned long arg, CPU_atomic_Order order ) -{ -#if defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_ATOMIC) - return obj->fetch_or( arg, order ); -#elif defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_STDATOMIC) - return atomic_fetch_or_explicit( obj, arg, order ); -#else - unsigned long val; - ISR_Level level; - - (void) order; - _ISR_Local_disable( level ); - val = *obj; - *obj = val | arg; - _ISR_Local_enable( level ); - - return val; -#endif -} - -/** - * @brief Fetches current value of Uintptr and ORs a value with the stored value. - * - * @param[in, out] obj The CPU atomic Uintptr to get the value from and OR @a arg to. - * @param arg The value to OR with @a obj. - * @param order The atomic order for the operation. - * - * @return The value of @a obj prior to the OR operation with @a arg. - */ -static inline uintptr_t _CPU_atomic_Fetch_or_uintptr( CPU_atomic_Uintptr *obj, uintptr_t arg, CPU_atomic_Order order ) -{ -#if defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_ATOMIC) - return obj->fetch_or( arg, order ); -#elif defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_STDATOMIC) - return atomic_fetch_or_explicit( obj, arg, order ); -#else - uintptr_t val; - ISR_Level level; - - (void) order; - _ISR_Local_disable( level ); - val = *obj; - *obj = val | arg; - _ISR_Local_enable( level ); - - return val; -#endif -} - -/** - * @brief Fetches current value of Uint and ANDs a value with the stored value. - * - * @param[in, out] obj The CPU atomic Uint to get the value from and AND @a arg to. - * @param arg The value to AND with @a obj. - * @param order The atomic order for the operation. - * - * @return The value of @a obj prior to the AND operation with @a arg. - */ -static inline unsigned int _CPU_atomic_Fetch_and_uint( CPU_atomic_Uint *obj, unsigned int arg, CPU_atomic_Order order ) -{ -#if defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_ATOMIC) - return obj->fetch_and( arg, order ); -#elif defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_STDATOMIC) - return atomic_fetch_and_explicit( obj, arg, order ); -#else - unsigned int val; - ISR_Level level; - - (void) order; - _ISR_Local_disable( level ); - val = *obj; - *obj = val & arg; - _ISR_Local_enable( level ); - - return val; -#endif -} - -/** - * @brief Fetches current value of Ulong and ANDs a value with the stored value. - * - * @param[in, out] obj The CPU atomic Ulong to get the value from and AND @a arg to. - * @param arg The value to AND with @a obj. - * @param order The atomic order for the operation. - * - * @return The value of @a obj prior to the AND operation with @a arg. - */ -static inline unsigned long _CPU_atomic_Fetch_and_ulong( CPU_atomic_Ulong *obj, unsigned long arg, CPU_atomic_Order order ) -{ -#if defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_ATOMIC) - return obj->fetch_and( arg, order ); -#elif defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_STDATOMIC) - return atomic_fetch_and_explicit( obj, arg, order ); -#else - unsigned long val; - ISR_Level level; - - (void) order; - _ISR_Local_disable( level ); - val = *obj; - *obj = val & arg; - _ISR_Local_enable( level ); - - return val; -#endif -} - -/** - * @brief Fetches current value of Uintptr and ANDs a value with the stored value. - * - * @param[in, out] obj The CPU atomic Uintptr to get the value from and AND @a arg to. - * @param arg The value to AND with @a obj. - * @param order The atomic order for the operation. - * - * @return The value of @a obj prior to the AND operation with @a arg. - */ -static inline uintptr_t _CPU_atomic_Fetch_and_uintptr( CPU_atomic_Uintptr *obj, uintptr_t arg, CPU_atomic_Order order ) -{ -#if defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_ATOMIC) - return obj->fetch_and( arg, order ); -#elif defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_STDATOMIC) - return atomic_fetch_and_explicit( obj, arg, order ); -#else - uintptr_t val; - ISR_Level level; - - (void) order; - _ISR_Local_disable( level ); - val = *obj; - *obj = val & arg; - _ISR_Local_enable( level ); - - return val; -#endif -} - -/** - * @brief Fetches current value of Uint and sets its value. - * - * @param[in, out] obj The CPU atomic Uint to get the value from and set the value to @a desired. - * @param arg The value to set for @a obj. - * @param order The atomic order for the operation. - * - * @return The value of @a obj prior to the exchange with @a desired. - */ -static inline unsigned int _CPU_atomic_Exchange_uint( CPU_atomic_Uint *obj, unsigned int desired, CPU_atomic_Order order ) -{ -#if defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_ATOMIC) - return obj->exchange( desired, order ); -#elif defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_STDATOMIC) - return atomic_exchange_explicit( obj, desired, order ); -#else - unsigned int val; - ISR_Level level; - - (void) order; - _ISR_Local_disable( level ); - val = *obj; - *obj = desired; - _ISR_Local_enable( level ); - - return val; -#endif -} - -/** - * @brief Fetches current value of Ulong and sets its value. - * - * @param[in, out] obj The CPU atomic Ulong to get the value from and set the value to @a desired. - * @param arg The value to set for @a obj. - * @param order The atomic order for the operation. - * - * @return The value of @a obj prior to the exchange with @a desired. - */ -static inline unsigned long _CPU_atomic_Exchange_ulong( CPU_atomic_Ulong *obj, unsigned long desired, CPU_atomic_Order order ) -{ -#if defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_ATOMIC) - return obj->exchange( desired, order ); -#elif defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_STDATOMIC) - return atomic_exchange_explicit( obj, desired, order ); -#else - unsigned long val; - ISR_Level level; - - (void) order; - _ISR_Local_disable( level ); - val = *obj; - *obj = desired; - _ISR_Local_enable( level ); - - return val; -#endif -} - -/** - * @brief Fetches current value of Uintptr and sets its value. - * - * @param[in, out] obj The CPU atomic Uintptr to get the value from and set the value to @a desired. - * @param arg The value to set for @a obj. - * @param order The atomic order for the operation. - * - * @return The value of @a obj prior to the exchange with @a desired. - */ -static inline uintptr_t _CPU_atomic_Exchange_uintptr( CPU_atomic_Uintptr *obj, uintptr_t desired, CPU_atomic_Order order ) -{ -#if defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_ATOMIC) - return obj->exchange( desired, order ); -#elif defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_STDATOMIC) - return atomic_exchange_explicit( obj, desired, order ); -#else - uintptr_t val; - ISR_Level level; - - (void) order; - _ISR_Local_disable( level ); - val = *obj; - *obj = desired; - _ISR_Local_enable( level ); - - return val; -#endif -} - -/** - * @brief Checks if value of Uint is as expected. - * - * This method checks if the value of @a obj is equal to the value of @a expected. If - * this is the case, the value of @a obj is changed to @a desired. Otherwise, the value - * of @a obj is changed to @a expected. - * - * @param[in, out] obj The CPU atomic Uint to operate upon. - * @param[in, out] expected The expected value of @a obj. If @a obj has a different - * value, @a expected is changed to the actual value of @a obj. - * @param desired The new value of @a obj if the old value of @a obj was as expected. - * @param succ The order if it is successful. - * @param fail The order if it fails. - * - * @retval true The old value of @a obj was as expected. - * @retval false The old value of @a obj was not as expected. - */ -static inline bool _CPU_atomic_Compare_exchange_uint( CPU_atomic_Uint *obj, unsigned int *expected, unsigned int desired, CPU_atomic_Order succ, CPU_atomic_Order fail ) -{ -#if defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_ATOMIC) - return obj->compare_exchange_strong( *expected, desired, succ, fail ); -#elif defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_STDATOMIC) - return atomic_compare_exchange_strong_explicit( obj, expected, desired, succ, fail ); -#else - bool success; - ISR_Level level; - unsigned int actual; - - (void) succ; - (void) fail; - _ISR_Local_disable( level ); - actual = *obj; - success = ( actual == *expected ); - if ( success ) { - *obj = desired; - } else { - *expected = actual; - } - _ISR_Local_enable( level ); - - return success; -#endif -} - -/** - * @brief Checks if value of Ulong is as expected. - * - * This method checks if the value of @a obj is equal to the value of @a expected. If - * this is the case, the value of @a obj is changed to @a desired. Otherwise, the value - * of @a obj is changed to @a expected. - * - * @param[in, out] obj The CPU atomic Ulong to operate upon. - * @param[in, out] expected The expected value of @a obj. If @a obj has a different - * value, @a expected is changed to the actual value of @a obj. - * @param desired The new value of @a obj if the old value of @a obj was as expected. - * @param succ The order if it is successful. - * @param fail The order if it fails. - * - * @retval true The old value of @a obj was as expected. - * @retval false The old value of @a obj was not as expected. - */ -static inline bool _CPU_atomic_Compare_exchange_ulong( CPU_atomic_Ulong *obj, unsigned long *expected, unsigned long desired, CPU_atomic_Order succ, CPU_atomic_Order fail ) -{ -#if defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_ATOMIC) - return obj->compare_exchange_strong( *expected, desired, succ, fail ); -#elif defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_STDATOMIC) - return atomic_compare_exchange_strong_explicit( obj, expected, desired, succ, fail ); -#else - bool success; - ISR_Level level; - unsigned long actual; - - (void) succ; - (void) fail; - _ISR_Local_disable( level ); - actual = *obj; - success = ( actual == *expected ); - if ( success ) { - *obj = desired; - } else { - *expected = actual; - } - _ISR_Local_enable( level ); - - return success; -#endif -} - -/** - * @brief Checks if value of Uintptr is as expected. - * - * This method checks if the value of @a obj is equal to the value of @a expected. If - * this is the case, the value of @a obj is changed to @a desired. Otherwise, the value - * of @a obj is changed to @a expected. - * - * @param[in, out] obj The CPU atomic Uintptr to operate upon. - * @param[in, out] expected The expected value of @a obj. If @a obj has a different - * value, @a expected is changed to the actual value of @a obj. - * @param desired The new value of @a obj if the old value of @a obj was as expected. - * @param succ The order if it is successful. - * @param fail The order if it fails. - * - * @retval true The old value of @a obj was as expected. - * @retval false The old value of @a obj was not as expected. - */ -static inline bool _CPU_atomic_Compare_exchange_uintptr( CPU_atomic_Uintptr *obj, uintptr_t *expected, uintptr_t desired, CPU_atomic_Order succ, CPU_atomic_Order fail ) -{ -#if defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_ATOMIC) - return obj->compare_exchange_strong( *expected, desired, succ, fail ); -#elif defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_STDATOMIC) - return atomic_compare_exchange_strong_explicit( obj, expected, desired, succ, fail ); -#else - bool success; - ISR_Level level; - uintptr_t actual; - - (void) succ; - (void) fail; - _ISR_Local_disable( level ); - actual = *obj; - success = ( actual == *expected ); - if ( success ) { - *obj = desired; - } else { - *expected = actual; - } - _ISR_Local_enable( level ); - - return success; -#endif -} - -/** - * @brief Clears the atomic flag. - * - * @param[out] obj The atomic flag to be cleared. - * @param order The atomic order for the operation. - */ -static inline void _CPU_atomic_Flag_clear( CPU_atomic_Flag *obj, CPU_atomic_Order order ) -{ -#if defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_ATOMIC) - obj->clear( order ); -#elif defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_STDATOMIC) - atomic_flag_clear_explicit( obj, order ); -#else - (void) order; - *obj = false; -#endif -} - -/** - * @brief Returns current flag state and sets it. - * - * @param[in, out] obj The atomic flag to be set. - * @param order The atomic order for the operation. - * - * @retval true @a obj was set prior to this operation. - * @retval false @a obj was not set prior to this operation. - */ -static inline bool _CPU_atomic_Flag_test_and_set( CPU_atomic_Flag *obj, CPU_atomic_Order order ) -{ -#if defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_ATOMIC) - return obj->test_and_set( order ); -#elif defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_STDATOMIC) - return atomic_flag_test_and_set_explicit( obj, order ); -#else - bool flag; - ISR_Level level; - - (void) order; - _ISR_Local_disable( level ); - flag = *obj; - *obj = true; - _ISR_Local_enable( level ); - - return flag; -#endif -} - -/** @} */ - -#endif /* _RTEMS_SCORE_CPUSTDATOMIC_H */ diff --git a/cpukit/include/rtems/score/isr.h b/cpukit/include/rtems/score/isr.h index bb1f3cee50..96ad816245 100644 --- a/cpukit/include/rtems/score/isr.h +++ b/cpukit/include/rtems/score/isr.h @@ -98,7 +98,11 @@ extern ISR_Handler_entry _ISR_Vector_table[ CPU_INTERRUPT_NUMBER_OF_VECTORS ]; #endif /** - * @brief Global symbol with a value equal to the configure interrupt stack size. + * @brief Provides the configured interrupt stack size through an address. + * + * The address of this global symbol is equal to the configured interrupt stack + * size. The address of this symbol has an arbitrary value an may not be + * representable in the code model used by the compiler. * * This global symbol is defined by the application configuration option * CONFIGURE_INIT_TASK_STACK_SIZE via <rtems/confdefs.h>. @@ -106,6 +110,14 @@ extern ISR_Handler_entry _ISR_Vector_table[ CPU_INTERRUPT_NUMBER_OF_VECTORS ]; RTEMS_DECLARE_GLOBAL_SYMBOL( _ISR_Stack_size ); /** + * @brief Provides the configured interrupt stack size through an object. + * + * This object is provided to avoid issues with the _ISR_Stack_size symbol + * address and the code model used by the compiler. + */ +extern const char * const volatile _ISR_Stack_size_object; + +/** * @brief The interrupt stack area begin. * * The interrupt stack area is defined by the application configuration via diff --git a/cpukit/include/rtems/score/mpci.h b/cpukit/include/rtems/score/mpci.h index 874c195e95..796c881929 100644 --- a/cpukit/include/rtems/score/mpci.h +++ b/cpukit/include/rtems/score/mpci.h @@ -40,9 +40,6 @@ #define _RTEMS_SCORE_MPCI_H #include <rtems/score/mppkt.h> -#include <rtems/score/thread.h> -#include <rtems/score/threadq.h> -#include <rtems/score/watchdog.h> #ifdef __cplusplus extern "C" { diff --git a/cpukit/include/rtems/score/mpciimpl.h b/cpukit/include/rtems/score/mpciimpl.h index b646d4be4d..d0c2d0558a 100644 --- a/cpukit/include/rtems/score/mpciimpl.h +++ b/cpukit/include/rtems/score/mpciimpl.h @@ -39,6 +39,9 @@ #define _RTEMS_SCORE_MPCIIMPL_H #include <rtems/score/mpci.h> +#include <rtems/score/thread.h> +#include <rtems/score/threadq.h> +#include <rtems/score/watchdog.h> #include <rtems/score/status.h> #ifdef __cplusplus diff --git a/cpukit/include/rtems/score/mrspimpl.h b/cpukit/include/rtems/score/mrspimpl.h index 7a6c86d57c..fd783bf2a0 100644 --- a/cpukit/include/rtems/score/mrspimpl.h +++ b/cpukit/include/rtems/score/mrspimpl.h @@ -130,6 +130,7 @@ static inline Priority_Control _MRSP_Get_priority( uint32_t scheduler_index; scheduler_index = _Scheduler_Get_index( scheduler ); + _Assert( scheduler_index < _Scheduler_Count ); return mrsp->ceiling_priorities[ scheduler_index ]; } @@ -149,6 +150,7 @@ static inline void _MRSP_Set_priority( uint32_t scheduler_index; scheduler_index = _Scheduler_Get_index( scheduler ); + _Assert( scheduler_index < _Scheduler_Count ); mrsp->ceiling_priorities[ scheduler_index ] = new_priority; } diff --git a/cpukit/include/rtems/score/processormask.h b/cpukit/include/rtems/score/processormask.h index ce23f6c10d..71ed37cd0e 100644 --- a/cpukit/include/rtems/score/processormask.h +++ b/cpukit/include/rtems/score/processormask.h @@ -39,9 +39,7 @@ #include <rtems/score/cpu.h> -#include <sys/cpuset.h> - -#include <strings.h> +#include <sys/_bitset.h> #ifdef __cplusplus extern "C" { @@ -123,381 +121,6 @@ extern "C" { */ typedef __BITSET_DEFINE( Processor_mask, CPU_MAXIMUM_PROCESSORS ) Processor_mask; -/** - * @brief Sets the bits of the mask to zero, also considers CPU_MAXIMUM_PROCESSORS. - * - * @param[out] mask The mask to set to zero. - */ -static inline void _Processor_mask_Zero( Processor_mask *mask ) -{ - __BIT_ZERO( CPU_MAXIMUM_PROCESSORS, mask ); -} - -/** - * @brief Checks if the mask is zero, also considers CPU_MAXIMUM_PROCESSORS. - * - * @param mask The mask to check whether is is zero - * - * @retval true The mask is zero. - * @retval false The mask is not zero. - */ -static inline bool _Processor_mask_Is_zero( const Processor_mask *mask ) -{ - return __BIT_EMPTY( CPU_MAXIMUM_PROCESSORS, mask ); -} - -/** - * @brief Fills the mask, also considers CPU_MAXIMUM_PROCESSORS. - * - * @param[out] mask The mask to fill - */ -static inline void _Processor_mask_Fill( Processor_mask *mask ) -{ - __BIT_FILL( CPU_MAXIMUM_PROCESSORS, mask ); -} - -/** - * @brief Copies the mask to another mask, also considers CPU_MAXIMUM_PROCESSORS. - * - * @param[out] dst The mask to copy @a src to. - * @param src The mask to copy to @a dst. - */ -static inline void _Processor_mask_Assign( - Processor_mask *dst, const Processor_mask *src -) -{ - __BIT_COPY( CPU_MAXIMUM_PROCESSORS, src, dst ); -} - -/** - * @brief Sets the specified index bit of the mask. - * - * @param[out] mask The mask to set the bit of. - * @param index The index of the bit that shall be set. - */ -static inline void _Processor_mask_Set( - Processor_mask *mask, - uint32_t index -) -{ - __BIT_SET( CPU_MAXIMUM_PROCESSORS, index, mask ); -} - -/** - * @brief Clears the specified index bit of the mask. - * - * @param[out] mask The mask to clear the bit of. - * @param index The index of the bit that shall be cleared. - */ -static inline void _Processor_mask_Clear( - Processor_mask *mask, - uint32_t index -) -{ - __BIT_CLR( CPU_MAXIMUM_PROCESSORS, index, mask ); -} - -/** - * @brief Checks if the specified index bit of the mask is set. - * - * @param mask The mask to check if the specified bit is set. - * @param index The index of the bit that is checked. - * - * @retval true The specified index bit is set. - * @retval false The specified index bit is not set. - */ -static inline bool _Processor_mask_Is_set( - const Processor_mask *mask, - uint32_t index -) -{ - return __BIT_ISSET( CPU_MAXIMUM_PROCESSORS, index, mask ); -} - -/** - * @brief Checks if the processor sets a and b are equal. - * - * @param a The first processor set. - * @param b The seconde processor set. - * - * @retval true The processor sets a and b are equal. - * @retval false The processor sets a and b are not equal. - */ -static inline bool _Processor_mask_Is_equal( - const Processor_mask *a, - const Processor_mask *b -) -{ - return !__BIT_CMP( CPU_MAXIMUM_PROCESSORS, a, b ); -} - -/** - * @brief Checks if the intersection of the processor sets a and b is - * non-empty. - * - * @param a The first processor set. - * @param b The second processor set. - * - * @retval true The intersection of the processor sets a and b is non-empty. - * @retval false The intersection of the processor sets a and b is empty. - */ -static inline bool _Processor_mask_Has_overlap( - const Processor_mask *a, - const Processor_mask *b -) -{ - return __BIT_OVERLAP( CPU_MAXIMUM_PROCESSORS, a, b ); -} - -/** - * @brief Checks if the processor set small is a subset of processor set - * big. - * - * @param big The bigger processor set. - * @param small The smaller processor set. - * - * @retval true @a small is a subset of @a big. - * @retval false @a small is not a subset of @a big. - */ -static inline bool _Processor_mask_Is_subset( - const Processor_mask *big, - const Processor_mask *small -) -{ - return __BIT_SUBSET( CPU_MAXIMUM_PROCESSORS, big, small ); -} - -/** - * @brief Performs a bitwise a = b & c. - * - * @param[out] a The processor mask that is set by this operation. - * @param b The first parameter of the AND-operation. - * @param c The second parameter of the AND-operation. - */ -static inline void _Processor_mask_And( - Processor_mask *a, - const Processor_mask *b, - const Processor_mask *c -) -{ - __BIT_AND2( CPU_MAXIMUM_PROCESSORS, a, b, c ); -} - -/** - * @brief Performs a bitwise a = b | c. - * - * @param[out] a The processor mask that is set by this operation. - * @param b The first parameter of the OR-operation. - * @param c The second parameter of the OR-operation. - */ -static inline void _Processor_mask_Or( - Processor_mask *a, - const Processor_mask *b, - const Processor_mask *c -) -{ - __BIT_OR2( CPU_MAXIMUM_PROCESSORS, a, b, c ); -} - -/** - * @brief Performs a bitwise a = b ^ c. - * - * @param[out] a The processor mask that is set by this operation. - * @param b The first parameter of the XOR-operation. - * @param c The second parameter of the XOR-operation. - */ -static inline void _Processor_mask_Xor( - Processor_mask *a, - const Processor_mask *b, - const Processor_mask *c -) -{ - __BIT_XOR2( CPU_MAXIMUM_PROCESSORS, a, b, c ); -} - -/** - * @brief Gets the number of set bits in the processor mask. - * - * @param a The processor mask of which the set bits are counted. - * - * @return The number of set bits in @a a. - */ -static inline uint32_t _Processor_mask_Count( const Processor_mask *a ) -{ - return (uint32_t) __BIT_COUNT( CPU_MAXIMUM_PROCESSORS, a ); -} - -/** - * @brief Finds the last set of the processor mask. - * - * @param a The processor mask wo find the last set of. - * - * @return The last set of @a a. - */ -static inline uint32_t _Processor_mask_Find_last_set( const Processor_mask *a ) -{ - return (uint32_t) __BIT_FLS( CPU_MAXIMUM_PROCESSORS, a ); -} - -/** - * @brief Returns the subset of 32 processors containing the specified index as - * an unsigned 32-bit integer. - * - * @param mask The processor mask. - * @param index The specified index. - * - * @return The subset containing the specified index as an unsigned 32-bit integer. - */ -static inline uint32_t _Processor_mask_To_uint32_t( - const Processor_mask *mask, - uint32_t index -) -{ - long bits = mask->__bits[ index / _BITSET_BITS ]; - - return (uint32_t) ( bits >> ( 32 * ( ( index % _BITSET_BITS ) / 32 ) ) ); -} - -/** - * @brief Creates a processor set from an unsigned 32-bit integer relative to - * the specified index. - * - * @param[out] mask The mask that is created. - * @param bits The bits for creating the mask. - * @param index The index to which the mask is relative. - */ -static inline void _Processor_mask_From_uint32_t( - Processor_mask *mask, - uint32_t bits, - uint32_t index -) -{ - _Processor_mask_Zero( mask ); - mask->__bits[ __bitset_words( index ) ] = ((long) bits) << (32 * (index % _BITSET_BITS) / 32); -} - -/** - * @brief Creates a processor set from the specified index. - * - * @param[out] The mask that is created. - * @param index The specified index. - */ -static inline void _Processor_mask_From_index( - Processor_mask *mask, - uint32_t index -) -{ - __BIT_SETOF( CPU_MAXIMUM_PROCESSORS, (int) index, mask ); -} - -typedef enum { - PROCESSOR_MASK_COPY_LOSSLESS, - PROCESSOR_MASK_COPY_PARTIAL_LOSS, - PROCESSOR_MASK_COPY_COMPLETE_LOSS, - PROCESSOR_MASK_COPY_INVALID_SIZE -} Processor_mask_Copy_status; - -/** - * @brief Checks if the copy status guarantees at most partial loss. - * - * @param status The copy status to check. - * - * @retval true At most partial loss can be guaranteed. - * @retval false The status indicates more than partial loss. - */ -static inline bool _Processor_mask_Is_at_most_partial_loss( - Processor_mask_Copy_status status -) -{ - return (unsigned int) status <= PROCESSOR_MASK_COPY_PARTIAL_LOSS; -} - -/** - * @brief Copies one mask to another. - * - * @param[out] dst The destination of the copy operation. - * @param dst_size The size of @a dst. - * @param src The source of the copy operation. - * @param src_size The size of @a src. - * - * @retval PROCESSOR_MASK_COPY_LOSSLESS It is guaranteed that the copy - * operation is lossless. - * @retval PROCESSOR_MASK_COPY_PARTIAL_LOSS Partial loss happened due - * to the sizes of @a src and @a dst. - * @retval PROCESSOR_MASK_COPY_COMPLETE_LOSS Complete loss happened due - * to the sizes of @a src and @a dst. - * @retval PROCESSOR_MASK_COPY_INVALID_SIZE One of the arguments sizes - * is invalid (bigger than the size of a long). - */ -Processor_mask_Copy_status _Processor_mask_Copy( - long *dst, - size_t dst_size, - const long *src, - size_t src_size -); - -/** - * @brief Copies one mask to another. - * - * @param src The source for the copy operation. - * @param dst_size The size of @a dst. - * @param[out] dst The destination for the copy operation. - * - * @retval PROCESSOR_MASK_COPY_LOSSLESS It is guaranteed that the copy - * operation is lossless. - * @retval PROCESSOR_MASK_COPY_PARTIAL_LOSS Partial loss happened due - * to the sizes of @a src and @a dst. - * @retval PROCESSOR_MASK_COPY_COMPLETE_LOSS Complete loss happened due - * to the sizes of @a src and @a dst. - * @retval PROCESSOR_MASK_COPY_INVALID_SIZE One of the arguments sizes - * is invalid (bigger than the size of a long). - */ -static inline Processor_mask_Copy_status _Processor_mask_To_cpu_set_t( - const Processor_mask *src, - size_t dst_size, - cpu_set_t *dst -) -{ - return _Processor_mask_Copy( - &dst->__bits[ 0 ], - dst_size, - &src->__bits[ 0 ], - sizeof( *src ) - ); -} - -/** - * @brief Copies one mask to another. - * - * @param src The source for the copy operation. - * @param src_size The size of @a src. - * @param[out] dst The destination for the copy operation. - * - * @retval PROCESSOR_MASK_COPY_LOSSLESS It is guaranteed that the copy - * operation is lossless. - * @retval PROCESSOR_MASK_COPY_PARTIAL_LOSS Partial loss happened due - * to the sizes of @a src and @a dst. - * @retval PROCESSOR_MASK_COPY_COMPLETE_LOSS Complete loss happened due - * to the sizes of @a src and @a dst. - * @retval PROCESSOR_MASK_COPY_INVALID_SIZE One of the arguments sizes - * is invalid (bigger than the size of a long). - */ -static inline Processor_mask_Copy_status _Processor_mask_From_cpu_set_t( - Processor_mask *dst, - size_t src_size, - const cpu_set_t *src -) -{ - return _Processor_mask_Copy( - &dst->__bits[ 0 ], - sizeof( *dst ), - &src->__bits[ 0 ], - src_size - ); -} - -extern const Processor_mask _Processor_mask_The_one_and_only; - /** @} */ #ifdef __cplusplus diff --git a/cpukit/include/rtems/score/processormaskimpl.h b/cpukit/include/rtems/score/processormaskimpl.h new file mode 100644 index 0000000000..bc997edfd4 --- /dev/null +++ b/cpukit/include/rtems/score/processormaskimpl.h @@ -0,0 +1,437 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ + +/** + * @file + * + * @ingroup RTEMSScoreProcessorMask + * + * @brief This header file provides the interfaces of the + * @ref RTEMSScoreProcessorMask. + */ + +/* + * Copyright (C) 2016, 2017 embedded brains GmbH & Co. KG + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _RTEMS_SCORE_PROCESSORMASKIMPL_H +#define _RTEMS_SCORE_PROCESSORMASKIMPL_H + +#include <rtems/score/processormask.h> + +#include <sys/cpuset.h> + +#include <strings.h> + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/** + * @addtogroup RTEMSScoreProcessorMask + * + * @{ + */ + +/** + * @brief Sets the bits of the mask to zero, also considers CPU_MAXIMUM_PROCESSORS. + * + * @param[out] mask The mask to set to zero. + */ +static inline void _Processor_mask_Zero( Processor_mask *mask ) +{ + __BIT_ZERO( CPU_MAXIMUM_PROCESSORS, mask ); +} + +/** + * @brief Checks if the mask is zero, also considers CPU_MAXIMUM_PROCESSORS. + * + * @param mask The mask to check whether is is zero + * + * @retval true The mask is zero. + * @retval false The mask is not zero. + */ +static inline bool _Processor_mask_Is_zero( const Processor_mask *mask ) +{ + return __BIT_EMPTY( CPU_MAXIMUM_PROCESSORS, mask ); +} + +/** + * @brief Fills the mask, also considers CPU_MAXIMUM_PROCESSORS. + * + * @param[out] mask The mask to fill + */ +static inline void _Processor_mask_Fill( Processor_mask *mask ) +{ + __BIT_FILL( CPU_MAXIMUM_PROCESSORS, mask ); +} + +/** + * @brief Copies the mask to another mask, also considers CPU_MAXIMUM_PROCESSORS. + * + * @param[out] dst The mask to copy @a src to. + * @param src The mask to copy to @a dst. + */ +static inline void _Processor_mask_Assign( + Processor_mask *dst, const Processor_mask *src +) +{ + __BIT_COPY( CPU_MAXIMUM_PROCESSORS, src, dst ); +} + +/** + * @brief Sets the specified index bit of the mask. + * + * @param[out] mask The mask to set the bit of. + * @param index The index of the bit that shall be set. + */ +static inline void _Processor_mask_Set( + Processor_mask *mask, + uint32_t index +) +{ + __BIT_SET( CPU_MAXIMUM_PROCESSORS, index, mask ); +} + +/** + * @brief Clears the specified index bit of the mask. + * + * @param[out] mask The mask to clear the bit of. + * @param index The index of the bit that shall be cleared. + */ +static inline void _Processor_mask_Clear( + Processor_mask *mask, + uint32_t index +) +{ + __BIT_CLR( CPU_MAXIMUM_PROCESSORS, index, mask ); +} + +/** + * @brief Checks if the specified index bit of the mask is set. + * + * @param mask The mask to check if the specified bit is set. + * @param index The index of the bit that is checked. + * + * @retval true The specified index bit is set. + * @retval false The specified index bit is not set. + */ +static inline bool _Processor_mask_Is_set( + const Processor_mask *mask, + uint32_t index +) +{ + return __BIT_ISSET( CPU_MAXIMUM_PROCESSORS, index, mask ); +} + +/** + * @brief Checks if the processor sets a and b are equal. + * + * @param a The first processor set. + * @param b The seconde processor set. + * + * @retval true The processor sets a and b are equal. + * @retval false The processor sets a and b are not equal. + */ +static inline bool _Processor_mask_Is_equal( + const Processor_mask *a, + const Processor_mask *b +) +{ + return !__BIT_CMP( CPU_MAXIMUM_PROCESSORS, a, b ); +} + +/** + * @brief Checks if the intersection of the processor sets a and b is + * non-empty. + * + * @param a The first processor set. + * @param b The second processor set. + * + * @retval true The intersection of the processor sets a and b is non-empty. + * @retval false The intersection of the processor sets a and b is empty. + */ +static inline bool _Processor_mask_Has_overlap( + const Processor_mask *a, + const Processor_mask *b +) +{ + return __BIT_OVERLAP( CPU_MAXIMUM_PROCESSORS, a, b ); +} + +/** + * @brief Checks if the processor set small is a subset of processor set + * big. + * + * @param big The bigger processor set. + * @param small The smaller processor set. + * + * @retval true @a small is a subset of @a big. + * @retval false @a small is not a subset of @a big. + */ +static inline bool _Processor_mask_Is_subset( + const Processor_mask *big, + const Processor_mask *small +) +{ + return __BIT_SUBSET( CPU_MAXIMUM_PROCESSORS, big, small ); +} + +/** + * @brief Performs a bitwise a = b & c. + * + * @param[out] a The processor mask that is set by this operation. + * @param b The first parameter of the AND-operation. + * @param c The second parameter of the AND-operation. + */ +static inline void _Processor_mask_And( + Processor_mask *a, + const Processor_mask *b, + const Processor_mask *c +) +{ + __BIT_AND2( CPU_MAXIMUM_PROCESSORS, a, b, c ); +} + +/** + * @brief Performs a bitwise a = b | c. + * + * @param[out] a The processor mask that is set by this operation. + * @param b The first parameter of the OR-operation. + * @param c The second parameter of the OR-operation. + */ +static inline void _Processor_mask_Or( + Processor_mask *a, + const Processor_mask *b, + const Processor_mask *c +) +{ + __BIT_OR2( CPU_MAXIMUM_PROCESSORS, a, b, c ); +} + +/** + * @brief Performs a bitwise a = b ^ c. + * + * @param[out] a The processor mask that is set by this operation. + * @param b The first parameter of the XOR-operation. + * @param c The second parameter of the XOR-operation. + */ +static inline void _Processor_mask_Xor( + Processor_mask *a, + const Processor_mask *b, + const Processor_mask *c +) +{ + __BIT_XOR2( CPU_MAXIMUM_PROCESSORS, a, b, c ); +} + +/** + * @brief Gets the number of set bits in the processor mask. + * + * @param a The processor mask of which the set bits are counted. + * + * @return The number of set bits in @a a. + */ +static inline uint32_t _Processor_mask_Count( const Processor_mask *a ) +{ + return (uint32_t) __BIT_COUNT( CPU_MAXIMUM_PROCESSORS, a ); +} + +/** + * @brief Finds the last set of the processor mask. + * + * @param a The processor mask wo find the last set of. + * + * @return The last set of @a a. + */ +static inline uint32_t _Processor_mask_Find_last_set( const Processor_mask *a ) +{ + return (uint32_t) __BIT_FLS( CPU_MAXIMUM_PROCESSORS, a ); +} + +/** + * @brief Returns the subset of 32 processors containing the specified index as + * an unsigned 32-bit integer. + * + * @param mask The processor mask. + * @param index The specified index. + * + * @return The subset containing the specified index as an unsigned 32-bit integer. + */ +static inline uint32_t _Processor_mask_To_uint32_t( + const Processor_mask *mask, + uint32_t index +) +{ + long bits = mask->__bits[ index / _BITSET_BITS ]; + + return (uint32_t) ( bits >> ( 32 * ( ( index % _BITSET_BITS ) / 32 ) ) ); +} + +/** + * @brief Creates a processor set from an unsigned 32-bit integer relative to + * the specified index. + * + * @param[out] mask The mask that is created. + * @param bits The bits for creating the mask. + * @param index The index to which the mask is relative. + */ +static inline void _Processor_mask_From_uint32_t( + Processor_mask *mask, + uint32_t bits, + uint32_t index +) +{ + _Processor_mask_Zero( mask ); + mask->__bits[ __bitset_words( index ) ] = ((long) bits) << (32 * (index % _BITSET_BITS) / 32); +} + +/** + * @brief Creates a processor set from the specified index. + * + * @param[out] The mask that is created. + * @param index The specified index. + */ +static inline void _Processor_mask_From_index( + Processor_mask *mask, + uint32_t index +) +{ + __BIT_SETOF( CPU_MAXIMUM_PROCESSORS, (int) index, mask ); +} + +typedef enum { + PROCESSOR_MASK_COPY_LOSSLESS, + PROCESSOR_MASK_COPY_PARTIAL_LOSS, + PROCESSOR_MASK_COPY_COMPLETE_LOSS, + PROCESSOR_MASK_COPY_INVALID_SIZE +} Processor_mask_Copy_status; + +/** + * @brief Checks if the copy status guarantees at most partial loss. + * + * @param status The copy status to check. + * + * @retval true At most partial loss can be guaranteed. + * @retval false The status indicates more than partial loss. + */ +static inline bool _Processor_mask_Is_at_most_partial_loss( + Processor_mask_Copy_status status +) +{ + return (unsigned int) status <= PROCESSOR_MASK_COPY_PARTIAL_LOSS; +} + +/** + * @brief Copies one mask to another. + * + * @param[out] dst The destination of the copy operation. + * @param dst_size The size of @a dst. + * @param src The source of the copy operation. + * @param src_size The size of @a src. + * + * @retval PROCESSOR_MASK_COPY_LOSSLESS It is guaranteed that the copy + * operation is lossless. + * @retval PROCESSOR_MASK_COPY_PARTIAL_LOSS Partial loss happened due + * to the sizes of @a src and @a dst. + * @retval PROCESSOR_MASK_COPY_COMPLETE_LOSS Complete loss happened due + * to the sizes of @a src and @a dst. + * @retval PROCESSOR_MASK_COPY_INVALID_SIZE One of the arguments sizes + * is invalid (bigger than the size of a long). + */ +Processor_mask_Copy_status _Processor_mask_Copy( + long *dst, + size_t dst_size, + const long *src, + size_t src_size +); + +/** + * @brief Copies one mask to another. + * + * @param src The source for the copy operation. + * @param dst_size The size of @a dst. + * @param[out] dst The destination for the copy operation. + * + * @retval PROCESSOR_MASK_COPY_LOSSLESS It is guaranteed that the copy + * operation is lossless. + * @retval PROCESSOR_MASK_COPY_PARTIAL_LOSS Partial loss happened due + * to the sizes of @a src and @a dst. + * @retval PROCESSOR_MASK_COPY_COMPLETE_LOSS Complete loss happened due + * to the sizes of @a src and @a dst. + * @retval PROCESSOR_MASK_COPY_INVALID_SIZE One of the arguments sizes + * is invalid (bigger than the size of a long). + */ +static inline Processor_mask_Copy_status _Processor_mask_To_cpu_set_t( + const Processor_mask *src, + size_t dst_size, + cpu_set_t *dst +) +{ + return _Processor_mask_Copy( + &dst->__bits[ 0 ], + dst_size, + &src->__bits[ 0 ], + sizeof( *src ) + ); +} + +/** + * @brief Copies one mask to another. + * + * @param src The source for the copy operation. + * @param src_size The size of @a src. + * @param[out] dst The destination for the copy operation. + * + * @retval PROCESSOR_MASK_COPY_LOSSLESS It is guaranteed that the copy + * operation is lossless. + * @retval PROCESSOR_MASK_COPY_PARTIAL_LOSS Partial loss happened due + * to the sizes of @a src and @a dst. + * @retval PROCESSOR_MASK_COPY_COMPLETE_LOSS Complete loss happened due + * to the sizes of @a src and @a dst. + * @retval PROCESSOR_MASK_COPY_INVALID_SIZE One of the arguments sizes + * is invalid (bigger than the size of a long). + */ +static inline Processor_mask_Copy_status _Processor_mask_From_cpu_set_t( + Processor_mask *dst, + size_t src_size, + const cpu_set_t *src +) +{ + return _Processor_mask_Copy( + &dst->__bits[ 0 ], + sizeof( *dst ), + &src->__bits[ 0 ], + src_size + ); +} + +extern const Processor_mask _Processor_mask_The_one_and_only; + +/** @} */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* _RTEMS_SCORE_PROCESSORMASKIMPL_H */ diff --git a/cpukit/include/rtems/score/smpimpl.h b/cpukit/include/rtems/score/smpimpl.h index 2ffc047070..a8e3a3be15 100644 --- a/cpukit/include/rtems/score/smpimpl.h +++ b/cpukit/include/rtems/score/smpimpl.h @@ -40,7 +40,7 @@ #include <rtems/score/smp.h> #include <rtems/score/percpu.h> -#include <rtems/score/processormask.h> +#include <rtems/score/processormaskimpl.h> #include <rtems/fatal.h> #ifdef __cplusplus diff --git a/cpukit/include/rtems/score/thread.h b/cpukit/include/rtems/score/thread.h index 9a9d2e038f..8ca7d85205 100644 --- a/cpukit/include/rtems/score/thread.h +++ b/cpukit/include/rtems/score/thread.h @@ -719,50 +719,50 @@ typedef struct { * The individual state flags must be a power of two to allow use of bit * operations to manipulate and evaluate the thread life state. */ -typedef enum { - /** - * @brief Indicates that the thread life is protected. - * - * If this flag is set, then the thread restart or delete requests are deferred - * until the protection and deferred change flags are cleared. It is used by - * _Thread_Set_life_protection(). - */ - THREAD_LIFE_PROTECTED = 0x1, +typedef unsigned int Thread_Life_state; - /** - * @brief Indicates that thread is restarting. - * - * If this flag is set, then a thread restart request is in pending. See - * _Thread_Restart_self() and _Thread_Restart_other(). - */ - THREAD_LIFE_RESTARTING = 0x2, +/** + * @brief Indicates that the thread life is protected. + * + * If this flag is set, then the thread restart or delete requests are deferred + * until the protection and deferred change flags are cleared. It is used by + * _Thread_Set_life_protection(). + */ +#define THREAD_LIFE_PROTECTED 0x1U - /** - * @brief Indicates that thread is terminating. - * - * If this flag is set, then a thread termination request is in pending. See - * _Thread_Exit() and _Thread_Cancel(). - */ - THREAD_LIFE_TERMINATING = 0x4, +/** + * @brief Indicates that thread is restarting. + * + * If this flag is set, then a thread restart request is in pending. See + * _Thread_Restart_self() and _Thread_Restart_other(). + */ +#define THREAD_LIFE_RESTARTING 0x2U - /** - * @brief Indicates that thread life changes are deferred. - * - * If this flag is set, then the thread restart or delete requests are deferred - * until the protection and deferred change flags are cleared. It is used by - * pthread_setcanceltype(). - */ - THREAD_LIFE_CHANGE_DEFERRED = 0x8, +/** + * @brief Indicates that thread is terminating. + * + * If this flag is set, then a thread termination request is in pending. See + * _Thread_Exit() and _Thread_Cancel(). + */ +#define THREAD_LIFE_TERMINATING 0x4U - /** - * @brief Indicates that thread is detached. - * - * If this flag is set, then the thread is detached. Detached threads do not - * wait during termination for other threads to join. See rtems_task_delete(), - * rtems_task_exit(), and pthread_detach(). - */ - THREAD_LIFE_DETACHED = 0x10 -} Thread_Life_state; +/** + * @brief Indicates that thread life changes are deferred. + * + * If this flag is set, then the thread restart or delete requests are deferred + * until the protection and deferred change flags are cleared. It is used by + * pthread_setcanceltype(). + */ +#define THREAD_LIFE_CHANGE_DEFERRED 0x8U + +/** + * @brief Indicates that thread is detached. + * + * If this flag is set, then the thread is detached. Detached threads do not + * wait during termination for other threads to join. See rtems_task_delete(), + * rtems_task_exit(), and pthread_detach(). + */ +#define THREAD_LIFE_DETACHED 0x10U /** * @brief Thread life control. diff --git a/cpukit/include/rtems/score/threadimpl.h b/cpukit/include/rtems/score/threadimpl.h index a82f412887..36ddb785e9 100644 --- a/cpukit/include/rtems/score/threadimpl.h +++ b/cpukit/include/rtems/score/threadimpl.h @@ -1598,12 +1598,12 @@ static inline Scheduler_Node *_Thread_Scheduler_get_node_by_index( size_t scheduler_index ) { + _Assert( scheduler_index < _Scheduler_Count ); #if defined(RTEMS_SMP) return (Scheduler_Node *) ( (uintptr_t) the_thread->Scheduler.nodes + scheduler_index * _Scheduler_Node_size ); #else - _Assert( scheduler_index == 0 ); (void) scheduler_index; return the_thread->Scheduler.nodes; #endif diff --git a/cpukit/include/rtems/score/tls.h b/cpukit/include/rtems/score/tls.h index fa3ee0afa2..8716c5230c 100644 --- a/cpukit/include/rtems/score/tls.h +++ b/cpukit/include/rtems/score/tls.h @@ -10,7 +10,7 @@ */ /* - * Copyright (C) 2014, 2022 embedded brains GmbH & Co. KG + * Copyright (C) 2014, 2023 embedded brains GmbH & Co. KG * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -59,31 +59,51 @@ extern "C" { * @{ */ -extern char _TLS_Data_begin[]; - -extern char _TLS_Data_end[]; +/** + * @brief Represents the TLS configuration. + */ +typedef struct { + /** + * @brief This member is initialized to _TLS_Data_begin. + */ + const char *data_begin; -extern char _TLS_Data_size[]; + /** + * @brief This member is initialized to _TLS_Data_size. + */ + const char *data_size; -extern char _TLS_BSS_begin[]; + /** + * @brief This member is initialized to _TLS_BSS_begin. + */ + const char *bss_begin; -extern char _TLS_BSS_end[]; + /** + * @brief This member is initialized to _TLS_BSS_size. + */ + const char *bss_size; -extern char _TLS_BSS_size[]; + /** + * @brief This member is initialized to _TLS_Size. + */ + const char *size; -extern char _TLS_Size[]; + /** + * @brief This member is initialized to _TLS_Alignment. + */ + const char *alignment; +} TLS_Configuration; /** - * @brief The TLS section alignment. + * @brief Provides the TLS configuration. * - * This symbol is provided by the linker command file as the maximum alignment - * of the .tdata and .tbss sections. The linker ensures that the first TLS - * output section is aligned to the maximum alignment of all TLS output - * sections, see function _bfd_elf_tls_setup() in bfd/elflink.c of the GNU - * Binutils sources. The linker command file must take into account the case - * that the .tdata section is empty and the .tbss section is non-empty. + * Directly using symbols with an arbitrary absolute address such as + * _TLS_Alignment may not work with all code models (for example the AArch64 + * tiny and small code models). Store the addresses in a read-only object. + * Using the volatile qualifier ensures that the compiler actually loads the + * address from the object. */ -extern char _TLS_Alignment[]; +extern const volatile TLS_Configuration _TLS_Configuration; typedef struct { /* @@ -116,38 +136,24 @@ typedef struct { } TLS_Index; /** - * @brief Gets the size of the thread-local storage data in bytes. - * - * @return Returns the size of the thread-local storage data in bytes. - */ -static inline uintptr_t _TLS_Get_size( void ) -{ - uintptr_t size; - - /* - * We must be careful with using _TLS_Size here since this could lead GCC to - * assume that this symbol is not 0 and the tests for 0 will be optimized - * away. - */ - size = (uintptr_t) _TLS_Size; - RTEMS_OBFUSCATE_VARIABLE( size ); - return size; -} - -/** * @brief Gets the size of the thread control block area in bytes. * + * @param config is the TLS configuration. + * * @return Returns the size of the thread control block area in bytes. */ -static inline uintptr_t _TLS_Get_thread_control_block_area_size( void ) +static inline uintptr_t _TLS_Get_thread_control_block_area_size( + const volatile TLS_Configuration *config +) { #if CPU_THREAD_LOCAL_STORAGE_VARIANT == 11 uintptr_t alignment; - alignment = (uintptr_t) _TLS_Alignment; + alignment = (uintptr_t) config->alignment; return RTEMS_ALIGN_UP( sizeof( TLS_Thread_control_block ), alignment ); #else + (void) config; return sizeof( TLS_Thread_control_block ); #endif } @@ -163,17 +169,23 @@ uintptr_t _TLS_Get_allocation_size( void ); /** * @brief Initializes the thread-local storage data. * + * @param config is the TLS configuration. + * * @param[out] tls_data is the thread-local storage data to initialize. */ -static inline void _TLS_Copy_and_clear( void *tls_data ) +static inline void _TLS_Copy_and_clear( + const volatile TLS_Configuration *config, + void *tls_data +) { - tls_data = memcpy( tls_data, _TLS_Data_begin, (uintptr_t) _TLS_Data_size ); + tls_data = + memcpy( tls_data, config->data_begin, (uintptr_t) config->data_size ); memset( (char *) tls_data + - (uintptr_t) _TLS_BSS_begin - (uintptr_t) _TLS_Data_begin, + (uintptr_t) config->bss_begin - (uintptr_t) config->data_begin, 0, - (uintptr_t) _TLS_BSS_size + (uintptr_t) config->bss_size ); } @@ -213,20 +225,22 @@ static inline void _TLS_Initialize_TCB_and_DTV( */ static inline void *_TLS_Initialize_area( void *tls_area ) { - uintptr_t alignment; - void *tls_data; - TLS_Thread_control_block *tcb; - TLS_Dynamic_thread_vector *dtv; - void *return_value; + const volatile TLS_Configuration *config; + uintptr_t alignment; + void *tls_data; + TLS_Thread_control_block *tcb; + TLS_Dynamic_thread_vector *dtv; + void *return_value; #if CPU_THREAD_LOCAL_STORAGE_VARIANT == 11 - uintptr_t tcb_size; + uintptr_t tcb_size; #endif #if CPU_THREAD_LOCAL_STORAGE_VARIANT == 20 - uintptr_t size; - uintptr_t alignment_2; + uintptr_t size; + uintptr_t alignment_2; #endif - alignment = (uintptr_t) _TLS_Alignment; + config = &_TLS_Configuration; + alignment = (uintptr_t) config->alignment; #ifdef __i386__ dtv = NULL; @@ -249,7 +263,7 @@ static inline void *_TLS_Initialize_area( void *tls_area ) #elif CPU_THREAD_LOCAL_STORAGE_VARIANT == 20 alignment_2 = RTEMS_ALIGN_UP( alignment, CPU_SIZEOF_POINTER ); tls_area = (void *) RTEMS_ALIGN_UP( (uintptr_t) tls_area, alignment_2 ); - size = _TLS_Get_size(); + size = (uintptr_t) config->size; tcb = (TLS_Thread_control_block *) ((char *) tls_area + RTEMS_ALIGN_UP( size, alignment_2 )); tls_data = (char *) tcb - RTEMS_ALIGN_UP( size, alignment ); @@ -259,7 +273,7 @@ static inline void *_TLS_Initialize_area( void *tls_area ) #endif _TLS_Initialize_TCB_and_DTV( tls_data, tcb, dtv ); - _TLS_Copy_and_clear( tls_data ); + _TLS_Copy_and_clear( config, tls_data ); return return_value; } diff --git a/cpukit/include/rtems/sysinit.h b/cpukit/include/rtems/sysinit.h index b973ecfc91..3e6f4d9933 100644 --- a/cpukit/include/rtems/sysinit.h +++ b/cpukit/include/rtems/sysinit.h @@ -1,7 +1,15 @@ /* SPDX-License-Identifier: BSD-2-Clause */ +/** + * @file + * + * @ingroup RTEMSAPISystemInit + * + * @brief This header file provides the API of the @ref RTEMSAPISystemInit. + */ + /* - * Copyright (C) 2015, 2020 embedded brains GmbH & Co. KG + * Copyright (C) 2015, 2023 embedded brains GmbH & Co. KG * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -34,6 +42,54 @@ extern "C" { #endif /* __cplusplus */ +/** + * @ingroup RTEMSImpl + * + * @brief Enables a verbose system initialization. + */ +void _Sysinit_Verbose( void ); + +/** + * @ingroup RTEMSImpl + * + * @brief Creates the system initialization item associated with the handler + * and index. + * + * The enum helps to detect typos in the module and order parameters of + * RTEMS_SYSINIT_ITEM(). + */ +#define _RTEMS_SYSINIT_INDEX_ITEM( handler, index ) \ + enum { _Sysinit_##handler = index }; \ + RTEMS_LINKER_ROSET_ITEM_ORDERED( \ + _Sysinit, \ + rtems_sysinit_item, \ + handler, \ + index \ + ) = { handler } + +/** + * @ingroup RTEMSImpl + * + * @brief Creates the system initialization item associated with the handler, + * module, and order. + * + * This helper macro is used to perform parameter expansion in + * RTEMS_SYSINIT_ITEM(). + */ +#define _RTEMS_SYSINIT_ITEM( handler, module, order ) \ + _RTEMS_SYSINIT_INDEX_ITEM( handler, 0x##module##order ) + +/** + * @defgroup RTEMSAPISystemInit System Initialization Support + * + * @ingroup RTEMSAPI + * + * @brief The system initialization support provides an ordered invocation of + * system initialization handlers registered in a linker set. + * + * @{ + */ + /* * The value of each module define must consist of exactly six hexadecimal * digits without a 0x-prefix. A 0x-prefix is concatenated with the module and @@ -133,29 +189,22 @@ typedef struct { rtems_sysinit_handler handler; } rtems_sysinit_item; -/* The enum helps to detect typos in the module and order parameters */ -#define _RTEMS_SYSINIT_INDEX_ITEM( handler, index ) \ - enum { _Sysinit_##handler = index }; \ - RTEMS_LINKER_ROSET_ITEM_ORDERED( \ - _Sysinit, \ - rtems_sysinit_item, \ - handler, \ - index \ - ) = { handler } - -/* Create index from module and order */ -#define _RTEMS_SYSINIT_ITEM( handler, module, order ) \ - _RTEMS_SYSINIT_INDEX_ITEM( handler, 0x##module##order ) - -/* Perform parameter expansion */ +/** + * @brief Creates the system initialization item associated with the handler, + * module, and order. + * + * @param handler is the system initialization handler. + * + * @param module is the system initialization module. It shall be a 6-digit + * hex number without a 0x-prefix. + * + * @param order is the system initialization order with respect to the module. + * It shall be a 2-digit hex number without a 0x-prefix. + */ #define RTEMS_SYSINIT_ITEM( handler, module, order ) \ _RTEMS_SYSINIT_ITEM( handler, module, order ) -/** - * @brief System initialization handler to enable a verbose system - * initialization. - */ -void _Sysinit_Verbose( void ); +/** @} */ #ifdef __cplusplus } diff --git a/cpukit/include/rtems/termiosdevice.h b/cpukit/include/rtems/termiosdevice.h new file mode 100644 index 0000000000..17d05e61f6 --- /dev/null +++ b/cpukit/include/rtems/termiosdevice.h @@ -0,0 +1,300 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ + +/** + * @file + * + * @ingroup TermiostypesSupport + * + * @brief This header file provides the interfaces of the + * @ref TermiostypesSupport. + */ + +/* + * Copyright (C) 2014, 2017 embedded brains GmbH & Co. KG + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _RTEMS_TERMIOSDEVICE_H +#define _RTEMS_TERMIOSDEVICE_H + +#include <rtems/thread.h> +#include <rtems/rtems/intr.h> + +#include <sys/ioccom.h> + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +struct rtems_libio_open_close_args; +struct rtems_termios_tty; +struct termios; + +/** + * @defgroup TermiostypesSupport RTEMS Termios Device Support + * + * @ingroup libcsupport + * + * @brief This group contains the Termios Device Support provided by RTEMS. + */ + +/** + * @brief Termios device context. + * + * @see RTEMS_TERMIOS_DEVICE_CONTEXT_INITIALIZER(), + * rtems_termios_device_context_initialize() and + * rtems_termios_device_install(). + */ +typedef struct rtems_termios_device_context { + union { + /* Used for TERMIOS_POLLED and TERMIOS_IRQ_DRIVEN */ + rtems_interrupt_lock interrupt; + + /* Used for TERMIOS_IRQ_SERVER_DRIVEN and TERMIOS_TASK_DRIVEN */ + rtems_mutex mutex; + } lock; + + void ( *lock_acquire )( + struct rtems_termios_device_context *, + rtems_interrupt_lock_context * + ); + + void ( *lock_release )( + struct rtems_termios_device_context *, + rtems_interrupt_lock_context * + ); +} rtems_termios_device_context; + +typedef enum { + TERMIOS_POLLED, + TERMIOS_IRQ_DRIVEN, + TERMIOS_TASK_DRIVEN, + TERMIOS_IRQ_SERVER_DRIVEN +} rtems_termios_device_mode; + +/** + * @brief Termios device handler. + * + * @see rtems_termios_device_install(). + */ +typedef struct { + /** + * @brief First open of this device. + * + * @param[in] tty The Termios control. This parameter may be passed to + * interrupt service routines since it must be provided for the + * rtems_termios_enqueue_raw_characters() and + * rtems_termios_dequeue_characters() functions. + * @param[in] context The Termios device context. + * @param[in] term The current Termios attributes. + * @param[in] args The open/close arguments. This is parameter provided to + * support legacy drivers. It must not be used by new drivers. + * + * @retval true Successful operation. + * @retval false Cannot open device. + * + * @see rtems_termios_get_device_context() and rtems_termios_set_best_baud(). + */ + bool (*first_open)( + struct rtems_termios_tty *tty, + rtems_termios_device_context *context, + struct termios *term, + struct rtems_libio_open_close_args *args + ); + + /** + * @brief Last close of this device. + * + * @param[in] tty The Termios control. + * @param[in] context The Termios device context. + * @param[in] args The open/close arguments. This is parameter provided to + * support legacy drivers. It must not be used by new drivers. + */ + void (*last_close)( + struct rtems_termios_tty *tty, + rtems_termios_device_context *context, + struct rtems_libio_open_close_args *args + ); + + /** + * @brief Polled read. + * + * In case mode is TERMIOS_IRQ_DRIVEN, TERMIOS_IRQ_SERVER_DRIVEN or + * TERMIOS_TASK_DRIVEN, then data is received via + * rtems_termios_enqueue_raw_characters(). + * + * @param[in] context The Termios device context. + * + * @retval char The received data encoded as unsigned char. + * @retval -1 No data currently available. + */ + int (*poll_read)(rtems_termios_device_context *context); + + /** + * @brief Polled write in case mode is TERMIOS_POLLED or write support + * otherwise. + * + * @param[in] context The Termios device context. + * @param[in] buf The output buffer. + * @param[in] len The output buffer length in characters. + */ + void (*write)( + rtems_termios_device_context *context, + const char *buf, + size_t len + ); + + /** + * @brief Set attributes after a Termios settings change. + * + * @param[in] context The Termios device context. + * @param[in] term The new Termios attributes. + * + * @retval true Successful operation. + * @retval false Invalid attributes. + */ + bool (*set_attributes)( + rtems_termios_device_context *context, + const struct termios *term + ); + + /** + * @brief IO control handler. + * + * Invoked in case the Termios layer cannot deal with the IO request. + * + * @param[in] context The Termios device context. + * @param[in] request The IO control request. + * @param[in] buffer The IO control buffer. + */ + int (*ioctl)( + rtems_termios_device_context *context, + ioctl_command_t request, + void *buffer + ); + + /** + * @brief Termios device mode. + */ + rtems_termios_device_mode mode; +} rtems_termios_device_handler; + +/** + * @brief Termios device flow control handler. + * + * @see rtems_termios_device_install(). + */ +typedef struct { + /** + * @brief Indicate to stop remote transmitter. + * + * @param[in] context The Termios device context. + */ + void (*stop_remote_tx)(rtems_termios_device_context *context); + + /** + * @brief Indicate to start remote transmitter. + * + * @param[in] context The Termios device context. + */ + void (*start_remote_tx)(rtems_termios_device_context *context); +} rtems_termios_device_flow; + +void rtems_termios_device_lock_acquire_default( + rtems_termios_device_context *ctx, + rtems_interrupt_lock_context *lock_context +); + +void rtems_termios_device_lock_release_default( + rtems_termios_device_context *ctx, + rtems_interrupt_lock_context *lock_context +); + +/** + * @brief Initializes a device context. + * + * @param[in] context The Termios device context. + * @param[in] name The name for the interrupt lock. This name must be a + * string persistent throughout the life time of this lock. The name is only + * used if profiling is enabled. + */ +static inline void rtems_termios_device_context_initialize( + rtems_termios_device_context *context, + const char *name +) +{ + rtems_interrupt_lock_initialize( &context->lock.interrupt, name ); + context->lock_acquire = rtems_termios_device_lock_acquire_default; + context->lock_release = rtems_termios_device_lock_release_default; +} + +/** + * @brief Initializer for static initialization of Termios device contexts. + * + * @param name The name for the interrupt lock. It must be a string. The name + * is only used if profiling is enabled. + */ +#define RTEMS_TERMIOS_DEVICE_CONTEXT_INITIALIZER( name ) \ + { \ + { RTEMS_INTERRUPT_LOCK_INITIALIZER( name ) }, \ + rtems_termios_device_lock_acquire_default, \ + rtems_termios_device_lock_release_default \ + } + +/** + * @brief Acquires the device lock. + * + * @param[in] context The device context. + * @param[in] lock_context The local interrupt lock context for an acquire and + * release pair. + */ +static inline void rtems_termios_device_lock_acquire( + rtems_termios_device_context *context, + rtems_interrupt_lock_context *lock_context +) +{ + ( *context->lock_acquire )( context, lock_context ); +} + +/** + * @brief Releases the device lock. + * + * @param[in] context The device context. + * @param[in] lock_context The local interrupt lock context for an acquire and + * release pair. + */ +static inline void rtems_termios_device_lock_release( + rtems_termios_device_context *context, + rtems_interrupt_lock_context *lock_context +) +{ + ( *context->lock_release )( context, lock_context ); +} + +/** @} */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* _RTEMS_TERMIOSDEVICE_H */ diff --git a/cpukit/include/rtems/termiostypes.h b/cpukit/include/rtems/termiostypes.h index 67f3461b1f..5cf418a5eb 100644 --- a/cpukit/include/rtems/termiostypes.h +++ b/cpukit/include/rtems/termiostypes.h @@ -39,8 +39,7 @@ #include <rtems/libio.h> #include <rtems/assoc.h> #include <rtems/chain.h> -#include <rtems/thread.h> -#include <sys/ioccom.h> +#include <rtems/termiosdevice.h> #include <stdint.h> #include <termios.h> @@ -49,11 +48,9 @@ extern "C" { #endif /** - * @defgroup TermiostypesSupport RTEMS Termios Device Support + * @addtogroup TermiostypesSupport * - * @ingroup libcsupport - * - * @brief RTEMS Termios Device Support Internal Data Structures + * @{ */ /* @@ -75,211 +72,6 @@ struct rtems_termios_rawbuf { rtems_binary_semaphore Semaphore; }; -typedef enum { - TERMIOS_POLLED, - TERMIOS_IRQ_DRIVEN, - TERMIOS_TASK_DRIVEN, - TERMIOS_IRQ_SERVER_DRIVEN -} rtems_termios_device_mode; - -struct rtems_termios_tty; - -/** - * @brief Termios device context. - * - * @see RTEMS_TERMIOS_DEVICE_CONTEXT_INITIALIZER(), - * rtems_termios_device_context_initialize() and - * rtems_termios_device_install(). - */ -typedef struct rtems_termios_device_context { - union { - /* Used for TERMIOS_POLLED and TERMIOS_IRQ_DRIVEN */ - rtems_interrupt_lock interrupt; - - /* Used for TERMIOS_IRQ_SERVER_DRIVEN or TERMIOS_TASK_DRIVEN */ - rtems_mutex mutex; - } lock; - - void ( *lock_acquire )( - struct rtems_termios_device_context *, - rtems_interrupt_lock_context * - ); - - void ( *lock_release )( - struct rtems_termios_device_context *, - rtems_interrupt_lock_context * - ); -} rtems_termios_device_context; - -void rtems_termios_device_lock_acquire_default( - rtems_termios_device_context *ctx, - rtems_interrupt_lock_context *lock_context -); - -void rtems_termios_device_lock_release_default( - rtems_termios_device_context *ctx, - rtems_interrupt_lock_context *lock_context -); - -/** - * @brief Initializes a device context. - * - * @param[in] context The Termios device context. - * @param[in] name The name for the interrupt lock. This name must be a - * string persistent throughout the life time of this lock. The name is only - * used if profiling is enabled. - */ -static inline void rtems_termios_device_context_initialize( - rtems_termios_device_context *context, - const char *name -) -{ - rtems_interrupt_lock_initialize( &context->lock.interrupt, name ); - context->lock_acquire = rtems_termios_device_lock_acquire_default; - context->lock_release = rtems_termios_device_lock_release_default; -} - -/** - * @brief Initializer for static initialization of Termios device contexts. - * - * @param name The name for the interrupt lock. It must be a string. The name - * is only used if profiling is enabled. - */ -#define RTEMS_TERMIOS_DEVICE_CONTEXT_INITIALIZER( name ) \ - { \ - { RTEMS_INTERRUPT_LOCK_INITIALIZER( name ) }, \ - rtems_termios_device_lock_acquire_default, \ - rtems_termios_device_lock_release_default \ - } - -/** - * @brief Termios device handler. - * - * @see rtems_termios_device_install(). - */ -typedef struct { - /** - * @brief First open of this device. - * - * @param[in] tty The Termios control. This parameter may be passed to - * interrupt service routines since it must be provided for the - * rtems_termios_enqueue_raw_characters() and - * rtems_termios_dequeue_characters() functions. - * @param[in] context The Termios device context. - * @param[in] term The current Termios attributes. - * @param[in] args The open/close arguments. This is parameter provided to - * support legacy drivers. It must not be used by new drivers. - * - * @retval true Successful operation. - * @retval false Cannot open device. - * - * @see rtems_termios_get_device_context() and rtems_termios_set_best_baud(). - */ - bool (*first_open)( - struct rtems_termios_tty *tty, - rtems_termios_device_context *context, - struct termios *term, - rtems_libio_open_close_args_t *args - ); - - /** - * @brief Last close of this device. - * - * @param[in] tty The Termios control. - * @param[in] context The Termios device context. - * @param[in] args The open/close arguments. This is parameter provided to - * support legacy drivers. It must not be used by new drivers. - */ - void (*last_close)( - struct rtems_termios_tty *tty, - rtems_termios_device_context *context, - rtems_libio_open_close_args_t *args - ); - - /** - * @brief Polled read. - * - * In case mode is TERMIOS_IRQ_DRIVEN, TERMIOS_IRQ_SERVER_DRIVEN or - * TERMIOS_TASK_DRIVEN, then data is received via - * rtems_termios_enqueue_raw_characters(). - * - * @param[in] context The Termios device context. - * - * @retval char The received data encoded as unsigned char. - * @retval -1 No data currently available. - */ - int (*poll_read)(rtems_termios_device_context *context); - - /** - * @brief Polled write in case mode is TERMIOS_POLLED or write support - * otherwise. - * - * @param[in] context The Termios device context. - * @param[in] buf The output buffer. - * @param[in] len The output buffer length in characters. - */ - void (*write)( - rtems_termios_device_context *context, - const char *buf, - size_t len - ); - - /** - * @brief Set attributes after a Termios settings change. - * - * @param[in] context The Termios device context. - * @param[in] term The new Termios attributes. - * - * @retval true Successful operation. - * @retval false Invalid attributes. - */ - bool (*set_attributes)( - rtems_termios_device_context *context, - const struct termios *term - ); - - /** - * @brief IO control handler. - * - * Invoked in case the Termios layer cannot deal with the IO request. - * - * @param[in] context The Termios device context. - * @param[in] request The IO control request. - * @param[in] buffer The IO control buffer. - */ - int (*ioctl)( - rtems_termios_device_context *context, - ioctl_command_t request, - void *buffer - ); - - /** - * @brief Termios device mode. - */ - rtems_termios_device_mode mode; -} rtems_termios_device_handler; - -/** - * @brief Termios device flow control handler. - * - * @see rtems_termios_device_install(). - */ -typedef struct { - /** - * @brief Indicate to stop remote transmitter. - * - * @param[in] context The Termios device context. - */ - void (*stop_remote_tx)(rtems_termios_device_context *context); - - /** - * @brief Indicate to start remote transmitter. - * - * @param[in] context The Termios device context. - */ - void (*start_remote_tx)(rtems_termios_device_context *context); -} rtems_termios_device_flow; - /** * @brief Termios device node for installed devices. * @@ -456,36 +248,6 @@ static inline void *rtems_termios_get_device_context( } /** - * @brief Acquires the device lock. - * - * @param[in] context The device context. - * @param[in] lock_context The local interrupt lock context for an acquire and - * release pair. - */ -static inline void rtems_termios_device_lock_acquire( - rtems_termios_device_context *context, - rtems_interrupt_lock_context *lock_context -) -{ - ( *context->lock_acquire )( context, lock_context ); -} - -/** - * @brief Releases the device lock. - * - * @param[in] context The device context. - * @param[in] lock_context The local interrupt lock context for an acquire and - * release pair. - */ -static inline void rtems_termios_device_lock_release( - rtems_termios_device_context *context, - rtems_interrupt_lock_context *lock_context -) -{ - ( *context->lock_release )( context, lock_context ); -} - -/** * @brief Sets the best baud value in the Termios control. * * The valid Termios baud values are between 0 and 460800. The Termios baud diff --git a/cpukit/include/rtems/score/gcov.h b/cpukit/include/rtems/test-gcov.h index 35e0480f6b..3664e91c64 100644 --- a/cpukit/include/rtems/score/gcov.h +++ b/cpukit/include/rtems/test-gcov.h @@ -3,10 +3,9 @@ /** * @file * - * @ingroup RTEMSScoreGcov + * @ingroup RTEMSImplGcov * - * @brief This header file provides the interfaces of the - * @ref RTEMSScoreGcov. + * @brief This header file provides the interfaces of the @ref RTEMSImplGcov. */ /* @@ -34,22 +33,22 @@ * POSSIBILITY OF SUCH DAMAGE. */ -#ifndef _RTEMS_SCORE_GCOV_H -#define _RTEMS_SCORE_GCOV_H +#ifndef _RTEMS_TEST_GCOV_H +#define _RTEMS_TEST_GCOV_H #include <gcov.h> #include <rtems/linkersets.h> -#include <rtems/score/io.h> +#include <rtems/dev/io.h> #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ /** - * @defgroup RTEMSScoreGcov Gcov Support + * @defgroup RTEMSImplGcov Gcov Support * - * @ingroup RTEMSScore + * @ingroup RTEMSTestFrameworkImpl * * @brief This group contains the gocv support. * @@ -84,4 +83,4 @@ void _Gcov_Dump_info_base64( IO_Put_char put_char, void *arg ); } #endif /* __cplusplus */ -#endif /* _RTEMS_SCORE_GCOV_H */ +#endif /* _RTEMS_TEST_GCOV_H */ diff --git a/cpukit/include/rtems/test-info.h b/cpukit/include/rtems/test-info.h index 055ed4f25b..a5c00c423a 100644 --- a/cpukit/include/rtems/test-info.h +++ b/cpukit/include/rtems/test-info.h @@ -1,5 +1,13 @@ /* SPDX-License-Identifier: BSD-2-Clause */ +/** + * @file + * + * @ingroup RTEMSTest + * + * @brief This header file provides interfaces of the RTEMS Test Support. + */ + /* * Copyright (C) 2014, 2018 embedded brains GmbH & Co. KG * @@ -29,7 +37,6 @@ #define _RTEMS_TEST_H #include <rtems.h> -#include <rtems/printer.h> #include <rtems/score/atomic.h> #include <rtems/score/smpbarrier.h> @@ -53,11 +60,6 @@ extern "C" { extern const char rtems_test_name[]; /** - * @brief Each test must define a printer. - */ -extern rtems_printer rtems_test_printer; - -/** * @brief Fatal extension for tests. */ void rtems_test_fatal_extension( @@ -125,13 +127,6 @@ int rtems_test_end(const char* name); */ RTEMS_NO_RETURN void rtems_test_exit(int status); -/** - * @brief Prints via the RTEMS printer. - * - * @return As specified by printf(). - */ -int rtems_test_printf(const char* format, ...) RTEMS_PRINTFLIKE(1, 2); - #define RTEMS_TEST_PARALLEL_PROCESSOR_MAX 32 typedef struct rtems_test_parallel_job rtems_test_parallel_job; diff --git a/cpukit/include/rtems/test-printer.h b/cpukit/include/rtems/test-printer.h new file mode 100644 index 0000000000..6625aa5a29 --- /dev/null +++ b/cpukit/include/rtems/test-printer.h @@ -0,0 +1,69 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ + +/** + * @file + * + * @ingroup RTEMSTest + * + * @brief This header file provides interfaces of the RTEMS Test Support. + */ + +/* + * Copyright (C) 2014, 2023 embedded brains GmbH & Co. KG + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _RTEMS_TEST_PRINTER_H +#define _RTEMS_TEST_PRINTER_H + +#include <rtems/printer.h> + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/** + * @addtogroup RTEMSTest + * + * @{ + */ + +/** + * @brief Provides an RTEMS printer for tests. + */ +extern rtems_printer rtems_test_printer; + +/** + * @brief Prints via the RTEMS test printer. + * + * @return Returns the count of output characters as specified by printf(). + */ +int rtems_test_printf( const char *format, ... ) RTEMS_PRINTFLIKE( 1, 2 ); + +/** @} */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* _RTEMS_TEST_PRINTER_H */ diff --git a/cpukit/include/rtems/test.h b/cpukit/include/rtems/test.h index 79313343a0..b8e7934883 100644 --- a/cpukit/include/rtems/test.h +++ b/cpukit/include/rtems/test.h @@ -1,6 +1,15 @@ -/* - * SPDX-License-Identifier: BSD-2-Clause +/* SPDX-License-Identifier: BSD-2-Clause */ + +/** + * @file * + * @ingroup RTEMSTestFramework + * + * @brief This header file provides interfaces of the + * RTEMS Test Framework. + */ + +/* * Copyright (C) 2017, 2021 embedded brains GmbH & Co. KG * * Redistribution and use in source and binary forms, with or without @@ -77,6 +86,11 @@ typedef struct T_fixture_node { unsigned int failures; } T_fixture_node; +typedef struct T_remark { + struct T_remark *next; + const char *remark; +} T_remark; + #define T_ARRAY_SIZE(array) (sizeof(array) / sizeof((array)[0])) /* @@ -98,7 +112,7 @@ typedef struct T_fixture_node { /** * @defgroup RTEMSTestFrameworkImpl RTEMS Test Framework Implementation * - * @ingroup RTEMSTestFramework + * @ingroup RTEMSImpl * * @brief Implementation details. * @@ -2318,6 +2332,8 @@ void *T_fixture_context(void); void T_set_fixture_context(void *); +void T_add_remark(T_remark *); + void *T_push_fixture(T_fixture_node *, const T_fixture *); void T_pop_fixture(void); diff --git a/cpukit/include/rtems/thread.h b/cpukit/include/rtems/thread.h index 739744b4e0..c3d7de67f4 100644 --- a/cpukit/include/rtems/thread.h +++ b/cpukit/include/rtems/thread.h @@ -1,5 +1,14 @@ /* SPDX-License-Identifier: BSD-2-Clause */ +/** + * @file + * + * @ingroup RTEMSAPISelfContainedObjects + * + * @brief This header file provides the API of + * @ref RTEMSAPISelfContainedObjects. + */ + /* * Copyright (c) 2017 embedded brains GmbH & Co. KG * @@ -45,6 +54,16 @@ void _Semaphore_Post_binary(struct _Semaphore_Control *); typedef struct _Mutex_Control rtems_mutex; +/** + * @defgroup RTEMSAPISelfContainedObjects Self-Contained Objects + * + * @ingroup RTEMSAPI + * + * @brief This group contains the self-contained objects API. + * + * @{ + */ + #define RTEMS_MUTEX_INITIALIZER( name ) _MUTEX_NAMED_INITIALIZER( name ) static __inline void rtems_mutex_init( rtems_mutex *mutex, const char *name ) @@ -309,6 +328,8 @@ static __inline void rtems_binary_semaphore_destroy( _Semaphore_Destroy( &binary_semaphore->Semaphore ); } +/** @} */ + __END_DECLS #endif /* _RTEMS_THREAD_H */ diff --git a/cpukit/include/sys/_ffcounter.h b/cpukit/include/sys/_ffcounter.h index d83c48cd44..802c7d3224 100644 --- a/cpukit/include/sys/_ffcounter.h +++ b/cpukit/include/sys/_ffcounter.h @@ -1,3 +1,12 @@ +/** + * @file + * + * @ingroup RTEMSScoreTimecounter + * + * @brief This header file provides interfaces of the feed-forward clock + * counter. + */ + /*- * Copyright (c) 2011 The University of Melbourne * All rights reserved. diff --git a/cpukit/include/sys/endian.h b/cpukit/include/sys/endian.h index 0849a6a90b..cdd6201736 100644 --- a/cpukit/include/sys/endian.h +++ b/cpukit/include/sys/endian.h @@ -1,3 +1,12 @@ +/** + * @file + * + * @ingroup RTEMSAPISystemLibrary + * + * @brief This header file provides interfaces of the system endianness + * support. + */ + /*- * Copyright (c) 2002 Thomas Moestl <tmm@FreeBSD.org> * All rights reserved. diff --git a/cpukit/include/sys/priority.h b/cpukit/include/sys/priority.h index 855edb63c2..37d0d938dc 100644 --- a/cpukit/include/sys/priority.h +++ b/cpukit/include/sys/priority.h @@ -1,3 +1,11 @@ +/** + * @file + * + * @ingroup RTEMSAPISystemLibrary + * + * @brief This header file provides interfaces of the process priority support. + */ + /*- * SPDX-License-Identifier: BSD-4-Clause * diff --git a/cpukit/include/sys/statvfs.h b/cpukit/include/sys/statvfs.h index 52d8e9d3fa..655f9a596c 100644 --- a/cpukit/include/sys/statvfs.h +++ b/cpukit/include/sys/statvfs.h @@ -3,10 +3,11 @@ /** * @file * - * @brief Interface to the statvfs() Set of API Methods + * @ingroup RTEMSAPISystemLibrary * - * This include file defines the interface to the statvfs() set of - * API methods. The statvfs as defined by the SUS: + * @brief This header file provides the statvfs() and fstatvfs() interfaces. + * + * The statvfs() is defined by the SUS: * * - http://www.opengroup.org/onlinepubs/009695399/basedefs/sys/statvfs.h.html */ diff --git a/cpukit/include/sys/timeffc.h b/cpukit/include/sys/timeffc.h index c04de97f1d..13abd37a2b 100644 --- a/cpukit/include/sys/timeffc.h +++ b/cpukit/include/sys/timeffc.h @@ -1,3 +1,12 @@ +/** + * @file + * + * @ingroup RTEMSScoreTimecounter + * + * @brief This header file provides interfaces of the feed-back and + * feed-forward clock implementations. + */ + /*- * Copyright (c) 2011 The University of Melbourne * All rights reserved. diff --git a/cpukit/include/sys/timepps.h b/cpukit/include/sys/timepps.h index 030c734477..502d93833e 100644 --- a/cpukit/include/sys/timepps.h +++ b/cpukit/include/sys/timepps.h @@ -1,3 +1,12 @@ +/** + * @file + * + * @ingroup RTEMSScoreTimecounter + * + * @brief This header file provides interfaces of the Pulse Per Second (PPS) + * support. + */ + /*- * ---------------------------------------------------------------------------- * "THE BEER-WARE LICENSE" (Revision 42): diff --git a/cpukit/include/sys/timetc.h b/cpukit/include/sys/timetc.h index 1ef58b378d..8f2537692c 100644 --- a/cpukit/include/sys/timetc.h +++ b/cpukit/include/sys/timetc.h @@ -1,3 +1,12 @@ +/** + * @file + * + * @ingroup RTEMSScoreTimecounter + * + * @brief This header file provides interfaces of the timecounter + * implementation. + */ + /*- * ---------------------------------------------------------------------------- * "THE BEER-WARE LICENSE" (Revision 42): diff --git a/cpukit/include/sys/timex.h b/cpukit/include/sys/timex.h index 8e763bb30f..36b1fcdb5a 100644 --- a/cpukit/include/sys/timex.h +++ b/cpukit/include/sys/timex.h @@ -1,3 +1,12 @@ +/** + * @file + * + * @ingroup RTEMSScoreTimecounter + * + * @brief This header file provides interfaces of the Network Time Protocol + * (NTP) support. + */ + /*- *********************************************************************** * * |