Skip to content

Potentially incorrect processing of signed signals #36

@D-314

Description

@D-314

DBC with signed signal:

BO_ 427 SampleMSG: 8 Vector__XXX
	SG_ SampleSignal : 23|7@0- (0.049087,0.049087) [-3.092481|3.141568] "bananas" Vector__XXX

will generate the following code:

////// dbccodeconf.h ////////
#include <stdint.h>
typedef double sigfloat_t;

////// example-config.h ////////
#define EXAMPLE_USE_SIGFLOAT

////// example.h ////////
// def @SampleMSG CAN Message (427  0x1ab)
#define SampleMSG_IDE (0U)
#define SampleMSG_DLC (8U)
#define SampleMSG_CANID (0x1ab)
// signal: @SampleSignal_ro
#define EXAMPLE_SampleSignal_ro_CovFactor (0.049087)
#define EXAMPLE_SampleSignal_ro_toS(x) ( (int8_t) (((x) - (0.049087)) / (0.049087)) )
#define EXAMPLE_SampleSignal_ro_fromS(x) ( (((x) * (0.049087)) + (0.049087)) )

typedef struct
{
#ifdef EXAMPLE_USE_BITS_SIGNAL

  int8_t SampleSignal_ro : 7;                //  [-] Bits= 7 Offset= 0.049087           Factor= 0.049087        Unit:'bananas'

#ifdef EXAMPLE_USE_SIGFLOAT
  sigfloat_t SampleSignal_phys;
#endif // EXAMPLE_USE_SIGFLOAT

#else

  int8_t SampleSignal_ro;                    //  [-] Bits= 7 Offset= 0.049087           Factor= 0.049087        Unit:'bananas'

#ifdef EXAMPLE_USE_SIGFLOAT
  sigfloat_t SampleSignal_phys;
#endif // EXAMPLE_USE_SIGFLOAT

#endif // EXAMPLE_USE_BITS_SIGNAL

#ifdef EXAMPLE_USE_DIAG_MONITORS

  FrameMonitor_t mon1;

#endif // EXAMPLE_USE_DIAG_MONITORS

} SampleMSG_t;

////// example.c ////////
uint32_t Unpack_SampleMSG_EXAMPLE(SampleMSG_t* _m, const uint8_t* _d, uint8_t dlc_)
{
  (void)dlc_;
  _m->SampleSignal_ro = ((_d[2] >> 1) & (0x7FU));
#ifdef EXAMPLE_USE_SIGFLOAT
  _m->SampleSignal_phys = (sigfloat_t)(EXAMPLE_SampleSignal_ro_fromS(_m->SampleSignal_ro));
#endif // EXAMPLE_USE_SIGFLOAT

#ifdef EXAMPLE_USE_DIAG_MONITORS
  _m->mon1.dlc_error = (dlc_ < SampleMSG_DLC);
  _m->mon1.last_cycle = GetSystemTick();
  _m->mon1.frame_cnt++;

  FMon_SampleMSG_example(&_m->mon1, SampleMSG_CANID);
#endif // EXAMPLE_USE_DIAG_MONITORS

  return SampleMSG_CANID;
}

uint32_t Pack_SampleMSG_EXAMPLE(SampleMSG_t* _m, uint8_t* _d, uint8_t* _len, uint8_t* _ide)
{
  uint8_t i; for (i = 0; (i < SampleMSG_DLC) && (i < 8); _d[i++] = 0);

#ifdef EXAMPLE_USE_SIGFLOAT
  _m->SampleSignal_ro = EXAMPLE_SampleSignal_ro_toS(_m->SampleSignal_phys);
#endif // EXAMPLE_USE_SIGFLOAT

  _d[2] |= ((_m->SampleSignal_ro & (0x7FU)) << 1);

  *_len = SampleMSG_DLC;
  *_ide = SampleMSG_IDE;
  return SampleMSG_CANID;
}

////// main.c ////////
#include <stdio.h>
int main()
{
    
    SampleMSG_t msgTX,msgRX;
    msgTX.SampleSignal_phys = -0.981740;
    
    uint8_t data[8]; uint8_t len; uint8_t ext;
    Pack_SampleMSG_EXAMPLE(&msgTX, data, &len, &ext);
    
    Unpack_SampleMSG_EXAMPLE(&msgRX,data,len);
    
    printf("Packed\t%f bananas\n",msgTX.SampleSignal_phys);
    printf("Unpacked\t%f bananas\n",msgRX.SampleSignal_phys);
    
    return 0;
}

And output will be:

Packed      -0.981740 bananas
Unpacked     5.301396 bananas

The problem can be solved with replacing

  _m->SampleSignal_ro = ((_d[2] >> n) & (0x7FU));

by

  _m->SampleSignal_ro = (int8_t)((_d[2]) & (0x7FU << n)) / (1 << n);

or

#define EXAMPLE_USE_BITS_SIGNAL

See the generated code and dbc in attached file:
EXAMPLE.zip

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions