I've started tinkering with the NXP mbed device. This $60 board
has a strong community following, centered at
mbed.org. The toolset and
inexpensive hardware let you start development on the Cortex-m3 device
with very little up-front cost.
However, the compiler provided by NXP for writing your programs lives
on the web ("in the cloud"). I much prefer using my own tools,
residing on my desktop, for development. So I set out to create a
toolset I like that works in a Windows XP desktop.
Note that I am not the first person to try bare-metal development for
ARM processors, by any means. You can find plenty of sites
devoted to ARM development, mbed development, bare-metal GCC tool
chains, makefiles, and other essentials with some diligent
searches. I have borrowed heavily from others in my work here,
including
Martin
Thomas' site
and other sites reachable via the mbed.org link above. My thanks
to all who have shared their work to help others.
CodeSourcery
CodeSourcery G++ Lite is a gcc tool suite suitable for developing mbed
projects. You can download the full tool suite from Mentor
Graphics. Here is a link to the download page for the ARM EABI
suite, which works with the mbed board:
https://sourcery.mentor.com/sgpp/lite/arm/portal/release1802.
Since
I'm
using
Windows
XP,
I chose the IA32 Windows Installer from the
list of recommended packages. Save this installer to a folder on
your desktop, then double-click the installer to launch it.
Note that when you install, CodeSourcery will provide a default install
folder; DO NOT use the default! Provide a new install path that
does NOT contain spaces in the path! I used
c:\CodeSourcery. Immediately after the install finishes, use the
Windows file explorer to open the install folder and rename the folder
\Sourcery G++ Lite to
\SourceryG++Lite, again, to
eliminate spaces in the path to the various CS tools. If you
don't do these steps, you will have all kinds of issues later when you
try to build one of your projects.
Microsoft's Visual Studio 2005
CodeSourcery provides the compler, linker, assembler, make utility
(cs-make) and other common gcc tools, but does not provide an
integrated development environment (IDE). I first tried using AVR
Studio4 as an IDE for developing my mbed projects. I made it
work, but didn't like the results. The IDE didn't provide a
smooth connection between the many source and header files I was using,
which made it difficult to keep the flow of code in my head as I
searched through the many folders involved. After a while, I gave
up on AVR Studio4 and tried my hand at integrating CS G++ Lite with
Visual Studio 2005 (VS2005).
I'm certainly not a fan of MS, but I'll give them credit when
due. VS2005 and its later iterations are superb IDEs. I
have used them for years and always cringe when I have to use something
else. If you've never used VS2005, you are in for a treat when
you switch over mbed development to this IDE. The ability to
right-click on a function name, for example, and immediately open up
the associated file, with the text line defining that function right in
front of you, is huge. No trudging through all the files in your
project (or in distantly associated folders, such as the CS include
folders), trying to find some obscure macro definition. Just
right-click on the name, select
Go to
Definition, and you're there!
However, VS2005 was built to use Microsoft's compiler tools, not
GCC's. Below, I provide instructions on integrating most of the
GCC tool suite into VS2005, but there are a few rough edges yet.
Note, however, that even with these rough edges and missing features, I
consider the resulting IDE way beyond, for example, AVR Studio 4.
makefiles
Before I get to the instructions for setting up VS2005, I need to
comment on the use of makefiles. You will be creating your own
makefiles as part of the development process. Yes, makefiles are
not the simplest tool in the box to use, but they are not all that hard
to grasp and there are LOTS of tutorials on the web for using
them. Plus, I will provide you with some boilerplate makefiles
suitable for mbed compiling. But expect to learn some of the
makefile basics if you want to do much bare-metal mbed development.
Integrating VS2005 with GCC
The following instructions work for VS2005. I suspect they will
work as well with later versions of VS, but I don't have those and
can't confirm.
VS2005 wants to organize your work in a hierarchy. At the bottom
of the pyramid are the source and header files, along with other
related files. The next layer up contains projects, which are
collections of files for a common purpose. At the top of the
pyramid are solutions, which are collections of projects that define a
final executable you are trying to create.
This layout for your work is quite powerful. It helps you divide
up your code into manageable projects that are all available to you in
VS2005's Solution Explorer. The Solutions Explorer lets you
select single projects for rebuild, so you can focus on that project,
or select all projects (the entire solution) for rebuild as needed.
Note that you don't have to set up your work using the solution/project
model. You can certainly go with just a single project, putting
all header and source files in a single folder, and I've done several
projects just that way. But at least go through the use of
solutions so you know it is available later if you find the
single-project model has limitations.
For my sample, I'm going to create a solution called blinky, since
everyone blinks an LED as a first coding exercise. blinky will
consist of two separate projects. The first project contains the
start-up code that runs immediately after reset of the mbed
device. The second project contains the code for blinking an LED
on the mbed board.
I'll begin by creating a project for the blinky source code.
Start by opening up VS2005. You should see a blank page similar
to this:
The Solution Explorer in the leftmost column is empty. In the
Recent Projects window, you can see some of my earlier work.
To create a new solution, select
File/New/Project
From
Existing
Code. You will see a window like this:
Leave the project type as
Visual C++.
Click
Next >. You
should see a window that allows you to select a project location and
files to include. I've filled out the window for the blinky
solutions here:
I've called the project blinky_spinloops because I'm going to use
spin-loops to control the blinkrate of the LED. The source code
for this project will live in the folder called out in the
Project file location field you see
here. Note that I've unchecked the box marked
Show all files in Solution Explorer.
If
you
don't
uncheck
this
box, the Solution Explorer window can get
pretty crowded. I find it better to start with an empty view in
the Solution Explorer, then add the files I want to access.
When you're all set up, click
Next.
You
should
see
a
window
that allows you to select the project's build
settings. Here, I've selected an external build system:
When you click
Next > at
this point, you should see a screen that allows you to set up the debug
configuration. VS2005 uses two main configurations for your
projects and solutions. The debug configuration is assumed to be
one you will be debugging with and will likely have extra debug code
and hooks built into it. The other configuration, release, is
intended for shipping code that has no debug hooks built in.
Here, I've set up my debug configuration by providing the name of the
CodeSourcery tool used to execute a makefile.
Note that building the code later requires that the path to the
cs-make.exe utility in CodeSourcery's /bin folder must be in your PATH
environment variable! If necessary, use the approriate tool in
your control panel to add this path.
After clicking
Next >, you
should see a window for setting up the release configuration.
This window by default uses the same setup information as the debug
configuration. Simply click
Finish.
At this point, I have a solution named blinky_spinloops and an empty
project named blinky_spinloops. Time to add some source code.
Start by clicking
File/New/File...
and selecting the Text template. This will get you an empty text
file in the editor window. Now use
File/Save <textfile> As... to
rename the file and save it into your blinky_spinloops folder as
blinky_spinloops.c. Here's what my editor page looks like now:
I've added the source code for the blinky_spinloops.c file to the
editor window. You can download the files for the
blinky_spinloops project from the link at the bottom of this page.
At this point, I have the source for the LED blinker program, but I'm
missing two important pieces. First, I need the startup code,
which takes control immediately after reset. Second, I need a
makefile to build all of this source into a final executable.
I already have a universal startup file, named startup_LPC17xx.s, that
I use on all of my mbed projects. This is an assembly language
file, as denoted by its .s extension, that does only the most basic
initialization of the MCU before handing off control to the main()
function. The startup file sets the stack pointer, zeroes out all
declared variables, initializes all variables that require it, then
jumps to main(). Additional initialization, such as setting up
the PLL that controls the MCU's timing, is left to the main()
function. You can find the files for my startup_LPC17xx project
in the link at the bottom of this page.
I could copy the startup source file into the same folder as my
blinky_spinloops.c file. Instead, I put the startup file and a
few other common source files into a single folder called
\object. If I am working on a solution that requires the startup
file (and they all will), I simply include the startup project in my
solution.
To add an existing project to a solution you are developing, go into
the Solution Explorer and right-click on the solution (the text and
icon on the first line in the Solution Explorer window), then select
Add and
Existing Project.... Navigate
to the folder holding the project file for the new project and select
that project file; in this case, that would be the file
startup_LPC17xx.vcproj in the folder
C:\projects\mbed\object.
At this point, my blinky_spinloops solution looks like this:
That takes care of the startup code. Now I need the
makefile. Actually, I need two makefiles, one for the
blinky_spinloops project and one for the startup_LPC17xx project.
This is because each project is built separately and each project is
defined with its own makefile; refer to the above steps where I set up
the debug and release configurations as I was creating the
blinky_spinloops project.
I like to keep the makefile in a separate folder, named
Others, within the project.
This folder holds any miscellaneous files for the project, such as the
makefile, any listings, a map file if there is such, etc. As you
can see in the above image, the startup_LPC17xx project already has an
Others folder where I've put its makefile. To add an Others
folder to the blinky_spinloops project, just right-click on the icon
for the blinky_spinloops project (not solution!), then select
Add and
New Filter. (I'm sure there is
a good reason why this is called a filter and not a folder, but I don't
know what that reason is.) Enter a name for the filter of
Others, then press Enter.
To place an existing file, such as the blinky_spinloops.mak file, into
one of the folders within a project, right-click the appropriate
folder, then select
Add/Existing
Item..., locate the file of interest, and select it. Now
you can open a folder and view the list of files from within the
Solution Explorer.
Now I need to create the actual makefile. I have a universal
makefile for mbed development, so all I really need to do is create a
new text file, copy the template into the text file, then rename the
text file to blinky_spinloops.mak and add that file to the Others
folder I just made. I can then open the makefile, change a couple
of lines so the makefile creates the blinky_spinloop binary file, and
save the changes back. Here is what the editor window looks like
while viewing the updated makefile:
Now all of the pieces are in place. Assuming I have not yet built
the startup project, building the entire blinky_spinloops project is a
two-step process. First, build startup_LPC17xx.o by
right-clicking on the icon for the
startup_LPC17xx
project and selecting
Project
Only/Rebuild Only startup_LPC17xx. Second, use the same
actions to select and
rebuild the blinky_spinloops project.
Here is the editor window following a successful rebuild of the
blinky_spinloops project:
Limitations and issues
The above example barely scratches the surface of what you can do with
VS2005 in support of mbed development. For example, I haven't
shown anything about how IntelliSense eases the editing and project
management tasks for larger, multi-file projects.
But there are some limits in what you see here. For example, if
you get errors during a compile, you cannot just double-click on the
error message and have VS2005 take you directly to the offending
line. That should be working, but I don't have it correct yet.
Another limitation in this setup is the dependency on makefiles.
I've tried to keep my makefiles as simple and generic as possible, but
such makefiles won't work in all cases and you will have to be strong
enough with makefiles to find and fix any issues.
Speaking of dependencies, VS2005 allows you to alter build order based
on projects depending on other projects building first. This can
become an issue when working with multi-project solutions and is
handled gracefully by VS2005 when working with the VS compilers.
However, the dependency feature doesn't work very well in the setup I
show here, because the makefile for a dependent project is fired off
inside the directory for the higher-level project. This means the
object file for the dependent project is written to the root folder for
the higher-level project and is now outside of the link path when the
final executable is linked. I might be able to fix this with
modified makefiles, or there might be a simple method inside VS2005
that I've overlooked. For now, I am careful to rebuild each
project when it is changed, then build the final project
(blinky_spinloops, in this case) only after all underlying projects
have been rebuilt. This is more error-prone than I like, so I'll
try and come up with a fix.
The executable
The point of the entire exercise above was to get a bare-metal LED
blinker running. The final executable, blinky_spinloops.bin,
weighs in at 792 bytes and works like a charm. I just copy it
into the MBED USB drive, reset the mbed device, and watch the light
blink.
The files
Here is a
zip file of the source
and make files for this project.
NOTE: There was an error in the
PLL setup code in the original version of these files (30 Dec
11). If you grabbed that set, please reload!
You will need to go through the
steps I've outlined above to create your own VS2005 solution for this
project. Be sure you have the path to cs-make.exe (in the
CodeSourcery /bin folder) in your PATH environment variable! I've
tried to add comments to my makefiles to help you understand how things
are set up and where you might need to make changes to match your own
system.
Note that the files blinky_spinloops.c and start_LPC17xx.s provide a
working example of setting up a bare-metal mbed project from the moment
following reset through system setup to blinking an LED. This
makes a great example for how to design your own bare-metal apps.
One of the files in the collection is the linker script, used in the
blinky_spinloops makefile to place the final executable code in the
MCU's memory. This linker script, LPC17xx.ld, lives in the folder
c:\projects\mbed\linker in my
system. You can see how the path to this script is set up in the
makefile by locating the variable LSCRIPT.
OK, that's a wrap. This has been a large page and I appreciate
you taking the time to wade through all of this. If you have
questions or (even better) ways to improve what I have here, please
drop me an email.
Home