Welcome, Guest
Username: Password: Remember me
  • Page:
  • 1
  • 2

TOPIC: Modbus module offset issues

Modbus module offset issues 5 years 5 months ago #9948

  • barnes
  • barnes's Avatar
  • OFFLINE
  • Expert Boarder
  • Posts: 92
  • Karma: 0
I am having a data offset issue. I wiresharked the data and can see the modbus packets are correct. So I believe there is an indexing offset issue somewhere.



This image shows the number 192 in register 9 when the Modbus_Module StatusReadHRInsAndFloats is enabled.




This image shows the number 192 in register 4, the correct register, when the Modbus_Module StatusReadHRInsAndFloats is disabled.

I looked through the offset calculations with no luck.
It seems when there are two Modbus_modules inside the slave the indexing becomes incorrect.

I am happy to try to figure this out, please point me in the correct direction.
Last Edit: 5 years 5 months ago by barnes.
The administrator has disabled public write access.

Modbus module offset issues 5 years 5 months ago #9956

  • barnes
  • barnes's Avatar
  • OFFLINE
  • Expert Boarder
  • Posts: 92
  • Karma: 0
It seems this is an offset problem in rt_io_bus.c function io_bus_card_init. Its fairly complicated code.

It looks like there is an assumption that the data in the cards is always offset by the channels in the previous card.
The administrator has disabled public write access.

Modbus module offset issues 5 years 5 months ago #9957

  • barnes
  • barnes's Avatar
  • OFFLINE
  • Expert Boarder
  • Posts: 92
  • Karma: 0
Here is the code I modified to get it to work for the ChanIi's. Testing is ongoing





/*
*\
Initialization of a bus card.
\*
*/

pwr_tStatus io_bus_card_init( io_tCtx ctx,
io_sCard *cp,
unsigned int *input_area_offset,
unsigned int *input_area_chansize,
unsigned int *output_area_offset,
unsigned int *output_area_chansize,
pwr_tByteOrderingEnum byte_order,
io_eAlignment alignment)
{
int i;
// ********************************** Here ****************************************
*input_area_offset = 0; // set offset to zero for each new card

for ( i = 0; i < cp->ChanListSize; i++) { // go through each channel
io_sChannel *chanp = &cp->chanlist; // assign the array of channel information

switch (chanp->ChanClass) {

case pwr_cClass_ChanDi: {
pwr_sClass_ChanDi *chan_di = (pwr_sClass_ChanDi *) chanp->cop;
if (chan_di->Number == 0) {
*input_area_offset += *input_area_chansize;
*input_area_chansize = GetChanSize( chan_di->Representation);
chanp->size = *input_area_chansize;
}
if ( !chanp->sop)
continue;

if( alignment == io_eAlignment_Powerlink)
*input_area_offset = pwr_Align(*input_area_offset, *input_area_chansize);

chanp->offset = *input_area_offset;
chanp->mask = 1 << chan_di->Number;
chanp->size = *input_area_chansize;
if ( byte_order == pwr_eByteOrderingEnum_BigEndian) {
if ( chan_di->Representation == pwr_eDataRepEnum_Bit16)
chanp->mask = swap16( (unsigned short)chanp->mask);
else if ( chan_di->Representation == pwr_eDataRepEnum_Bit32)
chanp->mask = swap32( chanp->mask);
}
break;
}

case pwr_cClass_ChanAi: {
pwr_sClass_ChanAi *chan_ai = (pwr_sClass_ChanAi *) chanp->cop; // get the channel information

// ********************************** Here ****************************************
if(i!=0) *input_area_offset += *input_area_chansize; //add the channel size to the offset

*input_area_chansize = GetChanSize(chan_ai->Representation);
if ( !chanp->sop)
continue;

if( alignment == io_eAlignment_Powerlink)
*input_area_offset = pwr_Align(*input_area_offset, *input_area_chansize);

chanp->offset = *input_area_offset; // here may be the problem, --> if not a new card
chanp->size = *input_area_chansize;
chanp->mask = 0;
io_AiRangeToCoef(chanp);
break;
}

case pwr_cClass_ChanAit: {
pwr_sClass_ChanAit *chan_ai = (pwr_sClass_ChanAit *) chanp->cop;
*input_area_offset += *input_area_chansize;
*input_area_chansize = GetChanSize(chan_ai->Representation);
if ( !chanp->sop)
continue;

if( alignment == io_eAlignment_Powerlink)
*input_area_offset = pwr_Align(*input_area_offset, *input_area_chansize);

chanp->offset = *input_area_offset;
chanp->size = *input_area_chansize;
chanp->mask = 0;
io_AiRangeToCoef(chanp);
break;
}

case pwr_cClass_ChanIi: {
pwr_sClass_ChanIi *chan_ii = (pwr_sClass_ChanIi *) chanp->cop;

// ********************************** Here ****************************************
if(i!=0) *input_area_offset += *input_area_chansize;

*input_area_chansize = GetChanSize(chan_ii->Representation);
if ( !chanp->sop)
continue;

if( alignment == io_eAlignment_Powerlink)
*input_area_offset = pwr_Align(*input_area_offset, *input_area_chansize);

chanp->offset = *input_area_offset;
chanp->size = *input_area_chansize;
chanp->mask = 0;
break;
}

case pwr_cClass_ChanBi: {
pwr_sClass_ChanBi *chan_bi = (pwr_sClass_ChanBi *) chanp->cop;
*input_area_offset += *input_area_chansize;
*input_area_chansize = chan_bi->Size;
if ( !chanp->sop || !chan_bi->Size)
continue;

if( alignment == io_eAlignment_Powerlink)
*input_area_offset = pwr_Align(*input_area_offset, *input_area_chansize);

chanp->offset = *input_area_offset;
chanp->size = *input_area_chansize;
chanp->mask = 0;

if ( chanp->SigType == pwr_eType_Float32)
io_BiRangeToCoef(chanp);

break;
}

case pwr_cClass_ChanBo: {
pwr_sClass_ChanBo *chan_bo = (pwr_sClass_ChanBo *) chanp->cop;
*output_area_offset += *output_area_chansize;
*output_area_chansize = chan_bo->Size;
if ( !chanp->sop || !chan_bo->Size)
continue;

if( alignment == io_eAlignment_Powerlink)
*output_area_offset = pwr_Align(*output_area_offset, *output_area_chansize);

chanp->offset = *output_area_offset;
chanp->size = *output_area_chansize;
chanp->mask = 0;

if ( chanp->SigType == pwr_eType_Float32)
io_BoRangeToCoef(chanp);
break;
}

case pwr_cClass_ChanBiBlob: {
pwr_sClass_ChanBiBlob *chan_bi = (pwr_sClass_ChanBiBlob *) chanp->cop;
*input_area_offset += *input_area_chansize;
*input_area_chansize = chan_bi->Size;
if ( !chanp->sop || !chan_bi->Size)
continue;

if( alignment == io_eAlignment_Powerlink)
*input_area_offset = pwr_Align(*input_area_offset, *input_area_chansize);

chanp->offset = *input_area_offset;
chanp->size = *input_area_chansize;
chanp->mask = 0;

break;
}

case pwr_cClass_ChanBoBlob: {
pwr_sClass_ChanBoBlob *chan_bo = (pwr_sClass_ChanBoBlob *) chanp->cop;
*output_area_offset += *output_area_chansize;
*output_area_chansize = chan_bo->Size;
if ( !chanp->sop || !chan_bo->Size)
continue;

if( alignment == io_eAlignment_Powerlink)
*output_area_offset = pwr_Align(*output_area_offset, *output_area_chansize);

chanp->offset = *output_area_offset;
chanp->size = *output_area_chansize;
chanp->mask = 0;

break;
}

case pwr_cClass_ChanDo: {
pwr_sClass_ChanDo *chan_do = (pwr_sClass_ChanDo *) chanp->cop;
if (chan_do->Number == 0) {
*output_area_offset += *output_area_chansize;
*output_area_chansize = GetChanSize( chan_do->Representation);
chanp->size = *output_area_chansize;
}
if ( !chanp->sop)
continue;

if( alignment == io_eAlignment_Powerlink)
*output_area_offset = pwr_Align(*output_area_offset, *output_area_chansize);

chanp->offset = *output_area_offset;
chanp->mask = 1 << chan_do->Number;
chanp->size = *output_area_chansize;
if ( byte_order == pwr_eByteOrderingEnum_BigEndian) {
if ( chan_do->Representation == pwr_eDataRepEnum_Bit16)
chanp->mask = swap16( (unsigned short)chanp->mask);
else if ( chan_do->Representation == pwr_eDataRepEnum_Bit32)
chanp->mask = swap32( chanp->mask);
}
break;
}

case pwr_cClass_ChanAo: {
pwr_sClass_ChanAo *chan_ao = (pwr_sClass_ChanAo *) chanp->cop;
*output_area_offset += *output_area_chansize;
*output_area_chansize = GetChanSize(chan_ao->Representation);
if ( !chanp->sop)
continue;

if( alignment == io_eAlignment_Powerlink)
*output_area_offset = pwr_Align(*output_area_offset, *output_area_chansize);

chanp->offset = *output_area_offset;
chanp->size = *output_area_chansize;
chanp->mask = 0;
io_AoRangeToCoef(chanp);
break;
}

case pwr_cClass_ChanIo: {
pwr_sClass_ChanIo *chan_io = (pwr_sClass_ChanIo *) chanp->cop;
*output_area_offset += *output_area_chansize;
*output_area_chansize = GetChanSize(chan_io->Representation);
if ( !chanp->sop)
continue;

if( alignment == io_eAlignment_Powerlink)
*output_area_offset = pwr_Align(*output_area_offset, *output_area_chansize);

chanp->offset = *output_area_offset;
chanp->size = *output_area_chansize;
chanp->mask = 0;
break;
}

case pwr_cClass_ChanD: {
pwr_sClass_ChanD *chan_d = (pwr_sClass_ChanD *) chanp->cop;
if ( chan_d->Type == pwr_eDChanTypeEnum_Di) {
/* Di type */
if (chan_d->Number == 0) {
*input_area_offset += *input_area_chansize;
*input_area_chansize = GetChanSize( chan_d->Representation);
chanp->size = *input_area_chansize;
}
if ( !chanp->sop)
continue;

if( alignment == io_eAlignment_Powerlink)
*input_area_offset = pwr_Align(*input_area_offset, *input_area_chansize);

chanp->offset = *input_area_offset;
chanp->mask = 1 << chan_d->Number;
chanp->size = *input_area_chansize;
if ( byte_order == pwr_eByteOrderingEnum_BigEndian) {
if ( chan_d->Representation == pwr_eDataRepEnum_Bit16)
chanp->mask = swap16( (unsigned short)chanp->mask);
else if ( chan_d->Representation == pwr_eDataRepEnum_Bit32)
chanp->mask = swap32( chanp->mask);
}
}
else {
/* Do type */
if (chan_d->Number == 0) {
*output_area_offset += *output_area_chansize;
*output_area_chansize = GetChanSize( chan_d->Representation);
chanp->size = *output_area_chansize;
}
if ( !chanp->sop)
continue;

if( alignment == io_eAlignment_Powerlink)
*output_area_offset = pwr_Align(*output_area_offset, *output_area_chansize);

chanp->offset = *output_area_offset;
chanp->mask = 1 << chan_d->Number;
chanp->size = *output_area_chansize;
if ( byte_order == pwr_eByteOrderingEnum_BigEndian) {
if ( chan_d->Representation == pwr_eDataRepEnum_Bit16)
chanp->mask = swap16( (unsigned short)chanp->mask);
else if ( chan_d->Representation == pwr_eDataRepEnum_Bit32)
chanp->mask = swap32( chanp->mask);
}
}
break;
}

}

// ********************************** Here ****************************************
if(strstr(cp->Name, "TEST") !=NULL) {
printf("channel = %d ",i);
printf("Ref:%s ", cp->Name);
printf("chanp->offset %p chanp->size %d\n\n", (void *)chanp->offset, (int)chanp->size);
}


}



return IO__SUCCESS;
}
Last Edit: 5 years 5 months ago by barnes.
The administrator has disabled public write access.

