初始版本

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,146 @@
/**
* Copyright (c) 2016 - 2020, Nordic Semiconductor ASA
*
* 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.
*
*/
/** @file
*
* @defgroup sdk_nrf_svc_function Supervisor function
* @{
* @ingroup app_common
*
* @brief Macros to create Supervisor functions.
*/
#ifndef NRF_SVC_FUNCTION_H__
#define NRF_SVC_FUNCTION_H__
#include <stdint.h>
#include "nrf_section.h"
#include "app_util.h"
#include "nrf_svci.h"
#ifdef __cplusplus
extern "C" {
#endif
/** @brief Function to be called from an SVC handler.
*
* @warning This function prototype has no arguments. It will be cast to a function prototype
* that has 0 to 4 arguments. 4 arguments is the highest number of allowed arguments in
* a Supervisor call.
*
* @warning The nrf_svc_func_t function prototype should not have void as parameter list as there
* will be 0 to 4 arguments after casting.
*/
typedef uint32_t (*nrf_svc_func_t)();
/** @brief Type holding the SVC number, SVCI number, and the pointer to the corresponding handler
* function.
*
* @note The function that is pointed to must not change version.
*/
typedef struct
{
uint32_t svc_num; /**< Supervisor call number (actually 8-bit, padded for alignment). */
uint32_t svci_num; /**< Supervisor call indirect number. */
nrf_svc_func_t func_ptr;
} nrf_svc_func_reg_t;
// Verify that the size of nrf_svc_func_t is aligned to make sure it can be used in nrf_section.
STATIC_ASSERT(sizeof(nrf_svc_func_reg_t) % 4 == 0);
/** @brief Macro for registering a structure holding SVC number and SVC handler
* function pointer.
*
* @details This macro places a variable in a section named "svc_data" that
* the SVC handler uses during regular operation.
*
* @note This macro must be invoked from a source file. There should only be one
* registration by a given SVC number. SVC number 0 (zero) is invalid input
* and will cause a compile time assertion.
*
* @param[in] name Name of the structure. Logically accessible from the source file.
* @param[in] svc_number SVC number to register.
* @param[in] func Function to call for a given SVC number.
*
* @retval Variable registration in @ref lib_section_vars named svc_data.
*/
#define NRF_SVC_FUNCTION_REGISTER(svc_number, name, func) \
STATIC_ASSERT(svc_number != 0); \
NRF_SECTION_ITEM_REGISTER(svc_data, nrf_svc_func_reg_t const name) = \
{ \
.svc_num = svc_number, \
.svci_num = NRF_SVCI_SVC_NUM_INVALID, \
.func_ptr = (nrf_svc_func_t)func \
}
/** @brief Macro for registering a structure holding SVC number, SVCI number, and SVCI handler
* function pointer.
*
* @details This macro places a variable in a section named "svc_data" that
* the SVC handler uses during regular operation.
*
* @note This macro must be invoked from a source file. There should only be one registration
* for a given SVC indirect number.
*
* @param[in] name Name of the structure. Logically accessible from the source file.
* @param[in] svci_number SVC indirect number to register.
* @param[in] func Function to call for a given SVC indirect number.
*
* @retval Variable registration in @ref lib_section_vars named svc_data.
*/
#define NRF_SVCI_FUNCTION_REGISTER(svci_number, name, func) \
NRF_SECTION_ITEM_REGISTER(svc_data, nrf_svc_func_reg_t const name) = \
{ \
.svc_num = NRF_SVCI_SVC_NUM, \
.svci_num = svci_number, \
.func_ptr = (nrf_svc_func_t)func \
}
#ifdef __cplusplus
}
#endif
#endif // NRF_SVC_FUNCTION_H__
/** @} */

View File

