Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Potentially incorrect processing of signed signals #36

Open
D-314 opened this issue Nov 18, 2024 · 0 comments
Open

Potentially incorrect processing of signed signals #36

D-314 opened this issue Nov 18, 2024 · 0 comments

Comments

@D-314
Copy link

D-314 commented Nov 18, 2024

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant