#define _FUID1(x) __attribute__((section("__FUID1.sec"),space(prog))) int _FUID1 = (x);
I am trying to make sense of the about the above define. the _FUID(x) macro. This relates to program memory and has the attribute of the section defining in the code section memory area?
what does the above trying to accomplish?
The macro isn't doing anything interesting or complicated at all; it just outputs a declaration for int _FUID1, with its parameter as an initializer, and with an attributes list ahead of it.
As for what the attributes list means, look at the documentation for variable attributes in GCC. section puts the variable in a named section, which allows the linker to relocate it to a special address or do some other interesting thing to it, and space isn't documented, but space(prog) sounds like a directive to put a value into the program address space instead of the data address space on a Harvard-architecture machine.
I think this is hardware specific (some Microchip unit), it places a value, for example:
__attribute__((section("__FUID1.sec"),space(prog))) int _FUID1 = (0xf1);
into unit id register 1 (__FUID1.sec), in the program flash to configure the hardware. See the pic documentation (for references to FUID) and MPLAB C30 manual (for description of memory spaces).
Related
Are these attributes incompatible? The address attribute seems to be ignored, emitting no warnings (-Wall).
(For reference, EEMEM is defined in eeprom.h as: #define EEMEM __attribute__((section(".eeprom"))).)
Using a declaration like:
uint8_t storedFlags EEMEM __attribute__((address (100)));
(and similarly for all the others) results in the variables being placed in whatever order the linker prefers, ignoring my attribute. Order of attributes doesn't make a difference.
I am aware of the preferred method (creating sections and passing their locations to the linker). I was just looking to shove them around for the moment, as I'm in active development and adding and removing allocations in EEPROM; I'd rather things not move around every other build so I don't have to reprogram EEPROM from default values every damn time. Worst of all, I'm sure I've done precisely this before, and had it work. Version differences? Coincidental assignments? (I have GCC 3.4 and 8.1, not sure what that project used; I'm using 8.1 for this one.)
The documentation for the address attribute states:
Variables with the address attribute are used to address memory-mapped peripherals that may lie outside the io address range.
Looking at the AVR memory space shows the I/O addresses fall under the SRAM data memory space.
This explains why your construct doesn't work as expected since EEMEM and the address attribute map to conflicting memory sections.
Edit: Testing with avr-gcc 3.6.2 suggest that the section attribute overrides the address attribute (without warning). Using eeprom_read_byte to read data from EEPROM, the following example gets correctly compiled by avr-gcc (correct because the address 0x0123 is passed to the eeprom_read_byte function):
#include <avr/eeprom.h>
uint8_t __attribute__((address (0x0123))) storedFlags;
int main(void){
if (eeprom_read_byte(&storedFlags) == 1){
return 1;
}
}
Edit2: tested on avr-gcc 11.1, also generates correct instructions.
I often times write to memory mapped I/O pins like this
P3OUT |= BIT1;
I assumed that P3OUT was being replaced with something like this by my preprocessor:
*((unsigned short *) 0x0222u)
But I dug into an H file today and saw something along these lines:
volatile unsigned short P3OUT # 0x0222u;
There's some more expansion going on before that, but it is generally that. A symbol '#' is being used. Above that there are some #pragma's about using an extended set of the C language. I am assuming this is some sort of directive to the linker and effectively a symbol is being defined as being at that location in the memory map.
Was my assumption right for what happens most of the time on most compilers? Does it matter one way or the other? Where did that # notation come from, is it some sort of standard?
I am using IAR Embedded workbench.
This question is similar to this one: How to place a variable at a given absolute address in memory (with GCC).
It matches what I assumed my compiler was doing anyway.
Although an expression like (unsigned char *)0x1234 will, on many compilers, yield a pointer to hardware address 0x1234, nothing in the standard requires any particular relationship between an integer which is cast to a pointer and the resulting address. The only thing which the standard specifies is that if a particular integer type is at least as large as intptr_t, and casting a pointer to that particular type yields some value, then casting that particular value back to the original pointer type will yield a pointer equivalent to the original.
The IAR compiler offers a non-standard extension which allows the compiler to request that variables be placed at specified hard-coded addresses. This offers some advantages compared to using macros to create pointer expressions. For one thing, it ensures that such variables will be regarded syntactically as variables; while pointer-kludge expressions will generally be interpreted correctly when used in legitimate code, it's possible for illegitimate code which should fail with a compile-time error to compile but produce something other than the desired effect. Further, the IAR syntax defines symbols which are available to the linker and may thus be used within assembly-language modules. By contrast, a .H file which defines pointer-kludge macros will not be usable within an assembly-language module; any hardware which will be used in both C and assembly code will need to have its address specified in two separate places.
The short answer to the question in your title is "differently". What's worse is that compilers from different vendors for the same target processor will use different approaches. This one
volatile unsigned short P3OUT # 0x0222u;
Is a common way to place a variable at a fixed address. But you will also see it used to identify individual bits within a memory mapped location = especially for microcontrollers which have bit-wide instructions like the PIC families.
These are things that the C Standard does not address, and should IMHO, as small embedded microcontrollers will eventually end up being the main market for C (yes, I know the kernel is written in C, but a lot of user-space stuff is moving to C++).
I actually joined the C committee to try and drive for changes in this area, but my sponsorship went away and it's a very expensive hobby.
A similar area is declaring a function to be an ISR.
This document shows one of the approaches we considered
I'm pretty new to c programming and I have this following program to degub. Problem is, I have no idea what these lines of code even mean. Could anyone point me in the direction of what they mean as far as from a syntax point of view/functionality? What does the code do? The code is compiled with MPLab C30 v3.23 or higher.
fractional abcCoefficient[3] __attribute__ ((space(xmemory))); /*ABC Coefficients loaded from X memory*/
fractional controlHistory[3] __attribute__ ((space(ymemory))); /*Control History loaded from Y memory*/
fractional kCoeffs[] = {0,0,0}; /*Kp,Ki,and Kd gains array initialized to zero*/
These lines declare variables; there's no execution code associated with what you've pasted.
The environment this code is intended for understands that fractional is a type; either in the same file or in a header this file includes (directly or indirectly), fractional will be defined with a typedef statement. In your examples, each of the variables are arrays of three fractional types.
The __attribute__ ((space(?memory))) entries are attributes the compiler intended to build this understands and affect something regarding how the variables are managed. You'll want to consult the compiler documentation for the platform you're using.
See this page to learn about __attribute__ in gcc (however, I don't see a space(xmemory) option in there, consult your compiler's documentation if it's not gcc. If it is, then space() can be a macro).
fractional is also a custom type, search for typedef definitions for fractional.
Basically, the code is creating a bunch of arrays of type fractional. The first two make use of gcc's attribute extension (or whatever compiler you are using), and the last one is initialized to 0 on every position.
The first two lines declare arrays with three elements each. The type is fractional, which is probably a typedef (to a struct with numerator and denominator?).
The comments suggest that the data is stored in another memory space, perhaps some sort of Flash.
So the program seems to be for an embedded system.
It looks like "fractional" is a custom type, look for its typedef somewhere and it should get you started on what you're looking at. I expect these are variable declarations.
Macros are established using the "#define" preprocessor directive, so you can look for "#define space(x) code" somewhere to tell you what it does. Good luck.
void __attribute__((__interrupt__, no_auto_psv)) _T1Interrupt(void) // 5 Hz
__attribute__ directive or macro is from GCC but __interrupt__ and no_auto_psv is not , it's specific to a hardware. So, how does GCC Compiler understand __interrupt__ and no_auoto_psv, I searched and didn't find any declaration in anywhere else.
So basically the _T1Interrupt function takes no argument and return nothing but has the above attribute?
In particular, these attributes are platform-specific extensions used in the Microchip XC16 compiler for 16-bit PIC24 and dsPICs.
Attributes are essentially extra information added to the parse tree of a compiler. They exist outside the C language semantics and are there to provide additional information that the compiler uses to act consistently with your expectations. In this case __interrupt__ tells it to treat the function as an ISR (with slightly different function prolog and epilog than a normal function: dsPIC ISRs use the RETFIE return instruction, vs. RETURN for normal functions), and no_auto_psv controls whether the compiler sets the PSVPAG register:
The use of the no_auto_psv attribute omits code that will re-initialize the PSVPAG value to the default for auto psv variables (const or those placed into space auto_psv). If your code does not modify the PSVPAG register either explicitly or using the compiler managed psv or prog qualifiers then the use of no_auto_psv is safe. Also, if your interrupt service routine (or functions called by your interrupt service routine) does not use any const or space auto_psv variables, then it is safe to use no_auto_psv.
(from http://www.microchip.com/forums/m394382.aspx)
The documentation for __attribute__() says:
GCC plugins may provide their own attributes.
So perhaps that's how it's being used in your situation.
What unwind said is true and the attritbutes are defined by the MPLAB extension for gcc. It's been a while since i've worked with microcontrollers so i can't provide more details on this front. However for your specific application (embedded c on pic micro-controller). The above is the proper way of declaring a function that is meant to implement an interrupt subroutine for timer 1. Interrupt subroutines rarely return anything, If you need to capture the value in the register i recommend you use the following structure as a global variable:
typedef struct T1OUT
{
int timer_register_value;
int flag;
} T1InteruptCapture;
The timer_register_value is the value you want out of your subroutine. While the flag value is memory lock that prevents the subroutine from over-writing your previous value. There are different ways of getting values out of your subroutine. I found this to be the easiest and the most time efficient. You can also look into implementing a mini-buffer. I recommend you avoid pointer with embedded C. I don't know if things have changed, in the last couple of years.
edit 1: MPLAB has some of the best documentation i've ever seen. I recommend you have a look at the one for your specific microcontroller. They provide sample code with great explanations.
edit 2: I not sure why you're using gcc. I would recommend you get the pic compiler from MPLAB. I believe it was called C30. and the associated .h file.
How is scope of a variable is implemented by compilers?
I mean, when we say static variable, the scope is limited to the block or functions that defined in the same file where the static variable is defined?
How is this achieved in machine level or at memory level?
How actually is this restriction achieved?
How is this scoping resolved at program run time?
It is not achieved at all at the machine level. The compiler checks for scopes before machine code is actually generated. The rules of C are implemented by the compiler, not by the machine. The compiler must check those rules, the machine does not and cannot.
A very simplistic explanation of how the compiler checks this:
Whenever a scope is introduced, the compiler gives it a name and puts it in a structure (a tree) that makes it easy to determine the position of that scope in relation to other scopes, and it is marked as being the current scope. When a variable is declared, its assigned to the current scope. When accessing a variable, it is looked for in the current scope. If not found, the tree is looked up to find the scope above the current one. This continues until we reach the topmost scope. If the variable is still not found, then we have a scope violation.
inside compilers, its implementation defined. For example if I were writing a compiler, I would use a tree to define 'scope' and it would definitely be a symbol table inside a binary tree.
Some would use an arbitrary depth Hash table. Its all implementation defined.
I'm not 100% sure I understand what you are asking, but if you mean "how are static variables and functions stored in the final program", that is implementation-defined.
That said, a common way of storing such variables and functions is in the same place as any other global symbols (and some non-global ones) -- the difference is that these are not "exported", and thus not visible in any outside code trying to link to our software.
In other words, a program which has the following in it:
int var;
static int svar;
int func() { static int func_static; ... }
static int sfunc() { ... }
... might have the following layout in memory (let's say our data starts at 0xF000 and functions at 0xFF00):
0xF000: var
0xF004: svar
0xF008: func.func_static
...
0xFF00: func's data
0xFF40: sfunc's data /* assuming we needed 0x40 bytes for `func`! */
The list of exports, however, would only contain the non-static symbols, aka the exported ones:
var v 0xF000
func f 0xFF00
Again -- note how, while the static data is still written into the files (it has to be stored somewhere!), it is not exported; in layman's terms, our program does not tell anyone that it contains svar, sfunc and similar.
In Unices, you can list the symbols that a library or a program exports with the nm tool: http://unixhelp.ed.ac.uk/CGI/man-cgi?nm ; there do exist similar tools for Windows (GnuWin32 might have something similar).
In practice, executable code is often stored separately from the data (so that it can be protected from writes, for example), and it both may get reordered to minimize memory use and cache misses, but the idea remains the same.
Of course, optimizations can be applied -- for example, a static function could be inlined in its every invokation, meaning that no code is generated for the function itself at all, and thus it does not exist on its own anywhere.