söndag 2 december 2018

Get the default include paths from Clang


When porting our code to build for Win32 with Clang, on macOS, I got a bunch of intrinsics errors:


/usr/local/opt/llvm/bin/lld-link: error: dlib.lib(image_2.o): undefined symbol: __cpuid
/usr/local/opt/llvm/bin/lld-link: error: dlib.lib(image_2.o): undefined symbol: _mm_setr_epi16
/usr/local/opt/llvm/bin/lld-link: error: dlib.lib(image_2.o): undefined symbol: _mm_set1_epi32
/usr/local/opt/llvm/bin/lld-link: error: dlib.lib(image_2.o): undefined symbol: _mm_load_si128


This error is a bit unusual (for me at least) so it threw me off, since I had obviously linked against the dlib.lib before, only difference, it was using CL.exe at that time.

This isn't due to a missing library, but in fact a missing include.
And as it turns out, the order of includes.

The compiler checks the include file(s) to see what symbols to put in there, and if it recognises it, it outputs the correct intrinsic function in the code. Otherwise, it's unresolved, and will later become undefined.

And, in order to make the code a bit more resilient towards compiler version updates, I wanted to grep the include paths in a simple fashion on both OSX/Linux:

macOS:

$ /usr/local/opt/llvm/bin/clang++ -Wp,-v -x c++ - -fsyntax-only < /dev/null 2>&1 | grep -e /clang
 /usr/local/Cellar/llvm/6.0.1/lib/clang/6.0.1/include


Linux:
$ clang++ -Wp,-v -x c++ - -fsyntax-only < /dev/null 2>&1 | grep -e /clang
 /usr/local/lib/clang/6.0.0/include

lördag 1 december 2018

Compile cctools for Windows

I wanted to try building cctools for Windows,

I first tried (and failed) with cctools-port
Next, I tried (and succeeded) with osxcross and Cygwin (32 and 64 bit).

Also note that I needed no iOS/OSX SDK for this!

Here's a brief recap on what I had to do...


söndag 21 januari 2018

Memory allocation debugging

Sometimes it's beneficial to see the actual memory allocations done by an app, but you don't want to code a full memory allocation system. Perhaps you cannot even rebuild the app.

Then a good option is to use a dynamic library to override all the allocation functions.

The idea is simple, make sure the application finds your library before any other, and let it use the custom malloc-functions. Here is the source

On MacOS, you'll use

    $ DYLD_INSERT_LIBRARIES=libmemprofile.dylib ./a.out

and on Linux:

    $ LD_PRELOAD=libmemprofile.so ./a.out

The result will look like this:

$ DYLD_INSERT_LIBRARIES=libmemprofile.dylib ./a.out
Memory used: 
   Total: 512 bytes in 2 allocation(s)

   At exit: 0 bytes in 0 allocation(s)

onsdag 30 augusti 2017

Arduino + NodeMCU / ESP8266

To program for the ESP8266, you need to install some packages for the Arduino program/computer.

To add the ESP boards to the board list in Arduino, you


  • Add the line http://arduino.esp8266.com/stable/package_esp8266com_index.json into the preferences pane, in the "Additional Boards Manager URLs"
  • Then open Tools -> Board -> Boards Manager and install ESP8266
You can now select your proper board from the list.

Next, you need to make sure you can select the proper port it's connected to. To do that, you install the driver from here

Then, you choose the port named "/dev/cu.SLAB_USBtoUART"

Now you're ready to build and upload as usual for your NodeMCU board!

Sources:
https://github.com/esp8266/Arduino
http://www.instructables.com/id/Quick-Start-to-Nodemcu-ESP8266-on-Arduino-IDE/
https://roboindia.com/tutorials/nodemcu-amica-esp8266-board-installation

onsdag 31 maj 2017

Debugging your arduino

While I'm waiting for my first OLED screen to arrive, I decided to learn more about the debugging options available for the Arduino.

I found 4 alternatives:

  • Hardware
  • Emulators
  • Print
  • Drivers

In the end the option most attractive to me at this point is to add debugging drivers to my code.
But I'll list the other options first...

Hardware:

There are a few variants out there, costing ctom $10-$100+:
Atmega328P Xplained Mini, AVR Dragon, JTAGICE2, AVR One, JTAGICE3

