Actions

EmSys

Using Visual Studio Code for ARM Development – Build Tasks

From EdWiki

Revision as of 15:02, 22 March 2022 by Jshankar (Talk | contribs) (Toolchain CMake File)

Using Visual Studio Code for ARM Development – Build Tasks

We are going to use CMake with Make to build the project. CMake needs some information where to find the tools. A simple and easy way is to to add a the following file to the project. I have named it arm-toolchain.cmake and placed it in the project root folder.

Toolchain CMake File

  1. # Toolchain file for arm-none-eabi-gcc
  2. #
  3. set(CMAKE_SYSTEM_NAME Generic)
  4. set(CMAKE_SYSTEM_PROCESSOR ARM)
  5. set(CMAKE_CROSSCOMPILING "TRUE")
  6.  
  7. set(ARM_TOOLCHAIN_DIR "C:/ProgramData/chocolatey/bin")
  8. set(BINUTILS_PATH ${ARM_TOOLCHAIN_DIR}) 
  9.  
  10. set(TOOLCHAIN_PREFIX ${ARM_TOOLCHAIN_DIR}/arm-none-eabi-)
  11.  
  12. set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY)
  13.  
  14. set(CMAKE_C_COMPILER "${TOOLCHAIN_PREFIX}gcc.exe")
  15. set(CMAKE_ASM_COMPILER ${CMAKE_C_COMPILER})
  16. set(CMAKE_CXX_COMPILER "${TOOLCHAIN_PREFIX}g++.exe")
  17.  
  18. set(CMAKE_OBJCOPY ${TOOLCHAIN_PREFIX}objcopy CACHE INTERNAL "objcopy tool")
  19. set(CMAKE_SIZE_UTIL ${TOOLCHAIN_PREFIX}size CACHE INTERNAL "size tool")
  20.  
  21. set(CMAKE_FIND_ROOT_PATH ${BINUTILS_PATH})
  22. set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
  23. set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
  24. set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)


ARM_TOOLCHAIN_DIR specifies the compiler to be used. Additionally it defines extra tools as size and objcopy.

CMake CMakeLists.txt

To tell CMake what to do, create a file name CMakeList.txt in the project root.

  1. # CMake file for tm4c123gxl
  2. #
  3. cmake_minimum_required(VERSION 3.15.3)
  4.  
  5. # Optional: print out extra messages to see what is going on. Comment it to have less verbose messages
  6. set(CMAKE_VERBOSE_MAKEFILE ON)
  7.  
  8. # Path to toolchain file. This one has to be before 'project()' below
  9. set(CMAKE_TOOLCHAIN_FILE ${CMAKE_SOURCE_DIR}/arm-toolchain.cmake)
  10.  
  11. # Setup project, output and linker file
  12. project(blinky VERSION 0.1)
  13. set(EXECUTABLE ${PROJECT_NAME}.elf)
  14. set(LINKER_FILE ${CMAKE_SOURCE_DIR}/ld/tm4c123gh6pm.ld)
  15.  
  16. enable_language(C ASM)
  17. set(CMAKE_C_STANDARD 99)
  18. set(CMAKE_C_STANDARD_REQUIRED ON)
  19. set(CMAKE_C_EXTENSIONS OFF)
  20.  
  21. # Optional: issue a message to be sure it uses the correct toolchain file.
  22. message(STATUS "CMAKE_TOOLCHAIN_FILE is: ${CMAKE_TOOLCHAIN_FILE}")
  23.  
  24. # List of source files
  25. set(SRC_FILES
  26.         src/main.c
  27.         src/tm4c_startup.c
  28.         inc/tm4c_startup.h
  29.         )
  30.  
  31. # Build the executable based on the source files
  32. add_executable(${EXECUTABLE} ${SRC_FILES})
  33.  
  34. # List of compiler defines, prefix with -D compiler option
  35. target_compile_definitions(${EXECUTABLE} PRIVATE
  36.         -DPART_TM4C123GH6PM
  37.         )
  38.  
  39. # List of include directories
  40. target_include_directories(${EXECUTABLE} PRIVATE
  41.         src 
  42.         inc
  43.         "E:/ti/TivaWare_C_Series-2.2.0.295"
  44.         )
  45.  
  46. # Compiler options
  47. target_compile_options(${EXECUTABLE} PRIVATE
  48.         -mcpu=cortex-m4
  49.         -mthumb
  50.         -mfpu=fpv4-sp-d16
  51.         -mfloat-abi=hard
  52.  
  53.         -fdata-sections
  54.         -ffunction-sections
  55.  
  56.         -Wall
  57.         -O0
  58.         -g3
  59.         )
  60.  
  61. # Linker options
  62. target_link_options(${EXECUTABLE} PRIVATE
  63.         -T${LINKER_FILE}
  64.         -mcpu=cortex-m4
  65.         -mthumb
  66.         -mfpu=fpv4-sp-d16
  67.         -mfloat-abi=hard
  68.         -specs=nano.specs
  69.         -specs=nosys.specs
  70.         -lc
  71.         -lm
  72.         -Wl,-Map=${PROJECT_NAME}.map,--cref
  73.         -Wl,--gc-sections
  74.         -Xlinker -print-memory-usage -Xlinker
  75.         )
  76.  
  77. # Optional: Print executable size as part of the post build process
  78. add_custom_command(TARGET ${EXECUTABLE}
  79.         POST_BUILD
  80.         COMMAND ${CMAKE_SIZE_UTIL} ${EXECUTABLE})
  81.  
  82. # Optional: Create hex, bin and S-Record files after the build
  83. add_custom_command(TARGET ${EXECUTABLE}
  84.         POST_BUILD
  85.         COMMAND ${CMAKE_OBJCOPY} -O srec --srec-len=64 ${EXECUTABLE} ${PROJECT_NAME}.s19
  86.         COMMAND ${CMAKE_OBJCOPY} -O ihex ${EXECUTABLE} ${PROJECT_NAME}.hex
  87.         COMMAND ${CMAKE_OBJCOPY} -O binary ${EXECUTABLE} ${PROJECT_NAME}.bin)


