Archived

This forum has been archived. Please start a new discussion on GitHub.

IceStorm available for Ice-E?

I currently have a position tracking application that runs on Windows CE and Linux devices.

I would like to port this application to be an IceStorm publisher. Is this possible using Ice-E?

There is no reference to IceStorm in the Ice-E source.

Comments

  • mes
    mes California
    Welcome to the forum!

    It is possible to create an IceStorm publisher using Ice-E. In order to do this, you will need to translate the IceStorm Slice file using slice2cppe.

    Take care,
    - Mark
  • mes
    mes California
    In case it's not clear, here is how you can translate the IceStorm Slice file, assuming the Ice Slice files are installed in /opt/Ice/slice:

    $ slice2cppe -I/opt/Ice/slice --ice /opt/Ice/slice/IceStorm/IceStorm.ice

    Hope that helps.
    - Mark
  • I will give it a try.

    Thanks for the reply.
  • I managed to build a simple IceStorm publisher for my embedded linux platform (gumstix - http://www.gumstix.com).

    First I build Ice-E for the gumstix. Because development for the gumstix takes place using cross-compiler tools I had to make the following modifications:

    1. Edit config/Make.rules.Linux and add "ifeq ($(CXX),arm-linux-g++) ..." for the cross compiler.

    2. Edit include/IceE/Config.h to specify the endian for the gumstix platform.

    Then sliced the IceStorm ice files:

    $ slice2cppe -I<Ice src path>/slice --ice <Ice src path>/slice/IceStorm/IceStorm.ice
    $ slice2cppe -I<Ice src path>/slice --ice <Ice src path>/slice/SliceChecksumDict.ice

    I then simply compiled the resulting IceStorm.cpp and SliceChecksumDict.cpp into my application.

    The only problem I have encountered is with doubles.

    My slice file is:
    struct Position
    {
    byte unit;
    long time;
    double lat;
    double lon;
    int track;
    double pitch;
    double roll;
    byte satCount;
    bool averaged;
    };

    interface Monitor
    {
    void report( Position p );
    };

    In the struct Position the members arrive at the subscriber correctly EXCEPT the data members that are doubles.

    If I build the publisher on the same platform as the subscriber (Fedora Core 4 x86) then the doubles arrive ok.

    Any suggestions what I might be doing wrong?
  • bernard
    bernard Jupiter, FL
    It could be a problem with 'double' on your embedded platform.

    Did you try to run the IceE/operations test (or any simple program that uses double parameters) between your embedded system and Ice-E on FC4?

    Did you try with float instead of double?

    Cheers,
    Bernard
  • After further investigation I have discovered the following:

    simple IceE embedded client -> simple IceE embedded server ...... doubles ok
    simple Ice FC4 client -> simple IceE embedded server ...... doubles NOT ok
    simple IceE FC4 client -> simple IceE embedded server ...... doubles NOT ok
    IceE embedded publisher -> Ice FC4 subscriber ..... doubles NOT ok.

    It is as if the packing or unpacking of doubles is not working when 2 different hosts are involved....

    All of the IceE test work on my embedded platform except for the AliveTest in the thread test suit which fails with:

    AliveTest.cpp:98: assertion `!c.isAlive()' failed
    Aborted
  • bernard
    bernard Jupiter, FL
    Hi Steven,

    After a little google search, it appears that doubles on ARM (or at least some ARM versions) have a special representations: the two words are big-endian even on small-endian platforms.

    Note that current Linux/ARM is not an Ice-E supported platform. However I am unsure whether this issue affects Windows CE on ARM (a supported platform) or not... I am unable to verify right now.

    Could you try to update the marshaling and demarshaling of doubles in src/IceE/BasicStream.cpp?

    I suspect it should be something like:
    void
    IceInternal::BasicStream::write(Double v)
    {
        Container::size_type pos = b.size();
        resize(pos + sizeof(Double));
        Byte* dest = &b[pos];
    #ifdef ICE_BIG_ENDIAN
        const Byte* src = reinterpret_cast<const Byte*>(&v) + sizeof(Double) - 1;
        *dest++ = *src--;
        *dest++ = *src--;
        *dest++ = *src--;
        *dest++ = *src--;
        *dest++ = *src--;
        *dest++ = *src--;
        *dest++ = *src--;
        *dest = *src;
    #else
        const Byte* src = reinterpret_cast<const Byte*>(&v);
    #   if defined(_ARM_) // use the right macro here!
         dest[4] = *src++;
         dest[5] = *src++;
         dest[6] = *src++;
         dest[7] = *src++;
         dest[0] = *src++;
         dest[1] = *src++;
         dest[2] = *src++;
         dest[3] = *src;
         dest += 7;
    #   else
        *dest++ = *src++;
        *dest++ = *src++;
        *dest++ = *src++;
        *dest++ = *src++;
        *dest++ = *src++;
        *dest++ = *src++;
        *dest++ = *src++;
        *dest = *src;
    #   endif
    #endif
    }
    
    
    void
    IceInternal::BasicStream::read(Double& v)
    {
        if(b.end() - i < static_cast<int>(sizeof(Double)))
        {
    	throw UnmarshalOutOfBoundsException(__FILE__, __LINE__);
        }
        const Byte* src = &(*i);
        i += sizeof(Double);
    #ifdef ICE_BIG_ENDIAN
        Byte* dest = reinterpret_cast<Byte*>(&v) + sizeof(Double) - 1;
        *dest-- = *src++;
        *dest-- = *src++;
        *dest-- = *src++;
        *dest-- = *src++;
        *dest-- = *src++;
        *dest-- = *src++;
        *dest-- = *src++;
        *dest = *src;
    #else
        Byte* dest = reinterpret_cast<Byte*>(&v);
    #   if defined(_ARM_) // Use the right macro here
        dest[4] = *src++;
        dest[5] = *src++;
        dest[6] = *src++;
        dest[7] = *src++;
        dest[0] = *src++;
        dest[1] = *src++;
        dest[2] = *src++;
        dest[3] = *src;
        dest += 7;
    #   else
        *dest++ = *src++;
        *dest++ = *src++;
        *dest++ = *src++;
        *dest++ = *src++;
        *dest++ = *src++;
        *dest++ = *src++;
        *dest++ = *src++;
        *dest = *src;
    #   endif
    #endif
    }
    
    

    This code is obviously completely untested! Please let me know if it makes a difference ... if it works, you'll have to fix the marshaling/demarshaling of vector<double> as well (in the same file).

    Cheers,
    Bernard
  • Hi Bernard.

    I will give your code change a try when back at work early in the new year. I will post the results in this thread.

    I appreciate the help that you and Mark have given me for this problem.:)

    Regards

    Steven
  • Hi Bernard.

    Your code change suggestion works just fine.

    Thanks again for your help.

    Steven
  • bernard
    bernard Jupiter, FL
    Hi Steven,

    I am glad this worked out!

    For the benefit of other Ice-E users, could you describe the platform you're using (Linux version, GCC version, hardware)? Did you need to change anything else to run Ice-E on that platform?

    Thanks,
    Bernard
  • The gumstix device is based on the Intel PXA255 XScale processor. More information can be found at: http://www.gumstix.com

    The gumstix device runs version 2.6.10 of the linux kernel.

    All development is performed using cross compiler tools e.g GCC 3.4.2. More details of the gumstix SDK can be found at:
    http://www.gumstix.org/tikiwiki/tiki-index.php?page=programming

    Below is a description of the steps I had to take to enable me to build the IceE system and IceStorm based applications on the gumstix embedded linux platform.

    Modify the following files in the IceE source tree:
    src/IceE/BasicStream.cpp
    as described by Bernard in post 8 of this thread

    config/Make.rules.Linux
    added #ifeq($(CXX),arm-linux-g++) define to cope with the gumstix cross compiler.
    added CXXFLAGS += -DGUMSTIX_DOUBLE to the section added in the previous step.

    config/Make.rules
    modified to build static libs

    include/IceE/Config.h
    define ICE_LITTLE_ENDIAN if architecture is unknown

    The IceE libs where then simply compiled by:
    CXX=arm-linux-g++ make

    To allow IceStorm applications to be built I produced the appropriate source files by:
    $ slice2cppe -I<Ice src path>/slice --ice <Ice src path>/slice/IceStorm/IceStorm.ice
    $ slice2cppe -I<Ice src path>/slice --ice <Ice src path>/slice/SliceChecksumDict.ice

    I then simply compiled the resulting IceStorm.cpp and SliceChecksumDict.cpp into my application.