Placeholder Image

Subtitles section Play video

  • Welcome to the Modern Embedded Systems Programming course. My name is Miro Samek and in this

  • lesson I have decided to finally give in to the popular demand and switch the development

  • toolset from IAR to the free and unlimited GNU-ARM compiler and the Eclipse-based Integrated

  • Development Environment.

  • The switch of the toolset is actually a good opportunity to review the code and to see

  • what "code portability" means in practice. As you will see, much of the code you've written

  • so far will work with GNU-ARM without any changes, mostly due to the compliance with

  • the Cortex Microcontroller Software Interface Standard (CMSIS). However, a few IAR-specific

  • extensions in the startup code as well as board-support package will have to be replaced

  • with the GNU compiler equivalents.

  • So, today let's start with downloading and installing a development toolset for GNU-ARM.

  • Actually, there are many choices of such toolsets, but you need to look for a toolset that supports

  • your board. Here, the most important factor is the support for the specific debugger interface,

  • which in case of the TivaC LaunchPad board is the Stellaris-ICDI.

  • Since the board comes from Texas Instruments, the logical place to look is the TI.com website,

  • where indeed you can find the toolset called Code Composer Studio (CCS).

  • As usual these days, instead of giving you a specific fixed URL for downloading CCS,

  • which most likely won't work in a few weeks from now, I recommend using the search box.

  • So, when you search for CCS, you quickly find the right web-page.

  • In the download section, you can read that the CCS tool can be used for free with no

  • limits with the GNU-GCC toolset.

  • Click on the Windows download, which will lead you to the registration page and some

  • more forms to fill to comply with the export control regulations.

  • Eventually, however, you should be able to download the CCS setup program for windows.

  • You need to launch it and agree to the licensing terms.

  • In the next step you can choose the installation directory. You can leave the default, or choose

  • your own destination, but I would strongly recommend against using directory names with

  • spaces or any non-standard characters.

  • The following step allows you to choose the CCS components. Here you need to expand the

  • 32-bit ARM MCUs and select the Tiva-C Series support. Also, you need to explicitly select

  • the GCC ARM Compiler.

  • You don't need to make any more choices, so finally click Finish to start the installation,

  • which can take a couple of minutes.

  • When you launch Code Composer Studio, it will ask you for the location of the "workspace".

  • The concept of a "workspace" is common in all toolsets based on Eclipse and is intended

  • to group together related projects.

  • From what I see, most people tend to use one default workspace for everything they do,

  • but I recommend that you use separate workspaces for your different project groups. Specifically,

  • I recommend that you use a dedicated workspace for this Embedded Programming Course.

  • Since I keep all the projects for this course in the directory "embedded_programming", I

  • also create the CCS workspace there, in the "ccs" subdirectory.

  • So finally you are ready to create your first project. This part is specific to this particular

  • re-packaging of Eclipse as Code Composer Studio, but the general process is similar in all

  • Eclipse based Integrated Development Environments.

  • The first selection you make for a new project is the embedded target. Here you need to choose

  • the Tiva-C family and the specific TM4C MCU within the family that is soldered on your

  • TivaC LaunchPad board.

  • Next, you choose the connection to the target, which in case of your LanchPad is the Stellaris-ICDI.

  • Please note that the support for this particular debugger interface was the primary reason

  • you selected the CCS toolset in the first place.

  • In the next step, you need to name the project. Here, I suggest a generic name "lesson" for

  • projects belonging to this Embedded Programming Course. This name will be fitting for all

  • upcoming lessons, because you will simply clone this original project instead of creating

  • a new project from scratch each time.

  • For the same reason, you also cannot create the project in the default location inside

  • the workspace directory. Instead, you create the project in the directory where you keep

  • all previous lessons. On my machine this is "embedded_programming", but it can be different

  • on your computer.

  • To finish with the project location, you need to add the lesson19 sub-directory for this

  • particular project

  • The next and final step is critical. Here, you need to select the GNU toolset instead

  • of the default TI compiler for ARM.

  • When you click Finish, CCS will create your "lesson" project in the workspace and in the

  • "lesson19" directory on disk.

  • You can build the project by clicking on the hammer button at the top. As you can see,

  • the build process succeeds with 0 problems.

  • So, let's take a quick look at the code that CCS has generated for this project.

  • First, you get the main.c file with the empty main() function.

  • Second, is the startup code, which is very typical for code supplied by silicon vendors.

  • Unfortunately, it has all the shortcomings that I've covered in lessons 13, 14, and 15.

  • For starters, this startup code uses proprietary exception names that are not compliant with

  • CMSIS.

  • Also, the vector table requires editing every time you start or stop using a given interrupt

  • handler. For example, to use the SysTick_Handler interrupt, you would need to modify the appropriate

  • entry in the vector table, and you would also need to declare a prototype of the handler

  • at the top of the file.

  • And finally, the provided implementation of the exception handlers contains endless loops

  • that tie up the CPU. In other words, if any of such exception handler is ever executed,

  • the system will freeze, which the user will perceive as denial of service. This is not

  • acceptable in any production-grade code.

  • The generated code also contains the file with the extension .lds, which is the linker

  • script. The purpose of this file is to tell the linker where ROM and RAM are located in

  • the address space and where to place various program sections. You saw an example of a

  • linker script for the IAR toolset in lesson 14. Here you have a linker script for the

  • GNU toolset.

  • This is again a beaten-path linker script, which matches the startup code.

  • Among others, it allocates the stack as the last section in RAM. In my opinion this is

  • a mistake, because stack grows toward the lower addresses on ARM, and so a stack overflow

  • could damage the RAM sections above it. In fact, this seems the likely cause of failure

  • in the infamous Toyota unintended acceleration cases, as I have described in the article

  • "Are we shooting ourselves in the foot with stack overflow?". I provide a link to this

  • article in the comment section for this video.

  • So, it seems that the code generated by CCS is not terribly usable, but the good news

  • is that you can fix all the issues in it by applying the lessons you've learned so far.

  • The first thing then is to copy all the relevant code from the previous lesson18 to the lesson19

  • folder. The usable files are: bsp.h, bsp.c, main.c, startup_tm4c.c, and the master header

  • file for your TM4C MCU.

  • Interestingly, the files copied to the lesson19 folder immediately show up inside your project.

  • This is how all Eclipse projects behave. All source files in the project directory are

  • automatically included in the project and you don't need to explicitly add them as it

  • was the case in the IAR Embedded Workbench IDE.

  • This Eclipse policy has its disadvantages too, however.

  • For example, now you have two startup files in the project, so you need to delete one

  • of them.

  • So let's try to build this project.

  • This time you get some errors.

  • The first error is that the compiler cannot find the include file "core_cm4.h". This file

  • is part of the CMSIS, which is not directly available in Code Composer Studio, as it was

  • in IAR Embedded Workbench.

  • This is not a big problem, as you can easily provide CMSIS yourself.

  • Here, I have prepared for you a directory CMSIS, which contains the core header files

  • in the sub-directory Include.

  • You should copy the CMIS directory into the folder where you keep the lessons of this

  • video course. That way you can re-use CMSIS in all upcoming lessons.

  • Of course copying a directory is not enough, because you also need to tell the compiler

  • to look for include files in this new directory CMSIS/Include.

  • You accomplish this by means of the project Properties dialog box, which you open by right-clicking

  • on the project and selecting the Properties pop-up menu.

  • Specifically, you need to choose the Directories property in the GNU Compiler group, where

  • you find the "include paths" pane.

  • To add a new include directory, click on the plus button.

  • The first, easy way is to simply browse your file system for the CMSIS/Include directory.

  • But the big drawback of doing this is that you add an *absolute* include path, which

  • will only work on your computer with this specific C:\\embedded_programming\\CMSIS directory.

  • A much better approach is to create a *relative* include path, which will work on any computer.

  • The Eclipse IDE allows you to create relative paths by means of system variables. Specifically,

  • in the list of these variables, you can choose PROJECT_LOC, which will create paths relative

  • to the project location.

  • From the project location, you need to go one level up, and then you append CMSIS/Include.

  • Regarding the use of directory separators, on Windows you can use either back-slashes

  • or forward-slashes. I use forward-slashes, because they seem more universal.

  • When you build again, you see that the previous include error is gone, but you got a bunch

  • of new errors.

  • As it turns out, most of these new errors come from the startup code. This should not

  • be actually that surprising, because this code was written with IAR-specific extensions

  • to the C language, which the GNU compiler does not recognize.

  • So, here I have prepared for you the startup code, which was re-written with the GNU-specific

  • extensions to the C language.

  • As you will see in a minute, the startup code must closely match the linker script, so I

  • included a matching linker script as well.

  • To include these files in the project is simply copy them over to the lesson19 directory.

  • I need to allow overwriting the previous linker script and I also need to remove the previous

  • startup code.

  • When you switch over to the Eclipse IDE, you can see that the project is immediately updated

  • with the new files.

  • Let's quickly review the code, so that you know how it works.

  • First, in contrast to the old file, the new GNU-specific startup code is compliant with

  • the latest CMSIS 4.3.0.

  • When you scroll down to the vector table, you can see that it has a special attribute

  • section(.isr_vector). This is a GNU-specific extension, which tells the compiler to place

  • the following symbol--the vector table in this case--in the specified section.

  • To see where this section is, you can open the new GNU linker script, where you can see

  • that .isr_vector is the first section in ROM.

  • The ROM section, in turn, is located at address 0, so the vector table at the beginning of

  • ROM is also at zero, which is exactly what the ARM CPU needs.

  • As you hopefully remember from lesson-15, the first element of the ARM vector table

  • is the initial top of stack. So, here you see an ampersand, meaning address of, __stack_end__

  • cast on an int.

  • The symbol __stack_end__ comes again from the linker script. Indeed, when you scroll

  • a bit down, you can see the .stack section as the first section in RAM.

  • Contrary to the beaten-path approach of putting the stack at the last section in RAM, I recommend

  • placing it at the first section. That way, a stack overflow won't be able to damage any