• AVR Freaks

Helpful ReplyHot!How to get compiler directive _XTAL_FREQ to library file routines

Author
bigMoose
Starting Member
  • Total Posts : 7
  • Reward points : 0
  • Joined: 2012/11/29 14:51:42
  • Location: USA
  • Status: offline
2020/08/10 12:24:26 (permalink)
5 (1)

How to get compiler directive _XTAL_FREQ to library file routines

I put the statement:
#define _XTAL_FREQ 8000000        //needed by compiler for delay functions
for XC8 delay functions in a "main".h file   I have now composed a libraryBIG.c and libraryBIG.h file that contain many of the routines that I routinely use.  
 
I have to edit the libraryBIG.c file to add 
#include ""main".h"    // needed for crystal frequency define  (where "main" is the name of my main project file)
 
I would like to not have to have unique libraryBIG.c files for each project.  I have looked and looked and experimented how to circumvent this requirement and pass a "global" knowledge of _XTAL_FREQ to the compiler. 
 
I am at a loss, can a wise one help this ol' guy out?
 
#1
jtemples
عُضْوٌ جَدِيد
  • Total Posts : 11982
  • Reward points : 0
  • Joined: 2004/02/13 12:31:19
  • Location: Southern California
  • Status: offline
Re: How to get compiler directive _XTAL_FREQ to library file routines 2020/08/10 12:55:31 (permalink) ☄ Helpfulby bigMoose 2020/08/10 13:00:42
+2 (2)
The compiler compiles one .c  file.  The compiler has no knowledge of anything "global" unless your build system provides it to each file.
 
I'll often add a "target.h" file to a project that has target-specific stuff in it (like _XTAL_FREQ).  Include target.h in your application and libraries, and when you're using your library on a different target, target.h might contain something else (or it might be empty).  You might have a series of #ifdefs in target.h to automatically use the appropriate macros based on which target is being used.
#2
du00000001
Just Some Member
  • Total Posts : 3946
  • Reward points : 0
  • Joined: 2016/05/03 13:52:42
  • Location: Germany
  • Status: offline
Re: How to get compiler directive _XTAL_FREQ to library file routines 2020/08/10 14:51:18 (permalink) ☄ Helpfulby bigMoose 2020/08/10 16:12:19
+4 (4)
A fancy way to achieve this would be to make the definition a compiler call argument.
Syntax would be something like "-D_XTAL_FREQ=xxxxxxxx" (check for the exact syntax!).
 
Advantage: This way you won't need any definition of this in a header file. It's efficient and makes thevsymbol -D'ed available in every compile unit.
Disadvantage: this is nothing supported e.g. by MCC, so some manual fine-tuning might be required following an MCC code generation. And it's not (yet?) "the usual way". For me, I don't give much on the usual way.

PEBKAC / EBKAC / POBCAK / PICNIC (eventually see en.wikipedia.org)
#3
dan1138
Super Member
  • Total Posts : 3845
  • Reward points : 0
  • Joined: 2007/02/21 23:04:16
  • Location: 0
  • Status: offline
Re: How to get compiler directive _XTAL_FREQ to library file routines 2020/08/10 16:13:19 (permalink) ☄ Helpfulby bigMoose 2020/08/10 19:08:14
+2 (2)
bigMoose
I would like to not have to have unique libraryBIG.c files for each project.  I have looked and looked and experimented how to circumvent this requirement and pass a "global" knowledge of _XTAL_FREQ to the compiler. 
 
I am at a loss, can a wise one help this ol' guy out?

The Microchip documentation does a great job obscuring the way the __delay_ms() function is actually implemented.
 
For the XC8 compiler this is a preprocessor macro that invokes the _delay() function. This appears to be a function that the XC8 compiler creates the code for at each specific instance the __delay_ms() function is placed in your source file.
 
The documentation gives the impression that the __delay_ms() function can be called with variable parameter. XC8 supports only literal constants as the parameter for the __delay_ms() function.
 
The delay duration is computed at compile time but the final object code is generated by the linker based on the assembly code created at compiler time. So changes to the preprocessor #define _XTAL_FREQ do not seem to affect the delays invoked from library objects when that library is linked with a new project.
 
The short answer is that the __delay_ms() function is unusable from a tradition object code library.
 
So it you want to do a spin wait in a library object do not use the __delay_ms() function.
 
<EDIT>
Thanks ric !  Age, cut & paste with dyslexia, a triple threat, :)
post edited by dan1138 - 2020/08/10 18:52:22
#4
ric
Super Member
  • Total Posts : 28386
  • Reward points : 0
  • Joined: 2003/11/07 12:41:26
  • Location: Australia, Melbourne
  • Status: online
Re: How to get compiler directive _XTAL_FREQ to library file routines 2020/08/10 16:36:18 (permalink) ☄ Helpfulby bigMoose 2020/08/10 19:08:18
+2 (2)
bulk change "__dealy_ms()" to "__delay_ms()" in the previous post!
Note, Dan is describing what happens with a real library file.
If you're just talking about common source code included into your project, then du00000001's technique is ok.
 

