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.
Hi, I have an address on the APB which has a READ functionality and a WRITE functionality. If I read from it I get the status, and when I write to it, I set something else (Has nothing to do with the status).
I declared this address using a variable which is located using the _at_ keyword, and I get the "L30 memory space overflow" warning. Now I understand the warning is OK, but I wanted to know if there's a way to remove it for these specific addresses (I don't want to disable L30 entirely), or maybe uVision supports this specific issue somehow...
Thanks..
Could you use a 'union' ?
For anything that accesses hardware, especially with functionality like this, I would use an assembly module.
"For anything that accesses hardware"
That's a bit of a sweeping generalisation!
Especially in Keil C51, most hardware access is no more nor less effecient in C than assembler...
"especially with functionality like this"
Yes: 'C' lets you effectively define a read-only symbol by using 'const', but there's no equivalent for a write-only symbol.
:-(
This is quite an omission for a product like Keil, as such situations are not at all uncommon in the embedded microcontroller world...
"That's a bit of a sweeping generalisation!"
I really don't think so, it is what I do.
Maybe I should change the statement to: For anything that directly accesses hardware.
My projects are always constructed so that the 'driver modules' which access hardware are always written in assembler.
The higher level application components are then candidates for C; the deciding factor being the necessary level of optimisation.
With this rule I find it easier (or at least not so difficult) to port between different platforms and processor cores.
However, just about to embark on Cortex, so the rule 'might' change ;)
"For anything that directly accesses hardware."
Well, that's the beauty of the 8051: all "direct" hardware access is via SFRs or memory mapped - there are no special instructions, and no overhead from using 'C'!
"Well, that's the beauty of the 8051..."
True, but sometimes it's not just down to overheads.
I've had colleagues who directly accessed hardware in their C code and it just seemed to permeate through everything. So come the time of porting, it was not a fun task!
I'm of the opinion that a competent embedded programmer really shouldn't find it a difficult (or time consuming) task to write small hardware access functions in assembler.
A smattering of style, preferences and consistent rules can reap large dividends.
It works for me.
"directly accessed hardware in their C code and it just seemed to permeate through everything"
I see: so what you're really saying is to keep all the hardware specifics in one place - whether it's an assembler place or a 'C' place is a separate issue...
That certainly has plenty of merit, and just a few downsides...
"I see: so what you're really saying is to keep all the hardware specifics in one place - whether it's an assembler place or a 'C' place is a separate issue..."
In the past, maybe, but because I felt comfortable with the assembler, I ended up writing the complete driver modules in assembler. The whole module ended up being modular and very efficient (speedwise) and, I think, reasonably easy to maintain. Ok, some could have been done in C, but that would have probably made the structure more confusing.
For 8051 and 68000 and V55 core projects, this really has proven to be a reliable method of maintenance and porting - For me.
As I mentioned, if/when we go to the Cortex, it might be that we go for (close to) 100% C, so then the modules would be logically separated into groups.
ps ...
I meant to ask,
What would you consider to be the downsides?
every hardware access has to be via a function call - which incurs time & code size overheads.
On an 8051, the overhead would be considerable relative to a simple direct access to an SFR!
It depends a bit on compiler and architecture, but in some situations inline functions in a architecture-specific include file may be a good idea. It gives direct access without the function call.
And, in this case, C51 doesn't support inline functions.
That is a huge :(
"every hardware access has to be via a function call - which incurs time & code size overheads."
In the worst case scenario, yes.
But typically, I find that hardware accesses are not done in isolation; i.e., rarely is it the case that a function just gets called, access the hardware once and then returns.
There are normally a few hardware accesses strung together with some other logic; such as a little bit twiddling.
So, put it all together into a little assembler routine and it's really not difficult to end up with a function that is as least as good as the C equivalent - Usually, I would expect it to be better.
"There are normally a few hardware accesses strung together with some other logic"
Absolutely.
"So, put it all together into a little assembler routine"
but I still don't see the need to specifically insist that it must be an assembler routine. Especially for C51.
I would apply the same rule to these routines as to the rest of the code - do it in 'C' unless assembler is specifically necessary.
But, as you say, that's just my opinion.