Hi, I've got exactly the problem as in this thread: http://www.keil.com/forum/docs/thread171.asp
That was 6.5 years ago! Have you heard of a fix of some kind for this problem. The workaround is very complex and I'd rather not use it. In my program, the EXTS instruction sometimes works and some other times is ignored and I can't find out why.
I've got exactly the problem as in this thread:
Not to be disrespectful but are you really sure?
It would be best to post a snippet of code that shows behavior that you are experiencing. I can show you an example which works fine from a trap routine using the EXTS instruction sequence. It is also important not to get hung up on the disassembler syntax for the instruction.
So here is my code snippet as an example.
void main(void) { /* cause a class B trap */ volatile int i = *(unsigned int *)(0x8001); for(;;); } void Class_B_trap (void) interrupt 0x0A { trapRegister = TFR; *((volatile unsigned int huge *)0xf1236ul) = 10; /* add your code here */ while (1); /* end-less loop */ }
Note that you will write "10" to absolute address 0xF1236. But when looking at the disassembly you think it is using DPP0. Is not, this is just the way the the instruction is decoded (by the disassembler not by the real device or simulator)!
00000158 0DFF JMPR CC_UC,SOFTBRK_trap(0x158) 88: void Class_B_trap (void) interrupt 0x0A { 89: 0000015A C6030300 SCXT DPP3,#0x0003 0000015E ECF4 PUSH R4 90: trapRegister = TFR; 91: 00000160 F6D60082 MOV DPP2:0x0200,TFR 92: *((volatile unsigned int huge *)0xf1236ul) = 10; 93: 94: /* add your code here */ 00000164 E0A4 MOV R4,#0x0A 00000166 D7000F00 EXTS #0x000F,#1 0000016A F6F43612 MOV DPP0:0x1236,R4 95: while (1); /* end-less loop */ 0000016E 0DFF JMPR CC_UC,0x00016E
To show another example, I will change the absolute address to 0xFD234. Now have a look you will see that the disassembler decoded DPP3 but again it is not using this as you have the EXTS instruction right before telling it to treat the next instruction as an extended segment sequence. EXTS #0x000F,#1
00000160 F6D60082 MOV DPP2:0x0200,TFR 92: *((volatile unsigned int huge *)0xfD236ul) = 10; 93: 94: /* add your code here */ 00000164 E0A4 MOV R4,#0x0A 00000166 D7000F00 EXTS #0x000F,#1 0000016A F6F436D2 MOV DPP3:0x1236,R4
Hope this helps.
Thanks for your answer. Yes I am sure the EXTS instruction is not working bacause I am using a monitor to read the values of the registers. The problem is it is working in a project and not in an other project. I am aware of what DPPx mean in an EXTS instruction, it is the first thing I's checked in the manual.
Here is my code:
61: if(StructTrap.CrashDetectorActive) 62: { 00016886 D7000C00 EXTS #0x000C,#1 0001688A F3F89C82 MOVB RL4,DPP2:0x029C 0001688E EA201C6A JMPA CC_Z,0x016A1C 63: if (ILLBUS == 1) 64: { 00016892 9AD60C00 JNB 0xD6.0,0x0168AE 65: EEPROM_value = 0x80; 00016896 E6FE8000 MOV R14,#0x0080 66: ILLBUS = 0; 0001689A 0ED6 BCLR 0xD6.0 67: StructTrap.NbOftraps[ILLBUS_]++; 0001689C D7000C00 EXTS #0x000C,#1 000168A0 F3F89E82 MOVB RL4,DPP2:0x029E 000168A4 0981 ADDB RL4,#1 000168A6 D7000C00 EXTS #0x000C,#1 000168AA F7F89E82 MOVB DPP2:0x029E,RL4 68: }
I'm running the code in debug mode with a monitor so I can see exactly what is in the RAM and the registers. The first EXTS instruction is not working and the value of RL4 is set to what is at address 0x829C and not what is at address 0xC829C. That mean the if executed even if the variable CrashDetectorActive is set to zero! Then the 2 other EXTS instructions are working fine and the variable at 0xC829E is incremented as expected. If I copy the same code in other project, its working fine. Note: it doesn't change anything if the global variable is part of a structure or stand alone. Nate2: the JUMPA instruction is not part of the EXTended segment and so it not the branch problem.
Given that the opcodes are in the actual code but the device does not execute them correctly I would suggest that you contact the micro vendor directly for further investigation. Perhaps you have discovered an errata with the device.
After one week working on this problem, I finaly found the cause and one solution. The instruction EXTS is designed so that the EXTended sequence is terminated if a class B trap occurs. Here is the warning text in the instruction set manual: "CAUTION: When a Class B trap interupts an ATOMIC or EXTended sequence, this sequence is terminated, the interrupt lock is removed and the standard condition is restored, before the trap routine is executed! The remaining instructions of the terminated sequence that are executed after returning from the trap routine will run under standard conditions!"
For this mater, in the description of this instruction, there is:
DO WHILE ((count) != 0 AND Class_B_trap_condition != TRUE)
So what happens when this instruction is used in a class B trap function? Aparently, nothing is specified in that case. And according to this code, it is just ignored! And that is what I got, most of the time. I have no idea what Class_B_trap_condition means but acording to the tests I've done, it seems to mean "all the class b request flags in TFR are 0." Therefore, once the bits have been cleared, the instruction EXTS is working fine. My solution was then to make a copy of the TFR register, to clear it, and then to work on the copy.
I've just checked on the latest version of the instruction set manual and this has been clarified by the following text: "Within a ClassA or ClassB trap service routine EXTend instructions do not work (i.e. override the DPP mechanism) as long as any of the ClassB trap flags is set." However, I've seen one example where it did work and that confused me. That just means "do not work" should be understand "should not be used".
So my conclusion is: allways check that you have the latest version of the manual!