Yesterday I applied for the University of Leicester’s PGCert in Reliable Embedded Systems. Fingers crossed – everything crossed – that I’ll be accepted.
Welcome to the latest instalment of my blog!
This time I’m getting stuck into the main code, line by line, and working out how exactly those three LEDs are able to flash on and off all on their own…
There’s quite a lot of text formatting needed in order to make this post intelligible. WordPress isn’t the best platform for that sort of thing, so I’ve written up the majority of the post as a Word file, saved in pdf format. Not ideal, I know, but the best solution I’ve come up with so far. You can download it here:
In writing this post I have had a strong feeling of fragmented bits of my existing knowledge coming together into a more coherent whole. Things that didn’t make sense before are finally now starting to make sense. I’ve tried to be as accurate as possible with my terminology, especially as it relates to the C language, as I feel this is a good habit to get into. But please feel free to point out any errors I may have made – that’s what the Comments section is for.
Just to reiterate, this blog isn’t intended to be a beginner’s guide to programming microcontrollers, or a definitive guide to C, or anything like that. It’s just a record of my personal journey into the world of embedded programming.
Until next time…
What I have learnt since last time…
Time to look a little closer at the Lab 2 main function. Here it is again, for reference.
Starting with the “#include” statements in lines 1 – 6, I mentioned in my previous post that some pieces of C code tend to be used over and over again, and so it makes sense to store those pieces of code in library locations which can be accessed by any program. When the compiler finds a reference to one of those pieces of code it simply goes to the appropriate library and copies over the relevant code into the program it is compiling. However, to do this, the compiler needs to know the name of the library file(s) in question, and this is where the #include statements come in. The “hash” (#) symbol is more properly known as the “preprocessor directive”, and the six preprocessor directives tell the compiler the names of the various library files it may need to access for successful compilation.
Files in angle brackets ( < and > ) are part of the standard libraries which are built in to the IDE whilst those in quotes are specific to the device for which the code is being compiled. These would be supplied by the device manufacturer and in this case would reside in the TI TivaWare C Series driver library.
By way of example, the function SysCtlClockSet (line 10) is found in the sysctl library, the GPIOPinTypeGPIOOutput function (line 12) is in the gpio library, and so on.
A few words on functions
I’ve used the term “function” quite a lot already without explaining what it means. So before we go any further, a definition:
A function is a pre-packaged piece of code which carries out a particular task or operation. Some functions are built in to the C language, and the programmer is also free to create his or her own functions or utilise libraries of functions written by other people. Functions can have parameters “passed” to them and can also “return” values.
The general format of a function is:
(from Deitel and Deitel, ch5, p152)
A simple illustration may make this clearer. In the following example, function “addtwo” takes two parameters (integers a and b) and returns the value of their sum, which is also an integer:
so if we “called” the function with the following statement
answer = addtwo(2, 5);
the function would add the numbers 2 and 5 together and assign the result (7) to the variable “answer”.
Note that functions need not necessarily return values or need parameters to be passed to them (many do not).
Note also that the integer variable c, defined within the function itself, is an example of a “local variable” A local variable is used only within the function and is not accessible outside of that function. You could not, therefore, go on to use the variable c elsewhere in a program.
This is a very simple example of how a hypothetical function might be used. The concept of the function is central to the C language, and is not something which I am qualified to explain in any great detail. For more information you might like to follow this link or consult the excellent Deitel book I referenced earlier.
The main function
Every C program must have at least one function – main – but main can also contain other functions and in general functions can be “called” (or executed) by other functions.
The structure of the main function can be seen to comply with the example described above. On line 7 the statement
shows us that the function’s name is “main”, that it returns an integer (or int) value and that no parameters are passed to it (“void”). The code which actually flashes the LaunchPad LEDs appears in lines 9 to 20.
There is some debate as to whether, in the context of an embedded system, it makes sense for main to return a value (return it to what?), but I’m really not going to get into that here. If you absolutely must, see this debate on StackExchange (amongst many others).
Further into main.
I had intended to now go into the details of the main function to explain how exactly it causes the three LaunchPad LEDs to flash in sequence. However this post is already over 700 words long, and so I think it better to start a new post on the internal workings of main. This has certainly been an interesting “refresher” for me, once again tying together fragments of knowledge from previous projects. Hopefully any errors in this post are not too egregious – feel free to point them out!
Until next time…
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:
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.
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.
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.
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.
It’s been a while… did you miss me?
That’s the thing about blogs, see: easy to start, not so easy to keep going.
But in my absence I have not been idle. Uh-uh. I done got me some learnin’.
You might recall, in my last post, that I’d found a cool CPD course on micros starting next September. I was also looking for more informal, non-academic training to do in the meantime, to get a head start on the subject. Did a lot of browsing around the ARM-based micro manufacturers and was starting to give up until I came across this.
I like this. I like it a lot. I like it because:
- Texas Instruments. ‘nuff said.
- There’s a full and extensive training course in the pdf workbook under the “Workshop Material” section near the end.
- It’s based on inexpensive hardware (demoboards) readily available from, for example, Farnell .
- The software is all free for personal/home/hobby use.
- There’s a whole design/support ecosystem around these micros. This is exactly what Microchip have been doing so well for years with their PIC range.
So as you might have gathered, I’m going with this one.
Last time I searched for learning resources for ARM-based micros, which was admittedly a few years ago now, I didn’t see anything like this. So this is undoubtedly progress.
I don’t know about you, but if I’m trying to follow something in printed text I much prefer actual paper rather than an on-screen pdf. I therefore invested twenty quid in having the workbook printed out – all 330 pages of it – at my local print shop. Here it is, in a colour coordinated ring binder with the teeny weeny LaunchPad evaluation board.
In future I’m going to aim for shorter, more frequent posts as I work through this course. So – more later, and hopefully not too much later this time.
OK, so. I want to learn how to program micros, and I’m looking for a micro and associated training material that will:
- If possible lead to some kind of qualification that I can wave at a future employer
- Allow home study
- Use readily available hardware and software
- Focus on programming in C (employers seem to want this)
Back in the day, pretty much the only way to earn paper qualifications (at least in the UK) was to attend a college or university in person for a period of several years and hopefully come away with a recognised qualification at the end of it. The one notable exception was the venerable Open University, which was founded in the late 1960s specifically to allow students to follow a non-traditional, distance-learning route to higher education.
Pre-internet, the OU’s material was delivered using a combination of written material, television programs and occasional short residential schools. More recently, delivery methods have also included electronic media such as DVD and delivery over the internet. It’s a great system which has allowed access to higher education for countless thousands of people around the world who otherwise would not have had the opportunity. I studied a single OU module myself in the 1990s (on thermodynamics) and the standard was exceptionally high.
In recent years, more institutions have started offering courses which can be studied by distance-learning. In engineering these range from BTEC HNC level all the way up to MSc and PhD. A couple of examples here and here. Some also allow students to study individual modules from a course as part of a process of Continued Professional Development (CPD).
For my purposes I’m not looking for another full degree or masters course as I don’t want to commit to a likely three or four years of study. Instead I’m after something shorter which still offers some kind of recognised qualification at the end. This does “narrow the field” somewhat, but after a lot of searching I finally hit gold with PGCert option of this course. The University of Leicester’s Postgraduate Certificate (PGCert) in Reliable Embedded Systems takes four modules from the MSc program of the same name and lasts for a single year. Study is distance-learning with four one-week residentials and the cost is definitely affordable. Start date is September 2017 and I’ve already confirmed that the course will run this year. Perfect – exactly what I’m looking for! So unless things change significantly between now and September, that’s what I’m going to do.
Of course, that does leave me with eight months or so before September. I already have plans as to what I’m going to do with that time, and yes it does involve micros. More on that next time…