Просмотр исходного кода

CMSIS-DSP: DSP_Lib_TestSuite can be built with cmake.

DSP_Lib_TestSuite can be built with cmake and run on FVP.
Some issues with CMSIS-DSP cmake where discovered and corrected.

Comments added to arm_biqaud_cascade_df2T+f32 since the Neon version
must be initialized differently (and thus the corresponding test
in DSP_Lib_TestSuite will have to be updated to pass with Neon version).
Christophe Favergeon 6 лет назад
Родитель
Сommit
04ed2f023b

+ 86 - 0
CMSIS/DSP/DSP_Lib_TestSuite/CMakeLists.txt

@@ -0,0 +1,86 @@
+cmake_minimum_required (VERSION 3.6)
+cmake_policy(SET CMP0077 NEW)
+# The tests are assuming that MATRIX_CHECK is enabled when building
+# CMSIS-DSP.
+set(MATRIXCHECK ON)
+set(FASTMATHCOMPUTATIONS OFF)
+option(DUMPPATTERN "Dump test patterns when test is failing" ON)
+project(DSP_Lib_TestSuite)
+
+# Needed to find the config modules
+list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/..)
+
+
+set(ROOT ${CMAKE_CURRENT_SOURCE_DIR}/../../..)
+
+
+file(GLOB MAIN "Common/src/*.c")
+file(GLOB BASICMATH_TESTS "Common/src/basic_math_tests/*.c")
+file(GLOB COMPLEXMATH_TESTS "Common/src/complex_math_tests/*.c")
+file(GLOB CONTROLLER_TESTS "Common/src/controller_tests/*.c")
+file(GLOB FASTMATH_TESTS "Common/src/fast_math_tests/*.c")
+file(GLOB FILTERING_TESTS "Common/src/filtering_tests/*.c")
+file(GLOB INTRINSINCS_TESTS "Common/src/intrinsics_tests/*.c")
+file(GLOB MATRIX_TESTS "Common/src/matrix_tests/*.c")
+file(GLOB STATISTICS_TESTS "Common/src/statistics_tests/*.c")
+file(GLOB SUPPORT_TESTS "Common/src/support_tests/*.c")
+file(GLOB TRANSFORM_TESTS "Common/src/transform_tests/*.c")
+file(GLOB JTEST_MAIN "Common/JTest/src/*.c")
+
+set(TESTSRC ${MAIN}
+  ${BASICMATH_TESTS}
+  ${COMPLEXMATH_TESTS}
+  ${CONTROLLER_TESTS}
+  ${FASTMATH_TESTS}
+  ${FILTERING_TESTS}
+  ${INTRINSINCS_TESTS}
+  ${MATRIX_TESTS}
+  ${STATISTICS_TESTS}
+  ${SUPPORT_TESTS}
+  ${TRANSFORM_TESTS}
+  ${JTEST_MAIN}
+  )
+
+set(JINCS 
+  Common/JTest/inc
+  Common/JTest/inc/arr_desc
+  Common/inc/basic_math_tests
+  Common/inc/complex_math_tests
+  Common/inc/controller_tests
+  Common/inc/fast_math_tests
+  Common/inc/filtering_tests
+  Common/inc/intrinsics_tests
+  Common/inc/matrix_tests
+  Common/inc/statistics_tests 
+  Common/inc/support_tests 
+  Common/inc/transform_tests
+  )
+
+add_subdirectory(../Source bin_dsp)
+add_subdirectory(RefLibs bin_ref)
+
+
+add_executable(DSP_Lib_TestSuite)
+
+if (DUMPPATTERN)
+      target_compile_definitions(DSP_Lib_TestSuite PRIVATE DUMPPATTERN)
+endif()
+
+# Change behavior of configBoot for scatter file
+set(TESTFRAMEWORK ON)
+
+include(configBoot)
+
+file(COPY ${ROOT}/CMSIS/DSP/Examples/ARM/boot/RTE_Components.h DESTINATION tempLink)
+
+target_link_libraries(DSP_Lib_TestSuite PRIVATE CMSISDSP)
+target_link_libraries(DSP_Lib_TestSuite PRIVATE DspRefLibs)
+
+target_sources(DSP_Lib_TestSuite PRIVATE ${TESTSRC})
+
+### Includes
+target_include_directories(DSP_Lib_TestSuite PRIVATE "Common/inc")
+target_include_directories(DSP_Lib_TestSuite PRIVATE "Common/inc/templates")
+target_include_directories(DSP_Lib_TestSuite PRIVATE ${JINCS})
+
+