Modbus module offset issues 5 years 5 months ago #9958

  • mhe
  • mhe's Avatar
  • OFFLINE
  • Fresh Boarder
  • Posts: 13
  • Karma: 0
If the i/o-Architecture ist designed as you think, why not try to find a solution without code-changes first?

e.g. would it not possible to configure "dummy-cards" to fill the "gaps"?
The administrator has disabled public write access.

Modbus module offset issues 5 years 5 months ago #9959

  • barnes
  • barnes's Avatar
  • OFFLINE
  • Expert Boarder
  • Posts: 92
  • Karma: 0
I went back to the base src install, recompiled with no modification, then added my mods one by one without changing the indexing and things are working now. So I am at a loss at what is going on.

I will keep an eye on things and report later.
Last Edit: 5 years 5 months ago by barnes.
The administrator has disabled public write access.

Modbus module offset issues 5 years 5 months ago #9960

  • barnes
  • barnes's Avatar
  • OFFLINE
  • Expert Boarder
  • Posts: 92
  • Karma: 0
Dummy cards did work. I just don't like dummy cards.

I'm still not sure what is happening, so I'm moving backwards in revisions until I can find the point where I broke it.

I'm just learning the code having some fun with the modifications.
The administrator has disabled public write access.
  • Page:
  • 1
  • 2
Time to create page: 8.047 seconds