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,
Anyone can tell me how I can know whether I need to use "using" attribute or not? Attribute "using" ranges 0-3, So which number I have to select? I read Cx51 user guide, it states that:
The using attribute may not be used in functions that return a value in registers. You must exercise extreme care to ensure that register bank switches are performed only in carefully controlled areas. Failure to do so may yield incorrect function results. Even when you use the same register bank, functions declared with the using attribute cannot return a bit value.
Unfortunately, I cannot get point.
Thanks, pak
Anyone can tell me how I can know whether I need to use "using" attribute or not?
I thought the manual page was pretty clear.
http://www.keil.com/support/man/docs/c51/c51_le_regbankspec.htm
Apart from that, there is no requirement that you use register banks ever! If you don't use register banks that memory is available for use by program variables and the stack (assuming you use no bit memory).
In general, I only use register banks for interrupts. So, my main C function and all the routines it calls use register bank 0. If I keep my interrupt service routines very small, they don't need to save lots of registers on the stack--and I don't need to use a different register bank. If your interrupt routine uses 4 registers and RB0, it must push and pop those registers each time it gets triggered. In some cases, this may take up too much time. Switching to a different register bank is very fast. But, you basically "reserve" those 8 bytes for that interrupt.
For interrupt routines that must be fast, I try to make them small so they don't use lots of registers in the first place. But, if I just can make that work, then I use a register bank.
I guess it boils down to how many interrupts you get in a second and how fast the service routine has to run and how short of memory you are. You must balance all of these things to figure out the answer.
Jon
So final conclusion is we use attribute 'using' for storing all 8 registers in the register bank instead of storing stack when processing interrupt or RTOS, am I right?
One more question, pls make it clear the following statement: The currently selected register bank is saved on the stack at function entry. The specified register bank is set. The former register bank is restored before the function is exited. why we need to use register bank rather than stack? Do all 8 registers stored in stack lost during interrupt?
Thanks, Pak
RTOS ....why we need to use register bank rather than stack? Do all 8 registers stored in stack lost during interrupt?
a very dangerous combo. Trying to use a RTOS (why on earth would anyone want to do that an a '51) and no understanding whatsoever of the architecture of the chip. While such is SOP on the PC, it is the road to absolute total failure when using the '51.
Erik
pls make it clear the following statement
The register bank number currently in use (0..3) is stored on the stack, so that it can be restored later. This is a value separate from the contents of the registers themselves.
main (using 0) ---> interrupt (using 1) ---> push reg bank 0 ---> set register bank = 1 ---> push other values ---> handle interrupt ---> restore values ---> set register bank = 0 ---> RETI main resumes
There are four register banks, each with 8 registers (R0..R7). The idea is that it can be faster to devote a register bank to an interrupt so that it does not have to save all 8 registers on entry. It simply changes the bank instead. The old registers are safe, because they're in another bank. The idea is similar to the hard-wired way an ARM works, with some registers replaced with duplicated during an ISR.
The feature assumes a fairly simple system, with few contexts (ISRs or tasks). If you have more contexts than you have register banks, then some of them must share. If the ones that share can interrupt each other, then they have to save values on the stack. Once you put in the code (and time) to save values on the stack into all your contexts, then you might just as well use one register bank. So, "using" is useful mostly for a very few (three or less) special interrupts that need very fast execution at the cost of permanently dedicated system resources.
For a system complicated enough to need an RTOS, you probably have too many contexts. I'd expect all the RTOS tasks to use one bank (0) and ignore the others, which might be given to ISRs.
Note that the registers are the first 32 bytes of data space, and that the 128 bytes of data space are usually a precious resource. Giving up 8 bytes for a register bank means that the other contexts are more likely to need xdata, and thus get bigger and slower.
"Using" is best used for a couple of highly important special interrupts. If you don't have a particular need for this sort of speed, then don't even bother with the feature.
If you have more contexts than you have register banks, then some of them must share. If the ones that share can interrupt each other, then they have to save values on the stack.
dead simple
you assign main and what it calls to stack 0 you assign ALL interrupts of low priority to stack 1 you assign ALL inyerrupts of high proiority to stack 2
interrupts of the same priority can not interrupt each other
Thank, Davis. Your explanation make me understand architecture of C51.
actually simple, no need to fiddle ,Thank for making thing simple, Eric. That is what I actually need.
Thanks for suggestion, pak