+ 3 - 3
CMSIS/DSP/DSP_Lib_TestSuite/Common/JTest/inc/jtest_fw.h

@@ -141,13 +141,13 @@ typedef struct JTEST_FW_struct
  *  Fill the buffer named buf_name with value and dump it to the Keil debugger
  *  using action.
  */
-#ifdef ARMv7A
+#if defined(ARMv7A) || defined(FILEIO)
 
 #define JTEST_ACT_DUMP(action, buf_name, value) \
     do                                          \
     {                                           \
         JTEST_CLEAR_BUFFER(buf_name);           \
-	printf("%s",value);                     \
+	    printf("%s",value);                     \
         strcpy(JTEST_FW.buf_name, (value));     \
         JTEST_TRIGGER_ACTION(action);           \
     } while (0)
@@ -206,7 +206,7 @@ typedef struct JTEST_FW_struct
 /**
  *  Dump a formatted string to the Keil Debugger.
  */
-#ifdef ARMv7A
+#if defined(ARMv7A) || defined(FILEIO)
 
 #define JTEST_DUMP_STRF(format_str, ... )                               \
     do                                                                  \

+ 81 - 18
CMSIS/DSP/DSP_Lib_TestSuite/Common/inc/templates/test_templates.h

@@ -62,25 +62,45 @@
 /**
  *  Assert that buffers A and B are byte-equivalent for a number of bytes.
  */
+#if defined(DUMPPATTERN)
 #define TEST_ASSERT_BUFFERS_EQUAL(buf_a, buf_b, bytes)  \
     do                                                  \
     {                                                   \
         if (memcmp(buf_a, buf_b, bytes) != 0)           \
         {                                               \
+            JTEST_DUMP_STRF("%s","DUMP PATTERNS\n");    \
+            for(unsigned long i=0;i < bytes; i++)       \
+            {                                           \
+                /*JTEST_DUMP_STRF("%0x %0x\n", *a,*b);*/\
+            }                                           \
             return JTEST_TEST_FAILED;                   \
         }                                               \
     } while (0)
 
+#else
+
+#define TEST_ASSERT_BUFFERS_EQUAL(buf_a, buf_b, bytes)\
+    do                                                \
+    {                                                 \
+        if (memcmp(buf_a, buf_b, bytes) != 0)         \
+        {                                             \
+            return JTEST_TEST_FAILED;                 \
+        }                                             \
+    } while (0)
+
+
+#endif 
+
 /**
  *  Assert that the two entities are equal.
  */