@@ -0,0 +1,154 @@
/**
* Copyright (c) 2016 - 2020, Nordic Semiconductor ASA
*
* 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.
*
*/
#include <stdbool.h>
#include <stdint.h>
#include "nrf_svc_function.h"
#include "nrf_error.h"
//lint -esym(526, svc_dataBase) -esym(526, svc_dataLimit)
NRF_SECTION_DEF(svc_data, const nrf_svc_func_t);
#define SVC_DATA_SECTION_ITEM_GET(i) NRF_SECTION_ITEM_GET(svc_data, nrf_svc_func_reg_t, (i))
#define SVC_DATA_SECTION_ITEM_COUNT NRF_SECTION_ITEM_COUNT(svc_data, nrf_svc_func_reg_t)
#ifdef __GNUC__
// Prevent GCC from removing this function (called from assembly branch)
void nrf_svc_handler_c(uint32_t* p_svc_args) __attribute__((used));
#endif
/**@brief Function for handling second stage of Supervisor Calls (SVC).
*
* @details The function will use loop through the registered svc functions stored
* in the named section "svc_data" and will call the registered function
* if the svn_num corresponds with the registration.
*
* @param[in] p_svc_args Argument list for the SVC.
*
* @return This function returns by updating p_svc_arsg[0]. This will be reported back to the caller of SVC
* @ref NRF_ERROR_SVC_HANDLER_MISSING is returned if no SVC handler is implemented for the
* provided svc_num.
*/
void nrf_svc_handler_c(uint32_t* p_svc_args)
{
uint32_t const num_funcs = SVC_DATA_SECTION_ITEM_COUNT;
bool handled = false;
uint8_t const svc_num = ((uint8_t *)p_svc_args[6])[-2];
uint32_t svci_num = NRF_SVCI_SVC_NUM_INVALID;
if (svc_num == NRF_SVCI_SVC_NUM)
{
// load the stacked R12 as the svci_num
svci_num = p_svc_args[4];
}
for (uint32_t i = 0; i < num_funcs; i++)
{
nrf_svc_func_reg_t const * func_reg = SVC_DATA_SECTION_ITEM_GET(i);
if (func_reg->svc_num != svc_num)
{
continue;
}
if (svci_num != NRF_SVCI_SVC_NUM_INVALID && func_reg->svci_num != svci_num)
{
continue;
}
// Return value is placed in R0
p_svc_args[0] = func_reg->func_ptr(p_svc_args[0], p_svc_args[1], p_svc_args[2], p_svc_args[3]);
handled = true;
break;
}
if (handled == false)
{
// Return value is placed in R0
p_svc_args[0] = NRF_ERROR_SVC_HANDLER_MISSING;
}
}
/**@brief Function for handling the first stage of Supervisor Calls (SVC) in assembly.
*
* @details The function will use the link register (LR) to determine the stack (PSP or MSP) to be
* used and then decode the SVC number afterwards. After decoding the SVC number,
* @ref C_SVC_Handler is called for further processing of the SVC.
*/
#if defined ( __CC_ARM )
__ASM void SVC_Handler(void)
{
tst lr, #4 ; Test bit 2 of EXT_RETURN to see if MSP or PSP is used
ite eq ;
mrseq r0, MSP ; If equal, copy stack pointer from MSP
mrsne r0, PSP ; If not equal, copy stack pointer from PSP
B __cpp(nrf_svc_handler_c) ; Call C-implementation of handler. Exception stack frame in R0
ALIGN 4 ; Protect with alignment
}
#elif defined ( __GNUC__ )
void __attribute__((naked)) SVC_Handler(void)
{
__ASM volatile
(
"tst lr, #4\t\n" // Test bit 2 of EXT_RETURN to see if MSP or PSP is used
"ite eq\t\n" //
"mrseq r0, MSP\t\n" // Move MSP into R0.
"mrsne r0, PSP\t\n" // Move PSP into R0.
"b nrf_svc_handler_c\t\n" // Call C-implementation of handler. Exception stack frame in R0
".align\t\n" // Protect with alignment
);
}
#elif defined ( __ICCARM__ )
void SVC_Handler(void)
{
__ASM volatile
(
"tst lr, #4\t\n" // Test bit in link register responsible for stack indication.
"ite eq\t\n" // Test bit 2 of EXT_RETURN to see if MSP or PSP is used
"mrseq r0, MSP\t\n" // Move MSP into R0.
"mrsne r0, PSP\t\n" // Move PSP into R0.
"b nrf_svc_handler_c\t\n" : // Call C-implementation of handler. Exception stack frame in R0
);
}
#else
#error Compiler not supported.
#endif

View File

