I have searched the entire knowlege base and have not found an answer to a specfic question.
how do you CAST a generic pointer to a memory specific pointer.
There are examples in the manual for casting a memory specific pointer to a generic, but not the other way around.
Specifically, I have an array of generic pointers to structures. the array is located in xram. I have found a bug in the compiler where in it gets confused as to what kind of pointer it is dealing with (more later). If I could type cast the pointer to generic it would most likely fix the problem.
The problem I'm currently up against, is the following where the compiler only generates the 0xFF identifier for a generic pointer when assigning a generic pointer read out of an array, to a generic pointer. to wit:
Below, is an abbreviated source. I'm not sure if this will exhibit the problem if compiled or not, but my code that uses the same lines of code below fails. Specfically in this example, at address 37F The compiler fails to copy a generic pointer into another generic pointer. All it does is load the memory type specifier into the pointer. This is a 7.5 compiler.
The target part is a silabs 040
very strange problem with indexing and pointers. Given the following structures, the code below breaks.
Sample values as examined in the silabs debugger show
in xdata, there is an array of pointers that is copied from flash. After the copy the table looks something like this 32B 32C 32D 32E 32F 330 0xFF 0x02 0x01 0xFF 0x0A 0xB8 the result of the code is that
current_treatment winds up with the following in it. 0xFF 00 00 00
the table is at 0x032B current_mode = 1;
Here is the listing code. As you can see, this does not copy the pointer, just the type. Something is clearly wrong here. In other versions of this, that I was debugging prior to compiling this one, I was seeing it index by 2, and pick up the values that way, which resulted in the current_treatment holding 0x01FF0A2B which is also wrong.
0361 7800 R MOV R0,#LOW current_mode 0363 E2 MOVX A,@R0 0364 FF MOV R7,A // here R7 = 1 0365 33 RLC A // double it 0366 95E0 SUBB A,ACC // results in 0 ! 0368 FE MOV R6,A // R6=0 0369 EF MOV A,R7 // ACC now = 1 036A 25E0 ADD A,ACC // ACC now = 2 (should be 3) 036C FF MOV R7,A // R6R7 now are 0002 036D EE MOV A,R6 // since the value is 1, there will be nothing rotated into R6 036E 33 RLC A 036F FE MOV R6,A // R6R7 now are 0002 0370 7400 R MOV A,#LOW treatments // puts 2B into a 0372 2F ADD A,R7 // adds 2 to it resulting in 2D 0373 F582 MOV DPL,A // dp = 002D 0375 7400 R MOV A,#HIGH treatments // this puts 03 into A 0377 3E ADDC A,R6 // adds 0 to it resulting in 03 0378 F583 MOV DPH,A // dptr now is 032D 037A A3 INC DPTR // increments to 032E which is CORRECT 037B E0 MOVX A,@DPTR // picks up the 0xFF 037C 900000 R MOV DPTR,#current_treatment 037F F0 MOVX @DPTR,A // saves 0xFF. and never picks up anyting else ; SOURCE LINE # 2367 0380 ?C0034: ; SOURCE LINE # 2375 0380 120000 R LCALL LCDClearScreen ; SOURCE LINE # 2376 0383 120000 R LCALL L?0870
struct treatment_table idata * current_treatment; struct treatment_table xdata * scroll_treatment;
code struct treatment_table user_control= { 1, /* only one step */ 0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,0xff,0xff,0xff,/* infinite time */ }; code struct treatment_table single_pulse_zero_d= { 1, /* only one step */ 0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,0xff,0xff,0xff,/* infinite time */ };
struct treatment_table xdata * treatments[]= { &user_control, // This is a holder for the user mode. 8-12-08 &single_pulse_zero_d }; // // No memory specifier, means that this will be a generic pointer table, so it can point to xram OR code. // the compiler takes care of this, though it generates much slower code 8-21-08 // code struct treatment_table * treatment_tbl[]= { &user_control, // This is a holder for the user mode. 8-12-08 &single_pulse_zero_d };
unsigned char current_mode; main() { current_mode=1; // // copies the treatment table from flash into xram. I can't make the keil compiler do this automatically for me. // when xdata is examined, there is a table of GENERIC pointers there. Each pointer is 3 bytes long, and starts // with an 0xFF which is correct, it says that it is a generic pointer to code memory. // memcpy(treatments,treatment_tbl,sizeof(treatments)); // this works just fine // // This however fails. It indexes treatments by 2 bytes, rather than 3 bytes, so it gets bogus pointers into current // treatment // current_treatment is GENERIC pointer. So indexing into an array of generic pointers and assigning one to // current_treatment SHOULD index by 3's and put the entire pointer there.
current_treatment=treatments[current_mode];
}