oddest linking issue

I am having an extremely odd issue: If I compile the C++ ZomB sources to an out file, ftp it to the cRIO as ZomB.out, and add it to startupdlls, using DBPacket mode will prevent IsDisabled() (and presumably IsEnabled()) from changing, and only Disabled will execute. On the other hand, if I take the exact same source files, and compile them with the main file, making one out file, everything works! Source files attached.

ZomBSimple.zip (913 KB)


ZomBSimple.zip (913 KB)

This sounds like a symbol-name collision in the ZomB code. VxWorks uses a dynamic loading mechanism wherein symbols may be loaded multiple times into the symbol table from multiple applications. When a symbol is searched, it takes the first symbol in the table that is encountered. However, the linker will resolve to potentially a different symbol by the same name. Hence, the linked symbol is different (at a different location in memory) than the “loaded” symbol.

So, I’d look for a symbol name clash between the two images. You can use the “nm-ppc” facility from the DOS command line or the lkup “symbolname” facility from the VxWorks shell (the RS-232 terminal or the “host shell” – the “->i” button on the menu bar).

HTH,

Mike

How would I do this?

I’ve managed to strip it down considerably, to the DriverStation::GetInstance()->GetHighPriorityDashboardPacker() call. If you compile the zomb stuff into an out, you can’t enable. If you compile the zomb into the main program, you can enable
ZomB section:

#include "Dashboard.h"
#include "DriverStation.h"

class ZomBDashboardPacketSender
{
        Dashboard &hp;
    public:
        ZomBDashboardPacketSender();
        ~ZomBDashboardPacketSender(){}
};
ZomBDashboardPacketSender::ZomBDashboardPacketSender() :
    hp(DriverStation::GetInstance()->GetHighPriorityDashboardPacker()){}

All you need to do is to make an instance of this class. Code attached

Debug.zip (762 KB)


Debug.zip (762 KB)

OK. I’ve got my Workbench running in front of me now. Go to workbench and select Project->Open Workbench Development Shell. This may present you with a couple of options (“Wind River Workbench 3.0” and “Wind River VxWorks 6.3”). Select the Workbench 3.0 option and you’ll get a DOS command box.

Next execute: “wrenv -p vxworks-6.3”. This sets up your search path so you can run the GNU tools from the command line. In fact, via makefiles, you could compiler your code from here as well, but I digress.

CD to the location where your code was compiled. E.g., for a program called SimpleTemplate, the directory would be something like:

c:\windriver\workspace\SimpleTemplate\PPC603gnu\SimpleTemplate\Debug\

And the program of interest would be SimpleTemplate.out.

Next, run “nmppc SimpleTemplate.out | less”. Hopefully, your WRS environment has “less” in the search path. The output of this program is a list of all of the symbols in the program. You’re looking for the “IsEnabled” and “IsDisabled” symbols. You can search for the symbol using the “/ IsDisabled” command. Look here: http://sourceware.org/binutils/docs/binutils/nm.html for more info on nm.

My quick look shows these symbols as “weak” symbols. This means that if they’re linked with a defined version (as would be the case of linking with the main code), then the main code’s symbol would take precedence. On the other hand, if the object is loaded during the boot sequence, then there will be two versions of the symbol. One from the ZomB code and one from the main WPILib.

So, what needs to be done is to ensure that the ZomB code uses the WPILib versions of those symbols. This is typically done by making the ZomB reference an “external” reference via the “extern” keyword and making sure that the WPILib version of the symbol is loaded into memory before the ZomB code is loaded. This can be dome by simply changing the order in which the code is loaded.

HTH,

Mike

Makes sense, but there are two problems. I may be running kernel task, and loading it on the fly, then how would I know when to load it? and, I don’t always have the C++ wpilib. I may have the Java or Labview WPILib. I’m pretty sure that I was able to enable with Labview. Any ideas on how to fix it? Should I compile a WPILib.a with ZomB in it and have a out file for others?

Hmm… The issue is that the symbol be resolved to a working version of the code. I’m not entirely sure of how the Java and Labview code accomplishes this on VxWorks, but as long as those symbols are in the symbol table before your code is loaded, then all should be good.

Alternatively, you can accomplish this by actually linking your code against the WPILib before loading to VxWorks. In the WRS project properties, there is an option to add additional libraries to be linked against. Simply add the WPILib as one of the libraries. At worst, there may be some duplication of code. But, as long as the symbol is resolved to a working block of code, then it should work fine.

HTH,

Mike

WPILib is already referenced, I just put the code in a simpletemplate example and changed the out name

LV and Java have their own libraries that don’t link to the C versions (Except the camera)

I think the issue is that there is duplication of code and therefore, duplication of work done. I’m guessing that calling DS::getinstance creates a second Ds that prevents the first from hearing anything