XC8: .asm to C ( i.e. Lowering One's Expectations)

Thread Starter

joeyd999

Joined Jun 6, 2011
6,337
Please make it an option to skip that color or turn the damn thing off. I've had to black tape new electronics with the BLUE bling.
OMG. That's what I do to the stupid blue lights on all the electronics in my bedroom. They feel like they're crashing through my skull at night when I'm trying to fall asleep*.

Are you sure you're not my brother from a different mother?

*I thought I was the only one who experienced this.
 

nsaspook

Joined Aug 27, 2009
16,348
OMG. That's what I do to the stupid blue lights on all the electronics in my bedroom. They feel like they're crashing through my skull at night when I'm trying to fall asleep*.

Are you sure you're not my brother from a different mother?

*I thought I was the only one who experienced this.
https://forum.allaboutcircuits.com/...-exposure-worsen-with-age.188363/post-1752094
https://forum.allaboutcircuits.com/threads/ht-old-home-theater-rebuild.183659/post-1732773
Dear manufacturers: please stop putting obnoxious blue LEDs on the front of my electronics. Sincerely, me.
1708119727189.png
 
Last edited:

Thread Starter

joeyd999

Joined Jun 6, 2011
6,337
I've got a state machine consisting of two state functions (so far -- more will be added):

C:
//********** BLE Receiver State Machine ***********

unsigned char BLE_RX_scan_for_verb(unsigned char rx_char)
{
    unsigned char verb = 0;

    do
    {
        if (rx_char == RESPONSES[rx_verb][rx_char_index])
        {
            if (!RESPONSES[rx_verb][++rx_char_index])
            {
                //response found.
               
                verb=rx_verb+1;
               
                rx_verb = 0;
                rx_char_index = 0;
            }
        //  else still matching -- need more characters
           
            return verb;
        }
    //  else drop down to next response
     
    }
    while (RESPONSES[++rx_verb][0]);
   
    //no response found

    rx_verb = 0;
    rx_char_index = 0;
   
    return 0;
}

unsigned char BLE_RX_scan_for_PS(unsigned char rx_char)
{
    unsigned char verb;

    if ((verb=BLE_RX_scan_for_verb(rx_char)) == BLE_VERB_END)
    {
        //"END" response received
       
        NOP();
    }
    else
    {
       
    }
   
    return verb;
}
They are called from this polling routine from an array of function pointers:

C:
unsigned char BLE_RX_poll(void)
{
    unsigned char result;

    static unsigned char (*BLE_RX_state_function[])(unsigned char rx_char) =
    {
        BLE_RX_scan_for_verb,           //State 0: Awaiting a response
        BLE_RX_scan_for_PS             //State 1: Awaiting Private Characteric UUID or "End"   
    };
    
    unsigned char rx_char;

    if (!UART_numRX())
        return 0;
    
    rx_char = UART_getByte();
  
    if ((result = BLE_RX_state_function[rx_state](rx_char)))
    {
        rx_response_bitmap.wordv = 1 << (result - 1);
    };
        
    return 0;
}
Note that the second state function, BLE_RX_scan_for_PS(), also calls the first state function, BLE_RX_scan_for_verb().

I get this compiler warning:

Non line specific message::: warning: (1481) call from non-reentrant function, "_BLE_RX_scan_for_PS", to "_BLE_RX_scan_for_verb" might corrupt parameters

I notice in the .asm output, both state functions are using the same register for the value of rx_char, which, I believe might be the reason for the error, even though -- in this particular case -- that won't cause data corruption.

My question: is there a way to declare the functions so as to avoid the warning? Or, is my reasoning for the warning incorrect and I'm just missing something stupidly obvious?
 

nsaspook

Joined Aug 27, 2009
16,348
It's just a warning that usually means the compiler has prevented an error in the most likely cases. Warnings can usually be suppressed with a #pragma.

I didn't look too hard but usually it's the modification, or possible modification, of global (file or program wide scope) variables that are outside some function stack. It might be in your functions that triggers the warning or some other system or library called by both functions.

What triggers X non-reentrant warning and what eliminates them, seems to never be obvious but the reduction in shared global value references might help.
 

Papabravo

Joined Feb 24, 2006
22,084
I was going to say that making things reentrant is probably an advance debugging feature. It will eliminate potential problems that are very hard to debug in a complex system.
 

nsaspook

Joined Aug 27, 2009
16,348
I was going to say that making things reentrant is probably an advance debugging feature. It will eliminate potential problems that are very hard to debug in a complex system.
XC8 has the capability for reentrant stacks and functions but that's usually not a good thing on a 8-bit controller for mainline code. It can be useful with interrupts to prevent the compiler from duplicating functions and using extra code space.
 

Thread Starter

joeyd999

Joined Jun 6, 2011
6,337
XC8 has the capability for reentrant stacks and functions but that's usually not a good thing on a 8-bit controller for mainline code. It can be useful with interrupts to prevent the compiler from duplicating functions and using extra code space.
I use reentrant code often in .asm to save code space. But that's not the case here.
 

Thread Starter

joeyd999

Joined Jun 6, 2011
6,337
After thinking about this a little bit, I am confused.

The definition of "reentrant" is code that can be interrupted and reentered (in a threaded system) or simultaneously executed (in a multiprocessor system).

This is none of these things. Why even the warning?
 

Thread Starter

joeyd999

Joined Jun 6, 2011
6,337
I usually include at least two in most XC8 programs.

#pragma warning disable 520
#pragma warning disable 1498
Until I am as smart as you, I don't wish to disable warnings. I'm still learning how XC8 interprets my thoughts (not always as I wish).

Edit: Sorry, I just replied to a comment from the first page of this thread. My browser discombobulated.
 

nsaspook

Joined Aug 27, 2009
16,348
After thinking about this a little bit, I am confused.

The definition of "reentrant" is code that can be interrupted and reentered (in a threaded system) or simultaneously executed (in a multiprocessor system).

This is none of these things. Why even the warning?
The compiler looks at all the external code functions your functions use to make this warning for the possibility of some interrupt or hardware process beyond it's knowledge of normal program flow causing corruption.
That's why you use such things as const volatile variables for the compiler to evaluate with memory mapped interfaces. It's read-only for your code process sequences but some external process (like DMA) could change it, so the compiler is advised not to optimize reads of that variable.
 

nsaspook

Joined Aug 27, 2009
16,348
Until I am as smart as you, I don't wish to disable warnings. I'm still learning how XC8 interprets my thoughts (not always as I wish).

Edit: Sorry, I just replied to a comment from the first page of this thread. My browser discombobulated.
Some are pretty safe.
1710355416107.png

1498 seems have been removed by the lastest compiler set. Guess I don't need that one anymore.
 

Thread Starter

joeyd999

Joined Jun 6, 2011
6,337
@nsaspook,

I made a discovery today, dammit. Look at this code snippet:

C:
    //Send Data & checksum   
    
    UART2_dataByte(
       -(     
            UART2_dataWord(vtemp) 
          + UART2_dataWord(vbias) 
          + UART2_dataWord(vduty) 
          + UART2_dataWord(vbatt) 
          + UART2_dataWord(PID_getTarget()) 
          + UART2_dataByte(PID_getLock())
          + UART2_dataByte(getGainIndex())
        )
    );
It took me the day today to realize that the functions (as part of a mathematical expression) are not necessarily executed in the order as written.

My checksum was calculated properly, but the datastream was all mixed up.

I should have realized this as I wrote it, but my subconscious fully expected the code to be executed as written.
 

cmartinez

Joined Jan 17, 2007
8,787
@nsaspook,

I made a discovery today, dammit. Look at this code snippet:

C:
    //Send Data & checksum  
   
    UART2_dataByte(
       -(    
            UART2_dataWord(vtemp)
          + UART2_dataWord(vbias)
          + UART2_dataWord(vduty)
          + UART2_dataWord(vbatt)
          + UART2_dataWord(PID_getTarget())
          + UART2_dataByte(PID_getLock())
          + UART2_dataByte(getGainIndex())
        )
    );
It took me the day today to realize that the functions (as part of a mathematical expression) are not necessarily executed in the order as written.

My checksum was calculated properly, but the datastream was all mixed up.

I should have realized this as I wrote it, but my subconscious fully expected the code to be executed as written.
Can't you force the routine to execute things the way you want?
 

Thread Starter

joeyd999

Joined Jun 6, 2011
6,337
Can't you force the routine to execute things the way you want?
In assembly, always. By definition.

C has a mind of its own, if you get too smart for your own good.

This executes in the proper order:

C:
    //Send Data & checksum   

    chksum  = UART2_dataWord(vtemp); 
    chksum += UART2_dataWord(vbias); 
    chksum += UART2_dataWord(vduty); 
    chksum += UART2_dataWord(vbatt);
    chksum += UART2_dataWord(PID_getTarget()); 
    chksum += UART2_dataByte(PID_getLock());
    chksum += UART2_dataByte(getGainIndex());
    
    UART2_dataByte(-chksum);
 

nsaspook

Joined Aug 27, 2009
16,348
In assembly, always. By definition.

C has a mind of its own, if you get too smart for your own good.

This executes in the proper order:

C:
    //Send Data & checksum  

    chksum  = UART2_dataWord(vtemp);
    chksum += UART2_dataWord(vbias);
    chksum += UART2_dataWord(vduty);
    chksum += UART2_dataWord(vbatt);
    chksum += UART2_dataWord(PID_getTarget());
    chksum += UART2_dataByte(PID_getLock());
    chksum += UART2_dataByte(getGainIndex());
   
    UART2_dataByte(-chksum);
And is a hell of a lot better C code, that will optimize just fine as compared to too smart for your own good code.
 
Top