diff --git a/Examples/.gitignore b/Examples/.gitignore new file mode 100755 index 00000000..567609b1 --- /dev/null +++ b/Examples/.gitignore @@ -0,0 +1 @@ +build/ diff --git a/Examples/ARM/arm_variance_example/CMakeLists.txt b/Examples/ARM/arm_variance_example/CMakeLists.txt new file mode 100755 index 00000000..e2bd12b9 --- /dev/null +++ b/Examples/ARM/arm_variance_example/CMakeLists.txt @@ -0,0 +1,44 @@ +cmake_minimum_required (VERSION 3.6) +project (arm_variance_example VERSION 0.1) + +# Needed to include the configBoot module +list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/../../..) + +################################### +# +# LIBRARIES +# +################################### + +########### +# +# CMSIS DSP +# + +add_subdirectory(../../../Source bin_dsp) + + +################################### +# +# TEST APPLICATION +# +################################### + + +add_executable(arm_variance_example) + +include(configBoot) + +target_sources(arm_variance_example PRIVATE arm_variance_example_f32.c) + +### Sources and libs + +target_link_libraries(arm_variance_example PRIVATE CMSISDSP) + +################################### +# +# INSTALLATION +# +################################### + +install (TARGETS arm_variance_example DESTINATION "${PROJECT_SOURCE_DIR}/varianceExampleBuild.axf") \ No newline at end of file diff --git a/Examples/ARM/arm_variance_example/arm_variance_example_f32.c b/Examples/ARM/arm_variance_example/arm_variance_example_f32.c index b067a846..5596d6f8 100644 --- a/Examples/ARM/arm_variance_example/arm_variance_example_f32.c +++ b/Examples/ARM/arm_variance_example/arm_variance_example_f32.c @@ -90,6 +90,7 @@ /** \example arm_variance_example_f32.c */ + #include #include "arm_math.h" @@ -144,6 +145,10 @@ int32_t main(void) status = ARM_MATH_SUCCESS; +#if defined(FILEIO) + printf("START\n"); +#endif + /* Calculation of mean value of input */ /* x' = 1/blockSize * (x(0)* 1 + x(1) * 1 + ... + x(n-1) * 1) */ @@ -188,17 +193,32 @@ int32_t main(void) diff = fabsf(refVarianceOut - variance); /* Comparison of variance value with reference */ + if (diff > DELTA) { status = ARM_MATH_TEST_FAILURE; } + +#if !defined(FILEIO) if ( status != ARM_MATH_SUCCESS) { while (1); } - while (1); /* main function does not return */ + while (1); /* main function does not return */ +#else + if (status == ARM_MATH_SUCCESS) + { + printf("SUCCESS\n"); + } + else + { + printf("FAILURE\n"); + } +#endif } /** \endlink */ + + diff --git a/Examples/ARM/boot/RTE_Components.h b/Examples/ARM/boot/RTE_Components.h new file mode 100755 index 00000000..db747a66 --- /dev/null +++ b/Examples/ARM/boot/RTE_Components.h @@ -0,0 +1,5 @@ +#ifndef RTE_COMPONENTS_H +#define RTE_COMPONENTS_H + + +#endif /* RTE_COMPONENTS_H */ \ No newline at end of file diff --git a/Include/arm_math.h b/Include/arm_math.h index 336df362..ef573911 100644 --- a/Include/arm_math.h +++ b/Include/arm_math.h @@ -116,6 +116,18 @@ * * Define macro ARM_MATH_LOOPUNROLL to enable manual loop unrolling in DSP functions * + * - ARM_MATH_NEON: + * + * Define macro ARM_MATH_NEON to enable Neon versions of the DSP functions. + * It is not enabled by default when Neon is available because performances are + * dependent on the compiler and target architecture. + * + * - ARM_MATH_NEON_EXPERIMENTAL: + * + * Define macro ARM_MATH_NEON_EXPERIMENTAL to enable experimental Neon versions of + * of some DSP functions. Experimental Neon versions currently do not have better + * performances than the scalar versions. + * *
* CMSIS-DSP in ARM::CMSIS Pack * ----------------------------- @@ -291,28 +303,11 @@ #endif +/* Included for instrinsics definitions */ #include "cmsis_compiler.h" #include "string.h" #include "math.h" -/* evaluate ARM architecture */ -#if defined (__ARM_ARCH_6M__) - #define ARM_MATH_CM0_FAMILY 1 -#elif defined (__ARM_ARCH_7M__) -//#define ARM_MATH_CM0_FAMILY 0 -#elif defined (__ARM_ARCH_7EM__) -//#define ARM_MATH_CM0_FAMILY 0 -#elif defined (__ARM_ARCH_8M_BASE__) - #define ARM_MATH_CM0_FAMILY 1 -#elif defined (__ARM_ARCH_8M_MAIN__) -//#define ARM_MATH_CM0_FAMILY 0 -#elif defined (ARM_MATH_NEON) - #include "core_ca.h" -// #define ARM_MATH_DSP -#else - #error "Unknown Arm Architecture!" -#endif - /* evaluate ARM DSP feature */ #if (defined (__ARM_FEATURE_DSP) && (__ARM_FEATURE_DSP == 1)) #define ARM_MATH_DSP 1 diff --git a/README.md b/README.md new file mode 100755 index 00000000..80877245 --- /dev/null +++ b/README.md @@ -0,0 +1,71 @@ +# README + +## How to use + +This document is explaining how to use cmake with CMSIS-DSP and AC6 ARM compiler. + +The examples arm_variance_f32 in folder Examples/ARM/arm_variance_f32 has been modified to also +support cmake and is used as an example in this document. + +If you don't use AC6, you'll need to modify the cmake files as explained below. + +### Generating the Makefiles + +To build example arm_variance_f32 with cmake, you need to create a build folder where the build will take place. Don't build in your source directory. + +You can create a build folder in Examples/ARM/arm_variance_f32 + +Once you are in the build folder, you can use cmake to generate the Makefiles. + +For instance, to build for m7 : +cmake -DCMAKE_TOOLCHAIN_FILE=../../../../armcc.cmake -DARM_CPU="cortex-m7" -G "Unix Makefiles" .. + +To build for A5 +cmake -DCMAKE_TOOLCHAIN_FILE=../../../../armcc.cmake -DARM_CPU="cortex-a5" -G "Unix Makefiles" .. + +To build for A5 with Neon acceleration +cmake -DCMAKE_TOOLCHAIN_FILE=../../../../armcc.cmake -DNEON=ON -DARM_CPU="cortex-a5" -G "Unix Makefiles" .. + +cmake will check it can find the cross compiling tools as defined in armcc.cmake + +### Toolchain + +You may have to change the "tools" variable in armcc.make. It is pointing to your toolchain. +The version of armcc.cmake on github is using the ARM AC6 compiler coming from the ArmDS environment. The tools variable is thus pointing to ArmDS. + +If you use a different clang toolchain, you can just modify the tools path. + +If you build with gcc, you'll need to change armcc.cmake, config.cmake and configUtils.cmake + +config.make is defining options like -mfpu and the value to pass to gcc (or other compiler) may be different. + +configUtils.cmake is defining the use of a scatter file and it may be different with gcc. + +### Building + +make VERBOSE=1 + +### Running + +The executable can run on a FVP. +For instance, if you built for m7, you could just do: + +FVP_MPS2_Cortex-M7.exe -a arm_variance_example + +## Customization + +armcc.make is use to cross compil with AC6 coming from ArmDS. + +You'll need to create a different toolchain file if you use something different. +Then you'll need to pass this file to cmake on the command line. + +config.cmake is included by the CMSIS-DSP cmake and is defining the options and include paths +needed to compile CMSIS-DSP. + +configBoot.cmake are definitions required to run an executable on a platform. It is using files from the Device folder of CMSIS. The result can run on FVP. + +If you need to run on something different, you'll need to modfy configBoot. If you need a different scatter file you'll need to modify configBoot. + +configBoot is relying on some functions defined in configUtils and most of the customizations should be done here. + + diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt new file mode 100755 index 00000000..6b4c1c3e --- /dev/null +++ b/Source/CMakeLists.txt @@ -0,0 +1,42 @@ +cmake_minimum_required (VERSION 3.6) + +project(CMSISDSP) + +# Needed to find the config module +list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/..) + + +########################### +# +# CMSIS DSP +# +########################### + +# DSP Sources +SET(DSP ".") +SET(COMMON "${DSP}/CommonTables") + +file(GLOB SOURCES_STATS "${DSP}/StatisticsFunctions/*_*.c") +file(GLOB SOURCES_BASIC "${DSP}/BasicMathFunctions/*_*.c") +file(GLOB SOURCES_COMPLEX "${DSP}/ComplexMathFunctions/*_*.c") +file(GLOB SOURCES_FAST "${DSP}/FastMathFunctions/*_*.c") +file(GLOB SOURCES_FILTERING "${DSP}/FilteringFunctions/*_*.c") +file(GLOB SOURCES_MATRIX "${DSP}/MatrixFunctions/*_*.c") +file(GLOB SOURCES_STATS "${DSP}/StatisticsFunctions/*_*.c") +file(GLOB SOURCES_SUPPORT "${DSP}/SupportFunctions/*_*.c") +file(GLOB SOURCES_TRANSFORM "${DSP}/TransformFunctions/*_*.c") + +SET(CMSISDSPSRC ${SOURCES_MATRIX} ${SOURCES_FILTERING} ${SOURCES_SUPPORT} ${SOURCES_COMPLEX} ${SOURCES_TRANSFORM} ${SOURCES_FAST} ${SOURCES_BASIC} ${SOURCES_STATS}) + +add_library(CMSISDSP STATIC ${COMMON}/arm_common_tables.c ${COMMON}/arm_const_structs.c) + +include(config) + +### Sources +target_sources(CMSISDSP PRIVATE ${CMSISDSPSRC}) + +### Includes +target_include_directories(CMSISDSP PUBLIC "${DSP}/../Include") + + + diff --git a/armcc.cmake b/armcc.cmake new file mode 100755 index 00000000..544a8349 --- /dev/null +++ b/armcc.cmake @@ -0,0 +1,48 @@ +# Setting Linux is forcing th extension to be .o instead of .obj when building on WIndows. +# It is important because armlink is failing when files have .obj extensions (error with +# scatter file section not found) +SET(CMAKE_SYSTEM_NAME Linux) +SET(CMAKE_SYSTEM_PROCESSOR arm) + + + +SET(tools "C:/PROGRA~1/ARM/DEVELO~1.0/sw/ARMCOM~1.12") + +SET(CMAKE_C_COMPILER "${tools}/bin/armclang.exe") +SET(CMAKE_CXX_COMPILER "${tools}/bin/armclang.exe") + +SET(CMAKE_AR "${tools}/bin/armar.exe") +SET(CMAKE_CXX_COMPILER_AR "${tools}/bin/armar.exe") +SET(CMAKE_C_COMPILER_AR "${tools}/bin/armar.exe") +SET(CMAKE_LINKER "${tools}/bin/armlink.exe") +SET(CMAKE_C_LINK_EXECUTABLE " -o ") +set(CMAKE_C_RESPONSE_FILE_LINK_FLAG "--via ") +SET(CMAKE_C_OUTPUT_EXTENSION .o) +SET(CMAKE_CXX_OUTPUT_EXTENSION .o) +SET(CMAKE_ASM_OUTPUT_EXTENSION .o) +# When library defined as STATIC, this line is needed to describe how the .a file must be +# create. Some changes to the line may be needed. +SET(CMAKE_C_CREATE_STATIC_LIBRARY "${tools}/bin/armar.exe -r -s --create " ) +set(ARMAC6 ON) +# default core + +if(NOT ARM_CPU) + set( + ARM_CPU "cortex-a5" + CACHE STRING "Set ARM CPU. Default : cortex-a5" + ) +endif(NOT ARM_CPU) + +SET(CMAKE_C_FLAGS "-mcpu=${ARM_CPU} --target=arm-arm-none-eabi" CACHE INTERNAL "C compiler common flags") +SET(CMAKE_CXX_FLAGS "-mcpu=${ARM_CPU} --target=arm-arm-none-eabi" CACHE INTERNAL "C compiler common flags") +SET(CMAKE_ASM_FLAGS "-g -x assembler-with-cpp -masm=auto -mcpu=${ARM_CPU} --target=arm-arm-none-eabi" CACHE INTERNAL "ASM compiler common flags") +#SET(CMAKE_EXE_LINKER_FLAGS "-flto" CACHE INTERNAL "linker flags") + +# Where is the target environment +SET(CMAKE_FIND_ROOT_PATH "${tools}") +# Search for programs in the build host directories +SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) +# For libraries and headers in the target directories +SET(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) +SET(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) + diff --git a/config.cmake b/config.cmake new file mode 100755 index 00000000..e985fb47 --- /dev/null +++ b/config.cmake @@ -0,0 +1,134 @@ +include(CMakePrintHelpers) + +SET(CORTEXM ON) +option(FASTMATH "Fast Math enabled" ON) +option(NEON "Neon acceleration" OFF) +option(NEONEXPERIMENTAL "Neon experimental acceleration" OFF) +option(LOOPUNROLL "Loop unrolling" ON) +option(ROUNDING "Rounding" OFF) +option(MATRIXCHECK "Matrix Checks" OFF) + +################### +# +# ALL CORTEX +# + +target_compile_options(CMSISDSP PUBLIC "-mfloat-abi=hard;-mlittle-endian") + +if (FASTMATH) + target_compile_options(CMSISDSP PUBLIC "-ffast-math") +endif() + +if (LOOPUNROLL) + target_compile_definitions(CMSISDSP PRIVATE ARM_MATH_LOOPUNROLL) +endif() + +if (ROUNDING) + target_compile_definitions(CMSISDSP PRIVATE ARM_MATH_ROUNDING) +endif() + +if (MATRIXCHECK) + target_compile_definitions(CMSISDSP PRIVATE ARM_MATH_MATRIX_CHECK) +endif() + + +################### +# +# CORTEX-A +# + +# CORTEX-A9 +if (ARM_CPU STREQUAL "cortex-a9" ) + target_include_directories(CMSISDSP PUBLIC "${DSP}/../../Core_A/Include") + SET(CORTEXM OFF) + + if (NOT (NEON OR NEONEXPERIMENTAL)) + target_compile_options(CMSISDSP PUBLIC "-mfpu=vfpv3-d16-fp16") + endif() + +endif() + +# CORTEX-A7 +if (ARM_CPU STREQUAL "cortex-a7" ) + target_include_directories(CMSISDSP PUBLIC "${DSP}/../../Core_A/Include") + SET(CORTEXM OFF) + + if (NOT (NEON OR NEONEXPERIMENTAL)) + target_compile_options(CMSISDSP PUBLIC "-mfpu=vfpv4-d16") + endif() + +endif() + +# CORTEX-A5 +if (ARM_CPU STREQUAL "cortex-a5" ) + target_include_directories(CMSISDSP PUBLIC "${DSP}/../../Core_A/Include") + SET(CORTEXM OFF) + + if ((NEON OR NEONEXPERIMENTAL)) + target_compile_options(CMSISDSP PUBLIC "-mfpu=neon-vfpv4") + else() + target_compile_options(CMSISDSP PUBLIC "-mfpu=vfpv4-d16") + endif() +endif() + + +################### +# +# CORTEX-M +# + +# CORTEX-M35 +if (ARM_CPU STREQUAL "cortex-m35") + target_include_directories(CMSISDSP PUBLIC "${DSP}/../../Core/Include") +endif() + +# CORTEX-M33 +if (ARM_CPU STREQUAL "cortex-m33") + target_include_directories(CMSISDSP PUBLIC "${DSP}/../../Core/Include") +endif() + +# CORTEX-M23 +if (ARM_CPU STREQUAL "cortex-m23") + target_include_directories(CMSISDSP PUBLIC "${DSP}/../../Core/Include") +endif() + +# CORTEX-M7 +if (ARM_CPU STREQUAL "cortex-m7") + target_include_directories(CMSISDSP PUBLIC "${DSP}/../../Core/Include") +endif() + +# CORTEX-M4 +if (ARM_CPU STREQUAL "cortex-m4") + target_include_directories(CMSISDSP PUBLIC "${DSP}/../../Core/Include") + +endif() + +# CORTEX-M3 +if (ARM_CPU STREQUAL "cortex-m3") + target_include_directories(CMSISDSP PUBLIC "${DSP}/../../Core/Include") +endif() + +# CORTEX-M0plus +if (ARM_CPU STREQUAL "cortex-m0p") + target_include_directories(CMSISDSP PUBLIC "${DSP}/../../Core/Include") +endif() + +# CORTEX-M0 +if (ARM_CPU STREQUAL "cortex-m0") + target_include_directories(CMSISDSP PUBLIC "${DSP}/../../Core/Include") +endif() + +################### +# +# FEATURES +# + + + +if (NEON AND NOT CORTEXM) + target_compile_definitions(CMSISDSP PRIVATE ARM_MATH_NEON __FPU_PRESENT) +endif() + +if (NEONEXPERIMENTAL AND NOT CORTEXM) + target_compile_definitions(CMSISDSP PRIVATE ARM_MATH_NEON_EXPERIMENTAL __FPU_PRESENT) +endif() diff --git a/configBoot.cmake b/configBoot.cmake new file mode 100755 index 00000000..52e7717c --- /dev/null +++ b/configBoot.cmake @@ -0,0 +1,115 @@ +include(CMakePrintHelpers) +include(configUtils) + +enable_language(C ASM) + +option(FILEIO "Test trace using printf" ON) + +# Otherwise there is a .obj on windows and it creates problems +# with armlink. +SET(CMAKE_C_OUTPUT_EXTENSION .o) +SET(CMAKE_CXX_OUTPUT_EXTENSION .o) +SET(CMAKE_ASM_OUTPUT_EXTENSION .o) + + +get_filename_component(PROJECT_NAME ${CMAKE_CURRENT_SOURCE_DIR} NAME) + +cmake_print_variables(PROJECT_NAME) + +set(ROOT ${CMAKE_CURRENT_SOURCE_DIR}/../../../../..) + +if (ARMAC6) + + ################### + # + # Cortex cortex-m7 + # + if (ARM_CPU STREQUAL "cortex-m7") + cortexm(ARMCM7) + + target_compile_definitions(${PROJECT_NAME} PRIVATE ARMCM7_DP) + + + endif() + + ################### + # + # Cortex cortex-m4 + # + if (ARM_CPU STREQUAL "cortex-m4") + cortexm(ARMCM4) + target_compile_definitions(${PROJECT_NAME} PRIVATE ARMCM4_FP) + endif() + + ################### + # + # Cortex cortex-m35p + # + if (ARM_CPU STREQUAL "cortex-m35") + cortexm(ARMCM35P) + target_compile_definitions(${PROJECT_NAME} PRIVATE ARMCM35P) + endif() + + ################### + # + # Cortex cortex-m33 + # + if (ARM_CPU STREQUAL "cortex-m33") + cortexm(ARMCM33) + target_compile_definitions(${PROJECT_NAME} PRIVATE ARMCM33) + endif() + + ################### + # + # Cortex cortex-m23 + # + if (ARM_CPU STREQUAL "cortex-m23") + cortexm(ARMCM23) + target_compile_definitions(${PROJECT_NAME} PRIVATE ARMCM23) + endif() + + ################### + # + # Cortex cortex-m0+ + # + if (ARM_CPU STREQUAL "cortex-m0p") + cortexm(ARMCM0plus) + endif() + + ################### + # + # Cortex cortex-m0 + # + if (ARM_CPU STREQUAL "cortex-m0") + cortexm(ARMCM0) + endif() + + ################### + # + # Cortex cortex-a5 + # + if (ARM_CPU STREQUAL "cortex-a5") + cortexa(ARMCA5) + endif() + + ################### + # + # Cortex cortex-a7 + # + if (ARM_CPU STREQUAL "cortex-a7") + cortexa(ARMCA7) + endif() + + ################### + # + # Cortex cortex-a9 + # + if (ARM_CPU STREQUAL "cortex-a9") + cortexa(ARMCA9) + endif() + +endif() + +if (FILEIO) + target_compile_definitions(${PROJECT_NAME} PRIVATE FILEIO) +endif() \ No newline at end of file diff --git a/configUtils.cmake b/configUtils.cmake new file mode 100755 index 00000000..ba3ac630 --- /dev/null +++ b/configUtils.cmake @@ -0,0 +1,36 @@ +function(cortexm CORE) + target_sources(${PROJECT_NAME} PRIVATE ${ROOT}/Device/ARM/${CORE}/Source/ARM/startup_${CORE}.s) + target_sources(${PROJECT_NAME} PRIVATE ${ROOT}/Device/ARM/${CORE}/Source/system_${CORE}.c) + 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") + + target_link_options(${PROJECT_NAME} PRIVATE "--info=sizes;--entry=Reset_Handler;--scatter=${SCATTERFILE}") + +endfunction() + +function(cortexa CORE) + target_sources(${PROJECT_NAME} PRIVATE ${ROOT}/Device/ARM/${CORE}/Source/mmu_${CORE}.c) + target_sources(${PROJECT_NAME} PRIVATE ${ROOT}/Device/ARM/${CORE}/Source/system_${CORE}.c) + target_sources(${PROJECT_NAME} PRIVATE ${ROOT}/CMSIS/Core_A/Source/irq_ctrl_gic.c) + + target_include_directories(${PROJECT_NAME} PRIVATE ${ROOT}/Device/ARM/${CORE}/Include) + target_include_directories(${PROJECT_NAME} PRIVATE ${ROOT}/Device/ARM/${CORE}/Config) + 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) + + # Copy the mem file to the build directory + # so that it can be find when preprocessing the scatter file + # since we cannot pass an include path to armlink + file(COPY ${ROOT}/Device/ARM/${CORE}/Config/mem_${CORE}.h DESTINATION tempLink) + file(COPY ${ROOT}/Device/ARM/${CORE}/Source/AC6/${CORE}.sct DESTINATION tempLink) + + target_compile_definitions(${PROJECT_NAME} PRIVATE -DCMSIS_device_header="${CORE}.h") + + target_link_options(${PROJECT_NAME} PRIVATE "--info=sizes;--entry=Vectors;--scatter=${SCATTERFILE}") +endfunction() \ No newline at end of file