Placeholder Image

字幕列表 影片播放

  • 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

  • other RAM sections. As an additional bonus, a stack overflowing into the un-mapped memory

  • below RAM will be detected automatically by executing the HardFault exception, so you

  • will know about it.

  • Speaking of the stack, you can change its size by adjusting the symbol STACK_SIZE at

  • the top of the linker script.

  • Going back to the startup code, the symbol __stack_end__ is provided by the linker, but

  • the compiler does not know about it. To tell the compiler, you need to declare __stack_end__

  • as an external variable at the top of the startup file.

  • The other elements of the vector table are addresses of handler functions for Cortex-M

  • exceptions and interrupts. As you can see, the table already contains all the specific

  • handlers, with names compliant with CMSIS, so you don't need to edit the code at all

  • to use any of these exceptions or interrupts.

  • At the same time, if you don't use a given exception or interrupt, it will be automatically

  • replaced by the Default_Handler implementation.

  • This is accomplished by means of a pair of GNU-specific attributes weak and alias.

  • The weak attribute means that such a symbol definition can be overridden by another definition

  • and the linker will quietly discard the weak definition without reporting that the symbol

  • was defined twice.

  • The alias attribute means that if the symbol is not defined, the alias symbol should be

  • used instead.

  • So, for example, if you define the SysTick_Handler in your application, the linker will take

  • your non-weak definition. If you don't define SysTick_Hanler, the linker will take the Default_Handler

  • alias for it and will not report any errors.

  • Notice though that not all handlers are aliased. This is because the standard fault handlers

  • are actually defined in this startup code so that you don't need to define them in your

  • application.

  • But these handlers are not the primitive endless loops with denial of service. The provided

  • implementations use inline assembly to carefully avoid any use of the stack, which might be

  • corrupted at this point. The assembly code stores the information about the fault in

  • r0 and r1 registers and then branches to assert_handler, where you can perform your last damage control.

  • Here you encounter another GNU-specific attribute "naked", which instructs the compiler not

  • do any stack operations for this function.

  • When you try to build again, you still have an error, this time in bsp.c.

  • By now you should know what's the problem. The extended keyword __stackless was an IAR

  • extension for stackless functions. In GNU, you need to replace it with attribute("naked").

  • Another build. This time, the compiler complains about __enable_interrupts(), which was an

  • IAR intrinsic function. In GNU this operation needs to be replaced with __enable_irq().

  • Another build, and..., Hallelujah! No errors at all.

  • Congratulations, you have just finished your first port of deeply embedded code from one

  • toolset to another.

  • Time to plug in your Tiva LaunchPad board and test the code.

  • To download the code to the flash memory of the board and start debugging, you press the

  • bug button at the top.

  • The debugger is setup to stop at the beginning of main and indeed it does. Press the Go button

  • to run the code and watch the LED change color once a second.

  • Click on the Pause button to break into the code and watch it stop in the background loop.

  • By the way, the different screen layout that you see now is called in Eclipse the "Debug

  • Perspective". This is to differentiate this view from the "Edit Perspective" that you

  • saw during editing the code.

  • The Debug Perspective provides all the debugger views that you encountered in IAR, such as

  • the disassembly view.

  • You can also single-step through the code and watch the LED being turned on and off.

  • You can set breakpoints, like for example inside the SysTick_Handler to see how frequently

  • this interrupt is called.

  • To stop the debug session and return to the "Edit Perspective", press the Stop button

  • at the top.

  • As the final step of this lesson, let's modify the behavior of the code copied from your

  • previous IAR project to change the color of the toggled LED from red to blue, for example.

  • Build the project and start debugging as before...

  • Watch the LED blink in a new color.

  • This concludes this lesson about switching the toolset to GNU-ARM and Eclipse-based Code

  • Composer Studio (CCS). The startup code and linker script from this lesson are much closer

  • to production-quality than the typical code distributed by silicon vendors. The code is

  • compliant with CMSIS and will work with any toolset based on GNU-ARM, not just with CCS.

  • You can easily adapt it for any ARM Cortex-M microcontroller.

  • If you'd like to learn more about using the free GNU-ARM toolset, I would recommend my

  • 10-part article "Building Bare Metal ARM Systems with GNU", which in 2007 was the most popular

  • article on Embedded.com.

  • This article talks about the classic ARM7/ARM9 cores, but much of the information still applies

  • to Cortex-M as well. I provide a link to this article in the description of this video on

  • YouTube.

  • The project download for this lesson will come in two parts: the usual lesson19.zip

  • archive with the CCS project and code for the lesson and the CMSIS.zip archive with

  • the CMSIS code.

  • In the next lesson I will finally talk about race conditions, which is a concept that you

  • absolutely need to understand to effectively work with interrupts.

  • If you like this channel, please subscribe to stay tuned. You can also visit state-machine.com/quickstart

  • for the class notes and project file downloads.

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

字幕與單字

單字即點即查 點擊單字可以查詢單字解釋

B1 中級

嵌入式編程第19課:GNU-ARM和Eclipse (Embedded Programming Lesson 19: GNU-ARM and Eclipse)

  • 64 5
    Ed 發佈於 2021 年 01 月 14 日
影片單字