-#define TEST_ASSERT_EQUAL(a, b)                         \
-    do                                                  \
-    {                                                   \
-        if ((a) != (b))                                 \
-        {                                               \
-            return JTEST_TEST_FAILED;                   \
-        }                                               \
+#define TEST_ASSERT_EQUAL(a, b)      \
+    do                               \
+    {                                \
+        if ((a) != (b))              \
+        {                            \
+            return JTEST_TEST_FAILED;\
+        }                            \
     } while (0)
 
 /**
@@ -111,31 +131,74 @@
  *  Assert that the SNR between a reference and test sample is above a given
  *  threshold.
  */
-#define TEST_ASSERT_SNR(ref_ptr, tst_ptr, block_size, threshold)    \
+#if defined(DUMPPATTERN)
+
+#define TEST_ASSERT_SNR(ref_ptr, tst_ptr, block_size, threshold)  \
+    do                                                            \
+    {                                                             \
+        float32_t snr = arm_snr_f32(ref_ptr, tst_ptr, block_size);\
+        if ( snr <= threshold)                                    \
+        {                                                         \
+            JTEST_DUMP_STRF("%s","DUMP PATTERNS\n");                   \
+            for(unsigned long i=0;i < block_size; i++)            \
+            {                                                     \
+                /*JTEST_DUMP_STRF("%f %f\n", ref_ptr[i],tst_ptr[i]);*/\
+            }                                                     \
+            JTEST_DUMP_STRF("SNR: %f\n", snr);                    \
+            return JTEST_TEST_FAILED;                             \
+        }                                                         \
+    } while (0)
+
+#else
+
+#define TEST_ASSERT_SNR(ref_ptr, tst_ptr, block_size, threshold)  \
+    do                                                            \
+    {                                                             \
+        float32_t snr = arm_snr_f32(ref_ptr, tst_ptr, block_size);\
+        if ( snr <= threshold)                                    \
+        {                                                         \
+            JTEST_DUMP_STRF("SNR: %f\n", snr);                    \
+            return JTEST_TEST_FAILED;                             \
+        }                                                         \
+    } while (0)
+
+#endif
+/**
+ *  Assert that the SNR between a reference and test sample is above a given
+ *  threshold.  Special case for float64_t
+ */
+#if defined(DUMPPATTERN)
+
+#define TEST_ASSERT_DBL_SNR(ref_ptr, tst_ptr, block_size, threshold)\
     do                                                              \
     {                                                               \
-        float32_t snr = arm_snr_f32(ref_ptr, tst_ptr, block_size);  \
-        if ( snr <= threshold)                                       \
+        float64_t snr = arm_snr_f64(ref_ptr, tst_ptr, block_size);  \
+        if ( snr <= threshold)                                      \
         {                                                           \
+            JTEST_DUMP_STRF("%s","DUMP PATTERNS\n");                    \
+            for(unsigned long i=0;i < block_size; i++)              \
+            {                                                       \
+               /* JTEST_DUMP_STRF("%f %f\n", ref_ptr[i],tst_ptr[i]);*/  \
+            }                                                       \
             JTEST_DUMP_STRF("SNR: %f\n", snr);                      \
             return JTEST_TEST_FAILED;                               \
         }                                                           \
-    } while (0)                                                      \
+    } while (0)
 
-/**
- *  Assert that the SNR between a reference and test sample is above a given
- *  threshold.  Special case for float64_t
- */
-#define TEST_ASSERT_DBL_SNR(ref_ptr, tst_ptr, block_size, threshold)    \
+#else
+
+#define TEST_ASSERT_DBL_SNR(ref_ptr, tst_ptr, block_size, threshold)\
     do                                                              \
     {                                                               \
         float64_t snr = arm_snr_f64(ref_ptr, tst_ptr, block_size);  \
-        if ( snr <= threshold)                                       \
+        if ( snr <= threshold)                                      \
         {                                                           \
             JTEST_DUMP_STRF("SNR: %f\n", snr);                      \
             return JTEST_TEST_FAILED;                               \
         }                                                           \
-    } while (0)                                                      \
+    } while (0)
+
+#endif
 
 /**
  *  Compare test and reference elements by converting to float and

+ 3 - 0
CMSIS/DSP/DSP_Lib_TestSuite/Common/src/all_tests.c

@@ -21,6 +21,9 @@ JTEST_DEFINE_GROUP(all_tests)
   JTEST_GROUP_CALL(complex_math_tests);
   JTEST_GROUP_CALL(controller_tests);
   JTEST_GROUP_CALL(fast_math_tests);
+  /* Biquad df2T_f32 will fail with Neon. The test must be updated.
+  Neon implementation is requiring a different initialization.
+  */
   JTEST_GROUP_CALL(filtering_tests);
   JTEST_GROUP_CALL(matrix_tests);
   JTEST_GROUP_CALL(statistics_tests);

