In my efforts to smartify my house, one of the first things I did was to install an energy meter and connect it to the internet. I connected a TP-link TL-MR3020 to a Modbus capable energy meter to do this.
Here are my efforts this far:
The next involved writing and compiling some native code to interface with the energy meter using Modbus. The Selec MFM383C energy is connected to TL-MR3020 over UART. My TL-MR3020 has a USB hub connected to it. One of the slots has a 8GB USB Flash drive in it with the rootfs on it. Another slot has FT232 and MAX485 based USB-UART bridge. I use this USB-UART communicate with my mfm383c using Modbus.
------------
Problem statement: Cross compile C code into an OpenWrt ipkg in case which requires fetching and compilation of dependent libraries as well.
Detailed problem statement:
- Cross compile a piece of software (native, C program)
- The software depends on a library whose repository is maintained online - a tar archive of which can be fetched during make/
- Target: TL-MR3020 running OpenWRT 15.05 Chaos Calmer
- Development machine: Ubuntu x64 15.10
- Output should be an installable ipkg. We should be able to use opkg to install the software as well as its dependency.
- The software and the library it depends on should be complied using a single make command.
- During make, the sources for the library will be fetched from its online repository automatically.
Bit more details about our software:
Its a C program that uses libmodbus to communicate with a modbus capable energy meter (Selec MFM383C) over USB <> UART (FT232RL) to read specified registers depending on the parameters passed to it via command line.
- Preparation Step 1 - Setting up Ubuntu 15.10 x64 Virtual Machine on your Windows PC
- Download Ubuntu 15.10 x64 virtual machine image from osboxes.org
- Import it into your VirtualBox
- Make sure to share a couple of folder between Ubuntu and Windows. Also share the clipboards. (click here to know how todo this http://www.electronicsfaq.com/2013/04/sharing-folders-between-ubuntu-12041.html)
- Install git and build tools on your VM
sudo apt-get install autoconf build-essential
- Preparation Step 2 - Install toolchain, prepare router, install Chaos Calmer on Router.Click here to kno how to perform all of the following steps: http://www.electronicsfaq.com/2015/12/openwrt-1505-chaos-calmer-on-tl-mr3020.html)
- Install the toolchain
- Open your router and solder a USB - > serial bridge
- Mount an external USB flash drive
- Finally compile and install chaos calmer on it
- Now we need to figure out the folders in which we need to download (git clone) the library (library) and where to place the source files for our own application. We also need to know what should go into the makefiles and where to place them. So here are the details:
- You need to place your source and Makefiles in subfolders created in:
~/OpenWrt-SDK-15.05-ar71xx-generic_gcc-4.8-linaro_uClibc-0.9.33.2.Linux-x86_64/package - There will already be a Makefile (last modified 25 July 2015) in there. No need to touch it.
- Create a subfolder in the packages folder for your software (I called mine "mfm383c") and place your .c source file and Makefile in sub-sub-folder named "src" in it.
- Create another subfolder in the packages folder for the library that is going to be downloaded and place your Makefile in it. No need to download any .c file. Instructions for cloning the git are already present in the Makefile. I named this folder "libmodbus"
Folder tree of the makefiles and sources
- You need to place your source and Makefiles in subfolders created in:
- The contents of these C files and Makefile are appended below. The relevant section that take care of downloading and ensuring dependencies are highlighted.
- Lets compile the stuff
- Lets export the variables
export PATH=~/OpenWrt-SDK-15.05-ar71xx-generic_gcc-4.8-linaro_uClibc-0.9.33.2.Linux-x86_64/staging_dir/toolchain-mips_34kc_gcc-4.8-linaro_uClibc-0.9.33.2/bin:$PATH
export STAGING_DIR=~/OpenWrt-SDK-15.05-ar71xx-generic_gcc-4.8-linaro_uClibc-0.9.33.2.Linux-x86_64/staging_dir - cd to ~/OpenWrt-SDK-15.05-ar71xx-generic_gcc-4.8-linaro_uClibc-0.9.33.2.Linux-x86_64
- And issue the make command
- The .ipk files will be placed in:~/OpenWrt-SDK-15.05-ar71xx-generic_gcc-4.8-linaro_uClibc-0.9.33.2.Linux-x86_64/bin/ar71xx/packages/base
- Install the packages on the router:
- Copy the two .ipk files from Linux VM to Windows and then transfer them to /root of your router using WinSCP
- Then SSH into your router using PuTTY and install the packages:
- opkg install libmodbus_3.0.6-1_ar71xx.ipk
- opkg install mfm383c_1.0.0-1_ar71xx.ipk
- And Done!
![]() |
Location of the output .ipk files |
Sources - Lets look at the 3 Makefiles first
These Makefiles are based on the ones supplied by OpenWrt on their wiki:
https://wiki.openwrt.org/doc/devel/packages
https://wiki.openwrt.org/doc/devel/packages
/package/libmodbus/Makefile
As you can note, there isn't much here. We are just telling the build system from where to fetch the tar ball of the sources from the internet, extract them and compile them. In this Makefile we are also specifying where to place the .so files (shared library files - they are like the .dlls on Windows) within the root filesystem (/usr/lib) of the router when the .ipk is installed on it. There are two .ipk files that are going to be generated - one for libmodbus and the other for our program that we have written (mfm383c)
1 | # Copyright (C) 2006-2015 OpenWrt.org |
/package/mfm383c/src/Makefile
This makefile specifies how to build the mfm383c.c and mfm383c.h files contained in the src folder.Notice the LIBS variable specifying that these source have a dependencies on libmodbus.
1 | # build mfm383c executable when user executes "make" |
/package/mfm383c/Makefile
This Makefile is the most important of the three - it tells the build system to build the libmodbus library before building mfm383c to ensure that the dependencies are met. We also need to make sure that the modbus.h file included in mfm383c.c can be found in the right place.1 | ############################################## |
Sources - .c and .h
Finally the sources for mfm383c.c and mfm383c.h placed in\package\mfm383c\src:
mfm383c.c
1 | #include <stdio.h> //Defines core input and output functions: printf(), scanf(), getchar(), puchar(), gets(), puts() etc. |
1 | #ifndef _MFM383C_H_ |