C/C++

How to resolve fatal error: bytecode stream generated with LTO version … instead of the expected …

Problem:

When compiling a program or library with GCC, you get an error message similar to this:

fatal error: bytecode stream generated with LTO version 5.1 instead of the expected 5.2

Solution:

This error basically means that you’ve got some binary build results (mostly object files) which are incompatible with other binary build results, but you’re trying to link them together. The LTO part just means that the incompatibility is due to you having link-time optimization enabled – but you don’t need to worry about that, you can just treat it like any other incompatibility.

In almost all cases, there is a very simple reason for the error: You have built your project with an older GCC version, then updated GCC and re-compiled (partially, as not all files have been changed) later. In this case, there is a simple solution: Just clean your build and re-build from scratch.

If you use make (or CMake), this is usually as simple as

make clean # Remove old, incompatible files
make # Rebuild

For other buildsystems, lookup how to clean your build accordingly – or just delete your build or dist directory if that doesn’t cause any unintended side effects.

In some very rare cases, an issue in the build system configuration causes the software to be built with two different compilers. If you think that might be the case (i.e. if the cleaning process does not help), I suggest trying to look at the verbose output of your build system — however, keep in mind that it’s more likely that you’re trying to link a stray object file that has been built with an older version of the compiler.

If you’re happy with just fixing the symptom while ignoring the possibility of hard-to-debug incompatibilities, you can just omit the -flto flag in the build system config. This hides the LTO incompatibility as it disables the link-time optimizer altogether, but even if no new error codes are shown, this approach is generally not recommended.

Posted by Uli Köhler in GCC errors

Advantages and disadvantages of hugepages

In a previous post, I’ve written about how to check and enable transparent hugepages in Linux globally.

Although this post is important if you actually have a usecase for hugepages, I’ve seen multiple people getting fooled by the prospect that hugepages will magically increase performance. However, hugepaging is a complex topic and, if used in the wrong way, might easily decrease overall performance. Continue reading →

Posted by Uli Köhler in C/C++, Performance

In-place trimming/stripping in C

For an explanation of in-place algorithms see my previous post on zero-copy in-place splitting

The problem

You have a C string possibly containing whitespace at the beginning and/or the end.

char* s = " abc   \n\r";

Using an in-place algorithm, you want to remove the whitespace from this string.

Doing this is also possible using boost::algorithm::trim, but it has the same caveats as boost::algorithm::split as discussed in my previous post about C splitting Continue reading →

Posted by Uli Köhler in C/C++

Zero-copy in-place string splitting in C

Let’s assume you have a string:

char* s = "1,23,456,7890";

You want to split said string at each comma in order to obtain its parts as C strings (with the number of parts being variable):

char* s1 = "1";
char* s2 = "23";
char* s3 = "456";
char* s4 = "7890";

Continue reading →

Posted by Uli Köhler in C/C++

Using Arduino Leonardo as an USB/UART adapter

In contrasts to older designs like the Arduino Uno, the Arduino Leonardo features a separate connection Serial1 for TTLUART whereas Serial is used for the USB CDC UART interface.

This allows one to use the Leonardo as an USB/UART bridge without having to resort to more expensive boards like the Arduino Mega 2560. In order to do this, use this sketch which can also be modified to provide an intelligent UART bridge.

Remember to adjust the baudrate for your application. This version of the sketch does not support automatic baudrate selection via the CDC peripheral.

Continue reading →

Posted by Uli Köhler in C/C++, Embedded

Accessing lwIP struct netif instance in ChibiOS

Problem

You are using the ChibiOS lwIP binding to access the network your microcontroller application.

You need to access the lwIP struct netif structure, for example to get the current DHCP IP address assigned to the network interface. However, the default ChibiOS implementaton in lwipthread.c does not export the interface structure.
Continue reading →

Posted by Uli Köhler in C/C++, Embedded

Reading the STM32 unique device ID in C

All STM32 microcontrollers feature a 96-bit factory-programmed unique device ID. However, for me it was hard to find an adequately licensed example on how to read it in a manner compatible with different families and compilers.

