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.
I'm trying to debug LPC1768 program in uVision 4.14 using ULink2 via JTAG. I have following scenario: - main calls public function (LCD_Image) from other module (LCD) with four arguments (passed through R0-R3) - this public function ONLY calls private module function (DrawImage) and passes the arguments to it (not sure, why the registers are moved back and forth...)
890: void LCD_Image(int x, int y, const lcd_image_t *image, lcd_pixel_op_t pixel_op) 0x00002932 E8BD81F0 POP {r4-r8,pc} 891: { 0x00002936 E92D41F0 PUSH {r4-r8,lr} 0x0000293A 4604 MOV r4,r0 0x0000293C 460D MOV r5,r1 0x0000293E 4616 MOV r6,r2 0x00002940 461F MOV r7,r3 892: DrawImage(x, y, image, pixel_op); 0x00002942 463B MOV r3,r7 0x00002944 4632 MOV r2,r6 0x00002946 4629 MOV r1,r5 0x00002948 4620 MOV r0,r4 0x0000294A F7FFFCDE BL.W DrawImage (0x0000230A) 893: }
- DrawImage then declares some local variables on stack
uint8_t org_page = y >> 3; uint8_t org_page_offset = y & 7; /* LSB->MSB direction is rising y coordinate */ uint8_t org_column = x; uint8_t last_img_page = (image->height - 1) >> 3; uint8_t last_fb_page = MIN(org_page + last_img_page, LCD_PAGES - 1); uint8_t last_column = MIN(org_column + image->width - 1, LCD_WIDTH - 1); uint8_t fb_page; uint8_t fb_column;
- The first three ones are calculated, stored to the registers and correctly shown, second triad (last_img_page, last_fb_page, last_column) is stored to stack locations and shown incorrectly. (All show 0x1a, which is value stored on stack top. The uVision ignores the offsets from SP).
575: static void DrawImage(int x, int y, const lcd_image_t *image, lcd_pixel_op_t pixel_op) 0x00002306 E8BD83F0 POP {r4-r9,pc} 576: { 0x0000230A E92D4FFF PUSH {r0-r11,lr} 0x0000230E B085 SUB sp,sp,#0x14 577: uint8_t org_page = y >> 3; 0x00002310 9D06 LDR r5,[sp,#0x18] 0x00002312 F3C503C7 UBFX r3,r5,#3,#8 578: uint8_t org_page_offset = y & 7; /* LSB->MSB direction is rising y coordinate */ 0x00002316 9D06 LDR r5,[sp,#0x18] 0x00002318 F0050407 AND r4,r5,#0x07 579: uint8_t org_column = x; 0x0000231C 9D05 LDR r5,[sp,#0x14] 0x0000231E F00508FF AND r8,r5,#0xFF 580: uint8_t last_img_page = (image->height - 1) >> 3; 0x00002322 7855 LDRB r5,[r2,#0x01] 0x00002324 1E6D SUBS r5,r5,#1 0x00002326 F3C505C7 UBFX r5,r5,#3,#8 0x0000232A 9504 STR r5,[sp,#0x10] 581: uint8_t last_fb_page = MIN(org_page + last_img_page, LCD_PAGES - 1); 0x0000232C 9D04 LDR r5,[sp,#0x10] 0x0000232E 441D ADD r5,r5,r3 0x00002330 2D07 CMP r5,#0x07 0x00002332 DA02 BGE 0x0000233A 0x00002334 9D04 LDR r5,[sp,#0x10] 0x00002336 441D ADD r5,r5,r3 0x00002338 E000 B 0x0000233C 0x0000233A 2507 MOVS r5,#0x07 0x0000233C B2ED UXTB r5,r5 0x0000233E 9503 STR r5,[sp,#0x0C] 582: uint8_t last_column = MIN(org_column + image->width - 1, LCD_WIDTH - 1); 583: uint8_t fb_page; 584: uint8_t fb_column;
Have you anybody also noticed this behaviour? I'm also going to send this to Keil support.
Looks like no one else encountered these problems. Anyway, Keil fixed this rapidly, so if anyone would be interested, I suppose they will provide solution (patch or next-release-fix).
I have reported a similar issue to Keil about 2 months ago, and it was fixed in 4.14 (but I have encountered a variant of it ever since). Hopefully this resolves it!
I've been sent a patch which, after applying to 4.14, fixed my issue (all locals placed on the stack and not in registers are now correctly shown in watch). You might want to ask Keil to send it to you also (I would do it, but wouldn't like to break any "legal" stuff).