Is the following flag variable available between interrupt and user code?

We inherited a project that targets the Renesas RX231 microcontroller that I was looking at.

This uC has only one instruction that blocks the bus for atomicity (XCHG).

Since the processor is the only component that accesses RAM memory (without using DMA or DTC) to manipulate variables in user code that are shared by interrupts, interrupts are disabled (in the processor status word register) for access time, i.e.

disable_interrupts(); /* set_psw(get_psw() & ~(1 << 16)); */
/* access or modify shared variables */
enable_interrupts();  /* set_psw(get_psw() | (1 << 16)); */

However, there are also β€œflags” that are shared without protection, which are set in interrupts and are interrogated in the user code as follows:

volatile unsigned char event_request_message = 0;
unsigned char condition_sending_message = 0;

#pragma interrupt
void on_request_message()
{
     ...
     event_request_message = 1; // mov.l   #0x3df5, r14
                                // mov.b   #1, [r14]
     ... 
}

void user_code()
{
     for(;;)
     {
         ...
         /* might be evaluated multiple times before transmit message is completed */
         if(event_request_message && !condition_sending_message) // mov.l   #0x3df5, r14
                                                                 // movu.b  [r14], r14
                                                                 // cmp     #0, r14
                                                                 // beq.b   0xfff8e17b <user_code+185>
                                                                 // mov.l   #0x5990, r14
                                                                 // movu.b  [r14], r14
                                                                 // cmp     #0, r14
                                                                 // bne.b   0xfff8e16f <user_code+173>
         {
              event_request_message = 0;     // mov.l   #0x3df5, r14  
                                             // mov.b   #0, [r14]                  
              condition_sending_message = 1; // mov.l   #0x5990, r14               
                                             // mov.b   #1, [r14]
              /* transmit message */ 
              ... 
         }
         ...
     }
}

( ) :

  • , "" : //
  • ,
  • // , /

: ? "" ?
/?

  • , .
  • , "" ( 0 1, ( )) ( , ..).

, ?
" "?

"" , .

, , .

PS. : "cc-rx", "rxv2-instruction-set", "rx231".

+4
1

, , , , :

  • , . , :

    int a = 0;
    volatile int b = 0;
    
    void interrupt_a(void) 
    {
        a = b + 1;
        b = 0;       // set b to zero when done
    }
    

    :

    load acc from [b]
    store 0 into [b]  // set b to zero *before* updating a, to mess with you a bit
    add 1 to acc
    store acc into [a]
    

    , . (, , C11 _Atomic memory_order_release memory_order_acquire .)

    UC, , , , , , ( MMIO UC). , , CPU , .

    , , toolchain , , , . .

    , ARM docs , "" , , ( " " ), Cortex M . , - , .

  • , . , uC/, - . , ARM Cortex DSB ISB , , .

    // you would have to do this on an ARM Cortex uC
    DisableIRQ(device_IRQn); // Disable certain interrupt by writing to NVIC_CLRENA
    DSB(); // data memory barrier
    ISB(); // instruction synchronization barrier
    
    // <-- this is where the interrupt is "really disabled"
    

    , disable_interrupts();, .

  • (x++) , "" . , UC, - .

, , , , . -, , , , , , , , , .

+3

Source: https://habr.com/ru/post/1695155/


All Articles