Skip to content

Potentially incorrect processing of signed signals #36

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

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

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