Changes between Initial Version and Version 1 of OpenWrt/SDK


Ignore:
Timestamp:
10/22/2017 05:28:45 AM (7 years ago)
Author:
trac
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • OpenWrt/SDK

    v1 v1  
     1[[PageOutline]]
     2
     3= Building applications for an OpenWrt Target =
     4There are several ways you can use an OpenWrt Software Development Kit (SDK) or Toolchain to compile your own applications outside of the OpenWrt buildroot :
     5 * use prebuilt OpenWrt toolchain to build applications (ie from http://dev.gateworks.com/openwrt/latest/)
     6 * use prebuilt OpenWrt SDK to build an OpenWrt package (ie from http://dev.gateworks.com/openwrt/latest/)
     7 * use toolchain in your OpenWrt buildroot staging_dir tree (what you may need to do if your running your own firmware with a different lib/kernel config than Gateworks pre-built images)
     8
     9The point of using the OpenWrt toolchain or SDK is that it can be pre-built and installed on a host that does not have the OpenWrt buildroot.
     10
     11Note: Custom programming can be achieved through shell scripts on the Gateworks boards (most examples on the Gateworks wiki are shell commands).  C code can be used when desired.
     12
     13== OpenWrt Prebuilt Toolchain ==
     14If you are using pre-built firmware from http://dev.gateworks.com/openwrt then you can use the pre-built toolchain there to build your own code.
     15
     16For example, if you wanted to build a hello-world for laguna (cns3xxx) platform:
     17{{{
     18$ wget http://dev.gateworks.com/openwrt/latest/cns3xxx/OpenWrt-Toolchain-cns3xxx-for-arm_v6k-gcc-4.6-linaro_uClibc-0.9.33.2_eabi.tar.bz2
     19$ tar xvf OpenWrt-Toolchain-cns3xxx-for-arm_v6k-gcc-4.6-linaro_uClibc-0.9.33.2_eabi.tar.bz2
     20$ PATH=$PWD/OpenWrt-Toolchain-cns3xxx-for-arm_v6k-gcc-linaro_uClibc-0.9.32_eabi/toolchain-arm_v6k_gcc-linaro_uClibc-0.9.32_eabi/bin:$PATH
     21$ cat << EOF > hello-world.c
     22#include <stdio.h>
     23
     24int main (int argc, char** argv)
     25{
     26printf("Hello World\n");
     27return 0;
     28}
     29EOF
     30$ arm-openwrt-linux-uclibcgnueabi-gcc hello-world.c -o hello-world
     31$ file hello-world
     32hello-world: ELF 32-bit LSB executable, ARM, version 1 (SYSV), dynamically linked (uses shared libs), not stripped
     33}}}
     34
     35Note:  The prebuilt toolchain may have some issue if the script arm-openwrt-linux-uclibcgnueabi-wrapper.sh is used (with regard to paths having whitespace).
     36
     37=== Ventana Notes ===
     38If desired, download the Ventana OpenWrt Toolchain [http://marketing.gateworks.com/acton/formfd/2923/0007:d-0013 here] and skip to step 4[[BR]]
     39
     40The Ventana OpenWrt SDK file is for download [http://marketing.gateworks.com/acton/formfd/2923/0007:d-0014 here][[BR]]
     41
     421. Turn on Toolchain in make menuconfig -> Build the OpenWrt based Toolchain
     432. Compile using make -j8 v=99 in trunk directory
     443. Find compiled toolchain in trunk/bin/imx6/OpenWrt-Toolchain-imx6-for-arm_cortex-a9+neon-gcc-4.6-linaro_uClibc-0.9.33.2_eabi.tar.bz2
     454. Download the toolchain to a different directory on your PC where you will want to do some compiling, such as ~/compiling
     465. Extract the toolchain
     47{{{
     48ryan@Ryan:~/Documents/toolchain$ tar xvf OpenWrt-Toolchain-imx6-for-arm_cortex-a9+neon-gcc-4.6-linaro_uClibc-0.9.33.2_eabi.tar.bz2
     49OpenWrt-Toolchain-imx6-for-arm_cortex-a9+neon-gcc-4.6-linaro_uClibc-0.9.33.2_eabi/
     50OpenWrt-Toolchain-imx6-for-arm_cortex-a9+neon-gcc-4.6-linaro_uClibc-0.9.33.2_eabi/LICENSE
     51OpenWrt-Toolchain-imx6-for-arm_cortex-a9+neon-gcc-4.6-linaro_uClibc-0.9.33.2_eabi/toolchain-arm_cortex-a9+neon_gcc-4.6-linaro_uClibc-0.9.33.2_eabi/
     52OpenWrt-Toolchain-imx6-for-arm_cortex-a9+neon-gcc-4.6-linaro_uClibc-0.9.33.2_eabi/toolchain-arm_cortex-a9+neon_gcc-4.6-linaro_uClibc-0.9.33.2_eabi/lib64
     53OpenWrt-Toolchain-imx6-for-arm_cortex-a9+neon-gcc-4.6-linaro_uClibc-0.9.33.2_eabi/toolchain-arm_cortex-a9+neon_gcc-4.6-linaro_uClibc-0.9.33.2_eabi/share/
     54......
     55.....
     56}}}
     576. Set PATH
     58{{{
     59ryan@Ryan:~/Documents/toolchain$ PATH=$PWD/OpenWrt-Toolchain-imx6-for-arm_cortex-a9+neon-gcc-4.6-linaro_uClibc-0.9.33.2_eabi/toolchain-arm_cortex-a9+neon_gcc-4.6-linaro_uClibc-0.9.33.2_eabi/bin:$PATH
     60}}}
     617.  Create hello-world.c file as shown above,
     628. Compile hello-world.c. Note, when compiling, Gateworks uses hard float, so you may have to specify -mfloat-abi=hard as shown below
     63{{{
     64ryan@Ryan:~/Documents/toolchain$ arm-openwrt-linux-uclibcgnueabi-gcc -mfloat-abi=hard hello-world.c -o hello-world
     65arm-openwrt-linux-uclibcgnueabi-gcc.bin: warning: environment variable 'STAGING_DIR' not defined
     66arm-openwrt-linux-uclibcgnueabi-gcc.bin: warning: environment variable 'STAGING_DIR' not defined
     67arm-openwrt-linux-uclibcgnueabi-gcc.bin: warning: environment variable 'STAGING_DIR' not defined
     68/home/ryan/Documents/toolchain/OpenWrt-Toolchain-imx6-for-arm_cortex-a9+neon-gcc-4.6-linaro_uClibc-0.9.33.2_eabi/toolchain-arm_cortex-a9+neon_gcc-4.6-linaro_uClibc-0.9.33.2_eabi/bin/../lib/gcc/arm-openwrt-linux-uclibcgnueabi/4.6.4/../../../../arm-openwrt-linux-uclibcgnueabi/bin/ld: warning: .init_array section has zero size
     69ryan@Ryan:~/Documents/toolchain$
     70}}}
     719. Verify hello-world has been compiled in current directory
     72{{{
     73ryan@Ryan:~/Documents/toolchain$ file hello-world
     74hello-world: ELF 32-bit LSB executable, ARM, version 1 (SYSV), dynamically linked (uses shared libs), not stripped
     75}}}
     76
     77
     78
     79== OpenWrt Prebuilt SDK ==
     80If you are using pre-built firmware from http://dev.gateworks.com/openwrt then you can use the pre-built SDK there to build OpenWrt packages.  The SDK contains a cross toolchain, libraries, and the Makefile structure to be able to build OpenWrt packages without having an entire buildroot tree.  Note that you must also have the OpenWrt Toolchain (see below) in your path.  For example to build the OpenWrt nuttcp package for laguna (cns3xxx):
     81{{{
     82$ wget http://dev.gateworks.com/openwrt/latest/cns3xxx/OpenWrt-SDK-cns3xxx-for-linux-x86_64-gcc-4.6-linaro_uClibc-0.9.33.2.tar.bz2
     83$ tar xvf OpenWrt-SDK-cns3xxx-for-Linux-i686-gcc-linaro_uClibc-0.9.32.tar.bz2
     84$ PATH=$PWD/OpenWrt-SDK-imx61-for-linux-x86_64-gcc-4.6-linaro_uClibc-0.9.33.2/staging_dir/toolchain-arm_v7-a_gcc-4.6-linaro_uClibc-0.9.33.2_eabi/bin:$PATH
     85$ cd OpenWrt-SDK-imx61-for-linux-x86_64-gcc-4.6-linaro_uClibc-0.9.33.2
     86$ svn export svn://svn.openwrt.org/openwrt/packages/net/nuttcp package/nuttcp
     87$ make package/nuttcp/compile
     88$ ls bin/cns3xxx/packages/
     89nuttcp_6.1.2-2_cns3xxx.ipk  nuttcp-xinetd_6.1.2-2_cns3xxx.ipk
     90}}}
     91
     92== GDB - GNU Debugger ==
     93
     94GDB can be used on Gateworks SBC's.
     95
     96Gateworks has tested GDB in the following way on OpenWrt:
     97
     981. Compile GDB as a package using the make menuconfig option. Be sure it is GDB and not GDB server (example shows GDB server): [wiki:OpenWrt/Configuration#TurningonGDBServer]
     992. Install the ipk file on the target board: [wiki:ipkupload]
     1003. Compile your program using the toolchain described above but with GDB support.  Example is hello-world.
     101{{{
     102arm-openwrt-linux-uclibcgnueabi-gcc -g -mfloat-abi=hard hello-world.c -o hello-world
     103}}}
     1044. Copy program to target board and be sure it is executable (chmod)
     1055. Start gdb on target board (Ventana)
     1066. Run the gdb command from the Ventana command prompt:
     107{{{
     108(gdb) file hello-world
     109Load new symbol table from "/hello-world"? (y or n) y
     110Reading symbols from /hello-world...done.
     111}}}
     1127. Then type the run command:
     113{{{
     114(gdb) run 
     115Starting program: /hello-world
     116warning: Unable to find dynamic linker breakpoint function.
     117GDB will be unable to debug shared library initializers
     118and track explicitly loaded dynamic code.
     119warning: no loadable sections found in added symbol-file /lib/libgcc_s.so.1
     120warning: no loadable sections found in added symbol-file /lib/libc.so.0
     121Hello World
     122[Inferior 1 (process 17906) exited normally]
     123}}}
     1248. For more GDB reference please see this page: [http://www.gnu.org/software/gdb/documentation/ GDB Documentation] and other examples on Google search.
     125
     126=== Remote Debugging ===
     127A brief example:
     128
     1291. From the target start the server using the command to use over TCP on port 2345 the application hello-world
     130{{{
     131root@OpenWrt:/# gdbserver host:2345 hello-world
     132}}}
     133
     134Example Continues to step 2 below, shown below is the rest of the output:
     135{{{
     136root@OpenWrt:/# gdbserver host:2345 hello-world
     137Process hello-world created; pid = 21696
     138Listening on port 2345
     139Remote debugging from host 192.168.1.22
     140Hello World
     141
     142Child exited with status 0
     143GDBserver exiting
     144root@OpenWrt:/#
     145}}}
     146
     1472. From the host start the GDB from the SDK (Ventana example shown)
     148{{{
     149ryan@Ryan:~/sdk_ventana/OpenWrt-SDK-imx6-for-linux-x86_64-gcc-4.8-linaro_uClibc-0.9.33.2$ ./staging_dir/toolchain-arm_cortex-a9+neon_gcc-4.8-linaro_uClibc-0.9.33.2_eabi/bin/arm-openwrt-linux-uclibcgnueabi-gdb
     150}}}
     1513. Attach to target:
     152{{{
     153(gdb) target remote 192.168.1.1:2345
     154Remote debugging using 192.168.1.1:2345
     1550x76ff1e38 in ?? ()
     156(gdb)
     157}}}
     1584. Use the continue command and notice the program run on the target as shown in step 1
     159{{{
     160(gdb) continue
     161Continuing.
     162Cannot access memory at address 0x0
     163[Inferior 1 (process 23862) exited normally]
     164(gdb)
     165
     166}}}
     167
     168== Using Toolchain from staging_dir ==
     169If you are running firmware from your own OpenWrt build directory you can use the toolchain provided there.  The OpenWrt toolchain is placed in staging_dir under a directory name appropriate for your target configuration (toolchain-<arch-info>) and you can use it there to build applications for your target directly without using the buildroot:
     170 * laguna - staging_dir/toolchain-arm_v6k_gcc-linaro_uClibc-0.9.32_eabi
     171 * davinci - staging_dir/toolchain-arm_v5t_gcc-linaro_uClibc-0.9.32_eabi
     172 * avila/cambria (ixp4xx) - target-armeb_v5te_gcc-linaro_uClibc-0.9.32/
     173
     174For example, if you wanted to build hello-world for laguna:
     175{{{
     176$ ls staging_dir/toolchain-arm_v6k_gcc-linaro_uClibc-0.9.32_eabi/
     177arm-openwrt-linux                bin      info.mk  libexec  share  usr
     178arm-openwrt-linux-uclibcgnueabi  include  lib      sbin     stamp
     179$ cat << EOF > hello-world.c
     180#include <stdio.h>
     181
     182int main (int argc, char** argv)
     183{
     184printf("Hello World\n");
     185return 0;
     186}
     187EOF
     188$ ./staging_dir/toolchain-arm_v6k_gcc-linaro_uClibc-0.9.32_eabi/bin/arm-openwrt-linux-uclibcgnueabi-gcc ../hello-world.c -o hello-world
     189$ file hello-world
     190hello-world: ELF 32-bit LSB executable, ARM, version 1 (SYSV), dynamically linked (uses shared libs), not stripped
     191}}}
     192
     193 * *The STAGING_DIR may need to be set as noted here: [http://wiki.openwrt.org/doc/devel/crosscompile]
     194
     195= Other Notes =
     196 * uclibc is missing certain things that glibc on your desktop has - There really isn't a clear list of what those items are. 
     197
     198 * uclibc isn't your only libc option - OpenWrt has support for other popular alternatives to glibc as well (make menuconfig, Advanced configuration options -> Toolchain Options -> C Library implementation). 
     199 
     200 * Current OpenWrt (ie using our trunk BSP) supports uClibc (default) as well as eglibc and musl.
     201 * Note that eglibc is extremely popular and I believe Ubuntu has even switched to using it. 
     202
     203 * If you are missing features in the c++ lib then you can instead/also choose an alternative to uClibc++ via menuconfig 'Global build settings -> Preferred standard C++ library.
     204  *  In the toolchain/bin directory, there is a gcc-uc script which sets everything up for uclibc++.
     205  * c++ exceptions have special configuration as noted here [http://lists.uclibc.org/pipermail/uclibc-cvs/2012-May/030326.html]
     206 
     207 * Also, if you want to use compiler tools such as 'nm' you need to use the ones from the cross toolchain (ie arm-openwrt-linux-nm)
     208 
     209 * The STAGING_DIR may need to be set as noted here: [http://wiki.openwrt.org/doc/devel/crosscompile]
     210
     211= Additional Resources =
     212
     213
     214=== OpenWrt ===
     215OpenWrt is a open source software.  There are many OpenWrt resources around the web.[[BR]]
     216Open WRT Wiki for Cross Compile: [http://wiki.openwrt.org/doc/devel/crosscompile][[BR]]
     217OpenWrt Buildroot : [http://wiki.openwrt.org/doc/howto/buildroot.exigence]
     218OpenWrt Creating Packages : [http://wiki.openwrt.org/doc/devel/packages]
     219
     220=== Other C code examples: ===
     221
     222A userspace daemon has been written by Gateworks, source code is available[[BR]]
     223[http://trac.gateworks.com/wiki/gsc#GSCuserspaceDaemon]
     224[[BR]][[BR]]
     225[[BR]][[BR]]
     226Another small sample C program to read through input registers such as temp and voltage on the Gateworks GSC [http://trac.gateworks.com/wiki/gsc#SystemTemperatureandVoltageMonitor]
     227
     228Steps:
     229 1. Write the C code as a .c file such as input.c
     230 2. Compile the C code with the instructions above
     231 3. Transfer the resulting executable over to the Gateworks board.  One way to do this is through a wget command on the Gateworks board if the executable is hosted on a web server.
     232 4. Run the executable by chmod 777 if needed, and the type at the command line ./input
     233{{{
     234#include <stdio.h>
     235#include <string.h>
     236/*******************************
     237*
     238*  get value  of inputs on Gateworks Boards
     239*
     240**********************************/
     241int getValue(char *file)
     242{
     243
     244FILE *fp;
     245
     246int val=0;
     247
     248fp = fopen(file,"r");
     249if ( fp == NULL)
     250{
     251        printf("Bad open\n");
     252        exit(0);
     253}
     254
     255while(!feof(fp))
     256{
     257if(fscanf(fp,"%d", &val)!=1)
     258{
     259        break;
     260}
     261else
     262{
     263
     264        printf("\nVal=%d\n\n",val);
     265}
     266}
     267
     268fclose(fp);
     269
     270return val;
     271
     272
     273
     274}
     275/*******************************
     276*
     277*  get name of inputs on Gateworks Boards
     278*
     279**********************************/
     280const char * getName(char *file)
     281{
     282
     283FILE *fp;
     284
     285char label[100];
     286
     287fp = fopen(file,"r");
     288if ( fp == NULL)
     289{
     290        printf("Bad open\n");
     291        exit(0);
     292}
     293
     294while(!feof(fp))
     295{
     296if(fscanf(fp,"%s", &label)!=1)
     297{
     298        break;
     299}
     300else
     301{
     302        printf("\n\nLabel=%s",label);
     303}
     304}
     305
     306fclose(fp);
     307
     308}
     309
     310/*******************************
     311*
     312*  dispatch name and value request Gateworks Boards
     313*
     314**********************************/
     315void getNameValuePair(char *file)
     316{
     317char filelabel[360];
     318
     319strcpy(filelabel,file);
     320strcat (filelabel,"_label");
     321getName(filelabel);
     322strcat (file,"_input");
     323getValue(file);
     324}
     325
     326/*****************************
     327*
     328*   MAIN  read inputs such as voltage
     329*
     330*****************************/
     331int main (int argc, char** argv)
     332{
     333
     334        int i=0;
     335        char str[360];
     336        char ival[2];
     337        printf("About to read values...\n");
     338
     339
     340        for(i=0;i<13;i++)
     341        {
     342                strcpy (str," ");
     343                strcpy (str,"/sys/class/hwmon/hwmon0/device/in");
     344                sprintf(ival,"%d",i);
     345                strcat (str,ival);
     346                getNameValuePair(str);
     347
     348        }
     349        return 0;
     350}
     351
     352
     353
     354}}}
     355
     356The output once ran on the target Gateworks board looks like:
     357{{{
     358root@OpenWrt:/# ./input
     359About to read values...
     360
     361
     362Label=vin
     363Val=23852
     364
     365
     366
     367Label=3p3
     368Val=3295
     369
     370
     371
     372Label=bat
     373Val=3037
     374
     375
     376
     377Label=5p0
     378Val=4983
     379
     380
     381
     382Label=core
     383Val=1257
     384
     385
     386
     387Label=cpu1
     388Val=16777215
     389
     390
     391
     392Label=cpu2
     393Val=16777215
     394
     395
     396
     397Label=dram
     398Val=1837
     399
     400
     401
     402Label=ext_bat
     403Val=16777215
     404
     405
     406
     407Label=io1
     408Val=2505
     409
     410
     411
     412Label=io2
     413Val=16777215
     414
     415
     416
     417Label=pci2
     418Val=1517
     419
     420
     421
     422Label=current
     423Val=775
     424
     425root@OpenWrt:/#
     426
     427}}}