Saturday, October 11, 2014

ZT: OpenWRT c,c++ programing


http://fleshandmachines.wordpress.com/2011/08/22/openwrt-cc-programing/

We have an OpenWRT OS on our router, so what should we do now? Of course we want to create our program and run it on the OpenWRT. So Let’s get started.
First we need a developer platform or an SDK. I used my PC with Ubuntu for that.
Second we have to download the SDK that’s suit for us. What kind of SDK we need? It depends on the hardware that we use for running the OpenWRT. I have two OpenWRT compatible router the first is a Linksys WRT54GL, second is a WRT160NL. They have different architecture but that’s not a big problem.
The WRT54GL have Broadcom BCM5352, so I use brcm-2.4 .

The WRT160NL have a Atheros AR9130 rev 2, so I use ar71xx for that one.
Th latest OpenWRT release (when I write this post) is /backfire/10.03.1-rc5 . If I want my SDK for WRT54GL here can be found: http://downloads.openwrt.org/backfire/10.03.1-rc5/brcm-2.4/OpenWrt-SDK-brcm-2.4-for-Linux-i686-gcc-3.4.6_uClibc-0.9.30.1.tar.bz2
and for WRT160NL http://downloads.openwrt.org/backfire/10.03.1-rc5/ar71xx/OpenWrt-SDK-ar71xx-for-Linux-i686-gcc-4.3.3+cs_uClibc-0.9.30.1.tar.bz2. Now we have to download the one that’s fit for our project. After that we unpack the tar. We are done for this part, let’s do the coding.
C version:
Here is what look like an ordinary c code:
/****************
* Helloworld.c
* A test code.
*****************/
#include \

int main(void)
{
 printf("Hello world!");
 return 0;
}
here is the make file for it:

# build helloworld executable when user executes "make"
helloworld: helloworld.o
 $(CC) $(LDFLAGS) helloworld.o -o helloworld
helloworld.o: helloworld.c
 $(CC) $(CFLAGS) -c helloworld.c

# remove object files and executable when user executes "make clean"
clean:
 rm *.o helloworld
This far is like normal coding, to became a package we need to do few little things. We have to create a folders for the files. Like this: /Helloworld/src/ and copy the two files to the src folder. If we done with this, we need to create the package make file. So we create /Helloworld/Makefile , it will be like that:

##############################################
# OpenWrt Makefile for helloworld program
#
#
# Most of the variables used here are defined in
# the include directives below. We just need to 
# specify a basic description of the package, 
# where to build our program, where to find 
# the source files, and where to install the 
# compiled program on the router. 
# 
# Be very careful of spacing in this file.
# Indents should be tabs, not spaces, and 
# there should be no trailing whitespace in
# lines that are not commented.
# 
##############################################

include $(TOPDIR)/rules.mk

# Name and release number of this package
PKG_NAME:=helloworld
PKG_RELEASE:=1


# This specifies the directory where we're going to build the program.  
# The root build directory, $(BUILD_DIR), is by default the build_mipsel 
# directory in your OpenWrt SDK directory
#PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME)


include $(INCLUDE_DIR)/package.mk



# Specify package information for this program. 
# The variables defined here should be self explanatory.
# If you are running Kamikaze, delete the DESCRIPTION 
# variable below and uncomment the Kamikaze define
# directive for the description below
define Package/helloworld
   SECTION:=utils
   CATEGORY:=Utilities
   TITLE:=Helloworld -- prints a snarky message
endef

define Package/helloworld/description
 It is a helloworld.
endef

# Uncomment portion below for Kamikaze and delete DESCRIPTION variable above
#define Package/helloworld/description
#endef



# Specify what needs to be done to prepare for building the package.
# In our case, we need to copy the source files to the build directory.
# This is NOT the default.  The default uses the PKG_SOURCE_URL and the
# PKG_SOURCE which is not defined here to download the source from the web.
# In order to just build a simple program that we have just written, it is
# much easier to do it this way.
define Build/Prepare
 mkdir -p $(PKG_BUILD_DIR)
 $(CP) ./src/* $(PKG_BUILD_DIR)/
endef


# We do not need to define Build/Configure or Build/Compile directives
# The defaults are appropriate for compiling a simple program such as this one


# Specify where and how to install the program. Since we only have one file, 
# the helloworld executable, install it by copying it to the /bin directory on
# the router. The $(1) variable represents the root directory on the router running 
# OpenWrt. The $(INSTALL_DIR) variable contains a command to prepare the install 
# directory if it does not already exist.  Likewise $(INSTALL_BIN) contains the 
# command to copy the binary file from its current location (in our case the build
# directory) to the install directory.
define Package/helloworld/install
 $(INSTALL_DIR) $(1)/bin
 $(INSTALL_BIN) $(PKG_BUILD_DIR)/helloworld $(1)/bin/
endef


# This line executes the necessary commands to compile our program.
# The above define directives specify all the information needed, but this
# line calls BuildPackage which in turn actually uses this information to
# build a package.
$(eval $(call BuildPackage,helloworld))
Here is the documentation about how create a package make file: http://wiki.openwrt.org/doc/devel/packages
Now we have to copy the helloworld folder to the sdk, in the package subfolder. Then use the make command in the SDK folder. If there are problems, we have use the make V=99 command, it will show where might we find the source of the bug. If there wasn’t any problem we can find the binary package at the SDK/bin/packages/mipsel. Now copy the package to the openwrt. For linux you might use: scp helloworld_1_mipsel.ipk root@192.168.1.100: For windows you can use WinScp. If you uploaded the file, you have to ssh to the OpenWRT or the router and use this command opkg intall helloworld_1_mipsel.ipk . More about OPKG. Only one thing is left, to run the file, we have use helloworld command. If everything was ok, then we see this at console: Hello world!
And the C++ version
The C++ version has just a little difference. You have to write a c++ code. Here is what I preprared:
Helloworldcxx.cpp:

/****************
* Helloworldcxx.cpp
*****************/
#include ;