@@ -0,0 +1,300 @@
/**
* Copyright (c) 2016 - 2020, Nordic Semiconductor ASA
*
* 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.
*
*/
/** @file
*
* @defgroup sdk_nrf_svci Supervisor instructions with indirect number
* @{
* @ingroup app_common
*
* @brief Macros to create Supervisor instructions using indirect number.
*/
#ifndef NRF_SVCI_H__
#define NRF_SVCI_H__
#include "stdint.h"
#include "compiler_abstraction.h"
#include "app_util.h"
#ifdef __cplusplus
extern "C" {
#endif
#define NRF_SVCI_SVC_NUM 0 /**< SVC number used for all SVCI functions. */
#define NRF_SVCI_SVC_NUM_INVALID (0xFFFFFFFF) /**< Invalid SVCI number. */
#ifdef __cplusplus
#define GCC_CAST_CPP (uint16_t)
#else
#define GCC_CAST_CPP
#endif
#if (__LINT__ != 1)
#if defined (__CC_ARM)
#define SVCI_DECL(svci_num, return_type, function_name, ...) \
return_type __svc_indirect(NRF_SVCI_SVC_NUM) \
svci_ ## function_name(uint32_t _svci_num, ##__VA_ARGS__);
#define SVCI_DECL_0(svci_num, return_type, function_name) \
return_type __svc_indirect(NRF_SVCI_SVC_NUM) \
svci_ ## function_name(uint32_t _svci_num);
#define SVCI_0(svci_num, return_type, function_name) \
SVCI_DECL_0(svci_num, return_type, function_name) \
static __INLINE return_type function_name(void) \
{ \
return svci_ ## function_name(svci_num); \
}
#define SVCI_1(svci_num, return_type, function_name, p0t, p0n) \
SVCI_DECL(svci_num, return_type, function_name, p0t p0n) \
static __INLINE return_type function_name(p0t p0n) \
{ \
return svci_ ## function_name(svci_num, p0n); \
}
#define SVCI_2(svci_num, return_type, function_name, p0t, p0n, p1t, p1n) \
SVCI_DECL(svci_num, return_type, function_name, p0t p0n, p1t p1n) \
static __INLINE return_type function_name(p0t p0n, p1t p1n) \
{ \
return svci_ ## function_name(svci_num, p0n, p1n); \
}
#define SVCI_3(svci_num, return_type, function_name, p0t, p0n, p1t, p1n, p2t, p2n) \
SVCI_DECL(svci_num, return_type, function_name, p0t p0n, p1t p1n, p2t p2n) \
static __INLINE return_type function_name(p0t p0n, p1t p1n, p2t p2n) \
{ \
return svci_ ## function_name(svci_num, p0n, p1n, p2n); \
}
#define SVCI_4(svci_num, return_type, function_name, p0t, p0n, p1t, p1n, p2t, p2n, p3t, p3n) \
SVCI_DECL(svci_num, return_type, function_name, p0t p0n, p1t p1n, p2t p2n, p3t p3n) \
static __INLINE return_type function_name(p0t p0n, p1t p1n, p2t p2n, p3t p3n) \
{ \
return svci_ ## function_name(svci_num, p0n, p1n, p2n, p3n); \
}
#else
#if defined (__GNUC__)
#define SVCI_DECL_0(svci_num, return_type, function_name) \
_Pragma("GCC diagnostic push") \
_Pragma("GCC diagnostic ignored \"-Wreturn-type\"") \
__attribute__((naked, unused)) \
static return_type svci_ ## function_name(void) \
{ \
/* Do the SuperVisor call by using svc instruction with \
R12 containing the SVCI number */ \
__ASM __volatile \
( \
" ldr r12, =%0 \n" \
" svc %1 \n" \
" bx lr \n" \
" .ltorg" \
: /* output */ \
: /* input */ \
"X"(svci_num), \
"I"(GCC_CAST_CPP NRF_SVCI_SVC_NUM) \
: /* clobbers */ \
"r12" \
); \
} \
_Pragma("GCC diagnostic pop")
#define SVCI_DECL(svci_num, return_type, function_name, ...) \
_Pragma("GCC diagnostic push") \
_Pragma("GCC diagnostic ignored \"-Wreturn-type\"") \
__attribute__((naked, unused)) \
static return_type svci_ ## function_name(__VA_ARGS__) \
{ \
/* Do the SuperVisor call by using svc instruction with \
R12 containing the SVCI number */ \
__ASM __volatile \
( \
" ldr.w r12, =%0 \n" \
" svc %1 \n" \
" bx lr \n" \
" .ltorg" \
: /* output */ \
: /* input */ \
"X"(svci_num), \
"I"(GCC_CAST_CPP NRF_SVCI_SVC_NUM) \
: /* clobbers */ \
"r12" \
); \
} \
_Pragma("GCC diagnostic pop")
#elif defined (__ICCARM__)
#define SVCI_DECL_0(svci_num, return_type, function_name) \
/* Suppress return value warning. */ \
_Pragma("diag_suppress=Pe940") \
static __root return_type svci_ ## function_name(void) \
{ \
/* Do the SuperVisor call by using svc instruction with \
R12 containing the SVCI number */ \
__ASM volatile \
( \
" mov r12, %0 \n" \
" svc %1 \n" \
: /*no output*/ \
: "r" (svci_num), "I" (NRF_SVCI_SVC_NUM) \
: \
); \
}
#define SVCI_DECL(svci_num, return_type, function_name, ...) \
/* Suppress return value warning. */ \
_Pragma("diag_suppress=Pe940") \
static __root return_type svci_ ## function_name(__VA_ARGS__) \
{ \
/* We stack r0-r3 as r0 is used to set high register (r12) \
This CODE MUST BE IN ITS OWN __ASM BLOCK! */ \
__ASM volatile ( "push {r0, r1, r2, r3}\n\t" ); \
/* Set R12 to the svc_number, this will use r0 as indirect \
* storage. Pop r0-r3 to reset value before SVCI. */ \
__ASM volatile \
( \
" mov r12, %0 \n" \
" pop {r0, r1, r2, r3} \n" \
: /*no output */ \
: "r" (svci_num) \
: \
); \
/* Do the SuperVisor call by using svc instruction with \
R12 containing the SVCI number */ \
__ASM volatile \
( \
" svc %0 \n" \
" bx lr \n" \
: /*no output*/ \
: "I" (NRF_SVCI_SVC_NUM) \
: \
); \
}
#else // Not defined (__ICCARM__) or defined (__GNUC__)
#error Unsupported compiler for SVCI interface
#endif // Not defined (__ICCARM__) or defined (__GNUC__)
#define SVCI_0(svci_num, return_type, function_name) \
SVCI_DECL_0(svci_num, return_type, function_name) \
static __INLINE return_type function_name(void) \
{ \
return svci_ ## function_name(); \
}
#define SVCI_1(svci_num, return_type, function_name, p0t, p0n) \
SVCI_DECL(svci_num, return_type, function_name, p0t p0n) \
static __INLINE return_type function_name(p0t p0n) \
{ \
return svci_ ## function_name(p0n); \
}
#define SVCI_2(svci_num, return_type, function_name, p0t, p0n, p1t, p1n) \
SVCI_DECL(svci_num, return_type, function_name, p0t p0n, p1t p1n) \
static __INLINE return_type function_name(p0t p0n, p1t p1n) \
{ \
return svci_ ## function_name(p0n, p1n); \
}
#define SVCI_3(svci_num, return_type, function_name, p0t, p0n, p1t, p1n, p2t, p2n) \
SVCI_DECL(svci_num, return_type, function_name, p0t p0n, p1t p1n, p2t p2n) \
static __INLINE return_type function_name(p0t p0n, p1t p1n, p2t p2n) \
{ \
return svci_ ## function_name(p0n, p1n, p2n); \
}
#define SVCI_4(svci_num, return_type, function_name, p0t, p0n, p1t, p1n, p2t, p2n, p3t, p3n) \
SVCI_DECL(svci_num, return_type, function_name, p0t p0n, p1t p1n, p2t p2n, p3t p3n) \
static __INLINE return_type function_name(p0t p0n, p1t p1n, p2t p2n, p3t p3n) \
{ \
return svci_ ## function_name(p0n, p1n, p2n, p3n); \
}
#endif // Not __CC_ARM
#define VA_NARGS_IMPL(_0, _1, _2, _3, _4, _5, _6, _7, _8, N, ...) N
#define VA_NARGS(...) VA_NARGS_IMPL(__VA_ARGS__, 4, 4, 3, 3, 2, 2, 1, 1, 0)
#ifdef SVCALL_INDIRECT_AS_NORMAL_FUNCTION
#define SVCI(svci_num, return_type, function_name, ...) \
return_type function_name(##__VA_ARGS__)
#else
#define SVCI_IMPLI(count, svci_num, return_type, function_name, ...) \
SVCI##_##count (svci_num, return_type, function_name, ##__VA_ARGS__)
#define SVCI_IMPL(count, svci_num, return_type, function_name, ...) \
SVCI_IMPLI(count, svci_num, return_type, function_name, ##__VA_ARGS__)
#define SVCI(svci_num, return_type, function_name, ...) \
SVCI_IMPL(VA_NARGS(__VA_ARGS__), svci_num, return_type, function_name, ##__VA_ARGS__)
#endif // SVCALL_INDIRECT_AS_NORMAL_FUNCTION
#else // (__LINT__ == 1)
#define SVCI(svci_num, return_type, function_name, ...)
#endif
#ifdef __cplusplus
}
#endif
#endif // NRF_SVCI_H__
/** @} */

View File

@@ -0,0 +1,191 @@
/**
* Copyright (c) 2017 - 2020, Nordic Semiconductor ASA
*
* 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.
*
*/
/** @file
*
* @defgroup sdk_nrf_svci_async_function Asynchronous Supervisor function interface
* @{
* @ingroup app_common
*
* @brief Macros to create Asynchronous Supervisor interface functions.
*/
#ifndef NRF_SVC_ASYNC_FUNCTION_H__
#define NRF_SVC_ASYNC_FUNCTION_H__
#include "nrf_svci.h"
#include "nrf_svci_async_handler.h"
#ifdef __cplusplus
extern "C" {
#endif
/**@brief Macro for creating type definition for SVCI interface init function.
*
* @warning Do not call this macro directly! Use @ref NRF_SVCI_ASYNC_FUNC_DECLARE instead.
*
* @param[in] name Name of async request function. Will be appended with _async_fn_t.
* @param[in] param_type Parameter type.
* @param[in] state_type State type.
*
* @retval Type definition a named SVCI async init function.
*/
#define NRF_SVCI_ACYNC_FUNC_TYPEDEF(name, param_type, state_type) \
typedef uint32_t (* name ## _async_fn_t)(param_type * p_param, state_type * p_state)
/**@brief Macro for creating type definition for SVCI interface event function.
*
* @warning Do not call this macro directly! Use @ref NRF_SVCI_ASYNC_FUNC_DECLARE instead.
*
* @details Calling this function with sys-events will report @ref NRF_ERROR_BUSY until
* the asynchronous calls is finished, at which time it will report either
* NRF_SUCCESS or any another error-message.
*
* @param[in] name Name of the event function. Will be appended with _event_fn_t
* @param[in] state_type Type parameter for the state.
*
* @retval Type definition for a named SVCI async event function.
*/
#define NRF_SVCI_ASYNC_EVENT_FUNC_TYPEDEF(name, state_type) \
typedef uint32_t (* name ## _event_fn_t)(uint32_t sys_evt, state_type * p_state)
/**@brief Macro for creating a declaration of a named async function for the SVCI interface.
*
* @details The async interface provides a method to call into a external application
* through the SVCI interface without relying on allocated or reserved memory inside the
* external application.
*
* This macro declares variables and function types in use by the async SVCI interface.
*
* @note This is intended to be invoked in a header file shared by both the
* caller and the recipient (handler).
*
* @param[in] svci_num SVC indirect number.
* @param[in] name Name of the async function.
* @param[in] param_type Type of the param used for the async interface.
* @param[in] state_type Type of the state used for the async interface.
*
* @retval A type definition of NAME_svc_async_t to be used for async access
* through the SVCI interface.
*/
#define NRF_SVCI_ASYNC_FUNC_DECLARE(svci_num, \
name, \
param_type, \
state_type) \
/*lint --e{19} */ \
NRF_SVCI_ACYNC_FUNC_TYPEDEF(name, param_type, state_type); \
NRF_SVCI_ASYNC_EVENT_FUNC_TYPEDEF(name, state_type); \
\
typedef struct \
{ \
name ## _async_fn_t async_func; \
name ## _event_fn_t sys_evt_handler; \
state_type state; \
} name ## _svci_async_t;
//lint -save --e{10, 19, 40, 102} -esym(526, *_init) -esym(628, *_init)
/**@brief Macro for defining a named SVCI async interface.
*
* @details The async interface provides a method to call into an external application
* through the SVCI interface without relying on allocated or reserved memory inside the
* external application.
*
* Running this macro creates a defintion of the structure that holds the
* information about the async function, the event handler, and the state.
*
* Running this macro also defines convenience functions to the SVCI interface.
*
* The available functions are:
* -NAME_init - Function to call to set up the async SVCI interface.
* -NAME - Function to call the async SVCI interface.
* -NAME_on_sys_event - Function to report sys events to the async
* SVCI interface.
* -NAME_is_initialized - Function to check if the async SVCI interface is
* initialized and ready to use.
*
* @note Invoking this macro is only possible in a source file as the macro creates
* a static variable for the async interface as well as static functions to call
* into the async interface.
*
* @param[in] svci_num SVC indirect number.
* @param[in] name Name of the async function.
* @param[in] param_type Type of the param used for the async interface.
*
* @retval Instance of the async SVCI interface and convenience functions for using it.
*/
#define NRF_SVCI_ASYNC_FUNC_DEFINE(svci_num, name, param_type) \
\
SVCI(svci_num, uint32_t, name ## _svci_async_init, name ## _svci_async_t *, p_async); \
static name ## _svci_async_t name ## _svci_async_def = {0}; \
\
static __INLINE uint32_t name ## _init (void) \
{ \
return name ## _svci_async_init(&name ## _svci_async_def); \
} \
\
static __INLINE uint32_t name(param_type * p_param) \
{ \
return name ## _svci_async_def.async_func(p_param, &name ## _svci_async_def.state); \
} \
\
static __INLINE uint32_t name ## _on_sys_evt(uint32_t sys_evt) \
{ \
return name ## _svci_async_def.sys_evt_handler(sys_evt, &name ## _svci_async_def.state); \
} \
\
static __INLINE uint32_t name ## _is_initialized(void) \
{ \
return (name ## _svci_async_def.async_func != NULL && \
name ## _svci_async_def.sys_evt_handler != NULL ); \
}
//lint -restore
#ifdef __cplusplus
}
#endif
#endif // NRF_SVC_ASYNC_FUNCTION_H__
/** @} */

View File

@@ -0,0 +1,93 @@
/**
* Copyright (c) 2016 - 2020, Nordic Semiconductor ASA
*
* 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.
*
*/
/** @file
*
* @defgroup sdk_nrf_svci_async_handler Asynchronous Supervisor handler functions
* @{
* @ingroup app_common
*
* @brief Macros to create Asynchronous Supervisor interface handler functions.
*/
#ifndef NRF_SVCI_ASYNC_HANDLER_H__
#define NRF_SVCI_ASYNC_HANDLER_H__
#include "nrf_svc_function.h"
#ifdef __cplusplus
extern "C" {
#endif
/**@brief Macro for creating a registration for an async handler for the SVCI interface
*
* @details Calling this macro will register a SVCI function handler using @ref
* NRF_SVCI_FUNCTION_REGISTER
*
* @note This macro must be invoked from a source file as it declares static functions
* to be implemented and because it creates a @ref lib_section_vars registration to
* SVCI interface which is intended to be unique.
*
* @param[in] svci_num SVC indirect number.
* @param[in] name Name of the async function.
* @param[in] param_type Type of the param to send when running the async interface.
* @param[in] state_type Type of the state to be called together with sys_event.
*
* @retval Static declarations to handler functions to be implemented in the form NAME_handler
* NAME_on_call, and NAME_on_sys_event.
*/
#define NRF_SVCI_ASYNC_HANDLER_CREATE(svci_num, \
name, \
param_type, \
state_type) \
\
static uint32_t name ## _handler(name ## _svci_async_t * p_async); \
static uint32_t name ## _on_call(param_type * p_param, state_type * p_state); \
static uint32_t name ## _on_sys_evt(uint32_t sys_event, state_type * p_state); \
\
NRF_SVCI_FUNCTION_REGISTER(svci_num, name ## _var, name ## _handler)
#ifdef __cplusplus
}
#endif
#endif // NRF_SVCI_ASYNC_HANDLER_H__
/** @} */