In C

Real life has intervened yet again and made this post much later than I had originally intended. Nevertheless, here I am again, and this time I’m going to look at some actual code! Whoop!

In Lab 2 I followed instructions for downloading a simple program to the micro on the LaunchPad demoboard. I didn’t mention anything about that code at the time, but now here it is in all its glory:

Lab2 main.png
Figure 1. The Lab 2 “main.c” code as seen in Code Composer Studio

The code shown in Figure 1 is written in a computer language called “C” (yup, just that – the letter C).

C is an extremely common programming language which has existed, in more or less the same form, since the late 1970s. There is a very informative history of the C language at this link. C is versatile, powerful and ubiquitous and is used for a huge number of different purposes, not just embedded programming.

My first exposure to C came in 2007 when I joined a work-based project based around an embedded microcontroller. Sadly the project was cancelled two years later, but in that time I managed to teach myself enough C to not be completely clueless when viewing code like the example shown in Figure 1. Disclaimer: this does not make me in any way a C expert, though! The book I used to learn C was “C How To Program” by P. J. and H. M. Deitel, which I highly recommend.

I was subsequently involved in two more embedded programming projects which were also cancelled before they came to fruition. Although this was frustrating, the positive take-away was that I also gained some exposure to the Eclipse Integrated Development Environment (on which TI’s CCS is based) and the processes of editing, linking, compiling and so on, which I’ll come to in due course. I suppose that in revisiting this subject, I’m really putting together a lot of fragments of knowledge from earlier projects into a more coherent whole.

Returning to the main.c example shown in Figure 1, if this example of code in its existing format was somehow downloaded into a microcontroller, it simply wouldn’t work – the micro wouldn’t have a clue what to do with it. That’s because C is an example of a “high-level” language i.e. a language which is easily understood by a human programmer. In order for the program to be usable by the micro it has to be translated into the micro’s own “machine level” language. This is essentially a large collections of ones and zeros, and is known as “executable code”. The process of creating executable code is shown in a somewhat simplified form in Figure 2.

Code creation process.jpg
Figure 2. The process of creating executable code (somewhat simplified)

Note that a similar process would be used for other microcontroller architectures such as the Microchip PIC architecture . The techniques learned for programming ARM-based micros are therefore somewhat “portable” to other architectures.

Every C program has a “main” component, more properly known as a “function” and the main function is where the programmer’s code is written. In Figure 1, main begins at line 7, with the code to make the LEDs flash sitting between lines 9 and 21. As well as the main function, a few other pieces of code are needed in order to produce a working executable file which can be downloaded to the micro. These include:

  • Library files. Certain pieces of code will typically be used over and over again in many projects. It therefore makes sense to store these pieces of code in locations where they can be copied (or “linked”) into a project as and when required, rather than constantly re-writing the same pieces of code. So referring to Figure 2, the compiler turns the C files into object code, but that code has gaps in it where the library functions need to be inserted. the linker understands this, and where those code libraries are kept, and inserts the necessary bits of code before turning the whole thing into the executable .out file.
  • The startup file. This code sets up various parts of the micro’s hardware and converts it from an inert piece of silicon into a machine with the potential to do useful things. I will examine the contents of the startup file in a later post.

So there you have it – a brief explanation of the code creation process as I understand it, hopefully without too many errors. Please be aware that I am writing this stuff to document my own learning in this field, not to provide an authoritative explanation of the subject to anyone else. If you see mistakes, please feel free to point them out.

Next time: a closer look at what’s going on in main.


PS: The title of this post – “In C” – is also the title of a piece of music by the minimalist composer Terry Riley. I participated in a performance of In C many years ago. Here’s one example from YouTube.


Just press the button!

Spent the past few days working through Labs 1 and 2 of the Workbook I mentioned in my previous post.

Lab 1 is all about downloading and installing the various bits of software, including Code Composer Studio (CCS), needed to run the subsequent Labs. It also covers connecting up the demoboard and ensuring that the drivers install and the hardware basically works. A pretty lengthy process, but a necessary one and all done without any significant problem.

Lab 2 moves on to actually building a simple project in CCS, downloading it to the demoboard and checking it runs. It’s often the case when learning new software (or anything else for that matter) that in the early stages you just have to follow the instructions without understanding why you’re doing what you’re doing. You just have to press the buttons like you’re told and trust that all will become clear(er) later on.

The buttons may not always be red, though.

Everything was going swimmingly, or so I thought, until it came to actually building and running the project. Many, many error message! And none of them comprehensible to my untutored brain. At this point there are two possible courses of action:

  • Randomly fiddle with things in the hope of making it work.
  • Ask for help.

One of these is more useful than the other – can you guess which?

Part of the Texas Instruments ecosystem is its “E2E” Community. This is a large collection of forums, blogs and other resources specifically designed to help people learn about and use TI’s products. I signed up, read the rules and posted a request for help. Was pretty sure I’d get a response, but was astonished when it came within minutes of posting, and was from Ki-Soo Lee, the forum moderator and TI employee. That was impressive – all the more so considering that this service is completely free. You can see the full exchange here.

Turns out the problem was a subtle inconsistency between the workbook and the configuration of CCS as it appeared on my PC. I’d inadvertently told CCS to look for an #include file but specified a search path location rather than an actual file. I think. I have some familiarity with the concept of #include files from  previous work on C and PICs, but the implementation in CCS is still very new to me.  Anyway, got it fixed and everything worked as expected.

All for now – next time I may try to get into the workings of some actual code. In the meantime, if you like big red buttons you might want to visit this page.