Configuring Clion and Cmake IDEs to work with STM32 and C ++

Before the example of my setup, a little lyrics.

I have long wanted to try myself in microcontrollers, or rather there were ideas with their use that I really wanted to implement. First started with PIC32 - fire controllers. It so happened that at first I shortened their ports, and overestimated the power - unkillable (not entirely sure, the port really burned out once, but the controller itself continued to work). The IDpl MplabX is not bad, it bribed a graphic block with the display of occupied RAM / Flash on the selected MK - conveniently, but NetBeans itself as an IDE is tin, well, not convenient once after Idea. But that was not the problem - as it turned out later, PICs are hard to get, few people carry them, and if they carry them, then at a relatively high price.

Then I decided to dig towards STM32 - they are in large quantities, they do not ask for much for the basic periphery, but the main thing is deliverability. (But STM’s code generator is worse than Microchip — the whole file is contaminated with comments and functions, of course it was very disappointing. For Microchip, all the generated functions are moved to separate files and main.c is almost clean - pretty).
(UPD: I admit I was mistaken here, thanks golf2109 , he suggested that you can get rid of the comments and functions of the main.c file, just turn on the option in the settings to put the generated code into separate files, but I'm still at a loss why default setting, it seems logical it would be)

Now about the IDE for STM32.

I tried the praised Keil - certainly better than a notepad, but terribly not convenient (neither normal hints, nor normal formatting, after Idea, in general, it’s not that coat, especially I still did not understand how to create packages, why you can’t just click on the box to create a package and continue - I want to mate).

Then I tried CooCox - the interface is much better and more pleasant, the formatting is well configured (I was directly pleased with the parameter transfer setting in the methods, and other settings are very useful), but again, there were not enough many goodies from Idea and, again, problems with organizing packages.

Clion is almost the same Idea only for C / C ++ and immediately wanted to fasten it, but it turned out to be quite problematic (especially for a person who is not strong with pluses, especially with all sorts of compilers and compilers, a couple of hundred compilation options). Started with the JetBrains blog . It’s described in some detail, but this is for previous versions of STM32CubeMX, the directory structure has changed a little, as a result of which I did not understand for some time why it does not compile. Then I figured it out - changed the paths, for cortex-m3 removed the -mfpu options. But again it did not compile. Further it turned out that I installed the wrong compiler, or rather I just downloaded it, but did not specify the path to it in the assembly file (well, it's hard to think late at night).

The main thing in Clion is to check the settings for 'Automaticaly Reload Cmake Project on Edit' (Settings -> Build, Execution, Deployment -> Cmake), then after editing you do not need to clear anything manually.

Another of the changes - the debugger mentioned in the blog, was renamed to Ozone, it has not been tested yet, I will unsubscribe later.

And the last problem, drilling the brain. I really wanted OOP, but the project did not compile if I added a C ++ file, a lot of errors with functions not found (for example, _exit, _sbrk, etc.). There were 2 problems here:

  • in the CMakeLists.txt file on the JetBrains blog, the CXX flag in the project directive was not set (needed for C ++ files)
  • to correct errors in the file from the blog, the -specs = nosys.specs -specs = nano.specs options after the -gc-sections option were missing. They just create these prototypes or vice versa ignore these methods (I can’t say for sure)

After that, the project began to compile normally and its size became within the normal range (without the -specs = nano.specs option, the size was 10 times larger for an empty project about 110 kb., With the option 18 kb.)

So, what I did:

  1. put Clion
  2. go to settings (Settings -> Build, Execution, Deployment -> Cmake) and check the box 'Automaticaly Reload Cmake Project on Edit'
  3. here we enter the parameter -DCMAKE_TOOLCHAIN_FILE = STM32L1xx.cmake in the Cmake options field and put build in the Generation path field (if you change it, you will need to change it in the CMakeLists.txt and STM32L1xx.cmake files too)
  4. put the ARM compiler ( here I took it )
  5. we import the project (which was previously generated in STM32CubeMx), we say that you can create CMakeLists.txt
  6. from here or from my repository, copy the contents of CMakeLists.txt to the one created in Clion and add the file STM32L1xx.cmake (you can call it anything you like)
  7. in STM32L1xx.cmake we correct the project name in the project directive and you can remove CXX if you do not need C ++
  8. replace in the CMakeLists.txt file in the add_definitions directive (-DSTM32L100xC) with your controller
  9. for reliability, you can do: Tools -> Cmake -> Reset Cache and Reload project and then Tools -> Cmake -> Reload Cmake Project
  10. now you can build

CMakeLists.txt File

project(Skeleton C CXX ASM)
cmake_minimum_required(VERSION 3.5.0)
add_definitions(-DSTM32L100xC)
set(FREERTOS_DIR Middlewares/Third_Party/FreeRTOS/Source/)
file(GLOB_RECURSE USER_SOURCES "Src/*.c")
file(GLOB_RECURSE HAL_SOURCES "Drivers/STM32L1xx_HAL_Driver/Src/*.c")
file(
    GLOB_RECURSE
    FREERTOS_SOURCES
    "${FREERTOS_DIR}/*.c"
    "${FREERTOS_DIR}/CMSIS_RTOS/*.c"
    "${FREERTOS_DIR}/portable/GCC/ARM_CM3/*.c"
)
add_library(
    CMSIS
    Src/system_stm32l1xx.c
    startup/startup_stm32l100xc.s
)
include_directories(Inc)
include_directories(Src/gps/parser/nmea)
include_directories(Drivers/STM32L1xx_HAL_Driver/Inc)
include_directories(Drivers/CMSIS/Include)
include_directories(Drivers/CMSIS/Device/ST/STM32L1xx/Include)
include_directories(${FREERTOS_DIR})
include_directories(${FREERTOS_DIR}/CMSIS_RTOS)
include_directories(${FREERTOS_DIR}/include)
include_directories(${FREERTOS_DIR}/portable/GCC/ARM_CM3/)
include_directories(${FREERTOS_DIR}/portable/GCC/MemMang)
add_executable(${PROJECT_NAME}.elf ${USER_SOURCES} ${HAL_SOURCES} ${LINKER_SCRIPT} ${FREERTOS_SOURCES})
target_link_libraries(${PROJECT_NAME}.elf CMSIS)
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,-Map=${PROJECT_SOURCE_DIR}/build/${PROJECT_NAME}.map")
set(HEX_FILE ${PROJECT_SOURCE_DIR}/build/${PROJECT_NAME}.hex)
set(BIN_FILE ${PROJECT_SOURCE_DIR}/build/${PROJECT_NAME}.bin)
add_custom_command(TARGET ${PROJECT_NAME}.elf POST_BUILD
        COMMAND ${CMAKE_OBJCOPY} -Oihex $ ${HEX_FILE}
        COMMAND ${CMAKE_OBJCOPY} -Obinary $ ${BIN_FILE}
        COMMENT "Building ${HEX_FILE} \nBuilding ${BIN_FILE}")

File STM32L1xx.cmake:

INCLUDE(CMakeForceCompiler)
SET(CMAKE_SYSTEM_NAME Generic)
SET(CMAKE_SYSTEM_VERSION 1)
# Specify the cross compiler. arm-none-eabi-gcc and arm-none-eabi-g++ are full path required
CMAKE_FORCE_C_COMPILER(arm-none-eabi-gcc GNU)
CMAKE_FORCE_CXX_COMPILER(arm-none-eabi-g++ GNU)
SET(LINKER_SCRIPT ${PROJECT_SOURCE_DIR}/STM32L100RCTx_FLASH.ld)
SET(COMMON_FLAGS "-mcpu=cortex-m3 -O2 -mthumb -ffunction-sections -fdata-sections -g -fno-common -fmessage-length=0")
SET(CMAKE_CXX_FLAGS_INIT "${COMMON_FLAGS} -std=c++11")
SET(CMAKE_C_FLAGS_INIT "${COMMON_FLAGS} -std=gnu99")
SET(CMAKE_EXE_LINKER_FLAGS_INIT "-Wl,-gc-sections -specs=nosys.specs -specs=nano.specs -T ${LINKER_SCRIPT}")

It became a pleasure to work, but for now I upload the firmware through the STM utility, later I will try to wind OZONE. I will answer questions (if I can).

Also popular now: