初始版本
This commit is contained in:
146
components/libraries/svc/nrf_svc_function.h
Normal file
146
components/libraries/svc/nrf_svc_function.h
Normal 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__
|
||||
|
||||
/** @} */
|
||||
154
components/libraries/svc/nrf_svc_handler.c
Normal file
154
components/libraries/svc/nrf_svc_handler.c
Normal 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
|
||||
300
components/libraries/svc/nrf_svci.h
Normal file
300
components/libraries/svc/nrf_svci.h
Normal 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__
|
||||
|
||||
|
||||
|
||||
|
||||
/** @} */
|
||||
191
components/libraries/svc/nrf_svci_async_function.h
Normal file
191
components/libraries/svc/nrf_svci_async_function.h
Normal 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__
|
||||
|
||||
/** @} */
|
||||
93
components/libraries/svc/nrf_svci_async_handler.h
Normal file
93
components/libraries/svc/nrf_svci_async_handler.h
Normal 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__
|
||||
|
||||
/** @} */
|
||||
Reference in New Issue
Block a user