+ 4 - 0
CMSIS/DSP/DSP_Lib_TestSuite/Common/src/main.c

@@ -16,12 +16,16 @@ void debug_init(void)
 
 int main(void)
 {
+#if !defined(FILEIO)
     debug_init();
+#endif
 
     JTEST_INIT();               /* Initialize test framework. */
 
     JTEST_GROUP_CALL(all_tests); /* Run all tests. */
 
     JTEST_ACT_EXIT_FW();        /* Exit test framework.  */
+#if !defined(FILEIO)
     while (1);                   /* Never return. */
+#endif
 }

+ 78 - 0
CMSIS/DSP/DSP_Lib_TestSuite/RefLibs/CMakeLists.txt

@@ -0,0 +1,78 @@
+cmake_minimum_required (VERSION 3.6)
+
+project(DspRefLibs)
+
+# Needed to find the config modules
+list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/../..)
+
+
+
+
+set(REFSRC src/BasicMathFunctions/abs.c
+  src/BasicMathFunctions/add.c
+  src/BasicMathFunctions/dot_prod.c
+  src/BasicMathFunctions/mult.c
+  src/BasicMathFunctions/negate.c
+  src/BasicMathFunctions/offset.c
+  src/BasicMathFunctions/scale.c
+  src/BasicMathFunctions/shift.c
+  src/BasicMathFunctions/sub.c
+  src/ComplexMathFunctions/cmplx_conj.c
+  src/ComplexMathFunctions/cmplx_dot_prod.c
+  src/ComplexMathFunctions/cmplx_mag.c
+  src/ComplexMathFunctions/cmplx_mag_squared.c
+  src/ComplexMathFunctions/cmplx_mult_cmplx.c
+  src/ComplexMathFunctions/cmplx_mult_real.c
+  src/ControllerFunctions/pid.c
+  src/ControllerFunctions/sin_cos.c
+  src/FastMathFunctions/cos.c
+  src/FastMathFunctions/sin.c
+  src/FastMathFunctions/sqrt.c
+  src/FilteringFunctions/biquad.c
+  src/FilteringFunctions/conv.c
+  src/FilteringFunctions/correlate.c
+  src/FilteringFunctions/fir.c
+  src/FilteringFunctions/fir_decimate.c
+  src/FilteringFunctions/fir_interpolate.c
+  src/FilteringFunctions/fir_lattice.c
+  src/FilteringFunctions/fir_sparse.c
+  src/FilteringFunctions/iir_lattice.c
+  src/FilteringFunctions/lms.c
+  src/HelperFunctions/mat_helper.c
+  src/HelperFunctions/ref_helper.c
+  src/Intrinsics/intrinsics.c
+  src/MatrixFunctions/mat_add.c
+  src/MatrixFunctions/mat_cmplx_mult.c
+  src/MatrixFunctions/mat_inverse.c
+  src/MatrixFunctions/mat_mult.c
+  src/MatrixFunctions/mat_scale.c
+  src/MatrixFunctions/mat_sub.c
+  src/MatrixFunctions/mat_trans.c
+  src/StatisticsFunctions/max.c
+  src/StatisticsFunctions/mean.c
+  src/StatisticsFunctions/min.c
+  src/StatisticsFunctions/power.c
+  src/StatisticsFunctions/rms.c
+  src/StatisticsFunctions/std.c
+  src/StatisticsFunctions/var.c
+  src/SupportFunctions/copy.c
+  src/SupportFunctions/fill.c
+  src/SupportFunctions/fixed_to_fixed.c
+  src/SupportFunctions/fixed_to_float.c
+  src/SupportFunctions/float_to_fixed.c
+  src/TransformFunctions/bitreversal.c
+  src/TransformFunctions/cfft.c
+  src/TransformFunctions/dct4.c
+  src/TransformFunctions/rfft.c
+  )
+
+add_library(DspRefLibs STATIC ${REFSRC})
+
+include(config)
+configdsp(DspRefLibs ../../Source)
+
+### Includes
+target_include_directories(DspRefLibs PUBLIC "inc")
+target_include_directories(DspRefLibs PUBLIC "../../Include")
+
+

