Cross Compling Code



  • I have never used the OpenWRT tool chain. It took me a bit to get the cross compile setup to a point where I think its working on an ubuntu system.

    I followed the steps from
    https://wiki.onion.io/Tutorials/Cross-Compile

    I setup a new package that's currently just a hello world example but will become an I2C to SPI library to use an SC18IS602 I2C to SPI converter (http://www.nxp.com/documents/data_sheet/SC18IS602B.pdf)

    When I build my new test package:
    $ make package/i2c_spi_bridge/compile
    make[1] package/i2c_spi_bridge/compile
    make[2] -C package/libs/toolchain compile
    make[2] -C package/i2c_spi_bridge compile

    so building appears fine but I can't tell where the compiled code is located, where did it go?

    I then compiled directly calling a gcc from the staging_dir/toolchain directory, not sure if this is the correct one but the code did compile. Is this the correct gcc to use?

    ../../../staging_dir/toolchain-mips_34kc_gcc-4.8-linaro_uClibc-0.9.33.2/bin/mips-openwrt-linux-uclibc-gcc i2c_spi_bridge.c -o test

    I haven't tested this yet because the onion is on a different wireless network then I'm on, but is hooked up to this machine using the usb port. Is there a way for me to send a file to the onion using the usb port?



  • @will-burke Congratulations on getting Cross Compile going with the OpenWrt tool chain - it takes quite an effort to figure it out and get it working :-)

    A few pointers that may assist with the issues you raise in your message:

    Hope that some of this may be helpful to you



  • @Kit-Bishop,

    Thanks for the tips. I have compiled and successfully tested on the Omega using the separate copy of the toolchain as you describe.

    I'm on to my next issue. I'm trying to use the I2C library:
    https://wiki.onion.io/Tutorials/Libraries/I2C-Library

    I copied over the libonioni2c.so from the onion and am trying to link to the .so. However when I call the i2c_ functions they are still undefined references.

    Command:
    mips-openwrt-linux-uclibc-g++ -O2 -fPIC -L./omega_libs -lonioni2c -loniondebug -I./i2c-exp-driver-master
    /include i2c_spi_bridge.c SC18IS602.cpp -o test1

    Output:
    /tmp/cc4spNYj.o: In function SC18IS602::WriteBytes(unsigned char*, unsigned char)': SC18IS602.cpp:(.text+0x2c): undefined reference toi2c_writeBuffer'
    /tmp/cc4spNYj.o: In function SC18IS602::ReadBytes(unsigned char*, unsigned char)': SC18IS602.cpp:(.text+0x80): undefined reference toi2c_read'
    /tmp/cc4spNYj.o: In function SC18IS602::ReadByte()': SC18IS602.cpp:(.text+0x198): undefined reference toi2c_readByte'
    /tmp/cc4spNYj.o: In function SC18IS602::WriteRegister(unsigned char, unsigned char)': SC18IS602.cpp:(.text+0x1f4): undefined reference toi2c_write'
    collect2: error: ld returned 1 exit status



  • @will-burke Glad to hear you have got something going on cross compilation.

    Don't know why you are having linking to libonioni2c.so
    I have not tried directly linking to .so files copied from the Omega.
    I normally compile such libraries myself from the sources and link to them.
    Having said that, i can see nothing immediately wrong in the information you posted.

    I tried copying libonioni2c.so from my Omega to my Kubuntu system so I could try running nm, objdump and readelf on it (these are not currently available on the Omega).
    While I don't know if there is any issues with running the Kubuntu versions of these programs against an Omega .so, they all indicated that there was no dynamic link entries for the functions you reference.



  • @will-burke Update to my previous message:

    I have found where to get nm, objdump and readelf for the Omega. Run opkg install binutils and they will be available on the Omega.

    Using these against /usr/lib/libonioni2c.so gives the same information as the Kubuntu versions. I.E. can find no reference to the required functions.

    So, sorry still no ideas :-(



  • That is most likely the issue. I'm trying to use the i2c library. What I really need is spi but I'm io limited so I can't just Bit Bang spi on the gpio. I need to use the i2c to spi bridge. I just assumed I was linking to the correct .so with those functions, it appears that I'm not.



  • @Kit-Bishop

    Thanks for the help. That was the issue. I had to include the src files from src/lib/onion-i2c.c and src/lib/onion-debug.c. The section on using the library was not completely clear and I assumed the header was just for reference the functions in the library.

    https://wiki.onion.io/Tutorials/Libraries/I2C-Library#the-c-library_using-the-library

    Header File

    To add the Onion I2C Library to your C/C++ program, include the header file in your C code:

    #include <onion-i2c.h>

    Library for Linker

    In your project's makefile, you will need to add the following static libraries to the linker command:

    -loniondebug -lonioni2c

    The static libraries are stored in /usr/lib on the Omega.



  • @will-burke Glad you have got something going :-)
    I confess I missed something in your original post. Where you use mips-openwrt-linux-uclibc-g++ -O2 -fPIC -L./omega_libs -lonioni2c -loniondebug -I./i2c-exp-driver-master
    /include i2c_spi_bridge.c SC18IS602.cpp -o test1
    you are trying to both compile and link in one go.
    Basically OK but not commonly used for anything but the simplest of programs. Also, as I believe you have found, you need to #include headers (.h files) in your source for anything for which you are not providing the code directly.

    More common way of building is to:

    • Compile each .cpp file to a .o (object file) using something like:
      mips-openwrt-linux-uclibc-g++ -c -O2 -fPIC xxx.cpp -o xxx.o
    • Then link all the .o files and any used libraries using something like:
      mips-openwrt-linux-uclibc-g++ -o <prog-name> <list-of-obj-files> -L<lib-dir> -l<libname1> -l<libname2>

    What I find a bit surprising/confusing is that throughout https://wiki.onion.io/Tutorials/Libraries/I2C-Library#the-c-library_using-the-library it refers to static libraries. Yet files like libonioni2c.so are dynamic libraries (and the examples in the reference use them as such). Access to the dynamic libraries are needed during linking to resolve the access to the functions, but (unlike static linked libraries) are NOT included in the linked code - rather, a reference is included in the linked code to the library name which is used to actually load the needed code at RUN time.



  • @Kit-Bishop

    I now have my code compiling and running. I successfully configure the I2C to SPI Bridge.

    As a first test I'm sending/receiving 0x55 and 0xAA bytes on the SPI bus. I looped MOSI to MISO so that I receive the data sent. This is working, however after successfully running and transmitting all bytes of data the program aborts. Could this abort be caused by the static vs dynamic linking that you are talking about?



  • @will-burke Well done on getting something running :-)

    Given that you say you are successfully sending and receiving data via you I2C to SPI bridge, your problem almost certainly is not due to any linking issues. It is more likely to be a bug somewhere in your code.
    In the absence of any remote interactive debugger system (that I know of) for debugging code running on the Omega, my best suggestion is that you liberally sprinkle meaningful diagnostic printf statements through out you code to track at what point it fails.

    While I don't have access to an I2C to SPI bridge device, I could cast an eye over your code if you sent me a copy of the source code and any Makefile (or commands you use to build it) to see if I can spot anything you might be doing wrong.



  • @Kit-Bishop

    The code successfully runs and I receive the correct data. I can verify this by breaking my loopback on the MISO/MOSI pins and also by watching those pins on a scope.

    section of output from running code on the onion:
    Communication send 0x55
    SC18IS602::transfer buf 55
    SC18IS602::WriteBytes buf U len 1
    SC18IS602::ReadBytes buf U len 1
    SC18IS602::transfer rec 55
    aa
    Rec: 55
    Communication send 0xAA
    SC18IS602::transfer buf aa
    SC18IS602::WriteBytes buf ▒ len 1
    SC18IS602::ReadBytes buf ▒ len 1
    SC18IS602::transfer rec aa
    aa
    Rec: aa
    Communication is good
    Aborted

    I have zipped up the source code and I'm using "build_test1" to generate the code

    i2c_spi_bridge_2016-03-03.zip



  • @will-burke I'll take a look at the code you sent and will get back to you if I spot anything.



  • @will-burke Have had a play with the code you sent.
    It all looks good and (as far as I can tell without having an I2c to SPI bridge myself) works as intented.
    Except for getting the Aborted at the end.
    I'm not sure why this would be so, but it seems to be due to creating i2cspi in i2c_spi_bridge.c on the stack rather than the heap. I made changes to i2c_spi_bridge.c to allocate i2cspi on the heap (this is the changed file: i2c_spi_bridge.c ). The changes consist of:

    1. Changing the line:
      SC18IS602 i2cspi=SC18IS602(SC18IS602_ADDRESS_000);
      to
      SC18IS602 * i2cspi=new SC18IS602(SC18IS602_ADDRESS_000);
    2. Replacing all instances of i2cspi. to i2cspi->
    3. Ensuring that delete i2cspi; is called before exit.

    Now all seems to be running OK.

    I have also taken the liberty of making some small changes to the following files which I also attach:

    1. onion-debug.c - the path is not needed in the #include since it is taken care of by the -I used in build_test1
    2. build_test1 - have removed the -L and -l stuff from the link step. You are not actually linking to these libraries since you build the .o files and include them already in the link step.

    Hope this all helps.


Log in to reply
 

Looks like your connection to Onion Community was lost, please wait while we try to reconnect.