I also post at: PicForum
Links to useful PIC information: http://picforum.ric323.co...opic.php?f=59&t=15
NEW USERS: Posting images, links and code - workaround for restrictions.
To get a useful answer, always state which PIC you are using!
#5
mad_c
Super Member
  • Total Posts : 1258
  • Reward points : 0
  • Joined: 2010/12/12 17:48:27
  • Location: Brisbane, Australia
  • Status: online
Re: How to get compiler directive _XTAL_FREQ to library file routines 2020/08/11 13:52:52 (permalink)
+3 (3)
dan1138 
The documentation gives the impression that the __delay_ms() function can be called with variable parameter. XC8 supports only literal constants as the parameter for the __delay_ms() function.

Hi,
 
Could you point out what part of the guide gave you the impression that the argument can be a variable, so I can check the wording. I just checked the current guide and for both _delay() and __delay_ms() library functions, and it states, "The argument must be a constant expression," but maybe I've missed this somewhere else.
 
Thanks, Jeff.
#6
bigMoose
Starting Member
  • Total Posts : 7
  • Reward points : 0
  • Joined: 2012/11/29 14:51:42
  • Location: USA
  • Status: offline
Re: How to get compiler directive _XTAL_FREQ to library file routines 2020/08/11 13:52:52 (permalink)
0
Folks thanks for your solutions!  I'm only a year or two away from 70 and working alone, so sometimes it is hard to discern these subtleties if you are "stumped."
 
I have tried two of the solutions out, and have a most excellent solution from you all!  Thanks again, BigMoose  
#7
dan1138
Super Member
  • Total Posts : 3845
  • Reward points : 0
  • Joined: 2007/02/21 23:04:16
  • Location: 0
  • Status: offline
Re: How to get compiler directive _XTAL_FREQ to library file routines 2020/08/11 14:46:10 (permalink)
0
mad_c
dan1138 
The documentation gives the impression that the __delay_ms() function can be called with variable parameter. XC8 supports only literal constants as the parameter for the __delay_ms() function.

Hi,
 
Could you point out what part of the guide gave you the impression that the argument can be a variable, so I can check the wording. I just checked the current guide and for both _delay() and __delay_ms() library functions, and it states, "The argument must be a constant expression," but maybe I've missed this somewhere else.
 
Thanks, Jeff.

Jeff,
 
The documentation is as clear as it perhaps can be on this point given that this is a legacy inherited from the Hi-Tech PIC compilers.
 
In an ANSI/ISO compliant compiler that kind of extension would require a function name like __builtin_delay_ms(); so that the developer would be compelled to at the very least actually read the compiler specific documentation.
 
The specific nit I am picking here is that the way most users encounter the XC8 delay function is as a part of some tutorial that has no information on how this class of delay function should be invoked.
 
There is little I expect that Microchip will do about this, as removing support for the __delay_ms() and _delay() functions will break a lot of code.
 
But then after dropping MPASM for MPLABX maybe Microchip is in a kill happy mood. So now that Microchip has made my MPASM code useless for future project why not do the same for my PICC code as well.
post edited by dan1138 - 2020/08/11 15:00:02
#8
mad_c
Super Member
  • Total Posts : 1258
  • Reward points : 0
  • Joined: 2010/12/12 17:48:27
  • Location: Brisbane, Australia
  • Status: online
Re: How to get compiler directive _XTAL_FREQ to library file routines 2020/08/11 15:20:06 (permalink)
+1 (1)
dan1138
In an ANSI/ISO compliant compiler that kind of extension would require a function name like __builtin_delay_ms(); so that the developer would be compelled to at the very least actually read the compiler specific documentation.

Point taken. Potentially, there could be an alias for it created; however, that will not change any existing code or documentation. The delay routines have been around for decades, so they are kind of entrenched.
 
Jeff.
 
#9
Ian.M
Super Member
  • Total Posts : 13272
  • Reward points : 0
  • Joined: 2009/07/23 07:02:40
  • Location: UK
  • Status: offline
Re: How to get compiler directive _XTAL_FREQ to library file routines 2020/08/12 02:46:05 (permalink)
+4 (4)
Unfortunately a significant number of PIC novices don't have a strong background in C, and XC8 is quite possibly the first C compiler they've ever used.  A lot more are refugees from 'Arduinoland' where the style is to use a variable for *everything*, even when it would be better as a constant or #define.
 
I suspect that you'd have to explain that a constant expression, after preprocessor macro expansion can only contain numbers and other literals, and  C operators.  i.e. *NO* functions or C constants.  That's not really 'in scope' for a compiler manual, but I would suggest putting a good definition of 'constant expression' in the glossary, and changing the title of the 'How To' section to
'How Can I Implement a Fixed Delay in My Code?'
and in it emphasizing that _delay() etc. cant generate a variable delay.

