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.
Hallo, I may have hit a bug in CX51 Ver 7.06. If a far variable is passed as an argument to printf function; it fails. I wrote this program:
#include <Philips\reg51m.h> #include <stdio.h> #pragma USERCLASS (HDATA=MYRAM) far long int l ; void main () { T2CON = 0x34 ; RCAP2H = 0xff ; RCAP2L = 0xdc ; SCON = 0x70 ; TI = 1 ; l = 100 ; printf("simple text message\n") ; printf("value = %ld\n",l) ; printf("value = %ld\n",12345678L) ; }
; printf("simple text message\n") ; ; SOURCE LINE # 16 MOV R3,#BYTE2 (?SC_0) MOV R2,#HIGH (?SC_0) MOV R1,#LOW (?SC_0) LCALL _printf ; printf("value = %ld\n",l) ; ; SOURCE LINE # 17 MOV R3,#BYTE2 (l) MOV R2,#HIGH (l) MOV R1,#LOW (l) LCALL ?C?LLDPTR MOV ?_printf?BYTE+06H,R7 MOV ?_printf?BYTE+05H,R6 MOV ?_printf?BYTE+04H,R5 MOV ?_printf?BYTE+03H,R4 LCALL _printf ; printf("value = %ld\n",12345678L) ; ; SOURCE LINE # 18 MOV R3,#BYTE2 (?SC_21) MOV R2,#HIGH (?SC_21) MOV R1,#LOW (?SC_21) MOV ?_printf?BYTE+06H,#04EH MOV ?_printf?BYTE+05H,#061H MOV ?_printf?BYTE+04H,#0BCH MOV ?_printf?BYTE+03H,#00H LJMP _printf
Do your 'far' variables work elsewhere?
Hallo Mr.Neil, Do your 'far' variables work elsewhere? Yes! no other problem with far variables.
Hello, In september i wrote a program using FAR variables on a TRISCEND E5, and for debug purpose i use printf, and i have NO problem, except that LX51 make wrong code packing. Keil has corrected that. So i use Cx51 V7.07a (not 7.06). And if you want to make a test, disable linker code packing... sincerely Christophe.
Dear Mr.Christophe, It is interesting to note that you did not have problems with printf and far variables. What processor did you use? I am using MX. Besides, the assembler code seems to be wrong (at least to me). The second and third printf are very similar, but the code is different. Consider the third printf (which works ok): pointer to format string is loaded in R1,R2, and R3. the long int argument (12345678L) is copied to (?_printf?BYTE+03H), (?_printf?BYTE+04H), (?_printf?BYTE+05H) and (?_printf?BYTE+06H). This works ok. Now compare this with the second printf: the long int argument (l) is copied to (?_printf?BYTE+03H), (?_printf?BYTE+04H), (?_printf?BYTE+05H) and (?_printf?BYTE+06H). But the pointer to format string is NOT loaded in R1, R2, R3. And the second printf does not work (prints nothing). If I assign the far var l to another non-far variable and then pass it to printf, then it works very well. This is the code generated:
; l2 = l ; ; SOURCE LINE # 19 MOV R3,#BYTE2 (l) MOV R2,#HIGH (l) MOV R1,#LOW (l) LCALL ?C?LLDPTR MOV l2+03H,R7 MOV l2+02H,R6 MOV l2+01H,R5 MOV l2,R4 ; printf("value = %ld\n",l2) ; ; SOURCE LINE # 20 MOV R3,#BYTE2 (?SC_21) MOV R2,#HIGH (?SC_21) MOV R1,#LOW (?SC_21) MOV ?_printf?BYTE+06H,R7 MOV ?_printf?BYTE+05H,R6 MOV ?_printf?BYTE+04H,R5 MOV ?_printf?BYTE+03H,R4 LCALL _printf
Dear Mr.Christophe, How to disable "linker code packing" ??? I could not find such an option. Meanwhile, I have another observation whiich further indicates that it is a bug. I changed the optimization to level 7 (earlier, it was the default level 8). And see what difference it made to the generated code:
; printf("value = %ld\n",l) ; ; SOURCE LINE # 18 MOV R3,#BYTE2 (?SC_21) MOV R2,#HIGH (?SC_21) MOV R1,#LOW (?SC_21) MOV R3,#BYTE2 (l) MOV R2,#HIGH (l) MOV R1,#LOW (l) LCALL ?C?LLDPTR MOV ?_printf?BYTE+06H,R7 MOV ?_printf?BYTE+05H,R6 MOV ?_printf?BYTE+04H,R5 MOV ?_printf?BYTE+03H,R4 LCALL _printf
Hello, My processor isn't a MX device. it's a 8051 with extended memory areas. For my test i use the version 7.07a. you can download it to the upgrade page on keil website. http://www.keil.com/update/c51.htm In the release note keil talk about far pointer and MX processors, in different manner, but your problem maybe solved with this release. Did you tried to make a step by step run in asm in this following line ? Just to check that all is ok and check what line goes wrong... (Like wrong address calculated by linker or another mistake... ) ? Christophe.
Hallo, Thanks! I will try to download the upgrade. I did not debug, but the error is obvious in the assembler code generated. The pointer to format string is simply not passed to printf function. As a result, there is no output. mk