+ 5 - 0
CMSIS/DSP/DSP_Lib_TestSuite/RefLibs/inc/ref.h

@@ -59,10 +59,15 @@ extern "C"
   } dataType;
 
 
+#ifndef FLT_MAX
 #define FLT_MAX  3.40282347e+38F
+#endif 
+
 #define DBL_MAX  1.79769313486231571e+308
 
+#ifndef FLT_MIN
 #define FLT_MIN  1.175494351e-38F
+#endif
 #define DBL_MIN  2.22507385850720138e-308
 
 #define SCHAR_MIN (-128)

+ 1 - 1
CMSIS/DSP/DSP_Lib_TestSuite/RefLibs/src/TransformFunctions/bitreversal.c

@@ -8,7 +8,7 @@
 ;* @param[in]      *pBitRevTab  points to bit reversal table.   
 ;* @return none.   
 ;*/
-void arm_bitreversal_32(uint32_t *pSrc, uint32_t bitRevLen, uint32_t *pBitRevTab)
+void ref_arm_bitreversal_32(uint32_t *pSrc, uint32_t bitRevLen, uint32_t *pBitRevTab)
 {
 	uint32_t a,b,i,tmp;
 	

+ 2 - 0
CMSIS/DSP/Examples/ARM/arm_variance_example/CMakeLists.txt

@@ -27,6 +27,8 @@ add_subdirectory(../../../Source bin_dsp)
 
 add_executable(arm_variance_example)
 
+set(ROOT ${CMAKE_CURRENT_SOURCE_DIR}/../../../../..)
+
 include(configBoot)
 
 target_sources(arm_variance_example PRIVATE arm_variance_example_f32.c)

+ 1 - 2
CMSIS/DSP/Include/arm_math.h

@@ -320,6 +320,7 @@
 
 #include "string.h"
 #include "math.h"
+#include "float.h"
 
 /* evaluate ARM DSP feature */
 #if (defined (__ARM_FEATURE_DSP) && (__ARM_FEATURE_DSP == 1))
@@ -817,8 +818,6 @@ compiler file in Core or Core_A would not make sense.
 
 #if defined(ARM_MATH_NEON)
 
-#define FLT_MIN 1E-37
-  
 static inline float32x4_t __arm_vec_sqrt_f32_neon(float32x4_t  x)
 {
     float32x4_t x1 = vmaxq_f32(x, vdupq_n_f32(FLT_MIN));

+ 1 - 2
CMSIS/DSP/Source/ControllerFunctions/CMakeLists.txt

@@ -2,8 +2,7 @@ cmake_minimum_required (VERSION 3.6)
 
 project(CMSISDSPController)
 
-
-add_library(CMSISDSPController STATIC ${SRC})
+add_library(CMSISDSPController STATIC)
 
 configdsp(CMSISDSPController ..)
 

+ 1 - 1
CMSIS/DSP/Source/FilteringFunctions/CMakeLists.txt

@@ -3,7 +3,7 @@ cmake_minimum_required (VERSION 3.6)
 project(CMSISDSPFiltering)
 
 
-add_library(CMSISDSPFiltering STATIC ${SRC})
+add_library(CMSISDSPFiltering STATIC)
 
 include(interpol)
 interpol(CMSISDSPFiltering)

+ 36 - 1
CMSIS/DSP/Source/FilteringFunctions/arm_biquad_cascade_df2T_init_f32.c

@@ -46,14 +46,39 @@
   @return        none
 
   @par           Coefficient and State Ordering
-                   The coefficients are stored in the array <code>pCoeffs</code> in the following order:
+                   The coefficients are stored in the array <code>pCoeffs</code> in the following order
+                   in the not Neon version.
   <pre>
       {b10, b11, b12, a11, a12, b20, b21, b22, a21, a22, ...}
   </pre>
+                   
   @par
                    where <code>b1x</code> and <code>a1x</code> are the coefficients for the first stage,
                    <code>b2x</code> and <code>a2x</code> are the coefficients for the second stage,
                    and so on.  The <code>pCoeffs</code> array contains a total of <code>5*numStages</code> values.
+
+                   For Neon version, this array is bigger. If numstages = 4x + y, then the array has size:
+                   32*x + 5*y
+                   and it must be initialized using the function
+                   arm_biquad_cascade_df2T_compute_coefs_f32 which is taking the
+                   standard array coefficient as parameters.
+
+                   But, an array of 8*numstages is a good approximation.
+
+                   Then, the initialization can be done with:
+  <pre>
+                   arm_biquad_cascade_df2T_init_f32(&SNeon, nbCascade, neonCoefs, stateNeon);
+                   arm_biquad_cascade_df2T_compute_coefs_f32(&SNeon,nbCascade,coefs);
+  </pre>
+
+  @par             In this example, neonCoefs is a bigger array of size 8 * numStages.
+                   coefs is the standard array:
+
+  <pre>
+      {b10, b11, b12, a11, a12, b20, b21, b22, a21, a22, ...}
+  </pre>
+
+
   @par
                    The <code>pState</code> is a pointer to state array.
                    Each Biquad stage has 2 state variables <code>d1,</code> and <code>d2</code>.
@@ -63,6 +88,16 @@
  */
 
 #if defined(ARM_MATH_NEON) 
+/*
+
+Must be called after initializing the biquad instance.
+pCoeffs has size 5 * nbCascade
+Whereas the pCoeffs for the init has size (4*4 + 4*4)* nbCascade 
+
+So this pCoeffs is the one which would be used for the not Neon version.
+The pCoeffs passed in init is bigger than the one for the not Neon version.
+
+*/
 void arm_biquad_cascade_df2T_compute_coefs_f32(
   arm_biquad_cascade_df2T_instance_f32 * S,
   uint8_t numStages,

+ 4 - 0
CMSIS/DSP/Source/TransformFunctions/CMakeLists.txt

@@ -38,6 +38,10 @@ target_sources(CMSISDSPTransform PRIVATE arm_cfft_radix4_q31.c)
 target_sources(CMSISDSPTransform PRIVATE arm_cfft_q31.c)
 endif()
 
+if (NOT CONFIGTABLE OR ALLFFT)
+target_sources(CMSISDSPTransform PRIVATE arm_cfft_radix2_init_q15.c)
+target_sources(CMSISDSPTransform PRIVATE arm_cfft_radix2_init_q31.c)
+endif()
 
 if (NOT CONFIGTABLE OR ALLFFT OR DCT4_F32_128 OR DCT4_F32_512 OR DCT4_F32_2048 OR DCT4_F32_8192)
 target_sources(CMSISDSPTransform PRIVATE arm_dct4_f32.c)

+ 3 - 2
CMSIS/DSP/config.cmake

@@ -1,7 +1,8 @@
 include(CMakePrintHelpers)
+cmake_policy(SET CMP0077 NEW)
 
 SET(CORTEXM ON)
-option(FASTMATH "Fast Math enabled" ON)
+option(FASTMATHCOMPUTATIONS "Fast Math enabled" ON)
 option(NEON "Neon acceleration" OFF)
 option(NEONEXPERIMENTAL "Neon experimental acceleration" OFF)
 option(LOOPUNROLL "Loop unrolling" ON)
@@ -22,7 +23,7 @@ function(configdsp PROJECTNAME DSP)
       target_compile_definitions(${PROJECTNAME} PUBLIC ARM_DSP_CONFIG_TABLES)
   endif()
   
-  if (FASTMATH)
+  if (FASTMATHCOMPUTATIONS)
     target_compile_options(${PROJECTNAME} PUBLIC "-ffast-math")
   endif()
   

+ 4 - 1
CMSIS/DSP/configBoot.cmake

@@ -16,7 +16,7 @@ get_filename_component(PROJECT_NAME ${CMAKE_CURRENT_SOURCE_DIR} NAME)
 
 cmake_print_variables(PROJECT_NAME)
 
-set(ROOT ${CMAKE_CURRENT_SOURCE_DIR}/../../../../..)
+#set(ROOT ${CMAKE_CURRENT_SOURCE_DIR}/../../../../..)
 
 if (ARMAC6)
 
@@ -90,6 +90,7 @@ if (ARMAC6)
   #
   if (ARM_CPU STREQUAL "cortex-a5")
     cortexa(ARMCA5)
+    target_compile_definitions(${PROJECT_NAME} PRIVATE ARMv7A) 
   endif()
 
   ###################
@@ -98,6 +99,7 @@ if (ARMAC6)
   #
   if (ARM_CPU STREQUAL "cortex-a7")
     cortexa(ARMCA7)
+    target_compile_definitions(${PROJECT_NAME} PRIVATE ARMv7A) 
   endif()
 
   ###################
@@ -106,6 +108,7 @@ if (ARMAC6)
   #
   if (ARM_CPU STREQUAL "cortex-a9")
     cortexa(ARMCA9)
+    target_compile_definitions(${PROJECT_NAME} PRIVATE ARMv7A) 
   endif()
   
 endif()

+ 18 - 3
CMSIS/DSP/configUtils.cmake

@@ -4,7 +4,13 @@ function(cortexm CORE)
     target_include_directories(${PROJECT_NAME} PRIVATE ${ROOT}/Device/ARM/${CORE}/Include)
     target_include_directories(${PROJECT_NAME} PRIVATE ${ROOT}/CMSIS/Core/Include)
   
-    set(SCATTERFILE "${ROOT}/Device/ARM/${CORE}/Source/ARM/${CORE}_ac6.sct")
+    if (TESTFRAMEWORK)
+      # Need bigger sections for test framework
+      # So we use the test framework scatter file
+      set(SCATTERFILE "${ROOT}/CMSIS/DSP/DSP_Lib_TestSuite/Common/platform/ARMCLANG/armcc6_arm.sct")
+    else()
+      set(SCATTERFILE "${ROOT}/Device/ARM/${CORE}/Source/ARM/${CORE}_ac6.sct")
+    endif()
 
     target_link_options(${PROJECT_NAME} PRIVATE "--info=sizes;--entry=Reset_Handler;--scatter=${SCATTERFILE}")
 
@@ -20,9 +26,18 @@ function(cortexa CORE)
     target_include_directories(${PROJECT_NAME} PRIVATE ${ROOT}/CMSIS/Core_A/Include)
     
     target_sources(${PROJECT_NAME} PRIVATE ${ROOT}/Device/ARM/${CORE}/Source/AC6/startup_${CORE}.c)
-    set(SCATTERFILE ${CMAKE_CURRENT_BINARY_DIR}/tempLink/${CORE}.sct)
     
-    target_include_directories(${PROJECT_NAME} PRIVATE ../boot)
+    if (TESTFRAMEWORK)
+      # Test scatter file is missing some sections required by startup file for
+      # cortex-a
+      #set(SCATTERFILE "${ROOT}/CMSIS/DSP/DSP_Lib_TestSuite/Common/platform/ARMCLANG/armcc6_arm.sct")
+      target_include_directories(${PROJECT_NAME} PRIVATE ../Examples/ARM/boot)
+    else()
+      target_include_directories(${PROJECT_NAME} PRIVATE ../boot)
+    endif()
+
+    set(SCATTERFILE ${CMAKE_CURRENT_BINARY_DIR}/tempLink/${CORE}.sct)
+
     
     # Copy the mem file to the build directory 
     # so that it can be find when preprocessing the scatter file