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

Multiple call to segment warning

I am seeing this warning when I try to compile my code

Warning L15: multiple call to segment
segment: ?pr?_nvmwrit?nvmem_cc
caller1: ?pr?spicommisr?spi_com_cc
caller2: ?c_c51startup

I looked through my code, I don't call nvmwrite in spicommisr routine. And what is this c51startup file?

thanks,
DG

Parents
  • guys, I am not sure if you really read through all the message before giving any suggestions. My second post, which is the 3rd from top, clearly says I already moved the function call out of ISR. Right now, ISR only sets flag, and supper loop in main takes care of function call.

    I'm afraid some respondents aren't very good at reading and understanding the written word. There's a preference for answering a favourite question rather than the one asked.

    Based on the information you've posted I'm struggling to come up with a plausible explanation beyond Neil Kurzman's suggestion. Did you try a rebuild all or manually deleting the object files? If yes, strip out everything except a cut-down version of your main function and the ISR. If that doesn't fix it, post the stripped down code.

Reply
  • guys, I am not sure if you really read through all the message before giving any suggestions. My second post, which is the 3rd from top, clearly says I already moved the function call out of ISR. Right now, ISR only sets flag, and supper loop in main takes care of function call.

    I'm afraid some respondents aren't very good at reading and understanding the written word. There's a preference for answering a favourite question rather than the one asked.

    Based on the information you've posted I'm struggling to come up with a plausible explanation beyond Neil Kurzman's suggestion. Did you try a rebuild all or manually deleting the object files? If yes, strip out everything except a cut-down version of your main function and the ISR. If that doesn't fix it, post the stripped down code.

Children
  • OK, I have narrowed it down now, although I just don't understand why.

    I am using ADI chip, its NVM is 4 bytes per page. So in order to save one byte, I define the follow data type:

     typedef struct {
        INT8U value;
        NT8U unused[3];
    } NVM_SingleByte_T;
    

    The segment is sSpiPSE. again, in my ISR, I set flag, and in super loop, if program sees flag, then execute SPI command handler based on index.

     void sSpiPSE(void)
    { NVM_SingleByte_T tmpvar;
      if(SpiCmdLoad[0] & 0x80)
      {tmpvar.value = 1;}
      else
      {tmpvar.value = 0;}
    }
    

    I already comment out some stuff, but if I compile now, it will give the warning of multiple call. But if I replace NVM_SingleByte_T with just INT8U type data, the compiler will not give that warning.

    Why does a tempvar define matter?

  • Why does a tempvar define matter?

    I suspect only a thorough inspection of the map file can reveal that. You may have to check the relevant list files, too.

  • I am checking the m51 file. I never really studied the map file before, so please help me out here.

    The warnings happen when I set optimizer level > 1, which means it is data overlaying causing the problem.

    Here is some section of overlay map:

    ?PR?SPICOMMISR?SPI_COM_CC
    >> --- +--> ?CO?SPI_COM_CC

    ?CO?SPI_COM_CC
    >> --- +--> ?PR?SSPIPSE?SPIHANDLERS_CC

    ?PR?_NVMWRITE?NVMEM_CC
    >> 0BH +--> ?CO?NVMEM_CC

    So the first one is that Spi ISR call my constant lookup table in code space? What does the second one mean? C51Startup calls main and C_INITSEG (which call ?CO?SENSOR_CC)

    So if multiple routines need to access constant in code space, will that cause "Multiple call to segment" warning?

    Thanks,

  • one more difference, I did a compile with optimizer set to be 1 then I search ?SPICOMMISR? in the map file.

    I find that SPICOMMISR show up in XDATA memory section besides CODE MEMORY and OVERLAY MAP:
    XDATA 066FH 0001H UNIT ?XD?SPICOMMISR?SPI_COM_CC

    And optimizer set > 1, SPICOMMISR only show up in CODE MEMORY and OVERLAY MAP area. So I guess the data overlaying process move ISR out of xdata space, and somehow mess up other stuff?

  • I don't quite understand that example, but this time I tried to exclude one segment from overlaying analysis and it worked!
    thank you!
    And last question: how to disable multiple segments from overlaying analysis?
    My warnings are:

    *** WARNING L15: MULTIPLE CALL TO SEGMENT
        SEGMENT: ?PR?SSPIPSE?SPIHANDLERS_CC
        CALLER1: ?PR?SPICOMMISR?SPI_COM_CC
        CALLER2: ?C_C51STARTUP
    *** WARNING L15: MULTIPLE CALL TO SEGMENT
        SEGMENT: ?PR?_NVMWRITE?NVMEM_CC
        CALLER1: ?PR?SPICOMMISR?SPI_COM_CC
        CALLER2: ?C_C51STARTUP
    

  • I finally figure it out. Thanks all for the help.
    From the link Jon provide, it says:
    "automatic overlay analysis cannot be successfully accomplished when references are made via pointers to functions. "

    I do have function call via pointer, although I use exactly same method to handle my UART command and the compiler never has any problem with that...

    Anyway, once I specific exclude segment from overlaying analysis, the warnings are all gone.

    Thanks,

  • Anyway, once I specific exclude segment from overlaying analysis, the warnings are all gone.

    With the scarce resources of the '51 overlaying analysis is almost mandatory for any project greater than blinky. Get rid of the function pointer instead. You may get by without overlaying analysis for now, but some day you may see "data space overflow" and at that time a restructuring, that should be easy now, may be a 'project'.

    Erik

  • Or...

    Simply add the function called via pointer into the call tree where it belongs.

    Jon

  • Simply add the function called via pointer into the call tree where it belongs.

    What do you mean by that? Is that also through linker settings in Keil?

    what I have in my code is this, I define typedef struct:

    typedef struct {
            UINT8 Num_Input_Byte;
            void (*cmdFunc)(void);
    } cSpiInputStruct_T;
    

    After I receive information from SPI, I check the header then in my super loop, I have this:

    void SPIProcess(void)
    {
            if (SpiCmdReady)
            {
                    cSpiInputTbl[SpiCmdIdx].cmdFunc();
                    SpiCmdReady = FALSE;
            }
    }
    

    I am using similar method to handle UART command too and never have any problem there.

  • What do you mean by that? Is that also through linker settings in Keil?

    Yes. Take a look at the linker manual. There is an entire chapter devoted to this topic.

    www.keil.com/.../bl51_ol_manipulations.htm

    Jon