The cheapest one is the Atmega328P Xplained Mini at ~$10. Unfortunately, it seems very tied to the Atmel Studio which is only supported on Windows.

Emulators:

I found 2 emulators, each with similar feature sets, but one seems a bit legacy at this point:


Both emulators have the option to sample the output pins, and log the values into a .vcd file, which can be displayed with gtkwave.

Print:

It's of course important to mention that you can do print debugging too when you need it

Drivers:

After stumbling across this post by Jan Dolinay, I wanted to see it it worked for my cheap arduino.
I turned out it was farily easy to build it. There was a few caveats (mentioned by Jan in his post) regarding the serial interface, but in essence, you cannot use the Serial class since the debugger uses the serial port. But there is a debug_message(const char* msg) that can be used instead.

Build notes:


  • Add the avr8-stub.c to your build, add avr8-stub.h to your main.cpp
  • Overwrite the WInterrupts.c in your core library
  • Call debug_init() in your setup() function
  • [Optional] Set programmatic breakpoints using breakpoint()
  • Add flags "-Og" and "-gdwarf-2"

Debugging:

Once you've built the .hex file and uploaded it, it's time to run avr-gdb:
  • Upload the myprog.hex file with avrdude
  • Run debugger with, connecting to your serial port:
    • avr-gdb -ex "target remote /dev/cu.wchusbserial1410" -b 115200 myprog.elf
And, that's it! Now you can debug using breakpoints as usual.

Happy Debugging!

söndag 28 maj 2017

Sublime Text 3 custom build

Adding a custom build step to Sublime Text 3 is easy.

Simply choose
"Tools -> Build System -> New Build System"
and it will create a new .sublime-build file that you can configure to your liking.

How to configure it, can be found in the Configuration manual.

In my case, I wanted to invoke the build.sh file in the project root directory:

// The initial version
{
    "cmd": ["sh", "build.sh"],
    "working_dir": "${project_path:${folder}}"
}


Build output

The final output

Next, I needed to capture the output from the compiler, and in this case, it's from the arduino compilers. Unfortunately, the ansi output they produce couldn't be handled by either Sublime Text 3 or the plugin ANSIescape. The only solution I managed to conjure up was to install ansifilter and use that.

$ brew install ansifilter

And, since the "cmd" tag doesn't support more than one command, and because "shell_cmd" doesn't support "working_dir", I ended up with this:

// Final version
{
    "shell_cmd": "cd ${project_path:${folder}} && ./build.sh 2>&1 | ansifilter",
    "file_regex": "^(..[^:]*):([0-9]+):?([0-9]+)?:? (.*)$",
    "syntax": "Packages/Makefile/Make Output.sublime-syntax"
}
Note that when using the "shell_cmd", it create a shell for each build. So if you do something time consuming things in your bash startup scripts, it will take extra long time to build in Sublime as well.



You can read more on the subject here

Command line Arduino builds

Now that I have the Arduino up and running, I knew I wanted to use my editor of choice and command line build tools.

There is of course the alternative of using the Arduino IDE as a command line tool, but it still felt too clunky for my needs.

Secondly, there is the Arduino Makefile project, which would be a better fit, was it not... you know... make. And I saw a few results for CMake when googling, don't get me started.

So, again, I set out to create my first built scripts.
I looked at these instructions and changed it slightly for my needs. I also looked here.


$ brew tap osx-cross/avr
$ brew install avr-libc avr-gdb
$ brew install avrdude --with-usb

After that, I looked at the verbose output from the Arduino IDE to figure out most settings. And I also compared them to other packages (Arduino-make etc).

In the end, I got this build.sh

Monitor

To communicate with the Arduino (e.g. displaying the debug output), I use "screen" on osx (On windows there's PuTTY).
You quit "screen" with ^A+K:

$ screen /dev/cu.wchusbserial1410 9600

Foot note:

I compared the turnaround time between my script and Arduino-make:

./build.sh:

$ time ./build.sh
real 0m3.264s
user 0m0.185s
sys 0m0.100s

Arduino-make:

$ time (make -f ../Makefile && make -f ../Makefile verify_size reset do_upload)
real 0m6.275s
user 0m1.224s
sys 0m1.120s
That's 3 seconds longer. That's going to get annoying real fast! Of course you get a ton of extra features, but I just don't need them.