Переструктурирован проект. Сурсы вынесены за этот гит. Здесь осталась только оболочка
также был тест компилятора mingw, следующие ошибки: - переопределение __INT64_C, __UINT64_C - и еше какие-то проблемы с intmax_t uintmax_t
This commit is contained in:
10
MCU.mexw64.manifest
Normal file
10
MCU.mexw64.manifest
Normal file
@@ -0,0 +1,10 @@
|
||||
<?xml version='1.0' encoding='UTF-8' standalone='yes'?>
|
||||
<assembly xmlns='urn:schemas-microsoft-com:asm.v1' manifestVersion='1.0'>
|
||||
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
|
||||
<security>
|
||||
<requestedPrivileges>
|
||||
<requestedExecutionLevel level='asInvoker' uiAccess='false' />
|
||||
</requestedPrivileges>
|
||||
</security>
|
||||
</trustInfo>
|
||||
</assembly>
|
||||
@@ -0,0 +1,414 @@
|
||||
/*
|
||||
* Copyright (c) 2016, 2019 ARM Limited.
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to
|
||||
* deal in the Software without restriction, including without limitation the
|
||||
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
* sell copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
#ifndef __ARM_COMPUTE_NEMATH_H__
|
||||
#define __ARM_COMPUTE_NEMATH_H__
|
||||
|
||||
|
||||
#if defined(ARM_MATH_NEON)
|
||||
/** Calculate floor of a vector.
|
||||
*
|
||||
* @param[in] val Input vector value in F32 format.
|
||||
*
|
||||
* @return The calculated floor vector.
|
||||
*/
|
||||
static inline float32x4_t vfloorq_f32(float32x4_t val);
|
||||
|
||||
/** Calculate inverse square root.
|
||||
*
|
||||
* @param[in] x Input value.
|
||||
*
|
||||
* @return The calculated inverse square root.
|
||||
*/
|
||||
static inline float32x2_t vinvsqrt_f32(float32x2_t x);
|
||||
|
||||
/** Calculate inverse square root.
|
||||
*
|
||||
* @param[in] x Input value.
|
||||
*
|
||||
* @return The calculated inverse square root.
|
||||
*/
|
||||
static inline float32x4_t vinvsqrtq_f32(float32x4_t x);
|
||||
|
||||
/** Calculate reciprocal.
|
||||
*
|
||||
* @param[in] x Input value.
|
||||
*
|
||||
* @return The calculated reciprocal.
|
||||
*/
|
||||
static inline float32x2_t vinv_f32(float32x2_t x);
|
||||
|
||||
/** Calculate reciprocal.
|
||||
*
|
||||
* @param[in] x Input value.
|
||||
*
|
||||
* @return The calculated reciprocal.
|
||||
*/
|
||||
static inline float32x4_t vinvq_f32(float32x4_t x);
|
||||
|
||||
/** Perform a 7th degree polynomial approximation using Estrin's method.
|
||||
*
|
||||
* @param[in] x Input vector value in F32 format.
|
||||
* @param[in] coeffs Polynomial coefficients table. (array of flattened float32x4_t vectors)
|
||||
*
|
||||
* @return The calculated approximation.
|
||||
*/
|
||||
static inline float32x4_t vtaylor_polyq_f32(float32x4_t x, const float32_t *coeffs);
|
||||
|
||||
/** Calculate exponential
|
||||
*
|
||||
* @param[in] x Input vector value in F32 format.
|
||||
*
|
||||
* @return The calculated exponent.
|
||||
*/
|
||||
static inline float32x4_t vexpq_f32(float32x4_t x);
|
||||
|
||||
/** Calculate logarithm
|
||||
*
|
||||
* @param[in] x Input vector value in F32 format.
|
||||
*
|
||||
* @return The calculated logarithm.
|
||||
*/
|
||||
static inline float32x4_t vlogq_f32(float32x4_t x);
|
||||
|
||||
/** Calculate hyperbolic tangent.
|
||||
*
|
||||
* tanh(x) = (e^2x - 1)/(e^2x + 1)
|
||||
*
|
||||
* @note We clamp x to [-5,5] to avoid overflowing issues.
|
||||
*
|
||||
* @param[in] val Input vector value in F32 format.
|
||||
*
|
||||
* @return The calculated Hyperbolic Tangent.
|
||||
*/
|
||||
static inline float32x4_t vtanhq_f32(float32x4_t val);
|
||||
|
||||
/** Calculate n power of a number.
|
||||
*
|
||||
* pow(x,n) = e^(n*log(x))
|
||||
*
|
||||
* @param[in] val Input vector value in F32 format.
|
||||
* @param[in] n Powers to raise the input to.
|
||||
*
|
||||
* @return The calculated power.
|
||||
*/
|
||||
static inline float32x4_t vpowq_f32(float32x4_t val, float32x4_t n);
|
||||
|
||||
#ifdef __ARM_FEATURE_FP16_VECTOR_ARITHMETIC
|
||||
/** Calculate hyperbolic tangent.
|
||||
*
|
||||
* tanh(x) = (e^2x - 1)/(e^2x + 1)
|
||||
*
|
||||
* @note We clamp x to [-5,5] to avoid overflowing issues.
|
||||
*
|
||||
* @param[in] val Input vector value in F32 format.
|
||||
*
|
||||
* @return The calculated Hyperbolic Tangent.
|
||||
*/
|
||||
static inline float16x8_t vtanhq_f16(float16x8_t val);
|
||||
|
||||
/** Calculate reciprocal.
|
||||
*
|
||||
* @param[in] x Input value.
|
||||
*
|
||||
* @return The calculated reciprocal.
|
||||
*/
|
||||
static inline float16x4_t vinv_f16(float16x4_t x);
|
||||
|
||||
/** Calculate reciprocal.
|
||||
*
|
||||
* @param[in] x Input value.
|
||||
*
|
||||
* @return The calculated reciprocal.
|
||||
*/
|
||||
static inline float16x8_t vinvq_f16(float16x8_t x);
|
||||
|
||||
/** Calculate inverse square root.
|
||||
*
|
||||
* @param[in] x Input value.
|
||||
*
|
||||
* @return The calculated inverse square root.
|
||||
*/
|
||||
static inline float16x4_t vinvsqrt_f16(float16x4_t x);
|
||||
|
||||
/** Calculate inverse square root.
|
||||
*
|
||||
* @param[in] x Input value.
|
||||
*
|
||||
* @return The calculated inverse square root.
|
||||
*/
|
||||
static inline float16x8_t vinvsqrtq_f16(float16x8_t x);
|
||||
|
||||
/** Calculate exponential
|
||||
*
|
||||
* @param[in] x Input vector value in F16 format.
|
||||
*
|
||||
* @return The calculated exponent.
|
||||
*/
|
||||
static inline float16x8_t vexpq_f16(float16x8_t x);
|
||||
|
||||
/** Calculate n power of a number.
|
||||
*
|
||||
* pow(x,n) = e^(n*log(x))
|
||||
*
|
||||
* @param[in] val Input vector value in F16 format.
|
||||
* @param[in] n Powers to raise the input to.
|
||||
*
|
||||
* @return The calculated power.
|
||||
*/
|
||||
static inline float16x8_t vpowq_f16(float16x8_t val, float16x8_t n);
|
||||
#endif /* __ARM_FEATURE_FP16_VECTOR_ARITHMETIC */
|
||||
|
||||
/** Exponent polynomial coefficients */
|
||||
extern const float32_t exp_tab[4*8];
|
||||
|
||||
|
||||
/** Logarithm polynomial coefficients */
|
||||
extern const float32_t log_tab[4*8];
|
||||
|
||||
#ifndef DOXYGEN_SKIP_THIS
|
||||
inline float32x4_t vfloorq_f32(float32x4_t val)
|
||||
{
|
||||
static const float32_t CONST_1[4] = {1.f,1.f,1.f,1.f};
|
||||
|
||||
const int32x4_t z = vcvtq_s32_f32(val);
|
||||
const float32x4_t r = vcvtq_f32_s32(z);
|
||||
|
||||
return vbslq_f32(vcgtq_f32(r, val), vsubq_f32(r, vld1q_f32(CONST_1)), r);
|
||||
}
|
||||
|
||||
inline float32x2_t vinvsqrt_f32(float32x2_t x)
|
||||
{
|
||||
float32x2_t sqrt_reciprocal = vrsqrte_f32(x);
|
||||
sqrt_reciprocal = vmul_f32(vrsqrts_f32(vmul_f32(x, sqrt_reciprocal), sqrt_reciprocal), sqrt_reciprocal);
|
||||
sqrt_reciprocal = vmul_f32(vrsqrts_f32(vmul_f32(x, sqrt_reciprocal), sqrt_reciprocal), sqrt_reciprocal);
|
||||
|
||||
return sqrt_reciprocal;
|
||||
}
|
||||
|
||||
inline float32x4_t vinvsqrtq_f32(float32x4_t x)
|
||||
{
|
||||
float32x4_t sqrt_reciprocal = vrsqrteq_f32(x);
|
||||
sqrt_reciprocal = vmulq_f32(vrsqrtsq_f32(vmulq_f32(x, sqrt_reciprocal), sqrt_reciprocal), sqrt_reciprocal);
|
||||
sqrt_reciprocal = vmulq_f32(vrsqrtsq_f32(vmulq_f32(x, sqrt_reciprocal), sqrt_reciprocal), sqrt_reciprocal);
|
||||
|
||||
return sqrt_reciprocal;
|
||||
}
|
||||
|
||||
inline float32x2_t vinv_f32(float32x2_t x)
|
||||
{
|
||||
float32x2_t recip = vrecpe_f32(x);
|
||||
recip = vmul_f32(vrecps_f32(x, recip), recip);
|
||||
recip = vmul_f32(vrecps_f32(x, recip), recip);
|
||||
return recip;
|
||||
}
|
||||
|
||||
inline float32x4_t vinvq_f32(float32x4_t x)
|
||||
{
|
||||
float32x4_t recip = vrecpeq_f32(x);
|
||||
recip = vmulq_f32(vrecpsq_f32(x, recip), recip);
|
||||
recip = vmulq_f32(vrecpsq_f32(x, recip), recip);
|
||||
return recip;
|
||||
}
|
||||
|
||||
inline float32x4_t vtaylor_polyq_f32(float32x4_t x, const float32_t *coeffs)
|
||||
{
|
||||
float32x4_t A = vmlaq_f32(vld1q_f32(&coeffs[4*0]), vld1q_f32(&coeffs[4*4]), x);
|
||||
float32x4_t B = vmlaq_f32(vld1q_f32(&coeffs[4*2]), vld1q_f32(&coeffs[4*6]), x);
|
||||
float32x4_t C = vmlaq_f32(vld1q_f32(&coeffs[4*1]), vld1q_f32(&coeffs[4*5]), x);
|
||||
float32x4_t D = vmlaq_f32(vld1q_f32(&coeffs[4*3]), vld1q_f32(&coeffs[4*7]), x);
|
||||
float32x4_t x2 = vmulq_f32(x, x);
|
||||
float32x4_t x4 = vmulq_f32(x2, x2);
|
||||
float32x4_t res = vmlaq_f32(vmlaq_f32(A, B, x2), vmlaq_f32(C, D, x2), x4);
|
||||
return res;
|
||||
}
|
||||
|
||||
inline float32x4_t vexpq_f32(float32x4_t x)
|
||||
{
|
||||
static const float32_t CONST_LN2[4] = {0.6931471805f,0.6931471805f,0.6931471805f,0.6931471805f}; // ln(2)
|
||||
static const float32_t CONST_INV_LN2[4] = {1.4426950408f,1.4426950408f,1.4426950408f,1.4426950408f}; // 1/ln(2)
|
||||
static const float32_t CONST_0[4] = {0.f,0.f,0.f,0.f};
|
||||
static const int32_t CONST_NEGATIVE_126[4] = {-126,-126,-126,-126};
|
||||
|
||||
// Perform range reduction [-log(2),log(2)]
|
||||
int32x4_t m = vcvtq_s32_f32(vmulq_f32(x, vld1q_f32(CONST_INV_LN2)));
|
||||
float32x4_t val = vmlsq_f32(x, vcvtq_f32_s32(m), vld1q_f32(CONST_LN2));
|
||||
|
||||
// Polynomial Approximation
|
||||
float32x4_t poly = vtaylor_polyq_f32(val, exp_tab);
|
||||
|
||||
// Reconstruct
|
||||
poly = vreinterpretq_f32_s32(vqaddq_s32(vreinterpretq_s32_f32(poly), vqshlq_n_s32(m, 23)));
|
||||
poly = vbslq_f32(vcltq_s32(m, vld1q_s32(CONST_NEGATIVE_126)), vld1q_f32(CONST_0), poly);
|
||||
|
||||
return poly;
|
||||
}
|
||||
|
||||
inline float32x4_t vlogq_f32(float32x4_t x)
|
||||
{
|
||||
static const int32_t CONST_127[4] = {127,127,127,127}; // 127
|
||||
static const float32_t CONST_LN2[4] = {0.6931471805f,0.6931471805f,0.6931471805f,0.6931471805f}; // ln(2)
|
||||
|
||||
// Extract exponent
|
||||
int32x4_t m = vsubq_s32(vreinterpretq_s32_u32(vshrq_n_u32(vreinterpretq_u32_f32(x), 23)), vld1q_s32(CONST_127));
|
||||
float32x4_t val = vreinterpretq_f32_s32(vsubq_s32(vreinterpretq_s32_f32(x), vshlq_n_s32(m, 23)));
|
||||
|
||||
// Polynomial Approximation
|
||||
float32x4_t poly = vtaylor_polyq_f32(val, log_tab);
|
||||
|
||||
// Reconstruct
|
||||
poly = vmlaq_f32(poly, vcvtq_f32_s32(m), vld1q_f32(CONST_LN2));
|
||||
|
||||
return poly;
|
||||
}
|
||||
|
||||
inline float32x4_t vtanhq_f32(float32x4_t val)
|
||||
{
|
||||
static const float32_t CONST_1[4] = {1.f,1.f,1.f,1.f};
|
||||
static const float32_t CONST_2[4] = {2.f,2.f,2.f,2.f};
|
||||
static const float32_t CONST_MIN_TANH[4] = {-10.f,-10.f,-10.f,-10.f};
|
||||
static const float32_t CONST_MAX_TANH[4] = {10.f,10.f,10.f,10.f};
|
||||
|
||||
float32x4_t x = vminq_f32(vmaxq_f32(val, vld1q_f32(CONST_MIN_TANH)), vld1q_f32(CONST_MAX_TANH));
|
||||
float32x4_t exp2x = vexpq_f32(vmulq_f32(vld1q_f32(CONST_2), x));
|
||||
float32x4_t num = vsubq_f32(exp2x, vld1q_f32(CONST_1));
|
||||
float32x4_t den = vaddq_f32(exp2x, vld1q_f32(CONST_1));
|
||||
float32x4_t tanh = vmulq_f32(num, vinvq_f32(den));
|
||||
return tanh;
|
||||
}
|
||||
|
||||
inline float32x4_t vpowq_f32(float32x4_t val, float32x4_t n)
|
||||
{
|
||||
return vexpq_f32(vmulq_f32(n, vlogq_f32(val)));
|
||||
}
|
||||
#endif /* DOXYGEN_SKIP_THIS */
|
||||
|
||||
#ifdef __ARM_FEATURE_FP16_VECTOR_ARITHMETIC
|
||||
/** Exponent polynomial coefficients */
|
||||
/** Logarithm polynomial coefficients */
|
||||
#ifndef DOXYGEN_SKIP_THIS
|
||||
inline float16x8_t vfloorq_f16(float16x8_t val)
|
||||
{
|
||||
static const float16_t CONST_1[8] = {1.f,1.f,1.f,1.f,1.f,1.f,1.f,1.f};
|
||||
|
||||
const int16x8_t z = vcvtq_s16_f16(val);
|
||||
const float16x8_t r = vcvtq_f16_s16(z);
|
||||
|
||||
return vbslq_f16(vcgtq_f16(r, val), vsubq_f16(r, vld1q_f16(CONST_1)), r);
|
||||
}
|
||||
inline float16x4_t vinvsqrt_f16(float16x4_t x)
|
||||
{
|
||||
float16x4_t sqrt_reciprocal = vrsqrte_f16(x);
|
||||
sqrt_reciprocal = vmul_f16(vrsqrts_f16(vmul_f16(x, sqrt_reciprocal), sqrt_reciprocal), sqrt_reciprocal);
|
||||
sqrt_reciprocal = vmul_f16(vrsqrts_f16(vmul_f16(x, sqrt_reciprocal), sqrt_reciprocal), sqrt_reciprocal);
|
||||
return sqrt_reciprocal;
|
||||
}
|
||||
|
||||
inline float16x8_t vinvsqrtq_f16(float16x8_t x)
|
||||
{
|
||||
float16x8_t sqrt_reciprocal = vrsqrteq_f16(x);
|
||||
sqrt_reciprocal = vmulq_f16(vrsqrtsq_f16(vmulq_f16(x, sqrt_reciprocal), sqrt_reciprocal), sqrt_reciprocal);
|
||||
sqrt_reciprocal = vmulq_f16(vrsqrtsq_f16(vmulq_f16(x, sqrt_reciprocal), sqrt_reciprocal), sqrt_reciprocal);
|
||||
return sqrt_reciprocal;
|
||||
}
|
||||
|
||||
inline float16x4_t vinv_f16(float16x4_t x)
|
||||
{
|
||||
float16x4_t recip = vrecpe_f16(x);
|
||||
recip = vmul_f16(vrecps_f16(x, recip), recip);
|
||||
recip = vmul_f16(vrecps_f16(x, recip), recip);
|
||||
return recip;
|
||||
}
|
||||
|
||||
inline float16x8_t vinvq_f16(float16x8_t x)
|
||||
{
|
||||
float16x8_t recip = vrecpeq_f16(x);
|
||||
recip = vmulq_f16(vrecpsq_f16(x, recip), recip);
|
||||
recip = vmulq_f16(vrecpsq_f16(x, recip), recip);
|
||||
return recip;
|
||||
}
|
||||
|
||||
inline float16x8_t vtanhq_f16(float16x8_t val)
|
||||
{
|
||||
const float16_t CONST_1[8] = {1.f,1.f,1.f,1.f,1.f,1.f,1.f,1.f};
|
||||
const float16_t CONST_2[8] = {2.f,2.f,2.f,2.f,2.f,2.f,2.f,2.f};
|
||||
const float16_t CONST_MIN_TANH[8] = {-10.f,-10.f,-10.f,-10.f,-10.f,-10.f,-10.f,-10.f};
|
||||
const float16_t CONST_MAX_TANH[8] = {10.f,10.f,10.f,10.f,10.f,10.f,10.f,10.f};
|
||||
|
||||
const float16x8_t x = vminq_f16(vmaxq_f16(val, vld1q_f16(CONST_MIN_TANH)), vld1q_f16(CONST_MAX_TANH));
|
||||
const float16x8_t exp2x = vexpq_f16(vmulq_f16(vld1q_f16(CONST_2), x));
|
||||
const float16x8_t num = vsubq_f16(exp2x, vld1q_f16(CONST_1));
|
||||
const float16x8_t den = vaddq_f16(exp2x, vld1q_f16(CONST_1));
|
||||
const float16x8_t tanh = vmulq_f16(num, vinvq_f16(den));
|
||||
return tanh;
|
||||
}
|
||||
|
||||
inline float16x8_t vtaylor_polyq_f16(float16x8_t x, const float16_t *coeffs)
|
||||
{
|
||||
const float16x8_t A = vaddq_f16(vld1q_f16(&coeffs[8*0]), vmulq_f16(vld1q_f16(&coeffs[8*4]), x));
|
||||
const float16x8_t B = vaddq_f16(vld1q_f16(&coeffs[8*2]), vmulq_f16(vld1q_f16(&coeffs[8*6]), x));
|
||||
const float16x8_t C = vaddq_f16(vld1q_f16(&coeffs[8*1]), vmulq_f16(vld1q_f16(&coeffs[8*5]), x));
|
||||
const float16x8_t D = vaddq_f16(vld1q_f16(&coeffs[8*3]), vmulq_f16(vld1q_f16(&coeffs[8*7]), x));
|
||||
const float16x8_t x2 = vmulq_f16(x, x);
|
||||
const float16x8_t x4 = vmulq_f16(x2, x2);
|
||||
const float16x8_t res = vaddq_f16(vaddq_f16(A, vmulq_f16(B, x2)), vmulq_f16(vaddq_f16(C, vmulq_f16(D, x2)), x4));
|
||||
return res;
|
||||
}
|
||||
|
||||
inline float16x8_t vexpq_f16(float16x8_t x)
|
||||
{
|
||||
// TODO (COMPMID-1535) : Revisit FP16 approximations
|
||||
const float32x4_t x_high = vcvt_f32_f16(vget_high_f16(x));
|
||||
const float32x4_t x_low = vcvt_f32_f16(vget_low_f16(x));
|
||||
|
||||
const float16x8_t res = vcvt_high_f16_f32(vcvt_f16_f32(vexpq_f32(x_low)), vexpq_f32(x_high));
|
||||
return res;
|
||||
}
|
||||
|
||||
inline float16x8_t vlogq_f16(float16x8_t x)
|
||||
{
|
||||
// TODO (COMPMID-1535) : Revisit FP16 approximations
|
||||
const float32x4_t x_high = vcvt_f32_f16(vget_high_f16(x));
|
||||
const float32x4_t x_low = vcvt_f32_f16(vget_low_f16(x));
|
||||
|
||||
const float16x8_t res = vcvt_high_f16_f32(vcvt_f16_f32(vlogq_f32(x_low)), vlogq_f32(x_high));
|
||||
return res;
|
||||
}
|
||||
|
||||
inline float16x8_t vpowq_f16(float16x8_t val, float16x8_t n)
|
||||
{
|
||||
// TODO (giaiod01) - COMPMID-1535
|
||||
float32x4_t n0_f32 = vcvt_f32_f16(vget_low_f16(n));
|
||||
float32x4_t n1_f32 = vcvt_f32_f16(vget_high_f16(n));
|
||||
float32x4_t val0_f32 = vcvt_f32_f16(vget_low_f16(val));
|
||||
float32x4_t val1_f32 = vcvt_f32_f16(vget_high_f16(val));
|
||||
|
||||
float32x4_t res0_f32 = vexpq_f32(vmulq_f32(n0_f32, vlogq_f32(val0_f32)));
|
||||
float32x4_t res1_f32 = vexpq_f32(vmulq_f32(n1_f32, vlogq_f32(val1_f32)));
|
||||
|
||||
return vcombine_f16(vcvt_f16_f32(res0_f32), vcvt_f16_f32(res1_f32));
|
||||
}
|
||||
#endif /* DOXYGEN_SKIP_THIS */
|
||||
#endif /* __ARM_FEATURE_FP16_VECTOR_ARITHMETIC */
|
||||
#endif
|
||||
#endif /* __ARM_COMPUTE_NEMATH_H__ */
|
||||
@@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2017-2019 ARM Software
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Copyright (c) 2016, 2019 ARM Limited.
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to
|
||||
* deal in the Software without restriction, including without limitation the
|
||||
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
* sell copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
#include "arm_math.h"
|
||||
#include "NEMath.h"
|
||||
|
||||
#if defined(ARM_MATH_NEON)
|
||||
|
||||
/** Exponent polynomial coefficients */
|
||||
const float32_t exp_tab[4*8] =
|
||||
{
|
||||
1.f,1.f,1.f,1.f,
|
||||
0.0416598916054f,0.0416598916054f,0.0416598916054f,0.0416598916054f,
|
||||
0.500000596046f,0.500000596046f,0.500000596046f,0.500000596046f,
|
||||
0.0014122662833f,0.0014122662833f,0.0014122662833f,0.0014122662833f,
|
||||
1.00000011921f,1.00000011921f,1.00000011921f,1.00000011921f,
|
||||
0.00833693705499f,0.00833693705499f,0.00833693705499f,0.00833693705499f,
|
||||
0.166665703058f,0.166665703058f,0.166665703058f,0.166665703058f,
|
||||
0.000195780929062f,0.000195780929062f,0.000195780929062f,0.000195780929062f
|
||||
};
|
||||
|
||||
/** Logarithm polynomial coefficients */
|
||||
const float32_t log_tab[4*8] =
|
||||
{
|
||||
-2.29561495781f,-2.29561495781f,-2.29561495781f,-2.29561495781f,
|
||||
-2.47071170807f,-2.47071170807f,-2.47071170807f,-2.47071170807f,
|
||||
-5.68692588806f,-5.68692588806f,-5.68692588806f,-5.68692588806f,
|
||||
-0.165253549814f,-0.165253549814f,-0.165253549814f,-0.165253549814f,
|
||||
5.17591238022f,5.17591238022f,5.17591238022f,5.17591238022f,
|
||||
0.844007015228f,0.844007015228f,0.844007015228f,0.844007015228f,
|
||||
4.58445882797f,4.58445882797f,4.58445882797f,4.58445882797f,
|
||||
0.0141278216615f,0.0141278216615f,0.0141278216615f,0.0141278216615f
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,220 @@
|
||||
#ifndef _ARR_DESC_H_
|
||||
#define _ARR_DESC_H_
|
||||
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
/* Includes */
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
#include <stdint.h>
|
||||
#include <string.h> /* memset() */
|
||||
#include "../util/util.h" /* CONCAT() */
|
||||
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
/* Type Definitions */
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* Array-descriptor struct.
|
||||
*/
|
||||
typedef struct ARR_DESC_struct
|
||||
{
|
||||
void * data_ptr; /* Pointer to the array contents. */
|
||||
int32_t element_count; /* Number of current elements. */
|
||||
int32_t element_size; /* Size of current elements in bytes. */
|
||||
int32_t underlying_size; /* Size of underlying array in bytes. */
|
||||
} ARR_DESC_t;
|
||||
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
/* Macros and Defines */
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* Prefix of the array variable's name when creating an array and an array
|
||||
* descriptor at the same time.
|
||||
*/
|
||||
#define ARR_DESC_ARR_PREFIX ARR_DESC_ARR_
|
||||
|
||||
/**
|
||||
* Evaluate to the array variable's name when creating an array and an array
|
||||
* descriptor at the same time.
|
||||
*/
|
||||
#define ARR_DESC_ARR_NAME(name) \
|
||||
CONCAT(ARR_DESC_ARR_PREFIX, name)
|
||||
|
||||
/**
|
||||
* Define an #ARR_DESC_t by itself.
|
||||
*
|
||||
* @note The user must supply an array to store the data used by the
|
||||
* #ARR_DESC_t.
|
||||
*/
|
||||
#define ARR_DESC_INTERNAL_DEFINE(name, data_ptr, \
|
||||
element_count, element_size) \
|
||||
ARR_DESC_t name = { \
|
||||
data_ptr, \
|
||||
element_count, \
|
||||
element_size, \
|
||||
element_count * element_size \
|
||||
} \
|
||||
|
||||
/**
|
||||
* Define both an array and an #ARR_DESC_t that describes it.
|
||||
*
|
||||
* @note Use the #CURLY() macro for the content field; it provides the curly
|
||||
* braces necessary for an array initialization.
|
||||
*/
|
||||
#define ARR_DESC_DEFINE(type, name, element_count, content) \
|
||||
type ARR_DESC_ARR_NAME(name)[element_count] = content; \
|
||||
ARR_DESC_INTERNAL_DEFINE(name, \
|
||||
&ARR_DESC_ARR_NAME(name), \
|
||||
element_count, \
|
||||
sizeof(type)) /* Note the lacking semicolon */
|
||||
|
||||
/**
|
||||
* Create a #ARR_DESC_t which refers to a subset of the data in another.
|
||||
*
|
||||
* The new #ARR_DESC_t shares the same underlying array as the aliased
|
||||
* #ARR_DESC_t, but only describes a subset of the originals values.
|
||||
*/
|
||||
#define ARR_DESC_DEFINE_SUBSET(name, original, element_cnt) \
|
||||
ARR_DESC_INTERNAL_DEFINE(name, \
|
||||
&ARR_DESC_ARR_NAME(original), \
|
||||
element_cnt, \
|
||||
sizeof(ARR_DESC_ARR_NAME(original)[0]) \
|
||||
) /* Note the lacking semicolon */
|
||||
|
||||
/**
|
||||
* Creat an #ARR_DESC_t which points to the data in an existing array.
|
||||
*
|
||||
* @param start_idx Offset in array_ptr of first element.
|
||||
* @param element_cnt Number of elements to include in the #ARR_DESC_t.
|
||||
*
|
||||
* @example
|
||||
*
|
||||
* float my_floats[4] = {0.0f, 1.0f, 2.0f, 3.0f};
|
||||
*
|
||||
* ARR_DESC_DEFINE_USING_ARR(my_arr_desc, my_floats, 1, 3);
|
||||
*
|
||||
* printf("Element 0: %f\n", ARR_DESC_ELT(float, 0, &my_arr_desc));
|
||||
* printf("Element 1: %f\n", ARR_DESC_ELT(float, 1, &my_arr_desc));
|
||||
*
|
||||
* Outputs:
|
||||
*
|
||||
* Element 0: 1.000000
|
||||
* Element 1: 2.000000
|
||||
*
|
||||
* @warning There are no checks in place to catch invalid start indices; This
|
||||
* is left to the user.
|
||||
*/
|
||||
#define ARR_DESC_DEFINE_USING_ARR(type, name, array_ptr, start_idx, element_cnt) \
|
||||
ARR_DESC_INTERNAL_DEFINE( \
|
||||
name, \
|
||||
(type *) (array_ptr + start_idx), \
|
||||
element_cnt, \
|
||||
sizeof(type) \
|
||||
) /* Note the lacking semicolon*/
|
||||
|
||||
/**
|
||||
* Declare an #ARR_DESC_t object.
|
||||
*/
|
||||
#define ARR_DESC_DECLARE(name) \
|
||||
extern ARR_DESC_t name /* Note the lacking semicolon */
|
||||
|
||||
/**
|
||||
* Evaluate to the number of bytes stored in the #ARR_DESC_t.
|
||||
*/
|
||||
#define ARR_DESC_BYTES(arr_desc_ptr) \
|
||||
((arr_desc_ptr)->element_count * (arr_desc_ptr)->element_size)
|
||||
|
||||
/**
|
||||
* Set the contents of #ARR_DESC_t to value.
|
||||
*/
|
||||
#define ARR_DESC_MEMSET(arr_desc_ptr, value, bytes) \
|
||||
do \
|
||||
{ \
|
||||
memset((arr_desc_ptr)->data_ptr, \
|
||||
value, \
|
||||
BOUND(0, \
|
||||
(arr_desc_ptr)->underlying_size, \
|
||||
bytes) \
|
||||
); \
|
||||
} while (0)
|
||||
|
||||
/**
|
||||
* Perform a memcpy of 'bytes' bytes from the source #ARR_DESC_t to the
|
||||
* destination #ARR_DESC_t.
|
||||
*/
|
||||
#define ARR_DESC_MEMCPY(arr_desc_dest_ptr, arr_desc_src_ptr, bytes) \
|
||||
do \
|
||||
{ \
|
||||
memcpy((arr_desc_dest_ptr)->data_ptr, \
|
||||
(arr_desc_src_ptr)->data_ptr, \
|
||||
BOUND(0, \
|
||||
(arr_desc_dest_ptr)->underlying_size, \
|
||||
bytes)); \
|
||||
} while (0)
|
||||
|
||||
/**
|
||||
* Evaluate to true if the source #ARR_DESC_t contents will fit into the
|
||||
* destination #ARR_DESC_t and false otherwise.
|
||||
*/
|
||||
#define ARR_DESC_COPYABLE(arr_desc_dest_ptr, arr_desc_src_ptr) \
|
||||
(ARR_DESC_BYTES(arr_desc_src_ptr) <= \
|
||||
(arr_desc_dest_ptr)->underlying_size)
|
||||
|
||||
/**
|
||||
* Copy all the data from the source #ARR_DESC_t to the destination
|
||||
* #ARR_DESC_t.
|
||||
*
|
||||
* @note If the destination #ARR_DESC_t is too small to fit the source data the
|
||||
* copy is aborted and nothing happens.
|
||||
*/
|
||||
#define ARR_DESC_COPY(arr_desc_dest_ptr, arr_desc_src_ptr) \
|
||||
do \
|
||||
{ \
|
||||
if (ARR_DESC_COPYABLE(arr_desc_dest_ptr, \
|
||||
arr_desc_src_ptr)) \
|
||||
{ \
|
||||
ARR_DESC_MEMCPY(arr_desc_dest_ptr, \
|
||||
arr_desc_src_ptr, \
|
||||
ARR_DESC_BYTES(arr_desc_src_ptr)); \
|
||||
/* Update the properties*/ \
|
||||
(arr_desc_dest_ptr)->element_count = \
|
||||
(arr_desc_src_ptr)->element_count; \
|
||||
(arr_desc_dest_ptr)->element_size = \
|
||||
(arr_desc_src_ptr)->element_size; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
/**
|
||||
* Compare the data in two #ARR_DESC_t structs for the specified number of
|
||||
* bytes.
|
||||
*/
|
||||
#define ARR_DESC_MEMCMP(arr_desc_ptr_a, arr_desc_ptr_b, bytes) \
|
||||
memcmp((arr_desc_ptr_a)->data_ptr, \
|
||||
(arr_desc_ptr_b)->data_ptr, \
|
||||
bytes) /* Note the lacking semicolon */ \
|
||||
|
||||
/**
|
||||
* Zero out the contents of the #ARR_DESC_t.
|
||||
*/
|
||||
#define ARR_DESC_ZERO(arr_desc_ptr) \
|
||||
ARR_DESC_MEMSET(arr_desc_ptr, \
|
||||
0, \
|
||||
(arr_desc_ptr)->underlying_size)
|
||||
|
||||
/**
|
||||
* Evaluate to the data address in #ARR_DESC_t at offset.
|
||||
*/
|
||||
#define ARR_DESC_DATA_ADDR(type, arr_desc_ptr, offset) \
|
||||
((void*)(((type *) \
|
||||
((arr_desc_ptr)->data_ptr)) \
|
||||
+ offset))
|
||||
|
||||
/**
|
||||
* Evaluate to the element in #ARR_DESC_t with type at idx.
|
||||
*/
|
||||
#define ARR_DESC_ELT(type, idx, arr_desc_ptr) \
|
||||
(*((type *) ARR_DESC_DATA_ADDR(type, \
|
||||
arr_desc_ptr, \
|
||||
idx)))
|
||||
|
||||
#endif /* _ARR_DESC_H_ */
|
||||
@@ -0,0 +1,17 @@
|
||||
#ifndef _JTEST_H_
|
||||
#define _JTEST_H_
|
||||
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
/* Includes */
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
|
||||
#include "jtest_fw.h"
|
||||
#include "jtest_test.h"
|
||||
#include "jtest_test_define.h"
|
||||
#include "jtest_test_call.h"
|
||||
#include "jtest_group.h"
|
||||
#include "jtest_group_define.h"
|
||||
#include "jtest_group_call.h"
|
||||
#include "jtest_cycle.h"
|
||||
|
||||
#endif /* _JTEST_H_ */
|
||||
@@ -0,0 +1,65 @@
|
||||
#ifndef _JTEST_CYCLE_H_
|
||||
#define _JTEST_CYCLE_H_
|
||||
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
/* Includes */
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
|
||||
#include "jtest_fw.h" /* JTEST_DUMP_STRF() */
|
||||
#include "jtest_systick.h"
|
||||
#include "jtest_util.h" /* STR() */
|
||||
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
/* Declare Module Variables */
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
extern const char * JTEST_CYCLE_STRF;
|
||||
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
/* Macros and Defines */
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* Wrap the function call, fn_call, to count execution cycles and display the
|
||||
* results.
|
||||
*/
|
||||
/* skipp function name + param
|
||||
#define JTEST_COUNT_CYCLES(fn_call) \
|
||||
do \
|
||||
{ \
|
||||
uint32_t __jtest_cycle_end_count; \
|
||||
\
|
||||
JTEST_SYSTICK_RESET(SysTick); \
|
||||
JTEST_SYSTICK_START(SysTick); \
|
||||
\
|
||||
fn_call; \
|
||||
\
|
||||
__jtest_cycle_end_count = \
|
||||
JTEST_SYSTICK_VALUE(SysTick); \
|
||||
\
|
||||
JTEST_SYSTICK_RESET(SysTick); \
|
||||
JTEST_DUMP_STRF(JTEST_CYCLE_STRF, \
|
||||
STR(fn_call), \
|
||||
(JTEST_SYSTICK_INITIAL_VALUE - \
|
||||
__jtest_cycle_end_count)); \
|
||||
} while (0)
|
||||
*/
|
||||
#define JTEST_COUNT_CYCLES(fn_call) \
|
||||
do \
|
||||
{ \
|
||||
uint32_t __jtest_cycle_end_count; \
|
||||
\
|
||||
JTEST_SYSTICK_RESET(SysTick); \
|
||||
JTEST_SYSTICK_START(SysTick); \
|
||||
\
|
||||
fn_call; \
|
||||
\
|
||||
__jtest_cycle_end_count = \
|
||||
JTEST_SYSTICK_VALUE(SysTick); \
|
||||
\
|
||||
JTEST_SYSTICK_RESET(SysTick); \
|
||||
JTEST_DUMP_STRF(JTEST_CYCLE_STRF, \
|
||||
(JTEST_SYSTICK_INITIAL_VALUE - \
|
||||
__jtest_cycle_end_count)); \
|
||||
} while (0)
|
||||
|
||||
#endif /* _JTEST_CYCLE_H_ */
|
||||
@@ -0,0 +1,37 @@
|
||||
#ifndef _JTEST_DEFINE_H_
|
||||
#define _JTEST_DEFINE_H_
|
||||
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
/* Macros and Defines */
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* Makes a symbol for use as a struct name. Names made this way have two parts;
|
||||
* the first parts is a prefix common to all structs of that class. The second
|
||||
* is a specifier which differs for each instance of that struct type.
|
||||
*/
|
||||
#define JTEST_STRUCT_NAME(prefix, specifier) \
|
||||
CONCAT(prefix, specifier)
|
||||
|
||||
/**
|
||||
* Define a struct with type with a name generated by #JTEST_STRUCT_NAME().
|
||||
*/
|
||||
#define JTEST_DEFINE_STRUCT(type, struct_name) \
|
||||
type struct_name
|
||||
|
||||
/**
|
||||
* Declare a struct with type with a name generated by #JTEST_STRUCT_NAME().
|
||||
*/
|
||||
#define JTEST_DECLARE_STRUCT(struct_definition) \
|
||||
extern struct_definition
|
||||
|
||||
/**
|
||||
* Define and initialize a struct (created with JTEST_DEFINE_STRUCT()) and
|
||||
* initialize it with init_values.
|
||||
*/
|
||||
#define JTEST_INIT_STRUCT(struct_definition, init_values) \
|
||||
struct_definition = { \
|
||||
init_values \
|
||||
}
|
||||
|
||||
#endif /* _JTEST_DEFINE_H_ */
|
||||
@@ -0,0 +1,253 @@
|
||||
#ifndef _JTEST_FW_H_
|
||||
#define _JTEST_FW_H_
|
||||
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
/* Includes */
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
|
||||
#include <stdint.h> /* int32_t */
|
||||
#include <string.h> /* strcpy() */
|
||||
#include <stdio.h> /* sprintf() */
|
||||
#include "jtest_pf.h" /* Extend JTEST_FW_t with Pass/Fail data */
|
||||
#include "jtest_group.h"
|
||||
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
/* Type Definitions */
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* A struct used to interface with the Keil Debugger.
|
||||
*/
|
||||
typedef struct JTEST_FW_struct
|
||||
{
|
||||
/* Action Triggers: The Keil debugger monitors these values for changes. In
|
||||
* response to a change, the debugger executes code on the host. */
|
||||
volatile int32_t test_start;
|
||||
volatile int32_t test_end;
|
||||
volatile int32_t group_start;
|
||||
volatile int32_t group_end;
|
||||
volatile int32_t dump_str;
|
||||
volatile int32_t dump_data;
|
||||
volatile int32_t exit_fw;
|
||||
|
||||
JTEST_GROUP_t * current_group_ptr;
|
||||
|
||||
/* Buffers: The C-code cannot send strings and data directly to the
|
||||
* debugging framework. Instead, the debugger can be told to read 128 byte
|
||||
* (by default) chunks of memory. Data received in this manner requires
|
||||
* post-processing to be legible.*/
|
||||
char * str_buffer;
|
||||
char * data_buffer;
|
||||
|
||||
/* Pass/Fail Data */
|
||||
JTEST_PF_MEMBERS;
|
||||
|
||||
} JTEST_FW_t;
|
||||
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
/* Macros and Defines */
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* Default name for the JTEST_FW struct.
|
||||
*
|
||||
* Define your own if you want the variable containing the #JTEST_FW_t to have
|
||||
* a different name.
|
||||
*/
|
||||
#ifndef JTEST_FW
|
||||
#define JTEST_FW JTEST_FW
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Default name for the JTEST_FW_STR_BUFFER.
|
||||
*
|
||||
* Define your own if you want the variable containing the char buffer to have
|
||||
* a different name.
|
||||
*/
|
||||
#ifndef JTEST_FW_STR_BUFFER
|
||||
#define JTEST_FW_STR_BUFFER JTEST_FW_STR_BUFFER
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Size of the #JTEST_FW_t, output string-buffer.
|
||||
*
|
||||
* If you change this value, make sure the "dump_str_fn" and "dump_data_fn"
|
||||
* functions in jtest_fns.ini uses the same size. If you aren't sure, read the
|
||||
* documentation Keil Debugger Command 'DISPLAY'.
|
||||
*/
|
||||
#define JTEST_BUF_SIZE 256
|
||||
|
||||
|
||||
/**
|
||||
* The maximum number of bytes output at once using #JTEST_DUMP_STRF().
|
||||
*/
|
||||
#define JTEST_STR_MAX_OUTPUT_SIZE 128
|
||||
|
||||
/**
|
||||
* The maximum number of block transimissions needed to send a string from a
|
||||
* buffer with JTEST_BUF_SIZE.
|
||||
*/
|
||||
#define JTEST_STR_MAX_OUTPUT_SEGMENTS \
|
||||
(JTEST_BUF_SIZE / JTEST_STR_MAX_OUTPUT_SIZE)
|
||||
|
||||
/**
|
||||
* Initialize the JTEST framework.
|
||||
*/
|
||||
#define JTEST_INIT() \
|
||||
do \
|
||||
{ \
|
||||
JTEST_FW.str_buffer = JTEST_FW_STR_BUFFER; \
|
||||
} while (0)
|
||||
|
||||
/* Debugger Action-triggering Macros */
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* Dispatch macro to trigger various actions in the Keil Debugger.
|
||||
*/
|
||||
#define JTEST_TRIGGER_ACTION(action_name) \
|
||||
do \
|
||||
{ \
|
||||
action_name(); \
|
||||
} while (0)
|
||||
|
||||
/**
|
||||
* Trigger the "Test Start" action in the Keil Debugger.
|
||||
*/
|
||||
#define JTEST_ACT_TEST_START() \
|
||||
JTEST_TRIGGER_ACTION(test_start)
|
||||
|
||||
/**
|
||||
* Trigger the "Test End" action in the Keil Debugger.
|
||||
*/
|
||||
#define JTEST_ACT_TEST_END() \
|
||||
JTEST_TRIGGER_ACTION(test_end)
|
||||
|
||||
|
||||
/**
|
||||
* Trigger the "Group Start" action in the Keil Debugger.
|
||||
*/
|
||||
#define JTEST_ACT_GROUP_START() \
|
||||
JTEST_TRIGGER_ACTION(group_start)
|
||||
|
||||
/**
|
||||
* Trigger the "Group End" action in the Keil Debugger.
|
||||
*/
|
||||
#define JTEST_ACT_GROUP_END() \
|
||||
JTEST_TRIGGER_ACTION(group_end)
|
||||
|
||||
|
||||
/**
|
||||
* Fill the buffer named buf_name with value and dump it to the Keil debugger
|
||||
* using action.
|
||||
*/
|
||||
#define JTEST_ACT_DUMP(action, buf_name, value) \
|
||||
do \
|
||||
{ \
|
||||
JTEST_CLEAR_BUFFER(buf_name); \
|
||||
strcpy(JTEST_FW.buf_name, (value)); \
|
||||
JTEST_TRIGGER_ACTION(action); \
|
||||
} while (0)
|
||||
|
||||
/**
|
||||
* Trigger the "Exit Framework" action in the Keil Debugger.
|
||||
*/
|
||||
#define JTEST_ACT_EXIT_FW() \
|
||||
do \
|
||||
{ \
|
||||
JTEST_TRIGGER_ACTION(exit_fw); \
|
||||
} while (0)
|
||||
|
||||
|
||||
/* Buffer Manipulation Macros */
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* Clear the JTEST_FW buffer with name buf_name.
|
||||
*/
|
||||
#define JTEST_CLEAR_BUFFER(buf_name) \
|
||||
do \
|
||||
{ \
|
||||
memset(JTEST_FW.buf_name, 0, JTEST_BUF_SIZE); \
|
||||
} while (0)
|
||||
|
||||
/**
|
||||
* Clear the memory needed for the JTEST_FW's string buffer.
|
||||
*/
|
||||
#define JTEST_CLEAR_STR_BUFFER() \
|
||||
JTEST_CLEAR_BUFFER(str_buffer)
|
||||
|
||||
/**
|
||||
* Clear the memory needed for the JTEST_FW's data buffer.
|
||||
*/
|
||||
#define JTEST_CLEAR_DATA_BUFFER() \
|
||||
JTEST_CLEAR_BUFFER(data_buffer)
|
||||
|
||||
/**
|
||||
* Dump the given string to the Keil Debugger.
|
||||
*/
|
||||
#define JTEST_DUMP_STR(string) \
|
||||
JTEST_ACT_DUMP(dump_str, str_buffer, string)
|
||||
|
||||
/**
|
||||
* Dump a formatted string to the Keil Debugger.
|
||||
*/
|
||||
#define JTEST_DUMP_STRF(format_str, ... ) \
|
||||
do \
|
||||
{ \
|
||||
JTEST_CLEAR_STR_BUFFER(); \
|
||||
sprintf(JTEST_FW.str_buffer,format_str, __VA_ARGS__); \
|
||||
jtest_dump_str_segments(); \
|
||||
} while (0)
|
||||
|
||||
/* Pass/Fail Macros */
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* Increment the number of passed tests in #JTEST_FW.
|
||||
*/
|
||||
#define JTEST_FW_INC_PASSED(amount) \
|
||||
JTEST_PF_INC_PASSED(&JTEST_FW, amount)
|
||||
|
||||
/**
|
||||
* Increment the number of passed tests in #JTEST_FW.
|
||||
*/
|
||||
#define JTEST_FW_INC_FAILED(amount) \
|
||||
JTEST_PF_INC_FAILED(&JTEST_FW, amount)
|
||||
|
||||
/* Manipulating the Current Group */
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* Evaluate to the current_group_ptr in #JTEST_FW.
|
||||
*/
|
||||
#define JTEST_CURRENT_GROUP_PTR() \
|
||||
(JTEST_FW.current_group_ptr)
|
||||
|
||||
#define JTEST_SET_CURRENT_GROUP(group_ptr) \
|
||||
do \
|
||||
{ \
|
||||
JTEST_CURRENT_GROUP_PTR() = group_ptr; \
|
||||
} while (0)
|
||||
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
/* Declare Global Variables */
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
extern char JTEST_FW_STR_BUFFER[JTEST_BUF_SIZE];
|
||||
extern volatile JTEST_FW_t JTEST_FW;
|
||||
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
/* Function Prototypes */
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
void jtest_dump_str_segments(void);
|
||||
|
||||
void test_start (void);
|
||||
void test_end (void);
|
||||
void group_start (void);
|
||||
void group_end (void);
|
||||
void dump_str (void);
|
||||
void dump_data (void);
|
||||
void exit_fw (void);
|
||||
|
||||
|
||||
#endif /* _JTEST_FW_H_ */
|
||||
@@ -0,0 +1,66 @@
|
||||
#ifndef _JTEST_GROUP_H_
|
||||
#define _JTEST_GROUP_H_
|
||||
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
/* Includes */
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
|
||||
#include "jtest_pf.h"
|
||||
#include "jtest_util.h"
|
||||
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
/* Type Definitions */
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* A struct which represents a group of #JTEST_TEST_t structs. This struct is
|
||||
* used to run the group of tests, and report on their outcomes.
|
||||
*/
|
||||
typedef struct JTEST_GROUP_struct
|
||||
{
|
||||
void (* group_fn_ptr) (void); /**< Pointer to the test group */
|
||||
char * name_str; /**< Name of the group */
|
||||
|
||||
/* Extend the #JTEST_GROUP_t with Pass/Fail information.*/
|
||||
JTEST_PF_MEMBERS;
|
||||
} JTEST_GROUP_t;
|
||||
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
/* Macros and Defines */
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* Set the name of JTEST_GROUP_t.
|
||||
*/
|
||||
#define JTEST_GROUP_SET_NAME(group_ptr, name) \
|
||||
JTEST_SET_STRUCT_ATTRIBUTE(group_ptr, name_str, name)
|
||||
|
||||
#define JTEST_GROUP_SET_FN(group_ptr, fn_ptr) \
|
||||
JTEST_SET_STRUCT_ATTRIBUTE(group_ptr, group_fn_ptr, fn_ptr)
|
||||
|
||||
/**
|
||||
* Increment the number of tests passed in the JTEST_GROUP_t pointed to by
|
||||
* group_ptr.
|
||||
*/
|
||||
#define JTEST_GROUP_INC_PASSED(group_ptr, amount) \
|
||||
JTEST_PF_INC_PASSED(group_ptr, amount)
|
||||
|
||||
/**
|
||||
* Increment the number of tests failed in the JTEST_GROUP_t pointed to by
|
||||
* group_ptr.
|
||||
*/
|
||||
#define JTEST_GROUP_INC_FAILED(group_ptr, amount) \
|
||||
JTEST_PF_INC_FAILED(group_ptr, amount)
|
||||
|
||||
/**
|
||||
* Reset the pass/fail information of the #JTEST_GROUP_t pointed to by
|
||||
* group_ptr.
|
||||
*/
|
||||
#define JTEST_GROUP_RESET_PF(group_ptr) \
|
||||
do \
|
||||
{ \
|
||||
JTEST_PF_RESET_PASSED(group_ptr); \
|
||||
JTEST_PF_RESET_FAILED(group_ptr); \
|
||||
} while (0)
|
||||
|
||||
#endif /* _JTEST_GROUP_H_ */
|
||||
@@ -0,0 +1,126 @@
|
||||
#ifndef _JTEST_GROUP_CALL_H_
|
||||
#define _JTEST_GROUP_CALL_H_
|
||||
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
/* Includes */
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
|
||||
#include "jtest_fw.h"
|
||||
#include <inttypes.h>
|
||||
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
/* Macros and Defines */
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* Execute the test in the #JTEST_GROUP_t struct associated witht he identifier
|
||||
* group_fn.
|
||||
*/
|
||||
#define JTEST_GROUP_RUN(group_fn) \
|
||||
do \
|
||||
{ \
|
||||
JTEST_DUMP_STR("Group Name:\n"); \
|
||||
JTEST_DUMP_STR(JTEST_GROUP_STRUCT_NAME(group_fn).name_str); \
|
||||
JTEST_GROUP_STRUCT_NAME(group_fn).group_fn_ptr(); \
|
||||
} while (0)
|
||||
|
||||
|
||||
/**
|
||||
* Update the enclosing #JTEST_GROUP_t's pass/fail information using the
|
||||
* current #JTEST_GROUP_t's.
|
||||
*
|
||||
* @param group_ptr Pointer to the current #JTEST_GROUP_t.
|
||||
* @param parent_ptr Pointer to the enclosing #JTEST_GROUP_t.
|
||||
*
|
||||
* @warning Only run this if the current #JTEST_GROUP_t is being called within
|
||||
* the context of another #JTEST_GROUP_t.
|
||||
*/
|
||||
#define JTEST_GROUP_UPDATE_PARENT_GROUP_PF(group_ptr, parent_group_ptr) \
|
||||
do \
|
||||
{ \
|
||||
JTEST_GROUP_INC_PASSED(parent_group_ptr, \
|
||||
(group_ptr)->passed); \
|
||||
JTEST_GROUP_INC_FAILED(parent_group_ptr, \
|
||||
(group_ptr)->failed); \
|
||||
} while (0)
|
||||
|
||||
/**
|
||||
* Update the #JTEST_FW's pass/fail information using the current
|
||||
* #JTEST_GROUP_t's.
|
||||
*/
|
||||
#define JTEST_GROUP_UPDATE_FW_PF(group_ptr) \
|
||||
do \
|
||||
{ \
|
||||
JTEST_FW_INC_PASSED((group_ptr)->passed); \
|
||||
JTEST_FW_INC_FAILED((group_ptr)->failed); \
|
||||
} while (0)
|
||||
|
||||
/**
|
||||
* Update the enclosing context with the current #JTEST_GROUP_t's pass/fail
|
||||
* information. If this group isn't in an enclosing group, it updates the
|
||||
* #JTEST_FW's pass/fail info by default.
|
||||
*/
|
||||
#define JTEST_GROUP_UPDATE_PARENT_GROUP_OR_FW_PF(group_ptr, \
|
||||
parent_group_ptr) \
|
||||
do \
|
||||
{ \
|
||||
/* Update the pass fail counts in the parent group */ \
|
||||
if (parent_group_ptr /* Null implies Top*/) \
|
||||
{ \
|
||||
JTEST_GROUP_UPDATE_PARENT_GROUP_PF( \
|
||||
group_ptr, \
|
||||
parent_group_ptr); \
|
||||
} else { \
|
||||
JTEST_GROUP_UPDATE_FW_PF( \
|
||||
group_ptr); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
/**
|
||||
* Dump the results of running the #JTEST_GROUP_t to the Keil Debugger.
|
||||
*/
|
||||
#define JTEST_GROUP_DUMP_RESULTS(group_ptr) \
|
||||
do \
|
||||
{ \
|
||||
JTEST_DUMP_STRF( \
|
||||
"Tests Run: %" PRIu32 "\n" \
|
||||
"----------\n" \
|
||||
" Passed: %" PRIu32 "\n" \
|
||||
" Failed: %" PRIu32 "\n", \
|
||||
(group_ptr)->passed + (group_ptr)->failed, \
|
||||
(group_ptr)->passed, \
|
||||
(group_ptr)->failed); \
|
||||
} while (0)
|
||||
|
||||
/**
|
||||
* Call the #JTEST_GROUP_t associated with the identifier group_fn.
|
||||
*/
|
||||
#define JTEST_GROUP_CALL(group_fn) \
|
||||
do \
|
||||
{ /* Save the current group from JTEST_FW_t before swapping */ \
|
||||
/* it to this group (in order to restore it later )*/ \
|
||||
JTEST_GROUP_t * __jtest_temp_group_ptr = \
|
||||
JTEST_CURRENT_GROUP_PTR(); \
|
||||
JTEST_SET_CURRENT_GROUP(&JTEST_GROUP_STRUCT_NAME(group_fn)); \
|
||||
\
|
||||
/* Reset this group's pass/fail count. Each group */ \
|
||||
/* should only remember counts for its last execution. */ \
|
||||
JTEST_GROUP_RESET_PF(JTEST_CURRENT_GROUP_PTR()); \
|
||||
\
|
||||
/* Run the current group */ \
|
||||
JTEST_ACT_GROUP_START(); \
|
||||
JTEST_GROUP_RUN(group_fn); \
|
||||
JTEST_ACT_GROUP_END(); \
|
||||
\
|
||||
/* Update the pass fail counts in the parent group (or FW) */ \
|
||||
JTEST_GROUP_UPDATE_PARENT_GROUP_OR_FW_PF( \
|
||||
JTEST_CURRENT_GROUP_PTR(), \
|
||||
__jtest_temp_group_ptr); \
|
||||
\
|
||||
JTEST_GROUP_DUMP_RESULTS(JTEST_CURRENT_GROUP_PTR()); \
|
||||
\
|
||||
/* Restore the previously current group */ \
|
||||
JTEST_SET_CURRENT_GROUP(__jtest_temp_group_ptr); \
|
||||
} while (0)
|
||||
|
||||
#endif /* _JTEST_GROUP_CALL_H_ */
|
||||
@@ -0,0 +1,87 @@
|
||||
#ifndef _JTEST_GROUP_DEFINE_H_
|
||||
#define _JTEST_GROUP_DEFINE_H_
|
||||
|
||||
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
/* Includes */
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
|
||||
#include "jtest_util.h"
|
||||
#include "jtest_define.h"
|
||||
#include "jtest_group.h"
|
||||
|
||||
/* For defining macros with optional arguments */
|
||||
#include "opt_arg/opt_arg.h"
|
||||
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
/* Macros and Defines */
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* Prefix for all #JTEST_GROUP_t structs.
|
||||
*/
|
||||
#define JTEST_GROUP_STRUCT_NAME_PREFIX G_JTEST_GROUP_STRUCT_
|
||||
|
||||
/**
|
||||
* Define test template used by #JTEST_GROUP_t tests.
|
||||
*/
|
||||
#define JTEST_GROUP_FN_TEMPLATE(group_fn) \
|
||||
void group_fn(void)
|
||||
|
||||
#define JTEST_GROUP_FN_PROTOTYPE JTEST_GROUP_FN_TEMPLATE /**< Alias for
|
||||
#JTEST_GROUP_FN_TEMPLATE. */
|
||||
|
||||
/**
|
||||
* Evaluate to the name of the #JTEST_GROUP_t struct associated with group_fn.
|
||||
*/
|
||||
#define JTEST_GROUP_STRUCT_NAME(group_fn) \
|
||||
JTEST_STRUCT_NAME(JTEST_GROUP_STRUCT_NAME_PREFIX, group_fn)
|
||||
|
||||
/**
|
||||
* Define a #JTEST_GROUP_t struct based on the given group_fn.
|
||||
*/
|
||||
#define JTEST_GROUP_DEFINE_STRUCT(group_fn) \
|
||||
JTEST_DEFINE_STRUCT(JTEST_GROUP_t, \
|
||||
JTEST_GROUP_STRUCT_NAME(group_fn))
|
||||
|
||||
/**
|
||||
* Declare a #JTEST_GROUP_t struct based on the given group_fn.
|
||||
*/
|
||||
#define JTEST_GROUP_DECLARE_STRUCT(group_fn) \
|
||||
JTEST_DECLARE_STRUCT(JTEST_GROUP_DEFINE_STRUCT(group_fn))
|
||||
|
||||
/**
|
||||
* Contents needed to initialize a JTEST_GROUP_t struct.
|
||||
*/
|
||||
#define JTEST_GROUP_STRUCT_INIT(group_fn) \
|
||||
group_fn, \
|
||||
STR_NL(group_fn), \
|
||||
JTEST_PF_MEMBER_INIT
|
||||
|
||||
/**
|
||||
* Initialize the contents of a #JTEST_GROUP_t struct.
|
||||
*/
|
||||
#define JTEST_GROUP_INIT(group_fn) \
|
||||
JTEST_GROUP_DEFINE_STRUCT(group_fn) = { \
|
||||
JTEST_GROUP_STRUCT_INIT(group_fn) \
|
||||
}
|
||||
|
||||
/* Test Definition Macro */
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* Define a #JTEST_GROUP_t object and a test function.
|
||||
*/
|
||||
#define JTEST_DEFINE_GROUP(group_fn) \
|
||||
JTEST_GROUP_FN_PROTOTYPE(group_fn); \
|
||||
JTEST_GROUP_INIT(group_fn); \
|
||||
JTEST_GROUP_FN_PROTOTYPE(group_fn) /* Notice the lacking semicolon */
|
||||
|
||||
/**
|
||||
* Declare a #JTEST_GROUP_t object and a test function prototype.
|
||||
*/
|
||||
#define JTEST_DECLARE_GROUP(group_fn) \
|
||||
JTEST_GROUP_FN_PROTOTYPE(group_fn); \
|
||||
JTEST_GROUP_DECLARE_STRUCT(group_fn) /* Note the lacking semicolon */
|
||||
|
||||
#endif /* _JTEST_GROUP_DEFINE_H_ */
|
||||
@@ -0,0 +1,85 @@
|
||||
#ifndef _JTEST_PF_H_
|
||||
#define _JTEST_PF_H_
|
||||
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
/* Purpose */
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
/* jtest_pf.h Contains macros useful for capturing pass/fail data. */
|
||||
|
||||
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
/* Macros and Defines */
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* Members that can be added to other structs to extend them pass/fail data and
|
||||
* corresponding functionality.
|
||||
*/
|
||||
#define JTEST_PF_MEMBERS \
|
||||
uint32_t passed; \
|
||||
uint32_t failed /* Note the lacking semicolon*/ \
|
||||
|
||||
/**
|
||||
* Used for initializing JTEST_PF_MEMBERS in a struct declaration.
|
||||
*/
|
||||
#define JTEST_PF_MEMBER_INIT \
|
||||
0, \
|
||||
0
|
||||
|
||||
/* Member-Incrementing Macros */
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* Dispatch macro for incrementing #JTEST_PF_MEMBERS.
|
||||
*
|
||||
* @param xxx Values: 'passed', 'failed'
|
||||
*/
|
||||
#define JTEST_PF_INC_XXX(xxx, struct_pf_ptr, amount) \
|
||||
do \
|
||||
{ \
|
||||
((struct_pf_ptr)->xxx) += (amount); \
|
||||
} while (0)
|
||||
|
||||
/**
|
||||
* Specialization of the #JTEST_PF_INC_XXX macro to increment the passed
|
||||
* member.
|
||||
*/
|
||||
#define JTEST_PF_INC_PASSED(struct_pf_ptr, amount) \
|
||||
JTEST_PF_INC_XXX(passed, struct_pf_ptr, amount)
|
||||
|
||||
|
||||
/**
|
||||
* Specialization of the #JTEST_PF_INC_XXX macro to increment the failed
|
||||
* member.
|
||||
*/
|
||||
#define JTEST_PF_INC_FAILED(struct_pf_ptr, amount) \
|
||||
JTEST_PF_INC_XXX(failed, struct_pf_ptr, amount)
|
||||
|
||||
|
||||
/* Member-Resetting Macros */
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* Dispatch macro for setting #JTEST_PF_MEMBERS to zero.
|
||||
*
|
||||
* @param xxx Values: 'passed', 'failed'
|
||||
*/
|
||||
#define JTEST_PF_RESET_XXX(xxx, struct_pf_ptr) \
|
||||
do \
|
||||
{ \
|
||||
((struct_pf_ptr)->xxx) = UINT32_C(0); \
|
||||
} while (0)
|
||||
|
||||
/**
|
||||
* Specialization of #JTEST_PF_RESET_XXX for the 'passed' member.
|
||||
*/
|
||||
#define JTEST_PF_RESET_PASSED(struct_pf_ptr) \
|
||||
JTEST_PF_RESET_XXX(passed, struct_pf_ptr)
|
||||
|
||||
/**
|
||||
* Specialization of #JTEST_PF_RESET_XXX for the 'failed' member.
|
||||
*/
|
||||
#define JTEST_PF_RESET_FAILED(struct_pf_ptr) \
|
||||
JTEST_PF_RESET_XXX(failed, struct_pf_ptr)
|
||||
|
||||
#endif /* _JTEST_PF_H_ */
|
||||
@@ -0,0 +1,93 @@
|
||||
#ifndef _JTEST_SYSTICK_H_
|
||||
#define _JTEST_SYSTICK_H_
|
||||
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
/* Includes */
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
|
||||
/* Get access to the SysTick structure. */
|
||||
#if defined ARMCM0
|
||||
#include "ARMCM0.h"
|
||||
#elif defined ARMCM0P
|
||||
#include "ARMCM0plus.h"
|
||||
#elif defined ARMCM3
|
||||
#include "ARMCM3.h"
|
||||
#elif defined ARMCM4
|
||||
#include "ARMCM4.h"
|
||||
#elif defined ARMCM4_FP
|
||||
#include "ARMCM4_FP.h"
|
||||
#elif defined ARMCM7
|
||||
#include "ARMCM7.h"
|
||||
#elif defined ARMCM7_SP
|
||||
#include "ARMCM7_SP.h"
|
||||
#elif defined ARMCM7_DP
|
||||
#include "ARMCM7_DP.h"
|
||||
#elif defined ARMSC000
|
||||
#include "ARMSC000.h"
|
||||
#elif defined ARMSC300
|
||||
#include "ARMSC300.h"
|
||||
#elif defined ARMv8MBL
|
||||
#include "ARMv8MBL.h"
|
||||
#elif defined ARMv8MML
|
||||
#include "ARMv8MML.h"
|
||||
#elif defined ARMv8MML_DSP
|
||||
#include "ARMv8MML_DSP.h"
|
||||
#elif defined ARMv8MML_SP
|
||||
#include "ARMv8MML_SP.h"
|
||||
#elif defined ARMv8MML_DSP_SP
|
||||
#include "ARMv8MML_DSP_SP.h"
|
||||
#elif defined ARMv8MML_DP
|
||||
#include "ARMv8MML_DP.h"
|
||||
#elif defined ARMv8MML_DSP_DP
|
||||
#include "ARMv8MML_DSP_DP.h"
|
||||
|
||||
#else
|
||||
#warning "no appropriate header file found!"
|
||||
#endif
|
||||
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
/* Macros and Defines */
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* Initial value for the SysTick module.
|
||||
*
|
||||
* @note This is also the maximum value, important as SysTick is a decrementing
|
||||
* counter.
|
||||
*/
|
||||
#define JTEST_SYSTICK_INITIAL_VALUE 0xFFFFFF
|
||||
|
||||
/**
|
||||
* Reset the SysTick, decrementing timer to it's maximum value and disable it.
|
||||
*
|
||||
* This macro should leave the SysTick timer in a state that's ready for cycle
|
||||
* counting.
|
||||
*/
|
||||
#define JTEST_SYSTICK_RESET(systick_ptr) \
|
||||
do \
|
||||
{ \
|
||||
(systick_ptr)->LOAD = JTEST_SYSTICK_INITIAL_VALUE; \
|
||||
(systick_ptr)->VAL = 1; \
|
||||
\
|
||||
/* Disable the SysTick module. */ \
|
||||
(systick_ptr)->CTRL = UINT32_C(0x000000); \
|
||||
} while (0)
|
||||
|
||||
/**
|
||||
* Start the SysTick timer, sourced by the processor clock.
|
||||
*/
|
||||
#define JTEST_SYSTICK_START(systick_ptr) \
|
||||
do \
|
||||
{ \
|
||||
(systick_ptr)->CTRL = \
|
||||
SysTick_CTRL_ENABLE_Msk | \
|
||||
SysTick_CTRL_CLKSOURCE_Msk; /* Internal clk*/ \
|
||||
} while (0)
|
||||
|
||||
/**
|
||||
* Evaluate to the current value of the SysTick timer.
|
||||
*/
|
||||
#define JTEST_SYSTICK_VALUE(systick_ptr) \
|
||||
((systick_ptr)->VAL)
|
||||
|
||||
#endif /* _JTEST_SYSTICK_H_ */
|
||||
@@ -0,0 +1,100 @@
|
||||
#ifndef _JTEST_TEST_H_
|
||||
#define _JTEST_TEST_H_
|
||||
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
/* Includes */
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include "jtest_util.h"
|
||||
#include "jtest_test_ret.h"
|
||||
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
/* Type Definitions */
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* A struct which represents a Test in the JTEST framework. This struct is
|
||||
* used to enable, run, and describe the test it represents.
|
||||
*/
|
||||
typedef struct JTEST_TEST_struct
|
||||
{
|
||||
JTEST_TEST_RET_t ( * test_fn_ptr)(void); /**< Pointer to the test function. */
|
||||
char * test_fn_str; /**< Name of the test function */
|
||||
char * fut_str; /**< Name of the function under test. */
|
||||
|
||||
/**
|
||||
* Flags that govern how the #JTEST_TEST_t behaves.
|
||||
*/
|
||||
union {
|
||||
struct {
|
||||
unsigned enabled : 1;
|
||||
unsigned unused : 7;
|
||||
} bits;
|
||||
uint8_t byte; /* Access all flags at once. */
|
||||
} flags;
|
||||
|
||||
} JTEST_TEST_t;
|
||||
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
/* Macros and Defines */
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* Assign a test function to the #JTEST_TEST_t struct.
|
||||
*/
|
||||
#define JTEST_TEST_SET_FN(jtest_test_ptr, fn_ptr) \
|
||||
JTEST_SET_STRUCT_ATTRIBUTE(jtest_test_ptr, test_fn_ptr, fn_ptr)
|
||||
|
||||
/**
|
||||
* Specify a function under test (FUT) for the #JTEST_TEST_t struct.
|
||||
*/
|
||||
#define JTEST_TEST_SET_FUT(jtest_test_ptr, str) \
|
||||
JTEST_SET_STRUCT_ATTRIBUTE(jtest_test_ptr, fut_str, str)
|
||||
|
||||
/* Macros concerning JTEST_TEST_t flags */
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
|
||||
#define JTEST_TEST_FLAG_SET 1 /**< Value of a set #JTEST_TEST_t flag. */
|
||||
#define JTEST_TEST_FLAG_CLR 0 /**< Value of a cleared #JTEST_TEST_t flag. */
|
||||
|
||||
/**
|
||||
* Evaluate to the flag in #JTEST_TEST_t having flag_name.
|
||||
*/
|
||||
#define JTEST_TEST_FLAG(jtest_test_ptr, flag_name) \
|
||||
((jtest_test_ptr)->flags.bits.flag_name)
|
||||
|
||||
/**
|
||||
* Dispatch macro for setting and clearing #JTEST_TEST_t flags.
|
||||
*
|
||||
* @param jtest_test_ptr Pointer to a #JTEST_TEST_t struct.
|
||||
* @param flag_name Name of the flag to set in #JTEST_TEST_t.flags.bits
|
||||
* @param xxx Vaid values: "SET" or "CLR"
|
||||
*
|
||||
* @note This function depends on JTEST_TEST_FLAG_SET and JTEST_TEST_FLAG_CLR.
|
||||
*/
|
||||
#define JTEST_TEST_XXX_FLAG(jtest_test_ptr, flag_name, xxx) \
|
||||
do \
|
||||
{ \
|
||||
JTEST_TEST_FLAG(jtest_test_ptr, flag_name) = JTEST_TEST_FLAG_##xxx ; \
|
||||
} while (0)
|
||||
|
||||
/**
|
||||
* Specification of #JTEST_TEST_XXX_FLAG to set #JTEST_TEST_t flags.
|
||||
*/
|
||||
#define JTEST_TEST_SET_FLAG(jtest_test_ptr, flag_name) \
|
||||
JTEST_TEST_XXX_FLAG(jtest_test_ptr, flag_name, SET)
|
||||
|
||||
/**
|
||||
* Specification of #JTEST_TEST_XXX_FLAG to clear #JTEST_TEST_t flags.
|
||||
*/
|
||||
#define JTEST_TEST_CLR_FLAG(jtest_test_ptr, flag_name) \
|
||||
JTEST_TEST_XXX_FLAG(jtest_test_ptr, flag_name, CLR)
|
||||
|
||||
/**
|
||||
* Evaluate to true if the #JTEST_TEST_t is enabled.
|
||||
*/
|
||||
#define JTEST_TEST_IS_ENABLED(jtest_test_ptr) \
|
||||
(JTEST_TEST_FLAG(jtest_test_ptr, enabled) == JTEST_TEST_FLAG_SET)
|
||||
|
||||
#endif /* _JTEST_TEST_H_ */
|
||||
@@ -0,0 +1,121 @@
|
||||
#ifndef _JTEST_TEST_CALL_H_
|
||||
#define _JTEST_TEST_CALL_H_
|
||||
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
/* Includes */
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
#include "jtest_test.h"
|
||||
#include "jtest_test_define.h"
|
||||
#include "jtest_fw.h"
|
||||
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
/* Macros and Defines */
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* Exectute the test in the #JTEST_TEST_t struct associated with the identifier
|
||||
* test_fn and store the result in retval.
|
||||
*/
|
||||
#define JTEST_TEST_RUN(retval, test_fn) \
|
||||
do \
|
||||
{ \
|
||||
JTEST_DUMP_STR("Test Name:\n"); \
|
||||
JTEST_DUMP_STR(JTEST_TEST_STRUCT_NAME(test_fn).test_fn_str); \
|
||||
JTEST_DUMP_STR("Function Under Test:\n"); \
|
||||
JTEST_DUMP_STR(JTEST_TEST_STRUCT_NAME(test_fn).fut_str); \
|
||||
retval = JTEST_TEST_STRUCT_NAME(test_fn).test_fn_ptr(); \
|
||||
} while (0)
|
||||
|
||||
/**
|
||||
* Update the enclosing #JTEST_GROUP_t's pass/fail information based on
|
||||
* test_retval.
|
||||
*
|
||||
* @param test_retval A #JTEST_TEST_RET_enum for the current test.
|
||||
*
|
||||
* @warning Only use if #JTEST_TEST_t is called in the context of a
|
||||
* #JTEST_GROUP_t.
|
||||
*/
|
||||
#define JTEST_TEST_UPDATE_PARENT_GROUP_PF(test_retval) \
|
||||
do \
|
||||
{ \
|
||||
/* Update enclosing JTEST_GROUP_t with pass/fail info */ \
|
||||
if (test_retval == JTEST_TEST_PASSED) \
|
||||
{ \
|
||||
JTEST_GROUP_INC_PASSED(JTEST_CURRENT_GROUP_PTR(), 1); \
|
||||
} else { \
|
||||
JTEST_GROUP_INC_FAILED(JTEST_CURRENT_GROUP_PTR(), 1); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
/**
|
||||
* Update the #JTEST_FW with pass/fail information based on test_retval.
|
||||
*
|
||||
* @param test_retval A #JTEST_TEST_RET_enum for the current test.
|
||||
*/
|
||||
#define JTEST_TEST_UPDATE_FW_PF(test_retval) \
|
||||
do \
|
||||
{ \
|
||||
/* Update the JTEST_FW with pass/fail info */ \
|
||||
if (test_retval == JTEST_TEST_PASSED) \
|
||||
{ \
|
||||
JTEST_FW_INC_PASSED( 1); \
|
||||
} else { \
|
||||
JTEST_FW_INC_FAILED(1); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
/**
|
||||
* Update the enclosing JTEST_GROUP_t's pass/fail information, or the
|
||||
* #JTEST_FW's if this test has no enclosing #JTEST_GROUP_t.
|
||||
*
|
||||
* @param test_retval A #JTEST_TEST_RET_enum for the current test.
|
||||
*/
|
||||
#define JTEST_TEST_UPDATE_PARENT_GROUP_OR_FW_PF(test_retval) \
|
||||
do \
|
||||
{ \
|
||||
/* Update pass-fail information */ \
|
||||
if (JTEST_CURRENT_GROUP_PTR() /* Non-null */) \
|
||||
{ \
|
||||
JTEST_TEST_UPDATE_PARENT_GROUP_PF(test_retval); \
|
||||
} else { \
|
||||
JTEST_TEST_UPDATE_FW_PF(test_retval); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
/**
|
||||
* Dump the results of the test to the Keil Debugger.
|
||||
*/
|
||||
#define JTEST_TEST_DUMP_RESULTS(test_retval) \
|
||||
do \
|
||||
{ \
|
||||
if (test_retval == JTEST_TEST_PASSED) \
|
||||
{ \
|
||||
JTEST_DUMP_STR("Test Passed\n"); \
|
||||
} else { \
|
||||
JTEST_DUMP_STR("Test Failed\n"); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
/**
|
||||
* Call the #JTEST_TEST_t assocaited with the identifier test_fn.
|
||||
*/
|
||||
#define JTEST_TEST_CALL(test_fn) \
|
||||
do \
|
||||
{ \
|
||||
if (JTEST_TEST_IS_ENABLED(&JTEST_TEST_STRUCT_NAME(test_fn))) \
|
||||
{ \
|
||||
/* Default to failure */ \
|
||||
JTEST_TEST_RET_t __jtest_test_ret = JTEST_TEST_FAILED; \
|
||||
\
|
||||
JTEST_ACT_TEST_START(); \
|
||||
JTEST_TEST_RUN(__jtest_test_ret, test_fn); \
|
||||
\
|
||||
/* Update pass-fail information */ \
|
||||
JTEST_TEST_UPDATE_PARENT_GROUP_OR_FW_PF(__jtest_test_ret); \
|
||||
\
|
||||
JTEST_TEST_DUMP_RESULTS(__jtest_test_ret); \
|
||||
JTEST_ACT_TEST_END(); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#endif /* _JTEST_TEST_CALL_H_ */
|
||||
@@ -0,0 +1,133 @@
|
||||
#ifndef _JTEST_TEST_DEFINE_H_
|
||||
#define _JTEST_TEST_DEFINE_H_
|
||||
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
/* Includes */
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
|
||||
#include "jtest_util.h"
|
||||
#include "jtest_define.h"
|
||||
#include "jtest_test.h"
|
||||
|
||||
/* For defining macros with optional arguments */
|
||||
#include "opt_arg/opt_arg.h"
|
||||
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
/* Macros and Defines */
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* Prefix for all #JTEST_TEST_t structs.
|
||||
*/
|
||||
#define JTEST_TEST_STRUCT_NAME_PREFIX G_JTEST_TEST_STRUCT_
|
||||
|
||||
/**
|
||||
* Define test template used by #JTEST_TEST_t tests.
|
||||
*/
|
||||
#define JTEST_TEST_FN_TEMPLATE(test_fn) \
|
||||
JTEST_TEST_RET_t test_fn(void)
|
||||
|
||||
#define JTEST_TEST_FN_PROTOTYPE JTEST_TEST_FN_TEMPLATE /**< Alias for
|
||||
* #JTEST_TEST_FN_TEMPLATE. */
|
||||
|
||||
/**
|
||||
* Evaluate to the name of the #JTEST_TEST_t struct associated with test_fn.
|
||||
*/
|
||||
#define JTEST_TEST_STRUCT_NAME(test_fn) \
|
||||
JTEST_STRUCT_NAME(JTEST_TEST_STRUCT_NAME_PREFIX, test_fn)
|
||||
|
||||
/**
|
||||
* Define a #JTEST_TEST_t struct based on the given test_fn.
|
||||
*/
|
||||
#define JTEST_TEST_DEFINE_STRUCT(test_fn) \
|
||||
JTEST_DEFINE_STRUCT(JTEST_TEST_t, \
|
||||
JTEST_TEST_STRUCT_NAME(test_fn))
|
||||
|
||||
/**
|
||||
* Declare a #JTEST_TEST_t struct based on the given test_fn.
|
||||
*/
|
||||
#define JTEST_TEST_DECLARE_STRUCT(test_fn) \
|
||||
JTEST_DECLARE_STRUCT(JTEST_TEST_DEFINE_STRUCT(test_fn))
|
||||
|
||||
/**
|
||||
* Contents needed to initialize a JTEST_TEST_t struct.
|
||||
*/
|
||||
#define JTEST_TEST_STRUCT_INIT(test_fn, fut, enable) \
|
||||
test_fn, \
|
||||
STR_NL(test_fn), \
|
||||
STR_NL(fut), \
|
||||
{ \
|
||||
{ \
|
||||
enable, \
|
||||
0 \
|
||||
} \
|
||||
} \
|
||||
|
||||
|
||||
/**
|
||||
* Initialize the contents of a #JTEST_TEST_t struct.
|
||||
*/
|
||||
#define JTEST_TEST_INIT(test_fn, fut, enable) \
|
||||
JTEST_TEST_DEFINE_STRUCT(test_fn) = { \
|
||||
JTEST_TEST_STRUCT_INIT(test_fn, fut, enable) \
|
||||
}
|
||||
|
||||
/* Test Definition Macro */
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* Define a #JTEST_TEST_t object and a test function.
|
||||
*/
|
||||
#define _JTEST_DEFINE_TEST(test_fn, fut, enable) \
|
||||
JTEST_TEST_FN_PROTOTYPE(test_fn); \
|
||||
JTEST_TEST_INIT(test_fn, fut, enable); \
|
||||
JTEST_TEST_FN_PROTOTYPE(test_fn) /* Notice the lacking semicolon */
|
||||
|
||||
/**
|
||||
* Declare a #JTEST_TEST_t object and a test function prototype.
|
||||
*/
|
||||
#define JTEST_DECLARE_TEST(test_fn) \
|
||||
JTEST_TEST_FN_PROTOTYPE(test_fn); \
|
||||
JTEST_TEST_DECLARE_STRUCT(test_fn) /* Note the lacking semicolon */
|
||||
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
/* Macros with optional arguments */
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
|
||||
/* Top-level Interface */
|
||||
#define JTEST_DEFINE_TEST(...) \
|
||||
JTEST_DEFINE_TEST_(PP_NARG(__VA_ARGS__), ##__VA_ARGS__)
|
||||
|
||||
/* Dispatch Macro*/
|
||||
#define JTEST_DEFINE_TEST_(N, ...) \
|
||||
SPLICE(JTEST_DEFINE_TEST_, N)(__VA_ARGS__)
|
||||
|
||||
/* Default Arguments */
|
||||
#define JTEST_DEFINE_TEST_DEFAULT_FUT /* Blank */
|
||||
#define JTEST_DEFINE_TEST_DEFAULT_ENABLE \
|
||||
JTEST_TRUE /* Tests enabled by
|
||||
* default. */
|
||||
|
||||
/* Dispatch Cases*/
|
||||
#define JTEST_DEFINE_TEST_1(_1) \
|
||||
_JTEST_DEFINE_TEST( \
|
||||
_1, \
|
||||
JTEST_DEFINE_TEST_DEFAULT_FUT, \
|
||||
JTEST_DEFINE_TEST_DEFAULT_ENABLE \
|
||||
)
|
||||
|
||||
#define JTEST_DEFINE_TEST_2(_1, _2) \
|
||||
_JTEST_DEFINE_TEST( \
|
||||
_1, \
|
||||
_2, \
|
||||
JTEST_DEFINE_TEST_DEFAULT_ENABLE \
|
||||
)
|
||||
|
||||
#define JTEST_DEFINE_TEST_3(_1, _2, _3) \
|
||||
_JTEST_DEFINE_TEST( \
|
||||
_1, \
|
||||
_2, \
|
||||
_3 \
|
||||
)
|
||||
|
||||
#endif /* _JTEST_TEST_DEFINE_H_ */
|
||||
@@ -0,0 +1,17 @@
|
||||
#ifndef _JTEST_TEST_RET_H_
|
||||
#define _JTEST_TEST_RET_H_
|
||||
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
/* Type Definitions */
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* Values a #JTEST_TEST_t can return.
|
||||
*/
|
||||
typedef enum JTEST_TEST_RET_enum
|
||||
{
|
||||
JTEST_TEST_PASSED,
|
||||
JTEST_TEST_FAILED
|
||||
} JTEST_TEST_RET_t;
|
||||
|
||||
#endif /* _JTEST_TEST_RET_H_ */
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user