Here’s a simple header that defines a macro for the device ID address. While I checked the address for both STM32F4 and STM32F0 families, other families might have slightly different addresses for the device ID. Check the reference manual corresponding to your STM32 family if errors occur.

Continue reading →

Posted by Uli Köhler in C/C++, Embedded

Reading STM32F0 internal temperature and voltage using ChibiOS

The STM32F0 series of 32-bit ARM Cortex M0 microcontrollers contain a huge number of internal peripherals despite their low price starting at 0,32€ @1pc. Amongst them is an internal, factory-calibrated temperature sensor and a supply voltage sensor (that specifically senses VDDA, the analog supply voltage rail) connect to channels 16 and 17 of the internal ADC.

While I usually like the STM32 documentation, it was quite hard to implement code that produced realistic values. While the STM32F0 reference manual contains both formulas and a short section of example code, I believe that some aspects of the calculation are understated in the computation:

Section 13.9 in RM0091 provides a formula for computing the temperature from the raw temperature sensor output and the factory calibration values. However it is not stated anywhere (at least in Rev7, the current RM0091 revision) that this formula is only correct for a VDDA of exactly 3.30V.

Continue reading →

Posted by Uli Köhler in C/C++, Embedded

Using the lwIP SNTP client with ChibiOS

A common task with embedded systems is to use the RTC to timestamp events. However, the system architect needs to find a way of synchronizing the devices RTC time with an external time source. Additionally, the designer needs to deal with the problem of drifting RTC clocks, especially for long-running devices. This article discusses an lwIP+SNTP-based approach for STM32 devices using the ChibiOS RTOS. The lwIP-specific part of this article is also applicable to other types of microcontrollers.

For high-accuracy or long-running applications, RTC clock drift also has to be taken into account. Depending on the clock source in use, the clock frequency can deviate significantly from the nominal value.

On the STM32F4 for example, you can derive the RTC clock from: The HSE/HSI main oscillator The LSI oscillator * The LSE oscillator, i.e. a 32.768 kHz external crystal.

Continue reading →

Posted by Uli Köhler in C/C++, Embedded

Converting zhash_t to std::map

Problem:

You have a hash data structure represented by CZMQ’s zhash_t (see the zhash_t documentation for further information).

In order to be able to use it more conveniently in C++, you intend to convert said zhash_t to a std::map<std::string, std::string>.

Continue reading →

Posted by Uli Köhler in C/C++

Buffer-overflow safe readlink() in C++

Problem:

You want to use readlink() to get the file or directory a symbolic link points to, but you don’t know the buffer size that is required to store the symlink destination. You don’t want to allocate an incredibly large amount of memory (whatever amount you choose, it could always be insufficient), but you won’t risk buffer overflows.

Continue reading →

Posted by Uli Köhler in C/C++

mmap with Boost IOStreams: A minimalist’s example

The following C++ program uses boost::iostreams to memory-map a file, read it’s content into a std::string and print it to cout.

It provides a minimal example of how to use the boost::iostreams portable mmap functionality.

//Compile like this: g++ -o mmap mmap.cpp -lboost_iostreams
#include <boost/iostreams/device/mapped_file.hpp>
#include <iostream>
#include <string>
using namespace std;
using namespace boost::iostreams;

int main(int argc, char** argv) {
   //Initialize the memory-mapped file
   mapped_file_source file(argv[1]);
   //Read the entire file into a string
   string fileContent(file.data(), file.size());
   //Print the string
   cout << fileContent;
   //Cleanup
   file.close();
}

Also see A simple mmap() readonly example

Posted by Uli Köhler in C/C++

Reading TAR files in C++

This article describes a method of  reading TAR archives (including .tar.gz and .tar.bz2) in C++ using Boost IOStreams.

You could use libtar for this, but the original version hasn’t been updated since 2003 and doesn’t provide you flexibility and insight to the internal structure of a TAR archive. Continue reading →

Posted by Uli Köhler in Algorithms, C/C++