using namespace std;

int main()
{ 
        cout << "Hello world!\n\n";
 return 0;
} 
Makefile:

# build helloworldcxx executable when user executes "make"
helloworldcxx: helloworldcxx.o
 $(CXX) $(LDFLAGS) helloworldcxx.o -o helloworldcxx
helloworldcxx.o: helloworldcxx.cpp
 $(CXX) $(CXXFLAGS) -c helloworldcxx.cpp

# remove object files and executable when user executes "make clean"
clean:
 rm *.o helloworldcxx
Just like c code, we have to make it into a package, let’s create helloworldcxx\src directory, put these to file into it. Then create a make file for the OpenWRT SDK:
Makefile:

##############################################
# OpenWrt Makefile for helloworldcxx program
#
#
# Most of the variables used here are defined in
# the include directives below. We just need to 
# specify a basic description of the package, 
# where to build our program, where to find 
# the source files, and where to install the 
# compiled program on the router. 
# 
# Be very careful of spacing in this file.
# Indents should be tabs, not spaces, and 
# there should be no trailing whitespace in
# lines that are not commented.
# 
##############################################

include $(TOPDIR)/rules.mk

# Name and release number of this package
PKG_NAME:=helloworldcxx
PKG_RELEASE:=1


# This specifies the directory where we're going to build the program.  
# The root build directory, $(BUILD_DIR), is by default the build_mipsel 
# directory in your OpenWrt SDK directory
#PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME)


include $(INCLUDE_DIR)/package.mk



# Specify package information for this program. 
# The variables defined here should be self explanatory.
# If you are running Kamikaze, delete the DESCRIPTION 
# variable below and uncomment the Kamikaze define
# directive for the description below
define Package/helloworldcxx
   SECTION:=utils
   CATEGORY:=Utilities
   TITLE:=helloworldcxx -- prints a snarky message
endef

define Package/helloworldcxx/description
 It is a helloworldcxx.
endef


# Specify what needs to be done to prepare for building the package.
# In our case, we need to copy the source files to the build directory.
# This is NOT the default.  The default uses the PKG_SOURCE_URL and the
# PKG_SOURCE which is not defined here to download the source from the web.
# In order to just build a simple program that we have just written, it is
# much easier to do it this way.
define Build/Prepare
 mkdir -p $(PKG_BUILD_DIR)
 $(CP) ./src/* $(PKG_BUILD_DIR)/
endef


# We do not need to define Build/Configure or Build/Compile directives
# The defaults are appropriate for compiling a simple program such as this one


# Specify where and how to install the program. Since we only have one file, 
# the helloworldcxx executable, install it by copying it to the /bin directory on
# the router. The $(1) variable represents the root directory on the router running 
# OpenWrt. The $(INSTALL_DIR) variable contains a command to prepare the install 
# directory if it does not already exist.  Likewise $(INSTALL_BIN) contains the 
# command to copy the binary file from its current location (in our case the build
# directory) to the install directory.
define Package/helloworldcxx/install
 $(INSTALL_DIR) $(1)/bin
 $(INSTALL_BIN) $(PKG_BUILD_DIR)/helloworldcxx $(1)/bin/
endef


# This line executes the necessary commands to compile our program.
# The above define directives specify all the information needed, but this
# line calls BuildPackage which in turn actually uses this information to
# build a package.
$(eval $(call BuildPackage,helloworldcxx))
We have to build this one too with the SDK, just like before. Copy the directory structure into the SDK/package and use make command in the SDK folder. The builded binarys will be in the same directory (SDK/bin/package/mipsel/). Copy it to the OpenWRT running device.
There is only thing left to run the package, we have to install the libstdcpp package. This package is big, this is why it’s not standard installed. If you lack of storage space, you might use just c code. There are plenty of ways to have plus storage on the router, it’s depending on the resources what we have. For example you can use a pendrive if you have a router with USB port. Or you can use flashdrive, but you have to create the interface for that, there are many good tutorials how to do that. So if you have confidence in your self you can create a flashdrive port.
The good part is in creating a program in OpenWRT is if you have written good code, and you want to use it on a different architechture, all you have to do is to download it’s SDK, and compile the code with that.
Here is the tutorial that’s what I used for the first time to write code and to write my tutorial. Thanks the Gargoyle guys for their tutorial, it helped me a lot :].

No comments:

Post a Comment