I have an interrupt service routine that uses Register Bank 2. From within the ISR I call a function, passing a pointer as the argument-- e.g. XXX is defined in a typedef struct declaration The calling statement is: - myfunct(&myvar); where myvar is of type XXX and has the address X:0x00B0 The function header is: void myfunct(xxx xdata *psData) When I look at the disassembly file the parameter &myvar is correctly passed using registers R6 and R7. However, the C51 manual states that pointers are passed using R1 and R2 for the value and R3 for the memory type. It would appear that this parameter is being passed as an integer. On entering the function the address (0x00B0)should be loaded from R6 and R7 into the DPTR, but instead the DPTR is loaded from absolute data memory locations 0X06 and 0x07, WHICH ARE THE ADDRESSES FOR REGISTERS R6 AND R7 IN REGISTER BANK 0, NOT REGISTER BANK 2 I solved the problem by using #pragma NOAREGS (which is less efficient). Am I using pointers incorrectly and even if I am, why is the wrong register bank used in the called function?
However, the C51 manual states that pointers are passed using R1 and R2 for the value and R3 for the memory type My manual states that a generic pointer is passed in R1-3 however xxx xdata *psData is not generic erik
From within the ISR I call a function, This is where the problem starts. That's rarely a very good idea --- if a work unit is heavy enough to make it a separate function, you should try hard not to have to do it in any ISR. Am I using pointers incorrectly No. You're using the 'using' directive incorretly, though. and even if I am, why is the wrong register bank used in the called function? Because your source code said so. Read the manual sections about register banks again for the details.
No. You're using the 'using' directive incorretly, though. and even if I am, why is the wrong register bank used in the called function? Because your source code said so. Read the manual sections about register banks again for the details. I fully support Hans-Bernhard in posting "get familiar with the manual, and you will know" however, if you can not resolve it with some real manual reading in a day or so, come back. Erik PS with real reading I refer to the fact that you applied the text re generic pointers to xdata pointers.
I call a function from within the ISR because the ISR gets the data and calls a function to process it. In a code re-use scenario the basic ISR will not change (and may even be put into a library), but the way it is processed probably will change. OK, so I misread the bit about generic pointers, but you have not explianed why the parameter is read from the wrong addresses. The book (pp122) states:- "Functions which employ absolute register access must not be called from another function that uses a different register bank." I am not using a different register bank - I set register bank 2 in the ISR header and I assume that this will be the case until I exit the ISR. Or does this mean that although the ISR uses bank 2 the function that it calls DOES NOT inherit the register bank parameters - although the PSW shows that before, during and after the function is called by the ISR Register bank remains at 2?
The book (pp122) states:- "Functions which employ absolute register access must not be called from another function that uses a different register bank." And that's exactly what you're doing --- so it fails. I am not using a different register bank Oh, but of course you are --- the ISR is "using 2", the called function is "using 0" (by default). And the called function was using absolute register accesses, until you switched that around. I.e. not only the problem is documented, but the workaround you found also follows directly from the manual. Or does this mean that although the ISR uses bank 2 the function that it calls DOES NOT inherit the register bank parameters It inherits the register bank selector of the CPU alright --- but that does you no good for the absolute register accesses, because those are hardwired at compile time, long before anybody guessed you would be calling this function from an ISR using bank 2.
Thanks. Your last paragraph explains my problem perfectly. I can now explain it to myself as follows: - The function is compiled and this fixes the code by which parameters are recieved (let us assume absolute register addresses). If this function is then called by two other functions that each use different register banks - then in one case the system MUST FAIL since the code, once compiled, cannot be changed. I am now happy