Is it possible to assign a structure (in C) with defined bit-fields to a SFR that is not bit addressable to gain bit addressability ?
"same operations you would get from "mystruct.flags |= (1<<4)"...
How do you assign "mystruct.flags" to an SFR?
If the struct happens to be located over the address range holding the SFR then you get your bit fields overlapping SFR.
But did you not see my note about the solution not having well-defined behaviour?
Bit fields in C structures was added to allow may small variables to share a larger integer space in processors with little RAM - just like the 8051. But they where _not_ intended to be mapped on top of real hardware but just be smaller integers accessed by AND/OR operations on the larger container.
Manually playing with AND/OR operations means you can clear multiple bits at the same time. Using bit fields means you can only assign a value to one bit field at a time, unless you continue further on the "not well-defined" path and overlaps the bit fields with a union.
What do you think you will solve by using bit fields to access a SFR?
I'm reading a book titled "Embedded Multitasking with Small Microcontrollers" by Keith E. Curtis. In chapter 2 he spends several pages stating the usefulness of STRUCTURES for creating control and data variables linked to "system peripherals". He makes a convincing argument for using them, shows examples and promotes usage for organizational value.
I'm trying to determine if I agree with his advise. I realize the usefulness of "|=" and "&=". That is how I do bit operations on bytes now. I'm trying to expand my knowledge by listening to others (read books on the topic) to see if I may learn something new and useful...
You have replied twice but still haven't answered the question of how to link an SFR to a structure. The author states this is compiler dependent.
You can't link an SFR to a structure. But you can place a structure at an absolute location, which I did mention.
Guess how many people who have asked how to place a variable at an absolute address on tis forum? Guess how many answers that have been given?
Being compiler dependent means its normally documented in the compiler manual. What do you think happens if you read the Cx51 users manual and look at the section named "Absolute Variable Location"? http://www.keil.com/support/man/docs/c51/c51_le_absvarloc.htm
"Guess how many people who have asked how to place a variable at an absolute address on tis forum? Guess how many answers that have been given?"
"What do you think happens if you read the Cx51 users manual and look at the section named "Absolute Variable Location"?"
What's your point?
I hope it's because English is not your native language and your grammar is subpar. Your attitude is borderline condescending. I've been designing hardware for nearly 30 years but when it comes to writing C on a uC I'm a novice. Your technique of answering a question with a question is not appreciated nor appropriate. Don't reply if you think these questions are beneath you.
By the way, I've got a copy of the manual and referred to it many times. Do you think I haven't already read the pages that you sent a link to? What do you think? Why do you hang-out on this forum?
So if you have multiple times been reading the relevant manual pages, you'll just have to use your impeccable grammar and write a better question, letting other forum users know that you do know about that manual section and know exactly where you are stuck.
I wasn't answering a question with a question when I did tell you that an SFR can't be moved. So the way to get a struct on top of an SFR is obviously to move that struct to the correct location. The 8051 is lousy with pointers, so initializing a pointer to the address of the SFR bank and then access the registers indirectly through the pointer will give truly lousy results. Having a struct statically located on top of the SFR allows the compiler to ignore the offset of individual fields in the struct and use best possible addressing modes.
What information did you found lacking in the linked manual page.
so initializing a pointer to the address of the SFR bank and then access the registers indirectly through the pointer will give truly lousy results the SFRs in a '51 is only directly addressable
I would call that truly lousy results ;)
The thing with many programming books is that they are often written for more general-purpose processors even when they claim to be about embedded programming. Embedded is everything for a 4-bit processor with assembler software to a Linux-based system 100 times faster than the original PC.
Structures are heavilly used for ARM Cortex processors. But it does have full generic addressing modes. 8051 compilers normally doesn't even use normal stack space for parameters and local variables. Everything to try to get the best out of the chip with the instructions and addressing modes that exists.
"If the struct happens to be located over the address range holding the SFR then you get your bit fields overlapping SFR."
Can't do what you suggest. Refer to the following: http://www.keil.com/support/docs/1212.htm. It states that it is not possible to locate variables of any kind, except sfrs, in the SFR memory area. This has been confirmed. An error occurs when an attempt to locate a structure in SFR area. It is possible to locate a structure in address 0x80 - 0xFF using idata of course.
Unless there is a trick to use sfr/sbit to link a structure to SFR (it doesn't appear so) this concept is a bust. I can now drop this notion (for the 8051) based on sound empirical observation not anecdotal advise.
OK, then it's a dead end. The problem with the 8051 is that it has a number of memory blocks that all have different addressing modes, thereby giving overlapping address ranges.
The problem is to always keep track of what is available in the different memory regions so the correct addressing mode gets used. There are specific keywords xdata, pdata, idata, code, ... just to tell the compiler how to access the memory. If the keyword sfr isn't allowed as attribute for a struct but only as a special data type for a global variable then no alternative will be possible.
The main thing here is that there really isn't any loss from the above. A programmer wouldn't have gained anything from accessing an 8-bit SFR from a struct instead of directly. For 16-bit SFR, byte order could have been a problem - the sfr16 keyword already have limitations. Next is of course that the SFR that are most important to be able to access as bits have their bits aliased separately - someting C bit fields can't help with.
There really are a lot of limitations when it comes to accessing memory using the 8051 and the cmpiler vendors have had to spend a lot of time to fit the C language to the processor. Still, it's very much a task for the developer to fit the code to the processor instead of using generic implementations.
The 8051 have survived well, despite large numbers of quite drastic compromises just to be able to keep down on the transistor count.