We are running a survey to help us improve the experience for all of our members. If you see the survey appear, please take the time to tell us about your experience if you can.
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
this happens when a functions is called in isr as well as in general routines so to avoid it add reentrant in the declaration as well as in definition of the function eg: if foll function is called: void function(void) then rewrite it as void function(void) reentrant in declaration as well as in definition
you will also - in many cases - have to add NOAREG.
This calling a function from both ISR and main is something, that the implementation that Keil fortunately have chosen in order to to work the best with the 'features' that the '51 architecture has, get to be almost an "implementation violation".
Yes, you buggers that insist that "C is C who gives a hoot that it is on a '51" will, of course consider it an "unnecessarily cumbersome implementation of standard C". if you insist that "C is C" I suggest you get yourself a PC to program.
Erik
if you insist that "C is C" I suggest you get yourself a PC to program.
Too a harsh a judgment I think. A couple of years ago I was involved in the development of, what I still consider, the most beautiful piece of time critical C (and some C++) code I ever saw, which was written mostly in standard C/C++. Things were not taken to extremes to squeeze the processors (XC167CI), but that did not reduce the code's functional value and did not change the fact the it bread an entire generation of successful machines. I doubt whether the people that were/still are involved in that effort would appreciate your job offer :-)
Where did that clueless little rant spring from? You've been quite quiet for a while.
But please, if you really insist on making a public fool of yourself, at least try and moderate your language.
Things were not taken to extremes to squeeze the processors no such intent in my post, if you do not need to, then why try? However, there are some things where considering the achitectural facts and the compiler circumvention thereof get important. Basically what I comment on is the udder (yes it i bovine) refusal of some to adapt to what they are working with, namely Keil C51, not just "some C"
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 have double, triple, quadruple checked the ISR and global searched nvmwrite function call. However, I do not understand why linker still complain that I have nvmwrite call from ISR when I have optimization level > 2.
Maybe the compiler performs common-subexpression optmization, but not on sub-expressions but instead analyses functions with common code and then join the two code chains?
I don't work with the Keil C51 compiler, but quite funny things can happen when a compiler starts doing global optimization.
But a question asked earlier in this thread: Have you made sure that you have erased every single object file, so that the linker doesn't link in one object file from before the change?
I did rebuild all target files and I also tried delete all object files in my hard drive, then compile again. It does not seems to make any difference.
For the time being, I made the nvmwrite to be reentrant so I can keep working on my code. Now I am having a new "multiple call to segment" warning on a different function, but two callers are the same, ISR and C51startup.
Only when I change optimization level to 1, I wouldn't have that warning, but my code is, of course, much bigger.
I can post my code here, but it is kind long...
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.
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?
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?
Did you take a look at http://www.keil.com/support/man/docs/c51/c51_xf_recursivecode.htm ?
Jon
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.