初始版本

This commit is contained in:
xiaozhengsheng
2025-08-19 09:49:41 +08:00
parent 10f1ddf1c1
commit 6df0f7d96e
2974 changed files with 1712873 additions and 54 deletions

View File

@@ -0,0 +1,95 @@
/**
* Copyright (c) 2016 - 2020 Nordic Semiconductor ASA and Luxoft Global Operations Gmbh.
*
* All Rights Reserved.
*
* 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, except as embedded into a Nordic
* Semiconductor ASA integrated circuit in a product or a software update for
* such product, 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.
*
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* 4. This software, with or without modification, must only be used with a
* Nordic Semiconductor ASA integrated circuit.
*
* 5. Any software provided in binary form under this license must not be reverse
* engineered, decompiled, modified and/or disassembled.
*
*
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 SYS_CRC_H_INCLUDED
#define SYS_CRC_H_INCLUDED
#include <stdint.h>
#include <stddef.h>
/** @file
* This file contains declarations of the CRC computing routines and necessary macros/types.
*
* @defgroup sys_crc System CRC API
* @ingroup sys_15_4
* @{
* @brief Module to declare System CRC API.
* @details The CRC module implements a set of routines to compute the 16-bit CRC value for octet arrays.
*/
/**
* @brief Defines an initial value for the CRC sum.
*/
#define SYS_CRC_INIT 0
/**
* @brief CRC value type. This module uses 16-bit CRC.
*/
typedef uint16_t sys_crc_t;
/**
* @brief Function for computing CRC value for given data.
*
* @param[in] p_data Pointer to data to compute.
* @param[in] length Length of data.
*
* @return Returns the CRC value for input data.
*/
sys_crc_t sys_crc_calc(const uint8_t * p_data, size_t length);
/**
* @brief Function for updating the CRC value taking into the account the previously counted value.
*
* @details This function is used when input data is represented by several pieces.
* Consequently, a call to this function for each piece will give a correct
* total CRC value.
*
* @param[in] current_crc Previously counted CRC value. Should be SYS_CRC_INIT for the first piece.
* @param[in] p_data Pointer to the current piece of data.
* @param[in] length Length of the current piece of data.
*
* @return Returns the updated CRC value.
*/
sys_crc_t sys_crc_continue(sys_crc_t current_crc, const uint8_t * p_data, size_t length);
/** @} */
#endif /* SYS_CRC_H_INCLUDED */

View File

