This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

typedef-access in ISR

Hi,

I'm working on a project employing an XE164. In a ISR (CAN-RX-Interrupt) I want to fill a global variable with some values, then set a flag to signal the main program ok-to-read. The variable to fill is a structure, defined in the main program:

typedef struct {

unsigned char data[8];

unsigned char flags;

} t_data;

in main.c:

volatile t_data data;

The CAN-ISR is supposed to fill data[0..7] with the incoming bytes, then set flags to (e.g.) TRUE. The main program is supposed to look for the flag, handle the data, then reset the flag.

This works fine when I use a seperate variable. It does not always work, however, if "flags" is a member of a structure, like t_data.flags in the example above: It "mostly" works, but the main programm misses some new messages, about 10% of the time. Again, this does not occur if "flags" is a seperate variable.

Can anyone make sense of this? Could it be that read access by main to some other part of the structure also kills the ISR-write to the flags-part of the structure (or vv)?

Any help would be much apreciated.

Regs,
Alto Speckhardt

Parents Reply Children
  • Right. This was generated by DAVE, of course:

    ISR:

    
    void CAN_viSRN0(void) interrupt CAN_SRN0INT
    {
    [...]
    
            if(uwSRN0ObjHandler & MOSTAT_NEWDAT)       // if NEWDAT is set
            {
              if (uwSRN0ObjHandler & MOSTAT_MSGLST)    // if MSGLST is set
              {
              }
              else
              {
                // USER CODE BEGIN (SRN0_OBJ32,4)
    
            // transfer data:
            mydata.data[0] = CAN_HWOBJ[32].ubData[0];
    
            // new struct content:
            mydata.rxstatus |= UPDATED;
    
                // USER CODE END
              }
    
    

    main:

    typedef struct {
    
    
    ubyte rxstatus; ubyte data[8];
    } t_mydata;
    [...]
    volatile t_mydata mydata;
    [...]
    void can_rx() {
    // new data? if (mydata.rxstatus & UPDATED) {
    // handle data: [... read-access mydata.data[x] ...]
    // mark as handled: mydata.rxstatus &= ~UPDATED;
    }
    [...]

    ... and that's about it. The check "if rxstatus & UPDATED) misses out about 10% of the messages, sometimes more, sometimes less. The main applications is essentially doing loops, the check occurs about every 20ms.

    If I extract t_mydata.rxstatus into a seperate variable, there is no problem.

    Regs,
    Alto Speckhardt

  • have you tried your program by the uv3 debugger? you can trigger a conditional breakpoint when your flag changes.

  • The problem is that I'd rather need a breakpoint triggered when the flag _doesn't_ change... ;-)

    Ok, I will just do some more debugging and report back if I find a "smoking gun".

    Meanwhile, thanks for your advice!

    Regs,
    Alto Speckhardt