Posts Tagged ‘C++’

Synchronization primitives in Miosix

October 6, 2012

A small and backwards compatible change in Miosix 1.61 made me think about low-level synchronization primitives, and the fact that doumentation on how to use them was lacking. So, here’s a page dedicated to this topic.

Using a DMA capable SPI as an LCD controller

November 30, 2011

What if you have a graphic display without an embedded controller, and you want to drive it with an ARM microcontroller? Turns out that if a DMA is available, the task is not so impossible as it first seems.

If you’re interested, read the article on my website here.

Mxgui

September 22, 2011

Ok, here’s the new library for Miosix: Mxgui. As the name suggests, it’a a GUI library for microcontrollers, designed to work with the Miosix kernel.

Source code is here, while documentation here.

What can it be used for? 3D rendering on a microcontroller, for example.

Mxgui examples from fede.tft on Vimeo.

Miosix 1.54 released

October 3, 2010

After a lot of time spent coding, here’s the new release of Miosix, my OS kernel for microcontrollers.

New features include:

  • Porting for ST’s Cortex M3 microcontrollers
  • Preliminary implementation of the POSIX thread API (pthreads)
  • Improved statistics on memory usage and debugging messages
  • Bug fixes and other enhancements

If you’re interested, download the new release here: http://www.webalice.it/fede.tft/miosix/index.html

Digital voltmeter for power supply

October 2, 2010

This summer I finally found some time to fix my power supply.

It’s a rather old but relieable unit, and I have no intention of replacing it. Basically, it still works except for the voltage meter on the front panel. Over time, the pointer developed an offset of around 1V, which is visible in this image where the power supply is turned off. Instead of indicating exactly zero volt, the pointer is below the beginning of the scale.

This, together with the fact that today’s microcontroller require 3.3V to operate (while the voltmeter only has an 1V resolution), forced me to always use a multimeter when using it, to be able to precisely set the output voltage.

The solution I found was to simply replace the analog voltmeter with a digital one. Instead of using a voltmeter chip like the ICL7107 that usually require the measurement ground to be separated from the supply ground, these days it is easier to build a voltmeter using a microcontroller.

That’s because even the cheap and simple micros now have at least a 10 bit ADC which is more than enough for a voltage meter in the rage 3..15V (which is the range of my power supply). Since the task is easy there was no need to use an ARM microcontroller as I usually do, but instead an ATtiny26 proved more than enough, despite only having 2KBytes of FLASH and 128Bytes of RAM.

This is the result:

The circiut is simple, a 78L05 is used to reduce the 20V found in the power supply to 5V to power the microcontroller. A voltage divider made with 1% precision resistors is connected from the power supply input to an ADC capable GPIO on the microcontroller, and three LED displays show the voltage with 0.1V resolution.

The LED displays are ofcourse multiplexed so that the ATtiny, despite its low number of GPIOs, can drive the display with no other glue logic except for current limiting resistors.

Around 100 lines of C++ code keep the whole thing working.

Qt and serial ports

April 23, 2010

Update Jun 22, 2011 : Fixed a bug for compiling under visual studio 2010.

This is intended to be a small add-on to the article I’ve posted on my website which explains how to use boost’s asio library to interface with serial ports from C++ code. This blog post focuses on a topic not covered in the article: using serial ports in Qt GUI applications.

Since serial ports are used primarily to interface a computer with a microcontroller, we’ll focus on this case.

The additional problem that occurs when the application has a GUI is the result of two restrictions that GUI applications have:

  • The thread that runs the GUI event loop should not block for long periods of time (say, more than a second). If this happens, the GUI “freezes” and this annoys users who think the application has crashed and usually force-quit it.
  • Code that updates the GUI should not be called from threads different from the main thread.

Now, if the microcontroller never sends data to the serial port unless the computer sends a command to it, and replies are always fast there is no problem.

Let’s show a basic protocol of this kind:

  • The PC can send the command “A” to the microcontroller.
  • If the microcontroller receives “A”, it reads an ADC channel and sends the value back to the PC

As said, in this case there is no problem. A possible GUI would have a button to read the value, and a label to show the result.

Such an application can easily use the TimeoutSerial class, with code to write the letter “A” in the callback of the button, immediately followed by a read from the serial port to get the result and show it on the GUI. The timeout, set to an appropriate value (such as 500ms) would ensure that the GUI won’t freeze even if something goes wrong, and the programmer can catch the TimeoutException to show an error message to the user.

But what to do if the command takes much time to complete, say 10 seconds? In this case this simple approach won’t work, because the GUI will freeze for ten seconds with the main thread waiting for the response from the serial port.

And what to do with a protocol like this?

  • The microcontroller sends the value read from the ADC 20 times a second.

In this case the PC application should always listen on the serial port for incoming data.

Well, who has read my article will probably think of using the AsyncSerial class, which allows to register a callback that will be called every time some data arrives from the serial port.

But also this approach won’t work, because of the constraint that the GUI code can be called only from the main thread, but AsyncSerial calls the callback from a separate thread.

To show how to solve this problem I’ve written a class, called QAsyncSerial which is a wrapper class for AsyncSerial that uses Qt’s system of signals and slots. It basically emits a signal every time a line is received from the serial port, and because signals and slots are thread safe, the code works as expected.

To show everything in practice, this is a simple GUI that uses QAsyncSerial running on Linux:

This simple GUI allows to select a serial port and open it (the baud rate is fixed to 115200, 8N1 format). Once it is opened, there is a line where to write text to send to the serial port while received text is showed below.

The code of the QAsyncSerial class and of the GUI example is posted at the end of the original article (here). It is meant to be compiled with QtCreator. If you try to compile it don’t forget to edit the line “-L/usr/local/lib” in the SerialGUI.pro file to point to where you have the boost libraries installed.

Last note, since the Qt libraries are cross platform, here’s the same application running on a Mac:

CMake part 3: Finding libraries

March 7, 2010

Over time, I find myself more and more interested in CMake. That’s because I write many little programs, and those that use makefiles routinely break as I switch OS.

The last one was a program that depended on libpng. When I tried to compile it on Mac OS X, it failed to find the library. That’s because on Linux libpng.so is simply in /usr/lib and png.h is in /usr/include, both of which are in the compiler’s search path, so that all you need to do is add “-lpng” when linking.

But on a Mac libpng.dylib (yes, shared libraries on a Mac have .dylib extension) is in /usr/X11/lib and png.h is in /usr/X11/include that are not in the compiler’s search path, so that when compiling you need to add “-I/usr/X11/include” and when linking “-L/usr/X11/lib -lpng”.

The solution was not to keep two separate makefiles, but rather to throw away the makefile and replace it with a CMakeLists.txt

Which brings us to the question: how to link with libraries using CMake?

There are two ways, the first is the find_package command, the other is the find_library command.

Let’s start with find_package. CMake “knows” about many widely used libraries. For them, there is a script to find them in all supported platforms. So, to use a library all you need to do is find it with the find_package command. Here is a simple example of a program that uses threads and so depends on “-lpthread”, main.cpp:

#include <iostream>

using namespace std;

void *thread(void *argv)
{
    cout<<"Into a spawned thread"<<endl;
}

int main()
{
    pthread_t t;
    pthread_create(&t,NULL,thread,NULL);
    pthread_join(t,NULL);
    cout<<"Back in main thread"<<endl;
}

and here is the CMakeLists.txt file:

cmake_minimum_required(VERSION 2.6)
project(TEST)

## Target
set(TEST_SRCS main.cpp)
add_executable(test ${TEST_SRCS})

## Link libraries
find_package(Threads REQUIRED)
target_link_libraries(test ${CMAKE_THREAD_LIBS_INIT})

As can be seen, the first parameter passed to find_package is the name of the package, the second is “REQUIRED” and means that if the library could not be found, CMake should stop and print an error message.

Once the library is found, you have to say which executable needs it (because a single CMakeLists.txt can be used to produce many executable by just using more add_executable commands). This is achieved with the target_link_libraries command that appends a library to the list of libraries an executable needs. The first parameter is the executable name, the second is the library. Note that find_library generates a variable that contains the name of the library, in this case the name is CMAKE_THREAD_LIBS_INIT. This strange name is an exception, usually all find_package scripts create a variable with the name <libraryname>_LIBRARY.

Now a more complex example: the libpng issue I talked about earlier. It is more complex because you don’t just need to add a library when linking, you also need to tell the compiler where is the png.h file when compiling. Luckily, CMake has a package for libpng that does all that, and here is the CMakeLists.txt example:

cmake_minimum_required(VERSION 2.6)
project(TEST)

## Targets
set(TEST_SRCS test.cpp)
add_executable(test ${TEST_SRCS})

## Link libraries
find_package(PNG REQUIRED)
include_directories(${PNG_INCLUDE_DIR})
target_link_libraries(test ${PNG_LIBRARY})

The find_package command finds the PNG library, target_link_libraries adds the library to the list of libraries the executable needs, and include_directories adds the directory where the .h file is when compiling.

But this isn’t the end. Other than libraries there are collections of libraries. And CMake supports them too. One example are the boost libraries. There is no single libboost.so to link to; instead every sub-library has its .so file. So there should be a way to link only with the desired sub-libraries. This is an example CMakeLists.txt that does that:

cmake_minimum_required(VERSION 2.6)
project(TEST)

## Target
set(TEST_SRCS main.cpp)
add_executable(test ${TEST_SRCS})

## Link libraries
set(BOOST_LIBS thread date_time system)
find_package(Boost COMPONENTS ${BOOST_LIBS} REQUIRED)
target_link_libraries(test ${Boost_LIBRARIES})
find_package(Threads REQUIRED)
target_link_libraries(test ${CMAKE_THREAD_LIBS_INIT})

In this case we initialize a variable with the sub-libraries we want (boost.thread, boost.date_time and boost.system). Then we call find_package with the library name (Boost), the word COMPONENTS followed by the list of sub-libraries and as usual the REQUIRED word. Since boost.thread depends on the system’s thread library, we also use another find_package command to link with threads.

This ends the examples of find_package, but there is one last issue: what if we need a library for which there isn’t a package script? The solution is to use the find_library command. It will search in the system paths for the needed library. Here is an example that uses the command to find the Poco libraries:

cmake_minimum_required(VERSION 2.6)
project(TEST)

## Target
set(TEST_SRCS main.cpp)
add_executable(test ${TEST_SRCS})

## Link libraries
find_library(POCO_FOUNDATION PocoFoundation)
find_library(POCO_NET PocoNet)
target_link_libraries(test ${POCO_FOUNDATION} ${POCO_NET})
find_package(Threads REQUIRED)
target_link_libraries(test ${CMAKE_THREAD_LIBS_INIT})

The find_library command takes two parameters, the first is the variable where the found library will be stored, and the second is the library name (the name is camelcase in this example because Poco libraries are camelcase, the library name is really libPocoFoundation.so).
References: CMake wiki

STM32 GPIOs and Template Metaprogramming

December 23, 2009

I posted a new article on my website.

It talks about a performance optimized and high level way of handling STM32 GPIOs using Template Metaprogramming.

CMake part 2: Compiler flags

December 21, 2009

It’s not the first time I talk about CMake in this blog, for the introduction read here. Now it’s time to explore the CMake syntax further. The first CMakeLists.txt looked like this:

cmake_minimum_required(VERSION 2.6)
project(HELLO)

set(HELLO_SRCS main.cpp foo.cpp)
add_executable(hello ${HELLO_SRCS})

As already explained, it successfully creates an executable called “hello” using the main.cpp and foo.cpp source files. But let’s see exactly what CMake does to compile these files. To do so, it is possible to use the commands:

mkdir build && cd build
cmake ../
make VERBOSE=1

The interesting thing here is the VERBOSE=1 option. By default CMake hides the options passed to the compiler, and displays a higher level status indicator with the build completion percentage together with the name of the file currently being built (a much more elegant solution than autoconf). But if the goal is to see the compiler flags used, it is always possible to override this behaviour with the VERBOSE=1 option.

Here is the relevant part of the printout:

[...]
[ 50%] Building CXX object CMakeFiles/hello.dir/main.cpp.o
/usr/bin/c++     -o CMakeFiles/hello.dir/main.cpp.o -c /tmp/cmaketest/main.cpp
[100%] Building CXX object CMakeFiles/hello.dir/foo.cpp.o
/usr/bin/c++     -o CMakeFiles/hello.dir/foo.cpp.o -c /tmp/cmaketest/foo.cpp
Linking CXX executable hello
/usr/bin/c++      CMakeFiles/hello.dir/main.cpp.o CMakeFiles/hello.dir/foo.cpp.o  -o hello
-rdynamic
[...]

Now, if you’ve read my previous blog post on GCC’s compiler flags, you might probably not like what you see, since no optimization flag has been passed to GCC and as a result, your program won’t run as fast as it should.

That’s because no build type has been specified to CMake. The build type is a feature most IDE have, it allows you to compile your program in “debug” mode, for easily single-stepping through it with a debugger, or in “release” mode, with speed optimization enabled.

To fix this you simply need to specify a build type in the CMakeLists.txt file, in this way:

set(CMAKE_BUILD_TYPE Release)

at the end of your CMakeLists.txt file. Of course, change “Release” with “Debug” for debug builds.

With the Release build type, the options passed to the compiler are these:

[...]
[ 50%] Building CXX object CMakeFiles/hello.dir/main.cpp.o
/usr/bin/c++    -O3 -DNDEBUG   -o CMakeFiles/hello.dir/main.cpp.o -c /tmp/cmaketest/main.cpp
[100%] Building CXX object CMakeFiles/hello.dir/foo.cpp.o
/usr/bin/c++    -O3 -DNDEBUG   -o CMakeFiles/hello.dir/foo.cpp.o -c /tmp/cmaketest/foo.cpp
Linking CXX executable hello
/usr/bin/c++   -O3 -DNDEBUG   CMakeFiles/hello.dir/main.cpp.o CMakeFiles/hello.dir/foo.cpp.o
 -o hello -rdynamic
[...]

Much better than before. And if you find uncomfortable to have to edit the CMakeLists.txt file to switch between Release and Debug mode, you can also specify the option in the CMake command line, like this:

mkdir build && cd build
cmake -D CMAKE_BUILD_TYPE=Debug ../
make

Last, if you are a GCC wizard and you want full control of the options passed to the compiler, you can also set them manually. However, keep in mind that a CMakeLists.txt file should ideally work with many compilers. So before forcing compiler options, you need to check that the compiler is really GCC. This is an example that shows how to do it:

cmake_minimum_required(VERSION 2.6)
project(HELLO)

## Target
set(HELLO_SRCS main.cpp foo.cpp)
add_executable(hello ${HELLO_SRCS})

## Compiler flags
if(CMAKE_COMPILER_IS_GNUCXX)
    set(CMAKE_CXX_FLAGS "-O2")        ## Optimize
    set(CMAKE_EXE_LINKER_FLAGS "-s")  ## Strip binary
endif()

Note that you must not specify a build type (Debug or Release) since it apparently conflicts with the manually set compiler flags.

Last note, not necessarily CMake related, if you happen to have a multicore CPU and want to speed up builds, you can use the -jX option of make, where X is the number of cores in your CPU. It tells make to compile X files (lol :D) at the same time. So for a dual core, use:

mkdir build && cd build
cmake ../
make -j2

Using C++ on microcontrollers code size tricks

October 11, 2009

I posted a new article on my website.

It talks about some tecniques to minimize the code size when using GCC and C++ with microcontrollers. It also includes a fully functional template project for an LPC2138 microcontroller.


Follow

Get every new post delivered to your Inbox.

Join 30 other followers