@@ -0,0 +1,180 @@
/**
* Copyright (c) 2016 - 2020 Nordic Semiconductor ASA and Luxoft Global Operations Gmbh.
*
* All Rights Reserved.
*
* 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, except as embedded into a Nordic
* Semiconductor ASA integrated circuit in a product or a software update for
* such product, 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.
*
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* 4. This software, with or without modification, must only be used with a
* Nordic Semiconductor ASA integrated circuit.
*
* 5. Any software provided in binary form under this license must not be reverse
* engineered, decompiled, modified and/or disassembled.
*
*
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 SYS_DEBUG_H_INCLUDED
#define SYS_DEBUG_H_INCLUDED
#include "hal_debug_interface.h"
#include "hal_trace_interface.h"
#include <stdbool.h>
#include <stdarg.h>
/* This header file contains macros for debugging. */
#ifndef __FILENAME__
#define __FILENAME__ __FILE__
#endif // __FILENAME__
#ifndef ASSERT
#ifdef CONFIG_DEBUG
#define ASSERT(CONDITION_STATEMENT) \
do \
{ \
bool LOCAL_CONDITION_CHECK = (CONDITION_STATEMENT); \
if (LOCAL_CONDITION_CHECK != true) \
{ \
sys_assert_handler((#CONDITION_STATEMENT), __LINE__, __FILENAME__); \
} \
} while (0)
#else
#define ASSERT(CONDITION_STATEMENT)
#endif // CONFIG_DEBUG
#endif // ASSERT
#ifndef ASSERT_INFO
#ifdef CONFIG_DEBUG
#define ASSERT_INFO(CONDITION_STATEMENT, INFO_FMT, ...) \
do \
{ \
bool LOCAL_CONDITION_CHECK = (CONDITION_STATEMENT); \
if (LOCAL_CONDITION_CHECK != true) \
{ \
sys_assert_info_handler((#CONDITION_STATEMENT), __LINE__, __FILENAME__, \
INFO_FMT, __VA_ARGS__); \
} \
} while (0)
#else
#define ASSERT_INFO(CONDITION_STATEMENT, INFO_FMT, ...)
#endif // CONFIG_DEBUG
#endif // ASSERT_INFO
#ifndef ASSERT_STATIC
#ifdef CONFIG_DEBUG
#define ASSERT_STATIC(e) do { enum {SA = 1/(e)}; } while (0)
#else
#define ASSERT_STATIC(e)
#endif // CONFIG_DEBUG
#endif // ASSERT_STATIC
/**
* @defgroup sys_debug Debugging macros
* @ingroup sys_15_4
* @{
* @brief Functions used for debugging.
*/
/**@brief System assertion fault handler.
*
* @details This macro should be used whenever an assertion fault is detected.
*
* @param[in] CONDITION_STRING Assertion condition string, which occurred to be not true.
*/
#define SYS_ASSERT_HANDLER(CONDITION_STRING) \
do \
{ \
sys_assert_handler(CONDITION_STRING, __LINE__, __FILE__); \
} while (0)
#ifndef TRACE_PUTS
#ifdef CONFIG_TRACE
#define TRACE_PUTS(s) HAL_TRACE_INTERFACE_PUTS(s)
#else
#define TRACE_PUTS(s)
#endif //CONFIG_TRACE
#endif //TRACE_PUTS
#ifndef TRACE
#ifdef CONFIG_TRACE
#define TRACE(INFO_FMT, ...) sys_trace_handler(INFO_FMT, __VA_ARGS__)
#else
#define TRACE(INFO_FMT, ...)
#endif // CONFIG_DEBUG
#endif // TRACE
/**@brief System assertion fault handler function.
*
* @param[in] condition Assertion condition string, which was expected to be true.
*
* @param[in] line Line number.
*
* @param[in] file File name.
*/
extern void sys_assert_handler(
const char * condition, const int line, const char * file);
/**@brief System assertion fault handler function with additional assertion information.
*
* @param[in] condition Assertion condition string, which was expected to be true.
*
* @param[in] line Line number.
*
* @param[in] file File name.
*
* @param[in] info_fmt Format string for additional assert information.
*
* @param[in] ... Arguments list corresponding to the format string.
*/
extern void sys_assert_info_handler(
const char * condition, const int line, const char * file,
const char * info_fmt, ...);
/**@brief System trace output handler function.
*
* @param[in] fmt Format string for trace output.
*
* @param[in] ... Arguments list corresponding to the format string.
*/
extern void sys_trace_handler(const char * fmt, ...);
/** @} */
#endif // SYS_DEBUG_H_INCLUDED

View File

@@ -0,0 +1,167 @@
/**
* Copyright (c) 2016 - 2020 Nordic Semiconductor ASA and Luxoft Global Operations Gmbh.
*
* All Rights Reserved.
*
* 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, except as embedded into a Nordic
* Semiconductor ASA integrated circuit in a product or a software update for
* such product, 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.
*
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* 4. This software, with or without modification, must only be used with a
* Nordic Semiconductor ASA integrated circuit.
*
* 5. Any software provided in binary form under this license must not be reverse
* engineered, decompiled, modified and/or disassembled.
*
*
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 SYS_EVENTS_H_INCLUDED
#define SYS_EVENTS_H_INCLUDED
#include <stddef.h>
#include "sys_queue.h"
/** @file
* This file contains declarations of the Events API and necessary types. The Events feature is implemented
* using the Queue functionality.
*
* @defgroup sys_events System events API
* @ingroup sys_15_4
* @{
* @brief Module for declaring system events API.
* @details The Events module defines some routines to subscribe/unsubscribe to/from system events. The events pool
* can be extended by adding new events to the sys_event_id_t enumeration. The registered callbacks
* can be called for an array of events. The callbacks can be called implicitly via posting the event by the
* sys_event_post() routine.
*/
/**@brief IDs of globally available events.
*
* @details Event IDs are system extension points that allow the user to implement
* specific processing of predefined set of events, occurring in different modules.
*/
typedef enum
{
SYS_EVENT_FALLING_ASLEEP, /**< Falling asleep event. */
SYS_EVENT_WAKE_UP, /**< Waking up event. */
SYS_EVENT_OUT_OF_MEMORY, /**< Out of memory event. */
SYS_EVENT_MEMORY_FREED, /**< Memory was freed up event. */
/** \note The list of system events can be extended during the implementation phase. */
/* The following event IDs are used only for unit testing */
TST_EVENT_0, /**< Test event #0. */
TST_EVENT_1, /**< Test event #1. */
TST_EVENT_2, /**< Test event #2. */
#if (CONFIG_USE_SYS_TASK_NOTIFIER == 1)
/** This event is posted when there are unhandled events available in
* any of the schedulers.
*/
SYS_EVENT_NEW_TASK,
#endif
SYS_EVENTS_AMOUNT
} sys_event_id_t;
/**@brief Prototype of user-implemented callback for processing an event.
*
* @details This callback is registered for the given event by a *_subscribe routine,
* and is then called by the system events engine, when this event occurs.
*
* @param[in] p_data Pointer to the data, specific for this event.
*/
typedef void (* sys_event_callback_t)(const void * p_data);
/**@brief Event descriptor.
*
* @details This descriptor is used to subscribe/unsubscribe to/from the event.
*/
typedef struct
{
/** Service field. */
sys_queue_item_t queue_item;
/** ID of the event to which this callback is to be subscribed. */
sys_event_id_t event_id;
/** Callback function which is to be called when this event occurs. */
sys_event_callback_t callback;
} sys_event_desc_t;
/**@brief Function for initializing the global events infrastructure.
*/
void sys_events_init(void);
/**@brief Function for subscribing to a system event.
*
* @param[in] p_event_desc Pointer to the event descriptor.
*/
void sys_event_subscribe(sys_event_desc_t * p_event_desc);
/**@brief Function for unsubscribing from a system event event.
*
* @param[in] p_event_desc Pointer to the event descriptor.
*/
void sys_event_unsubscribe(sys_event_desc_t * p_event_desc);
/**@brief Function for subscribing to a group of events.
*
* @param[in] p_desc_array Pointer to the array of event descriptors.
* @param[in] desc_amount Amount of event descriptors in the array.
*/
void sys_events_array_subscribe(sys_event_desc_t * p_desc_array, size_t desc_amount);
/**@brief Function for unsubscribing from the group of events.
*
*
* @param[in] p_desc_array Pointer to the array of event descriptors.
* @param[in] desc_amount Amount of the event descriptors in the array.
*/
void sys_events_array_unsubscribe(sys_event_desc_t * p_desc_array, size_t desc_amount);
/**@brief Function for posting an event.
*
* @details This function is used to notify all the subscribers of the given events via
* their callbacks, when the given event occurs.
*
* @param[in] event_id ID of the event to be posted.
* @param[in] p_data Pointer to be passed to the event handlers' callbacks.
*/
void sys_event_post(sys_event_id_t event_id, const void * p_data);
/** @} */
#endif // SYS_EVENTS_H_INCLUDED

View File

@@ -0,0 +1,286 @@
/**
* Copyright (c) 2016 - 2020 Nordic Semiconductor ASA and Luxoft Global Operations Gmbh.
*
* All Rights Reserved.
*
* 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, except as embedded into a Nordic
* Semiconductor ASA integrated circuit in a product or a software update for
* such product, 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.
*
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* 4. This software, with or without modification, must only be used with a
* Nordic Semiconductor ASA integrated circuit.
*
* 5. Any software provided in binary form under this license must not be reverse
* engineered, decompiled, modified and/or disassembled.
*
*
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 SYS_FSM_H_INCLUDED
#define SYS_FSM_H_INCLUDED
#include <stdint.h>
#include <stdbool.h>
/** @file
* This file contains declarations of the Finite State Machine (FSM) primitives and necessary types.
*
* @defgroup sys_fsm Finite State Machine API
* @ingroup sys_15_4
* @{
* @brief Module to declare Finite State Machine API
* @details The FSM module implements the Finite State Machine abstraction. The user is intended to implement a transition
* table of states with guards and actions in order to represent some event-driven subject. When a table is
* implemented, call sys_fsm_init() to initialize the FSM. After that, the only routine to
* work with FSM is sys_fsm_event_post().
*/
/**@brief Fixed-size type for FSM state ID.
*/
typedef uint8_t sys_fsm_state_id_t;
/**@brief Fixed-size type for FSM event ID.
*/
typedef uint8_t sys_fsm_event_id_t;
/**@brief Fixed-size type for FSM guard condition ID.
*/
typedef uint8_t sys_fsm_guard_id_t;
/**@brief Fixed-size type for FSM action ID.
*/
typedef uint8_t sys_fsm_action_id_t;
/**@brief FSM transition description (item of FSM transition table).
*
* @details When an event with given event_id occurs, the guard condition with guard_id
* is checked, and if it returns true, the action with action_id is performed,
* and state machine is switched to the state with new_state_id.
*/
typedef struct
{
sys_fsm_event_id_t event_id; /**< FSM event ID. */
sys_fsm_guard_id_t guard_id; /**< FSM guard ID. */
sys_fsm_action_id_t action_id; /**< FSM action ID. */
sys_fsm_state_id_t new_state_id; /**< New state ID. */
#if defined(CONFIG_FSM_DEBUG)
const char * debug_string;
#endif
} sys_fsm_transition_t;
/**@brief FSM transition declaration (item of FSM transition table).
*/
#if defined(CONFIG_FSM_DEBUG)
# define SYS_FSM_TRANSITION(event_id, guard_id, action_id, new_state_id) \
{(event_id), (guard_id), (action_id), (new_state_id), \
"(" #event_id ", " #guard_id ", " #action_id " -> " #new_state_id ")"}
#else
# define SYS_FSM_TRANSITION(event_id, guard_id, action_id, new_state_id) \
{(event_id), (guard_id), (action_id), (new_state_id)}
#endif
/**@brief FSM state declaration.
*
* @details The state is an aggregator item of the FSM transition table, aggregating
* the transitions, declared immediately after this state declaration.
* All transition declaration items, following the state declaration item,
* will be aggregated in this state, until the next state declaration item,
* or the "end of table" item.
*/
#define SYS_FSM_STATE(state_id) \
{(state_id) | SYS_FSM_STATE_FLAG, 0, 0, 0}
/**@brief Empty guard condition ID.
*
* @details Special value of the guard_id field. If it is used in transition declaration,
* guard check will be omitted.
*/
#define SYS_FSM_NO_GUARD 0xFF
/**@brief Empty guard condition ID (useful synonym).
*
* @details Special value of the guard_id field. If it is used in transition declaration,
* guard check will be omitted.
*/
#define SYS_FSM_OTHERWISE 0xFF
/**@brief Empty guard condition ID (useful synonym).
*
* @details Special value of the guard_id field. If it is used in transition declaration,
* guard check will be omitted.
*/
#define SYS_FSM_ALWAYS 0xFF
/**@brief Empty action ID.
*
* @details Special value of the action_id field. If it is used in transition declaration,
* no action will be performed during the transition.
*/
#define SYS_FSM_NO_ACTION 0xFF
/**@brief Same state ID.
*
* @details Special value of the next_state_id field. If it is used in transition
* declaration, the current state will not be changed.
*/
#define SYS_FSM_SAME_STATE 0xFF
/**@brief Any state ID.
*
* @details Special value of the event_id field. If it is used in transition
* declaration table, then the transitions listed in this state will be applied
* in case they have not been listed in the transition table for the
* current FSM state.
* Only one SYS_FSM_STATE(SYS_FSM_ANY_STATE) can be present in the transition table.
*/
#define SYS_FSM_ANY_STATE 0xFF
/**@brief State declaration flag.
*
* @details Special flag of the event_id field. This flag is used to distinguish
* between state declaration and transition declaration.
*/
#define SYS_FSM_STATE_FLAG 0x80
/**@brief Prototype of a user-defined FSM guard condition function.
*
* @details You must implement a single FSM guard condition function which will
* use an ID of the needed guard check as a parameter.
*
* @param[in] guard_id Guard condition ID to be checked.
* @param[in] p_data Additional FSM specific data.
*
* @retval true Transition is allowed, false otherwise.
*/
typedef bool (* sys_fsm_guard_t)(sys_fsm_guard_id_t guard_id, void * p_data);
/**@brief Prototype of a user-defined FSM action function.
*
* @details You must implement a single FSM action function which will
* use an ID of the needed action as a parameter.
*
* @param[in] action_id Action ID to be performed.
* @param[in] p_data Additional FSM specific data.
*/
typedef void (* sys_fsm_action_t)(sys_fsm_action_id_t action_id, void * p_data);
/**@brief Constant FSM descriptor which can reside in read-only memory.
*/
typedef struct
{
#if defined(CONFIG_FSM_DEBUG)
const char * debug_fsm_name;
#endif
/** Pointer to the transition table.
*/
const sys_fsm_transition_t * transition_table;
/** Number of transitions in the transition table.
*/
uint8_t transitions_amount;
/** Initial state ID.
*/
sys_fsm_state_id_t initial_state;
/** Pointer to the guard condition function.
*/
sys_fsm_guard_t guard;
/** Pointer to the action function.
*/
sys_fsm_action_t action;
} sys_fsm_const_descriptor_t;
/**@brief FSM dynamic descriptor, holding the current state of the FSM.
*/
typedef struct
{
/** Pointer to the constant FSM descriptor which can reside in read-only memory.
*/
const sys_fsm_const_descriptor_t * fsm_const_desc;
/** Index of the "any state transitions" block.
*/
uint8_t any_state_transitions_index;
/** Current state ID.
*/
volatile sys_fsm_state_id_t current_state;
/** Recursion protection.
*/
volatile uint8_t recursion_protection;
} sys_fsm_t;
#if defined(CONFIG_FSM_DEBUG)
#define FSM_DEBUG_NAME(name_string) .debug_fsm_name = name_string,
#else
#define FSM_DEBUG_NAME(name_string)
#endif
/**@brief Function for initializing a specific FSM.
*
* @param[in] p_fsm Pointer to FSM descriptor to initialize.
* @param[in] p_fsm_const Pointer to constant FSM descriptor with transition table, etc.
*/
void sys_fsm_init(sys_fsm_t * p_fsm, const sys_fsm_const_descriptor_t * p_fsm_const);
/**@brief Function for posting an event to FSM.
*
* @details This function causes FSM transition from the current state to the new state,
* according to the transition table of this FSM.
* The corresponding guard check and action is performed.
*
* @param[in] p_fsm Pointer to FSM descriptor.
* @param[in] event_id Event ID to post.
* @param[in] p_data Pointer to the FSM-specific data.
*/
void sys_fsm_event_post(sys_fsm_t * p_fsm, sys_fsm_event_id_t event_id, void * p_data);
/** @} */
#endif // SYS_FSM_H_INCLUDED

View File

@@ -0,0 +1,69 @@
/**
* Copyright (c) 2016 - 2020 Nordic Semiconductor ASA and Luxoft Global Operations Gmbh.
*
* All Rights Reserved.
*
* 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, except as embedded into a Nordic
* Semiconductor ASA integrated circuit in a product or a software update for
* such product, 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.
*
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* 4. This software, with or without modification, must only be used with a
* Nordic Semiconductor ASA integrated circuit.
*
* 5. Any software provided in binary form under this license must not be reverse
* engineered, decompiled, modified and/or disassembled.
*
*
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 SYS_INIT_H_INCLUDED
#define SYS_INIT_H_INCLUDED
#include <stddef.h>
/**
* @defgroup sys_15_4_init Initialization API
* @ingroup sys_15_4
* @{
* @brief API for initizalizing the system abstraction library.
*/
/** @brief Initializes every component of this stack.
*
* This function must be called before using any of the components.
*
* @param[in] p_start Pool start address.
* @param[in] size Size of the pool in bytes.
*
* @details The pool start address must be aligned on the ALIGN_VALUE boundary, which is
* defined in @c sys_utils.h.
* The pool size should be multiple of an ALIGN_VALUE, which is defined in @c sys_utils.h.
*/
void sys_init(void * p_start, size_t size);
/** @} */
#endif /* SYS_INIT_H_INCLUDED */

View File

@@ -0,0 +1,248 @@
/**
* Copyright (c) 2016 - 2020 Nordic Semiconductor ASA and Luxoft Global Operations Gmbh.
*
* All Rights Reserved.
*
* 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, except as embedded into a Nordic
* Semiconductor ASA integrated circuit in a product or a software update for
* such product, 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.
*
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* 4. This software, with or without modification, must only be used with a
* Nordic Semiconductor ASA integrated circuit.
*
* 5. Any software provided in binary form under this license must not be reverse
* engineered, decompiled, modified and/or disassembled.
*
*
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 SYS_LIST_H_INCLUDED
#define SYS_LIST_H_INCLUDED
/** @file
* This file contains declarations of the doubly linked list primitives and necessary types.
* This implementation is Linux-proven and used in the memory management module.
*
* @defgroup sys_list Doubly linked list API.
* @ingroup sys_15_4
* @{
* @brief Module to declare the doubly linked list API.
*/
/**
* Internal list "head" struct.
*/
struct sys_list_head
{
struct sys_list_head * next;
struct sys_list_head * prev;
};
typedef struct sys_list_head sys_list_head_t;
/**
* @brief Initializes a list by variable name.
* @warning this macro assumes that a list "head" (sys_list_head_t) variable
* with name \a name is already created.
*
* @param[inout] name The "head" struct name.
*/
#define LIST_HEAD_INIT(name) { &(name), &(name) }
/**
* @brief Defines and initializes a new list.
* @details A call to this macro creates a new variable with the given name and
* initializes it as a list "head".
*
* @param[inout] name The "head" struct name.
*/
#define LIST_HEAD(name) sys_list_head_t name = { &(name), &(name) }
/**
* @brief Initializes a list by pointer.
*
* @param[inout] ptr Pointer to a list.
*/
#define INIT_LIST_HEAD(ptr) \
do \
{ \
(ptr)->prev = (ptr); \
(ptr)->next = (ptr); \
} while (0)
/**
* @brief Checks if a list is empty.
*
* @param[in] sys_list_head Pointer to a list.
* @return 0 if not empty, non-zero otherwise.
*/
#define IS_EMPTY(sys_list_head) (sys_list_head)->next == (sys_list_head)
/**
* @brief Adds a new item to the list between \a l_prev and \a l_next elements.
* @warning This routine assumes that \a l_next is next to \a l_prev in the list.
* @note This is an internal helper routine which is not intended to be used by the user.
*
* @param[in] l_prev Pointer to the previous element.
* @param[in] l_next Pointer to the next element.
* @param[in] l_new Pointer to a new element.
*/
static inline void sys_ll_list_add(sys_list_head_t * l_prev,
sys_list_head_t * l_next,
sys_list_head_t * l_new)
{
l_new->prev = l_prev;
l_prev->next = l_new;
l_next->prev = l_new;
l_new->next = l_next;
}
/**
* @brief Deletes an element between \a l_prev and \a l_next elements.
* @warning This macro assumes that \a l_next is next to \a l_prev in the list.
* @note This is an internal helper routine which is not intended to be used by the user.
*
* @param[in] l_prev Pointer to the previous element.
* @param[in] l_next Pointer to the next element.
*/
static inline void sys_ll_list_del(sys_list_head_t * l_next,
sys_list_head_t * l_prev)
{
l_next->prev = l_prev;
l_prev->next = l_next;
}
/**
* @brief Function for adding a new item to the head of the list.
*
* @param[in] new Pointer to a new element.
* @param[in] head Pointer to the list head.
*/
static inline void sys_list_add(sys_list_head_t * new, sys_list_head_t * head)
{
sys_ll_list_add(head, head->next, new);
}
/**
* @brief Function for adding a new item to the tail of the list.
*
* @param[in] new Pointer to a new element.
* @param[in] head Pointer to the list head.
*/
static inline void sys_list_add_tail(sys_list_head_t * new, sys_list_head_t * head)
{
sys_ll_list_add(head->prev, head, new);
}
/**
* @brief Function for deleting an entry from list.
*
* @param[in] entry The element to delete from the list.
*/
static inline void sys_list_del(sys_list_head_t * entry)
{
sys_ll_list_del(entry->next, entry->prev);
}
/**
* @brief Function for deleting an entry from the list and reinitializing it.
*
* @param[in] entry The element to delete from the list.
*/
static inline void sys_list_del_init(sys_list_head_t * entry)
{
sys_ll_list_del(entry->next, entry->prev);
INIT_LIST_HEAD(entry);
}
/**
* @brief Function for testing if a list is empty.
* @param[in] head The list to test.
* @return 0 if not empty, non-zero otherwise.
*/
static inline unsigned int sys_list_empty(sys_list_head_t * head)
{
return IS_EMPTY(head);
}
/**
* @brief Sets a pointer to a variable to the parent structure pointer using a
* pointer to a field in this structure.
*
* @note This is a version of @ref GET_PARENT_BY_FIELD() extended by setting to a variable.
*
* @param[out] ll_ret_var Variable pointer name to return.
* @param[in] ll_ptr Pointer to the structure field.
* @param[in] ll_type Name of the parent structure.
* @param[in] ll_member Name of the structure field.
*/
#define SYS_LIST_ENTRY(ll_ret_var, ll_ptr, ll_type, ll_member) \
do \
{ \
size_t p = (size_t) ll_ptr; \
size_t off = offsetof(ll_type, ll_member); \
ll_ret_var = (ll_type *) (p - off); \
} while (0)
/**
* @brief Iterates through the list.
* @note Use @ref SYS_LIST_FOR_EACH_SAFE() for thread-safe cases.
*
* @param[out] pos Iterator variable.
* @param[in] head Pointer to the list head.
*/
#define SYS_LIST_FOR_EACH(pos, head) \
for (pos = ((head)->next); \
((pos) != (head)); \
pos = (pos)->next)
/**
* @brief Thread-safe version of @ref SYS_LIST_FOR_EACH().
*
* @param[out] ll_pos Iterator variable.
* @param[out] ll_pos_n Temporary iterator variable (next entry).
* @param[in] ll_head Pointer to the list head.
*/
#define SYS_LIST_FOR_EACH_SAFE(ll_pos, ll_pos_n, ll_head) \
for (ll_pos = (ll_head)->next, ll_pos_n = (ll_head)->next->next; \
(ll_pos) != (ll_head); \
ll_pos = ll_pos_n, ll_pos_n = ll_pos->next)
/** @} */
#endif /* SYS_LIST_H_INCLUDED */

View File

@@ -0,0 +1,92 @@
/**
* Copyright (c) 2016 - 2020 Nordic Semiconductor ASA and Luxoft Global Operations Gmbh.
*
* All Rights Reserved.
*
* 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, except as embedded into a Nordic
* Semiconductor ASA integrated circuit in a product or a software update for
* such product, 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.
*
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* 4. This software, with or without modification, must only be used with a
* Nordic Semiconductor ASA integrated circuit.
*
* 5. Any software provided in binary form under this license must not be reverse
* engineered, decompiled, modified and/or disassembled.
*
*
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 SYS_MEMORY_MANAGER_H_INCLUDED
#define SYS_MEMORY_MANAGER_H_INCLUDED
#include <stddef.h>
#include <stdint.h>
/** @file
* This file contains declarations of the Memory manager API.
*
* @defgroup sys_memory_manager Memory Manager API
* @ingroup sys_15_4
* @{
* @brief Module to declare Memory Manager API.
* @details The Memory Manager module implements the standard API for allocating/freeing memory chunks. The module must
* be initialized by sys_mm_init() before a call to any alloc/free routines. The memory can be allocated by a
* call to sys_mm_alloc() and freed by a call to sys_mm_free(). Minimal chunk of memory to allocate is one byte,
* however the sys_mm_alloc() routine will allocate the number of bytes aligned to the length of the
* machine word (e.g. 4 bytes for 32-bit architectures). The module is implemented using the doubly linked
* lists API.
*/
/**@brief Function for initializing the memory manager.
* @details Initialize the memory manager pool of the 'size' bytes length at 'p_start' address.
*
* @param p_start Pool start address.
* @param size Size of the pool in bytes.
*/
void sys_mm_init(void * p_start, size_t size);
/**@brief Function for allocating memory in the pool.
* @details Search and allocate free memory resources.
*
* @param[in] size Size of the requested memory.
*
* @retval Pointer to allocated memory,
* NULL in case of error.
*/
void * sys_mm_alloc(size_t size);
/**@brief Function for freeing the allocated memory.
*
* @param[in] p_addr Pointer to the memory to free.
*
*/
void sys_mm_free(void * p_addr);
/** @} */
#endif // SYS_MEMORY_MANAGER_H_INCLUDED

View File

@@ -0,0 +1,290 @@
/**
* Copyright (c) 2016 - 2020 Nordic Semiconductor ASA and Luxoft Global Operations Gmbh.
*
* All Rights Reserved.
*
* 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, except as embedded into a Nordic
* Semiconductor ASA integrated circuit in a product or a software update for
* such product, 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.
*
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* 4. This software, with or without modification, must only be used with a
* Nordic Semiconductor ASA integrated circuit.
*
* 5. Any software provided in binary form under this license must not be reverse
* engineered, decompiled, modified and/or disassembled.
*
*
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 SYS_QUEUE_H_INCLUDED
#define SYS_QUEUE_H_INCLUDED
#include <stdbool.h>
#include <stdint.h>
/** @file
* This file contains declarations of the primitives to work with queues and necessary types.
*
* @defgroup sys_queues Queue API
* @ingroup sys_15_4
* @{
* @brief Module to declare the queue API.
* @details The queue module implements a set of routines to deal with queues. Before
* any calls to its API are issued, a queue must be initialized using sys_queue_init(). The following routines
* return queue items from different parts of an initialized queue without removing it from the queue:
* sys_queue_front(), sys_queue_back(), sys_queue_next(), and sys_queue_at().
* The following routines insert elements to the queue: sys_queue_push_front(),
* sys_queue_push_back(), sys_queue_push_predicated(), sys_queue_push_predicated_force(), and sys_queue_insert().
* The following routines remove elements from the queue: sys_queue_pop_front(), sys_queue_remove(),
* sys_queue_remove_after(). These helper routines get information about a queue: sys_queue_size() and
* sys_queue_is_empty(). The module also supports an iterator macro implemented by SYS_QUEUE_FOR_EACH().
*/
/**@brief Queue item descriptor.
*
* @details In order to store any user data struct in a queue, the user struct should contain
* a field of type 'sys_queue_item_t'. This field may be at any offset.
* The user data item can be cast from the queue item,
* by the \ref GET_PARENT_BY_FIELD() macro from sys_utils.h.
*/
typedef struct sys_queue_item_s
{
struct sys_queue_item_s * next;
} sys_queue_item_t;
/**@brief Queue descriptor.
*/
typedef sys_queue_item_t sys_queue_t;
/**@brief Prototype of a predicate function for pushing an item into the queue.
*
* @details As a user of the queue library, implement the predicate function and pass it
* as a parameter to \ref sys_queue_push_predicated(). You can choose
* whether insertion of a new item should be done before the given existing item of
* the queue, or not.
*
* @param[in] p_before_item Pointer to the existing item before which a new item
* should be inserted.
* @param[in] p_new_item Pointer to the item to be inserted into the queue.
*
* @retval true Insertion is to be done before the given item, false otherwise.
*/
typedef bool (* sys_queue_push_predicate_t)(
sys_queue_item_t * p_before_item,
sys_queue_item_t * p_new_item);
/**@brief Function for initializing the queue before any other usage of the queue.
*
* @details Initialize (reset) the queue to its initial state. The queue becomes empty.
*
* @param[in] p_queue Queue to be initialized.
*/
void sys_queue_init(sys_queue_t * p_queue);
/**@brief Function for getting the front (head) item of the queue without removing it.
*
* @details Return a pointer to the item from the head of the queue but leave it in the queue.
*
* @param[in] p_queue Queue to get the item from.
*
* @retval Pointer to the head item of the queue, or NULL if the queue is empty.
*/
sys_queue_item_t * sys_queue_front(const sys_queue_t * p_queue);
/**@brief Function for getting the back (tail) item of the queue without removing it.
*
* @details Return a pointer to the item from the tail of the queue but leave it in the queue.
*
* @param[in] p_queue Queue to get the item from.
*
* @retval Pointer to the tail item of the queue, or NULL if the queue is empty.
*/
sys_queue_item_t * sys_queue_back(const sys_queue_t * p_queue);
/**@brief Function for getting the item, next to the given item of the queue.
*
* @details Return a pointer to the next item after the given one, or NULL if the
* given item is the last item of the queue.
*
* @param[in] p_queue Pointer to the queue.
* @param[in] p_item Pointer to the item.
*
* @retval Pointer to the next item after the given one, or NULL if the
* given item is the last item of the queue.
*/
sys_queue_item_t * sys_queue_next(const sys_queue_t * p_queue, const sys_queue_item_t * p_item);
/**@brief Function for pushing an item to the front (head) of the queue.
*
* @details This function inserts an item to the head of the queue.
*
* @param[in] p_queue Queue to push the item to.
* @param[in] p_item Item to insert to the front of the queue.
*/
void sys_queue_push_front(sys_queue_t * p_queue, sys_queue_item_t * p_item);
/**@brief Function for pushing an item to the back (tail) of the queue.
*
* @details This function inserts an item to the tail of the queue.
*
* @param[in] p_queue Queue to push the item to.
* @param[in] p_item Item to insert to the tail of the queue.
*/
void sys_queue_push_back(sys_queue_t * p_queue, sys_queue_item_t * p_item);
/**@brief Function for pushing an item to the queue with a predicate.
*
* @details Conditionally push an item to the queue using the given predicate that tries to determine
* the insertion position.
*
* @param[in] p_queue Queue to push the item to.
* @param[in] p_item Item to be pushed.
* @param[in] predicate Predicate to be used to find the insertion position.
*
* @retval true The item was inserted into the queue, false otherwise.
*/
bool sys_queue_push_predicated(
sys_queue_t * p_queue,
sys_queue_item_t * p_item,
sys_queue_push_predicate_t predicate);
/**@brief Function for pushing an item to the queue with a predicate forcing insertion to the tail if the predicate
* fails.
*
* @details Unconditionally push an item to the queue using the given predicate that tries to
* determine the insertion position.
* If predicate returns false, then force the insertion to the tail of the queue.
*
* @param[in] p_queue Queue to push item to.
* @param[in] p_item Item to be pushed.
* @param[in] predicate Predicate to be used to find the insertion position.
*/
void sys_queue_push_predicated_force(
sys_queue_t * p_queue,
sys_queue_item_t * p_item,
sys_queue_push_predicate_t predicate);
/**@brief Function for getting and removing the front (head) item from the queue.
*
* @details Get an item from the head of the queue and remove it from the queue.
*
* @param[in] p_queue Queue to get and remove the head item from.
*
* @retval Pointer to the head item of queue or NULL if the queue is empty.
*/
sys_queue_item_t * sys_queue_pop_front(sys_queue_t * p_queue);
/**@brief Function for removing an item from the queue.
*
* @details The given item will be removed from the queue.
*
* @note The complexity of this function is O(n). Use function \ref sys_queue_remove_after()
* whenever the previous item of the queue is known.
*
* @param[in] p_queue Queue to remove the item from.
* @param[in] p_item Item to remove from the queue.
*/
void sys_queue_remove(sys_queue_t * p_queue, sys_queue_item_t * p_item);
/**@brief Function for removing the item after the given item from the queue.
*
* @details The item next to the given one will be removed from the queue.
*
* @param[in] p_queue Queue to remove the item from.
* @param[in] p_after_item Next to this item will be removed.
*/
void sys_queue_remove_after(sys_queue_t * p_queue, sys_queue_item_t * p_after_item);
/**@brief Function for returning the current size of a queue, i.e. number of elements inside it.
*
* @details This function goes through the whole queue, so it is relatively slow.
*
* @param[in] p_queue Queue to work with.
*
* @retval Number of items currently inserted into the queue.
*/
uint8_t sys_queue_size(const sys_queue_t * p_queue);
/**@brief Function for returning a pointer to the item inside a queue represented by an index.
*
* @details This function searches through the whole queue, so it is relatively slow.
*
* @param[in] p_queue Queue to work with.
* @param[in] index Requested index.
*
* @retval Pointer to the requested item or NULL if the queue size is less
* than \a index.
*/
sys_queue_item_t * sys_queue_at(const sys_queue_t * p_queue, const uint8_t index);
/**@brief Function for inserting an item at the specified position represented by an index in the queue.
* If this position is too big, it is inserted to the tail of the queue.
*
* @details This function searches through the whole queue, so it is relatively slow.
*
* @param[in] p_queue Queue to insert to.
* @param[in] p_item Item to be inserted.
* @param[in] pos Position inside the queue (0 is the front).
*/
void sys_queue_insert(sys_queue_t * p_queue, sys_queue_item_t * p_item, const uint8_t pos);
/**@brief Function for determining if a queue is empty.
*
* @param[in] p_queue Queue to be checked.
*
* @retval True if queue is empty, false otherwise.
*/
bool sys_queue_is_empty(const sys_queue_t * p_queue);
/**@brief Macro for iterating through all items in the queue.
*
* @param[in] p_queue Pointer to the queue (sys_queue_t *).
* @param[in] p_iterator Variable to be used as an iterator (sys_queue_item_t *).
*/
#define SYS_QUEUE_FOR_EACH(p_queue, p_iterator) \
for (sys_queue_item_t * p_iterator = sys_queue_front(p_queue); \
p_iterator != NULL; \
p_iterator = sys_queue_next(p_queue, p_iterator))
/** @} */
#endif // SYS_QUEUE_H_INCLUDED

View File

@@ -0,0 +1,202 @@
/**
* Copyright (c) 2016 - 2020 Nordic Semiconductor ASA and Luxoft Global Operations Gmbh.
*
* All Rights Reserved.
*
* 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, except as embedded into a Nordic
* Semiconductor ASA integrated circuit in a product or a software update for
* such product, 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.
*
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* 4. This software, with or without modification, must only be used with a
* Nordic Semiconductor ASA integrated circuit.
*
* 5. Any software provided in binary form under this license must not be reverse
* engineered, decompiled, modified and/or disassembled.
*
*
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 SYS_RINGBUFFER_H_INCLUDED
#define SYS_RINGBUFFER_H_INCLUDED
#include <stdint.h>
#include <stdlib.h>
#include <stdbool.h>
/** @file
* This file contains declarations of the Ring buffer routines and necessary types. Please note that
* each ring buffer element should have size of 1 byte.
*
* @defgroup sys_ringbuffer System Ring buffer API
* @ingroup sys_15_4
* @{
* @brief Module for declaring System Ring buffer API.
* @details The Ring Buffer module implements routines to deal with the ring buffer. The following routines are supported:
* sys_ringbuffer_insert(), sys_ringbuffer_remove() to operate with single element. The
* sys_ringbuffer_remove_multiple() can be used to remove (read) several elements at once. The
* sys_ringbuffer_clear(), sys_ringbuffer_init(), and sys_ringbuffer_init_over() functions are used to clean up and
* initialize the ring buffer. Some information about the initialized ring buffer is available via the
* following routines: sys_ringbuffer_size_get() to get the number of used elements, sys_ringbuffer_chunk_get()
* to return the biggest, available to read, continuous chunk of elements, sys_ringbuffer_is_empty() and
* sys_ringbuffer_is_full() to check if the ring buffer is empty/full, and sys_ringbuffer_max_size_get() to get
* the ring buffer capacity. One of the samples for ring buffer usage is the UART implementation.
*/
/** This structure holds all necessary information about a ring buffer. It is intentionally left undocumented
* by Doxygen.
*
* All these fields are private and must NOT be changed by the user.
*/
typedef struct
{
size_t write_index;
size_t read_index;
uint8_t * array;
size_t size;
bool is_full;
} sys_ringbuffer_t;
/** @brief Function for initializing an empty ring buffer over passed memory.
*
* @param[inout] buffer Instance of sys_ringbuffer_t that will be initialized.
* @param[in] memory Start address of the memory region used as a ring buffer.
* @param[in] length Size in bytes of the memory region used as a ring buffer.
*/
void sys_ringbuffer_init(sys_ringbuffer_t * buffer,
const void * memory,
const size_t length);
/** @brief Function for initializing a ring buffer over passed memory and marking all
* pre_init_length elements as inserted.
*
* @details This function may be used to initialize a buffer with some
* pre-initialized data in it. Passed memory region is interpreted by this function
* as an already filled (partly or fully) ring buffer so that \a pre_init_length
* elements are marked as inserted.
*
* @param[inout] buffer Instance of sys_ringbuffer_t that will be initialized.
* @param[in] memory Start address of the memory region used as a ring buffer.
* @param[in] pre_init_length Number of elements (bytes) that had already been in \a memory.
* They would be inserted into the newly-initialized ring buffer in a FIFO manner.
* @param[in] length Size of the memory region used as a ring buffer.
*/
void sys_ringbuffer_init_over(sys_ringbuffer_t * buffer,
const void * memory,
const size_t pre_init_length,
const size_t length);
/** @brief Function for removing an element from a ring buffer and returning it.
*
* @param[inout] buf Instance of @c sys_ringbuffer_t.
*
* @return Value of the removed element.
*
* @warning This buffer has no underflow control except assert.
*/
uint8_t sys_ringbuffer_remove(sys_ringbuffer_t * buf);
/** @brief Function for quickly removing up to chunk_size elements from a ring buffer
* and marking those elements as available in the ring buffer.
*
* @param[inout] buffer Instance of @c sys_ringbuffer_t.
* @param[in] chunk_size Number of elements to release.
*/
void sys_ringbuffer_remove_multiple(sys_ringbuffer_t * buffer,
const size_t chunk_size);
/** @brief Function for inserting a new element into a ring buffer.
*
* @param[inout] buffer Instance of @c sys_ringbuffer_t.
* @param[in] data Element value to insert.
*
* @warning In case of overflow, this buffer will overwrite the oldest
* element and the number of available elements will remain unchanged.
*/
void sys_ringbuffer_insert(sys_ringbuffer_t * buffer, const uint8_t data);
/** @brief Function for clearing an instance of \a sys_ringbuffer_t, making it empty.
*
* @param[inout] buffer Instance of @c sys_ringbuffer_t.
*/
void sys_ringbuffer_clear(sys_ringbuffer_t * buffer);
/** @brief Function for returning the number of used elements in a ring buffer instance.
*
* @param[inout] buf Instance of sys_ringbuffer_t.
*
* @return Number of elements.
*/
size_t sys_ringbuffer_size_get(const sys_ringbuffer_t * buf);
/** @brief Function for returning the biggest, available to read, continuous chunk from a ring buffer array.
*
* @param[inout] buffer Instance of @c sys_ringbuffer_t.
* @param[out] chunk Pointer to a memory chunk removed from the ring buffer.
* @param[out] chunk_size Size of the removed chunk.
*
* @warning The returned chunk is still part of the ring buffer. To make the chunk elements available
* for write, call @c sys_ringbuffer_remove_multiple() after the chunk is processed.
*/
void sys_ringbuffer_chunk_get(sys_ringbuffer_t * buffer,
void ** chunk,
size_t * chunk_size);
/** @brief Function for checking whether a ring buffer is empty.
*
* @param[inout] buf Instance of @c sys_ringbuffer_t.
*
* @return True if the ring buffer is empty.
*/
static inline bool sys_ringbuffer_is_empty(const sys_ringbuffer_t * buf)
{
return ((buf->write_index == buf->read_index) && (!buf->is_full));
}
/** @brief Function for checking whether a ring buffer is full.
*
* @param[inout] buf Instance of @c sys_ringbuffer_t.
*
* @return True if number of items in the buffer equals to (length - 1).
*/
static inline bool sys_ringbuffer_is_full(const sys_ringbuffer_t * buf)
{
return buf->is_full;
}
/** @brief Function for returning number of elements that can be potentially put into the buffer.
*
* @param[inout] buf Instance of @c sys_ringbuffer_t.
*
* @return Number of elements.
*/
static inline size_t sys_ringbuffer_max_size_get(const sys_ringbuffer_t * buf)
{
return buf->size;
}
/** @} */
#endif /* SYS_RINGBUFFER_H_INCLUDED */

View File

@@ -0,0 +1,142 @@
/**
* Copyright (c) 2016 - 2020 Nordic Semiconductor ASA and Luxoft Global Operations Gmbh.
*
* All Rights Reserved.
*
* 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, except as embedded into a Nordic
* Semiconductor ASA integrated circuit in a product or a software update for
* such product, 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.
*
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* 4. This software, with or without modification, must only be used with a
* Nordic Semiconductor ASA integrated circuit.
*
* 5. Any software provided in binary form under this license must not be reverse
* engineered, decompiled, modified and/or disassembled.
*
*
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 SYS_SLAB_ALLOCATOR_H_INCLUDED
#define SYS_SLAB_ALLOCATOR_H_INCLUDED
#include "phy_pd_data.h"
#ifndef CONFIG_SLAB_FRAME_POOL_SIZE
#define CONFIG_SLAB_FRAME_POOL_SIZE 4
#warning "CONFIG_SLAB_FRAME_POOL_SIZE not set in .config, using default"
#endif
/** @file
* This file contains declarations of the SLAB allocator API.
*
* @defgroup sys_slab_allocator SLAB Allocator API
* @ingroup sys_15_4
* @{
* @brief Module for declaring the SLAB Allocator API
*/
/**@brief The SLAB allocator buffer type (free or busy buffer).
*/
typedef enum
{
SYS_SLAB_FREE_BUFFER, /**< The buffer is free */
SYS_SLAB_BUSY_BUFFER, /**< The buffer is busy */
} sys_slab_buffer_type_t;
/**@brief Initializes the SLAB allocator.
*
* @details Preallocates the frame pool
*/
void sys_sa_init(void);
/**@brief Resets the SLAB allocator.
*
* @details Clear allocated the frame pools
*/
void sys_sa_reset(void);
/**@brief Inserts item into one of the queues of the SLAB allocator.
*
* @details This function is used to put the item into the SLAB allocator
* queue. Type of buffer shall be chosen.
*
* @param[in] type Type of an inserted buffer (free or busy).
* @param[in] p_item Pointer to an inserted buffer.
*/
void sys_sa_buffer_put(sys_slab_buffer_type_t type, pd_data_ind_t * p_item);
/**@brief Gets item from one of the queues of the SLAB allocator.
*
* @details This function is used to get the item from the SLAB allocator
* queues. Type of buffer shall be chosen. The buffer is deleted
* from the SLAB allocator
*
* @param[in] type Type of a gotten buffer (free or busy).
*
* @retval Pointer to a gotten buffer in case of success. NULL otherwise.
*/
pd_data_ind_t * sys_sa_buffer_get(sys_slab_buffer_type_t type);
/**@brief Deletes an allocated item from the heap.
*
* @details This function is used to delete allocated by SLAB allocator buffer
* from the heap. Pointer to a frame memory of an allocated item shall be used.
*
* @param[in] p_frame Pointer to a frame memory of an allocated item.
*/
void sys_sa_buffer_free(uint8_t * p_frame);
/**@brief Returns buffer back to queue of free buffers.
*
* @details This function is used to return allocated buffer back to the queue
* without allocation and deallocation.
*
* @param[in] p_item Pointer to an allocated item.
*/
void sys_sa_buffer_release(pd_data_ind_t * p_item);
/**@brief Allocates memory for the queue of free buffers.
*
* @details This function is used to allocate buffer from heap
* and put them into the queue
*
* @retval True in case of success. False otherwise.
*/
bool sys_sa_memory_allocate(void);
/**@brief Checks if there are any buffers in the SLAB allocator queue or not.
*
* @details Type of checked buffers shall be passed.
*
* @param[in] type Type of an checked buffers (free or busy).
*
* @retval True in case of absence of buffers. False otherwise.
*/
bool sys_sa_is_empty(sys_slab_buffer_type_t type);
/** @} */
#endif /* SYS_SLAB_ALLOCATOR_H_INCLUDED */

View File

@@ -0,0 +1,155 @@
/**
* Copyright (c) 2016 - 2020 Nordic Semiconductor ASA and Luxoft Global Operations Gmbh.
*
* All Rights Reserved.
*
* 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, except as embedded into a Nordic
* Semiconductor ASA integrated circuit in a product or a software update for
* such product, 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.
*
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* 4. This software, with or without modification, must only be used with a
* Nordic Semiconductor ASA integrated circuit.
*
* 5. Any software provided in binary form under this license must not be reverse
* engineered, decompiled, modified and/or disassembled.
*
*
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 SYS_SLEEP_H_INCLUDED
#define SYS_SLEEP_H_INCLUDED
#include <stdint.h>
#include "sys_events.h"
#include "hal_sleep.h"
/** @file
*
* @defgroup sys_sleep Falling Asleep API
* @ingroup sys_15_4
* @{
* @brief Module for declaring the Falling Asleep API.
* @details Because additional preparation may be required to be done by user modules,
* prior to putting hardware into the sleep mode, a notification and approval mechanism
* is provided to the user.
* Each module that wants to be notified about the "falling asleep" event, has to subscribe
* to the HAL_EVENT_FALLING_ASLEEP event, using sys_sleep_approver_register(), and to
* get the unique approver's ID value.
* In the handler of the HAL_EVENT_FALLING_ASLEEP event, the module is able to perform
* the required preparation before falling asleep, and to approve the falling asleep request,
* using the module unique approver ID, after all preparation to sleep is finished.
* The hardware will fall asleep only after all the registered approvers
* approve the fall asleep request.
*/
/**@brief Approver ID typedef.
*/
typedef uint8_t sys_sleep_approver_id_t;
/* Sanity check for CONFIG_MAX_SLEEP_APPROVERS
*/
#if (!defined(CONFIG_MAX_SLEEP_APPROVERS))
# error "CONFIG_MAX_SLEEP_APPROVERS must be defined in config file"
#elif (CONFIG_MAX_SLEEP_APPROVERS >= 256)
# error "CONFIG_MAX_SLEEP_APPROVERS must be less than 256"
#endif
/**@brief Function for initializing the system sleep module.
*
* @details This function must be called before any usage of the System Sleep module.
*/
void sys_sleep_init(void);
/**@brief Function for registering the approver of the system sleep request.
*
* @details After the sleep approver is registered with this function, the hardware will
* not fall asleep without its approval.
*
* @param[in] p_event_falling_asleep Event descriptor, which will handle
* the SYS_EVENT_FALLING_ASLEEP event.
* @param[in] p_event_wake_up Event descriptor, which will handle
* the SYS_EVENT_WAKE_UP event.
*
* @retval The unique approver ID, reserved for this newly-registered approver.
* This ID will be required to approve system sleep requests by this approver module.
*/
sys_sleep_approver_id_t sys_sleep_approver_register(
sys_event_desc_t * p_event_falling_asleep,
sys_event_desc_t * p_event_wake_up);
/**@brief Function for unregistering the approver of the system sleep request.
*
* @details After the approver is unregistered, its approval will not be
* required to put the system into sleep mode.
*
* @param[in] approver_id The unique approver ID to be unregistered.
* @param[in] p_event_falling_asleep Event descriptor to unsubscribe from
* the SYS_EVENT_FALLING_ASLEEP event.
* @param[in] p_event_wake_up Event descriptor to unsubscribe from
* the SYS_EVENT_WAKE_UP event.
*/
void sys_sleep_approver_unregister(
sys_sleep_approver_id_t approver_id,
sys_event_desc_t * p_event_falling_asleep,
sys_event_desc_t * p_event_wake_up);
/**@brief Function for approving the system sleep request.
*
* @details This function is to be called by the registered approver
* in order to approve putting the system into the sleep mode.
*
* @param[in] approver_id The unique approver ID.
*/
void sys_sleep_approve(sys_sleep_approver_id_t approver_id);
/**@brief Function for requesting the system to safely enter into sleep mode.
*
* @details This function notifies all the registered sleep approvers with the
* HAL_EVENT_FALLING_ASLEEP event, allowing them to perform all the needed preparation
* before the hardware falls asleep. The hardware will enter sleep mode only after
* all registered approvers approve the fall asleep request.
*
* @param[in] sleep_time_ms Defines sleep time in ms.
*/
void sys_sleep_request_ms(uint32_t sleep_time_ms);
/**@brief Function for getting information about the wakeup reason.
*
* @retval hal_wakeup_reason Interrupt source which was the wakeup reason.
*/
hal_wakeup_reason_t sys_sleep_wakeup_reason(void);
/** @} */
#endif // SYS_SLEEP_H_INCLUDED

View File

@@ -0,0 +1,121 @@
/**
* Copyright (c) 2016 - 2020 Nordic Semiconductor ASA and Luxoft Global Operations Gmbh.
*
* All Rights Reserved.
*
* 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, except as embedded into a Nordic
* Semiconductor ASA integrated circuit in a product or a software update for
* such product, 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.
*
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* 4. This software, with or without modification, must only be used with a
* Nordic Semiconductor ASA integrated circuit.
*
* 5. Any software provided in binary form under this license must not be reverse
* engineered, decompiled, modified and/or disassembled.
*
*
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 SYS_TASK_SCHEDULER_H_INCLUDED
#define SYS_TASK_SCHEDULER_H_INCLUDED
#include <stdint.h>
#include <stdbool.h>
#include "sys_utils.h"
#include "hal_atomic.h"
#include "sys_events.h"
/** @file
* @defgroup sys_task_scheduler Task scheduler
* @ingroup sys_15_4
* @{
* @brief Module for task scheduling.
*/
/**@brief Identificators for registered handlers.
*
* Handlers will be called from the task scheduler.
*/
typedef enum
{
PHY_TASK_ID,
HAL_TASK_ID,
#if (CONFIG_HIGHEST_LAYER_PHY == 0)
MAC_TASK_ID,
#endif
APP_TASK_ID,
SYS_TASK_ID,
SYS_TASKS_AMOUNT
} sys_task_ids_t;
/**@brief Prototype of a task handler.
*
* @details Handler which will be called by the scheduler.
*/
typedef void (* sys_task_handler_t)(void);
/**@brief Pending tasks.
*
* @details Variable which includes markers of pending tasks.
*/
extern volatile uint_fast16_t g_tasks;
/**@brief Notify task scheduler to add a task for execution.
*
* @details The function sets a marker for the task for execution.
* The task handler implements a tree architecture.
* Task handler of each layer includes handlers of the layer's components.
*
* @param[in] task_id Task identificator.
*/
static inline void sys_task_post(sys_task_ids_t task_id)
{
atomic_t atomic = 0;
hal_atomic_start(&atomic);
g_tasks |= BIT(task_id);
#if (CONFIG_USE_SYS_TASK_NOTIFIER == 1)
sys_event_post(SYS_EVENT_NEW_TASK, NULL);
#endif
hal_atomic_end(&atomic);
}
/**@brief Returns true, if there are any event flags awaiting in the system scheduler.
*/
static inline bool sys_tasks_pending(void)
{
return g_tasks != 0;
}
/**@brief Handle tasks in the main function.
*
* @details Handle tasks in the main function.
*/
void sys_task_run(void);
/** @} */
#endif // SYS_TASK_SCHEDULER_H_INCLUDED

View File

@@ -0,0 +1,180 @@
/**
* Copyright (c) 2016 - 2020 Nordic Semiconductor ASA and Luxoft Global Operations Gmbh.
*
* All Rights Reserved.
*
* 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, except as embedded into a Nordic
* Semiconductor ASA integrated circuit in a product or a software update for
* such product, 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.
*
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* 4. This software, with or without modification, must only be used with a
* Nordic Semiconductor ASA integrated circuit.
*
* 5. Any software provided in binary form under this license must not be reverse
* engineered, decompiled, modified and/or disassembled.
*
*
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 SYS_TIME_H_INCLUDED
#define SYS_TIME_H_INCLUDED
#include <stdint.h>
#include "sys_queue.h"
/** @file
* This file contains declarations of the primitives to work with Time (timers) and necessary types.
*
* @defgroup sys_time Time API
* @ingroup sys_15_4
* @{
* @brief Module for declaring Time API.
* @details The system time module implements some routines to deal with time (timers). The timer can be started by
* sys_timer_start(), stopped by sys_timer_stop(), and adjusted after sleep by sys_timer_adjust(). Some
* information can be acquired by sys_timer_is_started() and sys_time_get(). The correct API for implementing hardware
* delays is sys_time_delay_us(). Note that the module must be initialized by sys_timers_init() which
* is done by sys_init().
*/
/**@brief Unsigned type of system time.
*/
typedef uint64_t sys_time_t;
/**@brief Signed type of system time.
*/
typedef int64_t sys_signed_time_t;
/**@brief Prototype of the user-defined timer callback.
*
* @param p_data Pointer to the data, specific for this callback.
*/
typedef void (* sys_timer_callback_t)(void * p_data);
/**@brief System timer type (one-shot or periodic timer).
*/
typedef enum
{
SYS_TIMER_ONESHOT, /**< The timer is Oneshot */
SYS_TIMER_PERIODIC /**< The timer is Periodic */
} sys_timer_type_t;
/**@brief Timer descriptor.
*/
typedef struct
{
/** Service field. */
sys_queue_item_t item;
/** Service field. */
sys_time_t absolute_time;
/** Relevant time moment, at which this timer is programmed to be triggered,
* measured in microseconds.
*/
sys_time_t interval;
/** Periodic or one-shot timer.
*
* @details If type is set to SYS_TIMER_PERIODIC, the timer will restart automatically
* with the same period.
*/
sys_timer_type_t type;
/** Timer callback function.
*
* @details This function is to be called, when this timer triggers.
*/
sys_timer_callback_t callback;
/** Timer callback parameter.
*
* @details This pointer is to be passed to the timer callback function.
*/
void * p_data;
} sys_timer_t;
/**@brief Function for initializing the timers module.
*/
void sys_timers_init(void);
/**@brief Function for starting the timer.
*
* @details See the description of \ref sys_timer_t fields for the details
* on how to program the timer.
*
* @param[in] p_timer Pointer to a valid timer descriptor, which is filled by the user,
* according to \ref sys_timer_t fields description.
*/
void sys_timer_start(sys_timer_t * p_timer);
/**@brief Function for stopping the timer.
*
* @details This function is used to stop the timer, which was started earlier.
* After this function is called, the timer will not fire.
*
* @param[in] p_timer Pointer to a valid timer descriptor.
*/
void sys_timer_stop(sys_timer_t * p_timer);
/**@brief Function for checking if input timer has been started.
*
* @param[in] p_timer Pointer to a timer.
*
* @retval true p_timer has been started and has not been stopped yet.
* @retval false p_timer has never been started or already timed out.
*/
bool sys_timer_is_started(sys_timer_t * p_timer);
/**@brief Function for getting the current system time.
*
* @retval The current system timer counter value in microseconds.
*/
sys_time_t sys_time_get(void);
/**@brief Function for implementing a delay for short hardware delays.
*
* @warning Interrupts are NOT disabled inside this function.
*
* @param[in] delay_us Number of microseconds to delay.
*/
void sys_time_delay_us(uint32_t delay_us);
/**@brief Function for executing expired timers after sleep.
*/
void sys_timer_adjust(void);
/** @} */
#endif // SYS_TIME_H_INCLUDED

View File

@@ -0,0 +1,541 @@
/**
* Copyright (c) 2016 - 2020 Nordic Semiconductor ASA and Luxoft Global Operations Gmbh.
*
* All Rights Reserved.
*
* 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, except as embedded into a Nordic
* Semiconductor ASA integrated circuit in a product or a software update for
* such product, 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.
*
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* 4. This software, with or without modification, must only be used with a
* Nordic Semiconductor ASA integrated circuit.
*
* 5. Any software provided in binary form under this license must not be reverse
* engineered, decompiled, modified and/or disassembled.
*
*
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 SYS_UTILS_H_INCLUDED
#define SYS_UTILS_H_INCLUDED
#include <stdint.h>
#include <stddef.h>
#include <string.h>
#if (defined(__GNUC__) && !defined(__SES_ARM))
#include <strings.h>
#endif
#ifdef __MINGW32__
#define ffs __builtin_ffs
#endif
/** @file
* This file contains definitions of useful macros and types.
*
* @defgroup sys_utils System Utilities API
* @ingroup sys_15_4
* @{
* @brief Module to declare System Utilities API.
* @details The System Utilities module implements multiple useful macros and inlines for the whole stack. Including
* this header you will get access to GET_PARENT_BY_FIELD(), FIELD_SIZE() to work with complex structures,
* ARRAY_SIZE() for arrays, mathematics macros like IMP(), LL_MIN(), LL_MAX(), CEIL(), ROUND(), Bitmap helpers
* and many others. The variable arguments support macros are also defined here. Some SWAP routines are implemented
* by this module as well.
*/
/**@brief Returns the pointer to the data structure
*
* @param[in] struct_type name of the parent structure
* @param[in] field_name name of the structure field
* @param[in] field_pointer pointer to the structure field
*
* @retval Pointer to the parent structure which includes the field.
*/
#define GET_PARENT_BY_FIELD(struct_type, field_name, field_pointer) \
((struct_type*)(void*)(((uint8_t*)field_pointer) - offsetof(struct_type, field_name)))
/**@brief Returns the implication of two given expressions x and y.
* @details The implication means: if X==TRUE then Y==TRUE.
* The formula is: (X imp Y) = ((not X) or Y)
*/
#define IMP(x, y) ( !(x) || (y) )
/**@brief Returns the minimum of two given expressions x and y.
*/
#define LL_MIN(x, y) ( ((x) < (y)) ? (x) : (y) )
/**@brief Returns the maximum of two given expressions x and y.
*/
#define LL_MAX(x, y) ( ((x) > (y)) ? (x) : (y) )
/**@brief Returns the quotient of a divided by b rounded upwards to the nearest
* integer.
*/
#define CEIL(a, b) ((a) ? (((a) - 1U) / (b) + 1U) : 0U)
/**@brief Returns the quotient of a divided by b rounded to the nearest integer
* according to the standard arithmetic rules: if the fractional part of (a/b) is greater
* or equal to 0.5 then the result is rounded upwards; if the fractional part of (a/b) is
* less then 0.5 the result is rounded downwards.
*
* @note Use this formula only for unsigned arguments. The formula is not compatible with
* the signed arguments: when a and b have different signs it gives incorrect result.
*/
#define ROUND(a, b) ( ((a) + ((b) >> 1)) / (b) )
/**@brief Declares a long bitmap named name of size bits. The size is rounded
* upwards to come a multiple of 8.
*/
#define BITMAP_DECLARE(name, size) uint8_t name[CEIL(size, 8)]
/**@brief Clears all bits in given bitmap.
*/
#define BITMAP_RESET(name) memset((name), 0U, sizeof(name))
/**@brief Returns the value of a bit at position bit in the long bitmap named name.
*/
#define BITMAP_ISSET(name, bit) ( 0 != ((name)[(bit) >> 3] & (1 << ((bit) & 0x7))) )
/**@brief Sets the bit at position bit in the long bitmap named name.
*/
#define BITMAP_SET(name, bit) (name)[(bit) >> 3] |= (1 << ((bit) & 0x7))
/**@brief Clears the bit at position bit in the long bitmap named name.
*/
#define BITMAP_CLR(name, bit) (name)[(bit) >> 3] &= ~(1 << ((bit) & 0x7))
/**@brief Assigns the given bitmap with the second bitmap.
*/
#define BITMAP_ASSIGN(nameDst, nameSrc) memcpy((nameDst), (nameSrc), sizeof(nameDst))
/**@brief Compares two bitmaps and returns zero if they are equal.
*/
#define BITMAP_EQUAL(name1, name2) ((sizeof(name1) == sizeof(name2)) && \
(memcmp((name1), (name2), sizeof(name1)) == 0))
/**@brief Checks number. Return true if number is power of two.
*/
#define LL_IS_POWER_OF_TWO(name) ((0 != (name)) && (0 == ((name)&(name - 1))))
/**@brief Return True if mask is fully included into a given set and False otherwise
*/
#define IS_SUBSET_OF(mask, set) ((mask) == ((set) & (mask)))
/**@brief Creates a bit mask with single set bit on the specified position.
*/
#define BIT(pos) (1UL << (pos))
/**@brief Gets the given bit in the given value
*/
#define BIT_GET(val, pos) ((((uint32_t)val) & BIT(pos)) != 0)
/**@brief Sets or clears the given bit in the given value
*/
#define BIT_SET(val, pos, bit) { \
if (bit) \
{ \
val |= BIT(pos); \
} \
else \
{ \
val &= ~BIT(pos); \
} \
}
/**@brief Returns two to the income power.*/
#define POWER2(n) (1ULL << (n))
/**@brief Creates a bit mask of specified length.
*/
#define BIT_MASK(len) (BIT(len) - 1UL)
/**@brief Creates a bit field mask of specified length and start position.
*/
#define BIT_FIELD_MASK(start, len) (BIT_MASK(len) << (start))
/**@brief Creates a bit field mask of specified length, start position and value.
*/
#define BIT_FIELD_VALUE(value, start, len) (((value) & BIT_MASK(len)) << (start))
/**@brief Extracts a bit field value of specified start position and length.
*/
#define GET_BITFIELD_VALUE(bitmask, start, len) (((bitmask) >> (start)) & BIT_MASK(len))
/**@brief Inserts a bit field value with specified start position and length.
*/
#define SET_BITFIELD_VALUE(bitmask, start, len, value) \
(bitmask = (bitmask & ~BIT_FIELD_MASK(start, len)) | BIT_FIELD_VALUE(value, start, len))
/**@brief Extracts a mask from a BITMAP.
* BITMAP MUST be aligned and mask length MUST be one of 2, 4, 8, 16, 32.
*/
#define BITMAP_MASK_GET(bitmap, bit, len) \
GET_BITFIELD_VALUE(((uint32_t*)(bitmap))[(bit) >> 5], (bit) & 0x1F, len)
/**@brief Sets up a mask to a BITMAP.
* BITMAP MUST be aligned and mask length MUST be one of 2, 4, 8, 16, 32.
*/
#define BITMAP_MASK_SET(bitmap, bit, len, value) \
SET_BITFIELD_VALUE(((uint32_t*)(bitmap))[(bit) >> 5], (bit) & 0x1F, len, value)
/**@brief Gets amount of the arguments.
*/
#define VA_NARGS(...) VA_NARGS_EVAL(__VA_ARGS__)
#define VA_NARGS_EVAL(...) VA_NARGS_IMPL(__VA_ARGS__, \
/* 255, 254, */ 253, 252, 251, 250, 249, 248, 247, 246, 245, 244, 243, 242, 241, 240, \
239, 238, 237, 236, 235, 234, 233, 232, 231, 230, 229, 228, 227, 226, 225, 224, \
223, 222, 221, 220, 219, 218, 217, 216, 215, 214, 213, 212, 211, 210, 209, 208, \
207, 206, 205, 204, 203, 202, 201, 200, 199, 198, 197, 196, 195, 194, 193, 192, \
191, 190, 189, 188, 187, 186, 185, 184, 183, 182, 181, 180, 179, 178, 177, 176, \
175, 174, 173, 172, 171, 170, 169, 168, 167, 166, 165, 164, 163, 162, 161, 160, \
159, 158, 157, 156, 155, 154, 153, 152, 151, 150, 149, 148, 147, 146, 145, 144, \
143, 142, 141, 140, 139, 138, 137, 136, 135, 134, 133, 132, 131, 130, 129, 128, \
127, 126, 125, 124, 123, 122, 121, 120, 119, 118, 117, 116, 115, 114, 113, 112, \
111, 110, 109, 108, 107, 106, 105, 104, 103, 102, 101, 100, 99, 98, 97, 96, \
095, 94, 93, 92, 91, 90, 89, 88, 87, 86, 85, 84, 83, 82, 81, 80, \
079, 78, 77, 76, 75, 74, 73, 72, 71, 70, 69, 68, 67, 66, 65, 64, \
063, 62, 61, 60, 59, 58, 57, 56, 55, 54, 53, 52, 51, 50, 49, 48, \
047, 46, 45, 44, 43, 42, 41, 40, 39, 38, 37, 36, 35, 34, 33, 32, \
031, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, 16, \
015, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0)
/**@brief Helper macro. Gets amount of the arguments.
*/
#define VA_NARGS_IMPL(_________1, _2, _3, _4, _5, _6, _7, \
_8, _9, _10, _11, _12, _13, _14, _15, \
__16, _17, _18, _19, _20, _21, _22, _23, \
_24, _25, _26, _27, _28, _29, _30, _31, \
__32, _33, _34, _35, _36, _37, _38, _39, \
_40, _41, _42, _43, _44, _45, _46, _47, \
__48, _49, _50, _51, _52, _53, _54, _55, \
_56, _57, _58, _59, _60, _61, _62, _63, \
__64, _65, _66, _67, _68, _69, _70, _71, \
_72, _73, _74, _75, _76, _77, _78, _79, \
__80, _81, _82, _83, _84, _85, _86, _87, \
_88, _89, _90, _91, _92, _93, _94, _95, \
__96, _97, _98, _99, _100, _101, _102, _103, \
_104, _105, _106, _107, _108, _109, _110, _111, \
_112, _113, _114, _115, _116, _117, _118, _119, \
_120, _121, _122, _123, _124, _125, _126, _127, \
_128, _129, _130, _131, _132, _133, _134, _135, \
_136, _137, _138, _139, _140, _141, _142, _143, \
_144, _145, _146, _147, _148, _149, _150, _151, \
_152, _153, _154, _155, _156, _157, _158, _159, \
_160, _161, _162, _163, _164, _165, _166, _167, \
_168, _169, _170, _171, _172, _173, _174, _175, \
_176, _177, _178, _179, _180, _181, _182, _183, \
_184, _185, _186, _187, _188, _189, _190, _191, \
_192, _193, _194, _195, _196, _197, _198, _199, \
_200, _201, _202, _203, _204, _205, _206, _207, \
_208, _209, _210, _211, _212, _213, _214, _215, \
_216, _217, _218, _219, _220, _221, _222, _223, \
_224, _225, _226, _227, _228, _229, _230, _231, \
_232, _233, _234, _235, _236, _237, _238, _239, \
_240, _241, _242, _243, _244, _245, _246, _247, \
_248, _249, _250, _251, _252, _253, /* _254, _255, */\
N, ...) N
/**@brief Gets amount of the arguments. Execute by compiler.
*/
#define VA_NARGS_COMPILE_TIME(...) ((uint8_t)(sizeof((uint8_t[]){ __VA_ARGS__ })/sizeof(uint8_t)))
/**@brief Swaps values.
*/
#define SWAP_XOR(a, b) \
do \
{ \
(((b) ^= (a) ^= (b), (a) ^= (b))); \
} while(0);
/**@brief Compare two number and take care of overflow threshold limit.
*/
#define COMPARE_WITH_THRESHOLD(a, b, threshold) \
(((LL_MAX((a), (b)) - LL_MIN((a), (b))) < (threshold)) ? ((a) >= (b) ? 1 : 0) : ((a) > (b) ? 0 : 1))
#define ROUND_MASK(a) ((a) - 1)
#define ROUND_UP(x, a) (((x) + ROUND_MASK(a)) & ~ROUND_MASK(a))
#define ROUND_DOWN(x, a) ((x) & ~ROUND_MASK(a))
/**@brief Dereferences input pointer \a y as a type \a x.
*
* @param[in] x type name.
* @param[in] y pointer name.
*/
#define DEREF_VOID_PTR_AS(x, y) (*(x *)y)
/**@brief Extends some bit value to the left extending 2's complement value
* to 8-bit length.
*
* @param[out] result variable, where result is store to.
* @param[in] x input value.
* @param[in] sign_pos an integer in range 2..6 specifying bit position of sign bit.
*/
#define SIGN_EXTENSION(result, x, sign_pos) \
do \
{ \
result = x & (1 << sign_pos) ? \
x | (~((1 << (sign_pos + 1)) - 1)) : \
x & ((1 << (sign_pos + 1)) - 1); \
} while (0)
/**@brief Clears some most significant bits of integer value reducing it precision.
* Name and interface of the macro emphasizes complementary action to #SIGN_EXTENSION.
*
* @param[out] result variable, where result is store to.
* @param[in] x input value.
* @param[in] sign_pos an integer in range 2..6 specifying bit position of sign bit.
*/
#define SIGN_COMPRESSION(result, x, sign_pos) \
do \
{ \
result = x & ((1 << (sign_pos + 1)) - 1); \
} while (0)
/************************* PROTOTYPES **************************************************/
/**@brief Swaps values of two bytes.
*
*/
static inline void SWAP8(uint8_t * const x, uint8_t * const y)
{
uint8_t _x = *x;
*x = *y;
*y = _x;
}
/**@brief Swaps values of two double words (DWORD).
*
*/
static inline void SWAP32(uint32_t * const x, uint32_t * const y)
{
uint32_t _x = *x;
*x = *y;
*y = _x;
}
/**@brief Swaps values of two arrays.
*
* @param[inout] x array pointer
* @param[inout] y array pointer
* @param[in] length amount of bytes to swap
*/
static inline void SWAP_ARRAYS(void * x, void * y, uint32_t length)
{
uint8_t *_x = (uint8_t *)(void *)x;
uint8_t *_y = (uint8_t *)(void *)y;
if (0x0 == ((((size_t)_x) | ((size_t)_y)) & 0x3))
{
size_t len4 = length / sizeof(uint32_t);
for (size_t i = 0; i < len4; i++)
{
SWAP32((uint32_t*)_x, (uint32_t*)_y);
_x += sizeof(uint32_t);
_y += sizeof(uint32_t);
}
length &= 0x3;
}
for (size_t i = 0; i < length; i++)
{
SWAP8(_x, _y);
_x++;
_y++;
}
}
/**@brief Find the first bit of the bitmap with the given value
* (one or zero, as specified).
*
* @param[in] p_bitmap Pointer to bitmap.
* @param[in] bitmap_size Number of bits in the bitmap.
* @param[in] bit_value The bit value to find (one or zero).
*
* @retval Bit position of the bit with specified value, or bitmap_size if no such bit
* was found.
*/
static inline size_t bitmap_find_bit(uint8_t * p_bitmap, size_t bitmap_size, uint8_t bit_value)
{
#if (defined(__GNUC__) && !defined(__SES_ARM))
if (bitmap_size <= 32)
{
uint32_t bitmap;
memcpy(&bitmap, p_bitmap, sizeof(uint32_t));
if (!bit_value)
{
bitmap ^= 0xFFFFFFFF;
}
size_t result = ffs(bitmap);
if (result == 0 || result > bitmap_size)
{
return bitmap_size;
}
// built-in ffs implementation gives ffs(1) = 1, not 0
return result - 1;
}
else
#endif
{
for (size_t i = 0; i < bitmap_size; i++)
{
if (BITMAP_ISSET(p_bitmap, i) == bit_value)
{
return i;
}
}
return bitmap_size;
}
}
/**@brief Reverse the elements of array
*
* @param[in] ptr Pointer to array.
* @param[in] len Length of array.
*/
static inline void array_reverse(uint8_t * ptr, size_t len)
{
for (size_t i = 0; i < len/2; i++)
{
SWAP_XOR(ptr[i], ptr[len - 1 - i]);
}
}
/**@brief Returns least significant byte of word.
*/
#define LSB_WORD(x) ((uint8_t)(x & 0xFF))
/**@brief Returns least significant byte of halfword.
*/
#define LSB_HWORD(x) LSB_WORD(x)
/**@brief Returns most significant byte of halfword.
*/
#define MSB_HWORD(x) ((uint8_t)(x >> 8))
#define ALIGN_VALUE (sizeof(size_t))
/**@brief Compiler-independent definitions.
*/
#if defined ( __CC_ARM )
#ifndef __WEAK
#define __WEAK __weak
#endif
#ifndef PACK
#define PACK __attribute__ ((packed))
#endif
#ifndef BEGIN_PACK
#define BEGIN_PACK
#endif
#ifndef END_PACK
#define END_PACK
#endif
#ifndef __ALIGN
#define __ALIGN(n) __align(n)
#endif
#elif defined ( __ICCARM__ )
#ifndef __WEAK
#define __WEAK __weak
#endif
#ifndef PACK
#define PACK
#endif
#ifndef BEGIN_PACK
#define BEGIN_PACK _Pragma("pack(push, 1)")
#endif
#ifndef END_PACK
#define END_PACK _Pragma("pack(pop)")
#endif
#ifndef __ALIGN
#define __ALIGN(n)
#endif
#elif defined ( __GNUC__ )
#ifndef __WEAK
#define __WEAK __attribute__((weak))
#endif
#ifndef PACK
#define PACK __attribute__ ((packed))
#endif
#ifndef BEGIN_PACK
#define BEGIN_PACK _Pragma("pack(push,1)")
#endif
#ifndef END_PACK
#define END_PACK _Pragma("pack(pop)")
#endif
#ifndef __ALIGN
#define __ALIGN(n) __attribute__((aligned(n)))
#endif
#elif defined ( __TASKING__ )
#ifndef __WEAK
#define __WEAK __attribute__((weak))
#endif
#ifndef PACK
#define PACK __attribute__ ((packed))
#endif
#ifndef BEGIN_PACK
#define BEGIN_PACK
#endif
#ifndef END_PACK
#define END_PACK
#endif
#ifndef __ALIGN
#define __ALIGN(n) __align(n)
#endif
#endif
/** @} */
#endif /* SYS_UTILS_H_INCLUDED */