Duggle Posted October 15, 2003 Report Share Posted October 15, 2003 Hi,I've just realised the significance of BSR register for making sure RAM is accessable.My understanding is as follows:;;use macroSET_BSR my_var;;can now access vars on same ram page as my_var;;so long as BANKED flag is used with instructions.movf my_var,W,BANKEDSo my question is (to try to complete my knowledge): When don't one use the BANKED flag?Are there tricks or techniques to reduce the use of SET_BSR when working with algorithms that use variables from different RAM pages.thanks for any comments Quote Link to comment Share on other sites More sharing options...
TK. Posted October 18, 2003 Report Share Posted October 18, 2003 A really good question, because this is a point which has not been documented very well yet.so: FAQMARKERthe PIC18F offers two different addressing modes: ACCESS and BANKEDACCESS is the default mode, so you don't have to specify it explicitely on every instruction. It's independent from the BSR and allows you to access addresses between 0x00-0x7f and 0xf80-0xfff (SFR range) directly without initializing the BSRfor BANKED accesses you have to ensure that the BSR is set correctly. So, if you are doing a lot of BANKED operations to addresses between 0x80 and 0x37f (other addresses are reserved for MIOS), you should initialize the BSR before. so long as the BANKED addresses are in between a page of 128 bytes (0x80), you don't have to reinitialize the BSR before every access. This influences the "coding style": addresses which belong together should be located in between a 128 bytes range in order to reduce code (the need to change the BSR)it's alway possible to copy a register value to another register by using the "movff" instruction independent from the source/target address without initializing the BSR. So, the easiest way to copy any register to the working register is: "movff ANY_REGISTER, WREG" --- but note that the "movff" instruction allocates 4 bytes, a common instruction (also SET_BSR) is only 2 bytes long, so this method should only be used if just only one register has to be copied. As soon as you plan to access more than 2 register of the same 0x80 page, it makes sense to change the BSR or:it sometimes makes sense to address the register indirectly by using FSR0 (main program) or FSR2 (interrupt service routine). The FSR has to be initialized with "lfsr FSRx, ANY_REGISTER", thereafter you can access it via "INDF0", "POSTINC0", "POSTDEC0", "PLUSW0", etc...note that most MIOS function are changing the BSR and FSR1 and don't restore it to the old value (to save execution time). This means: if a change of BSR is notified in the MIOS function description, and if you are using BANKED accesses, you have to restore BSR after every MIOS call. So, if you have a lot of interaction between MIOS and your main program, the use of indirect addressing (FSR0/FSR2) or the use of "movff" should be prefered in order to save code spaceHint: registers which have to be accessed very often should just be located below 0x80 so that you don't have to take care for the page pointer. For example, MIOS_PARAMETER[123], TMP[12345] and IRQ_TMP[12345] are located between 0x00-0x0f which makes the use of this most frequently used addresses very easyBest Regards, Thorsten. Quote Link to comment Share on other sites More sharing options...
Duggle Posted October 18, 2003 Author Report Share Posted October 18, 2003 Does FSR2 get saved and restored in the ISRs?(if not then it can't be used in user routines without disabling interrupts)?MIOS routines use FSR1 so if I use FSR1 completely in-between MIOS calls it should be ok? (MIOS may destroy FSR1's content)Are there any dangers of using FSR0? (It gets used by main, are there any user hooks that should restore its content for use by main?thanks Quote Link to comment Share on other sites More sharing options...
TK. Posted October 18, 2003 Report Share Posted October 18, 2003 FSR2 is not restored when an interrupt has been invoked, only FSR0, FSR1, TBLPTR[LH], TABLAT and MIOS_PARAMETER[123] --- the reason for this is, that you normaly never need a third pointer, only on very special cases, so I decided to left it out to ensure best performance.Yes, by temporary disable interrupts with IRQ_DISABLE it's possible to use all three pointers in your main program. After the use of FSR2 you can enable interrupts again with IRQ_ENABLE. FSR2 don't has to be saved/restored. Such a routine should never run longer than ca. 300 uS to ensure the realtime capability (especially: receiving MIDI events). Yes, you can use FSR1 in between MIOS calles in your main program and in interrupt service routines w/o problems. The reason why I suggest FSR0 is not to confuse newbies too much...There is no MIOS task which uses FSR0, so it can be used without any danger.Best Regards, Thorsten. Quote Link to comment Share on other sites More sharing options...
TK. Posted November 20, 2003 Report Share Posted November 20, 2003 An enhanced version of this document plus some examples can now be found underhttp://www.ucapps.de/mios/mios_ram_handling.txtBest Regards, Thorsten. Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.