--
NEW USERS: Posting images, links and code - workaround for restrictions.
I also support http://picforum.ric323.com because this forum is sometimes too broken to use!
#10
mlp
boots too small
  • Total Posts : 965
  • Reward points : 0
  • Joined: 2012/09/10 15:12:07
  • Location: previously Microchip XC8 team
  • Status: offline
Re: How to get compiler directive _XTAL_FREQ to library file routines 2020/08/13 07:52:19 (permalink)
+1 (1)
Dan, I expected better from you.
 
dan1138
In an ANSI/ISO compliant compiler that kind of extension would require a function name like __builtin_delay_ms();

The language standard already (for 30+ years) has a provision for compiler-specific extensions. That provision is not the magic prefix "__builtin_" - it is the (granted, equally magic) prefix "__", just as in __delay_ms(). (C has never been particularly verbose.) If a programmer uses such a function without having looked up the details in the compiler manual first s/he is a very poor programmer.
 

The specific nit I am picking here is that the way most users encounter the XC8 delay function is as a part of some tutorial that has no information on how this class of delay function should be invoked.

And with third-part tutorials that's Microchip's fault, or responsibility to correct, how?
And if it were, how could they correct it? Oh yes, in the compiler manual.
 
Microchip does a lot of completely boneheaded things (which I'm now allowed to say, as a non-employee), but __delay_ms() is not one of them.
 

Mark (this opinion available for hire)
#11
dan1138
Super Member
  • Total Posts : 3845
  • Reward points : 0
  • Joined: 2007/02/21 23:04:16
  • Location: 0
  • Status: offline
Re: How to get compiler directive _XTAL_FREQ to library file routines 2020/08/13 15:48:21 (permalink)
0
mark.pappin
Dan, I expected better from you.

A lot of folks do, you would be surprised at how wide spread the disappointment is. :)
(He could do so much better if he'd just apply himself. My mother)
 
My personal hot button is that I really dislike spin waits like: __delay_ms()
 
Anyone that thinks they are good is by demonstration a "very poor programmer".
 
They are at times a necessary evil, but until you discover all of the _delay_ms() limitations in the XC8 compiler for the PIC18 family you have not yet faced true evil.
#12
ric
Super Member
  • Total Posts : 28386
  • Reward points : 0
  • Joined: 2003/11/07 12:41:26
  • Location: Australia, Melbourne
  • Status: online
Re: How to get compiler directive _XTAL_FREQ to library file routines 2020/08/13 15:57:13 (permalink)
+2 (2)
dan1138
...
They are at times a necessary evil, but until you discover all of the _delay_ms() limitations in the XC8 compiler for the PIC18 family you have not yet faced true evil.

I'm gonna poke the bear :)
Are you referring to the max duration limitation, that only affected PIC18F not PIC16F?
That was fixed several versions ago.
If not, what other limitations are you referring to?
 
(BTW, I agree, except for quick and dirty test code, the delay routines are usually NOT a good way to implement a delay in a full project.)
 

I also post at: PicForum
Links to useful PIC information: http://picforum.ric323.co...opic.php?f=59&t=15
NEW USERS: Posting images, links and code - workaround for restrictions.
To get a useful answer, always state which PIC you are using!
#13
dan1138
Super Member
  • Total Posts : 3845
  • Reward points : 0
  • Joined: 2007/02/21 23:04:16
  • Location: 0
  • Status: offline
Re: How to get compiler directive _XTAL_FREQ to library file routines 2020/08/13 16:02:02 (permalink)
0
ric
... Are you referring to the max duration limitation, that only affected PIC18F not PIC16F?

Yep, that's the one that gave me my hatred of compiler supplied spin waits.
#14
ric
Super Member
  • Total Posts : 28386
  • Reward points : 0
  • Joined: 2003/11/07 12:41:26
  • Location: Australia, Melbourne
  • Status: online
Re: How to get compiler directive _XTAL_FREQ to library file routines 2020/08/13 16:20:18 (permalink)
0
They fixed that in v1.40
Release notes
Improved/expanded in-built delay functions (XC8E-106, XC8E-16) The in-built delay routines (_delay(), _delaywdt(), __delay_us(), and __delay_ms(), etc.) have been improved. All devices can now generate a three-deep loop, allowing a maximum delay of 50,463,240 instruction cycles. The watchdog variant of this delay is now available for all devices. Several inaccuracies in the generated delay have been corrected. Delays for enhanced mid-range devices are more efficient and use less temporary variables. The delay times are now no longer affected by the location of temporary variables. The _delay3() in-built function is now implemented for enhanced mid-range devices.


I also post at: PicForum
Links to useful PIC information: http://picforum.ric323.co...opic.php?f=59&t=15
NEW USERS: Posting images, links and code - workaround for restrictions.
To get a useful answer, always state which PIC you are using!
#15
Jump to:
© 2020 APG vNext Commercial Version 4.5