The most important sections/entries are:

  • project(<your project name here>): Give your project a name
  • set(LINKER_FILE <your linker file here>): specify the linker file name
  • set(SRC_FILES <your source files here>): list of source files to compile
  • target_compile_definitions(${EXECUTABLE} PRIVATE <compiler defines here>): list of compiler #defines
  • target_include_directories(${EXECUTABLE} PRIVATE <list of include dir>): list of include directories
  • target_compile_options(${EXECUTABLE} PRIVATE <compiler options>): list of compiler options
  • target_link_options(${EXECUTABLE} PRIVATE <linker options>): list of linker options

This completes setting up the configuration for the build.


It isn’t strictly necessary to use Visual Studio Code to build your code. We can still drop to the command line and build it more directly. However, it is handy to be able to build with a shortcut key or not have to manage another window.

For example code, If we have a Makefile that we use with “make all” as the default target, and “make clean” to delete everything.

We can set up custom tasks within VSCode that can execute any shell command, even specifying which shell to use. There is a special “Default Build” task.

To start, select the “Terminal” menu, then “Configure Tasks”. If this is the first time, it will ask for a type – select “Make”; VSCode will create the .vscode/tasks.json file for us. Copy the following code and save it.


{
    "version": "2.0.0",
    "tasks": [
	{
	    "label": "Make",
	    "type": "shell",
	    "command": "make",
	    "presentation": {
	        "echo": true,
		"reveal": "always",
		"focus": false,
		"panel": "shared"
	    },
            "group": {
                "kind": "build",
		"isDefault": true
	    }
	},
	{
	    "label": "Make Clean",
	    "type": "shell",
	    "command": "make clean",
	    "presentation": {
	        "echo": true,
		"reveal": "always",
		"focus": false,
		"panel": "shared"
	    },
            "group": "build"
	}
    ]
}

The first task just runs the command-line “make”. The Terminal pane will be opened to show the results. This is the default build task, so it can be performed using ctrl-shift-B.

The second task is similar, but it runs “make clean”. It doesn’t have a defined shortcut key. However, this can be performed by selecting Terminal/Run Build Task... from the menu or alt-shift-B. You can then select from the defined tasks.

(VSCode does have configurable keybindings, so if you want to assign a task to a shortcut key, you can do this easily!)