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.
Hi all, I try to use the simulator with a code that contains struct or union, but it doesn't seem to see members. Here is an example code: struct chuf { unsigned char hi; unsigned char lo; }; union { struct chuf chi; unsigned int both; } buf; void main(void) { buf.chi.hi =5; buf.chi.lo =1; buf.both =0x1122; while (buf.both) buf.both>>=1; } When I try to see something like buf.both, it shows error 10. By the way, where can one see the list of simulator errors? When I look for just buf, it shows the first byte of this union. At the same time, within the memory it seems to work right. Can anything be done about it? Thanks, Michael.
It works fine for me using the Eval version of uVision v2.07 and C51 v6.03. What versions are you using? Does the message say anything other than just, "error 10?" Note that there is a bug in uVision2: the debug command line is supposed to be case-insensitive, which seems to be true for everything except structure member names! eg, buf.both and BUF.both both work, but buf.BOTH and BUF.BOTH both give:
*** error 54: undefined struct/union member
struct chuf { unsigned char hi; unsigned char lo; }; union { struct chuf chi; unsigned int both; } buf; void main(void) { buf.chi.hi =5; buf.chi.lo =1; buf.both =0x1122; while (buf.both) buf.both>>=1; }
Hi, Andrew, Thank you for your help. I use uVision V2.10 with C51.exe V6.10 and S8051.dll V2.10. In fact the error is: *** error 52: left side of '.'requires struct/union. And when I try to put the same thing into the watch window, it is ??????????. Do you think it's a bug, or I do something wrong? Michael.
I've now tried it with a full C51 v6.12b, BL51 v4.13, and uVision v2.12 and it still works fine: If I type "buf.chi.hi" or "buf.chi.lo" or "buf.both" at the debug prompt I get the expected result. What exactly are you typing when you get this message?
I type exactly what you type. Could it be anything in target options? By the way, where have you taken version 6.12? I thought I had the latest update. Michael.
Andrew, I've got it! We both were right. It works fine while assembler options of the file are turned off and it doesn't work at all when they are on. It seems to be one more Keil bug. Thank you. Michael.
Could you clarify precisely what you mean by "assembler options of the file are turned off?"
When assembler insertions are used in a C source file, it will not be compiled unless you turn on certain options for this file. In the file list, you click the file with the right mouse button and you have, among others, two options: Generate Assembler SRC File and Assemble SRC File. They should be turned on. I don't know the exact result of this action. It seems to me that assembler file is produced in any case, whether you use assembler insertions or not. But when these two options are turned on, you can use assembler insertions, but cannot use simulator to see structure or union members. When the are off, it's the opposite: you can see members, but you can't use assembler. Michael.
This doesn't sound like a bug to me. Here's why... If you create a C file and you compile it with the C compiler and generate an OBJ file, all line number information and symbolic information are stored in the OBJ file generated by the C compiler. If you create a C file and you compile it with the SRC option, the C compiler generates a .SRC file. The SRC file is an assembly source file. And, when you assemble the SRC file (with the assembler) you get an OBJ file generated by the assembler. Now, the OBJ file from the assembler references line numbers (from the SRC file -- NOT from the C file) and it references symbol information (again from the SRC file and NOT from the C file). The problem is that there is no assembler equivalent to the C structure. So, structure accesses in C that are compiled to a SRC file are REALLY accesses to the offset from the beginning of a symbol. And...that's why you only see 1 byte if you try to display a C struct that has been compiled to a SRC file and then assembled with the assembler. I guess one question is: Is this a bug? The answer is NO, because this is the way we designed it. The assembler is not supposed to generate symbol information and line number information that relate to the C source file. Jon
Jon, That's fair comment, but this is a commonly misunderstood area. I think Keil would do well to explain this thoroughly in the manual. After all, most people use #pragma ASM to just insert just a small snippet of assembler into a mainly-'C' source file (and this is the way it's presented in the manual). Perhaps it would help if the interleaved 'C'/Assembler listing were more accessible? How do other compilers cope with source-level debug for inline assembler?
Jon Ward has explained what's happening. You didn't mention that you were going via Assembler in your original post - which is why I couldn't reproduce your problem!
Perhaps it would help if the interleaved 'C'/Assembler listing were more accessible? I'm not sure what you mean. The .SRC file includes both the C and generated assembly code interleaved. How do other compilers cope with source-level debug for inline assembler? This is really implementation-defined. However, I guess that other C compilers (that generate assembler output instead of .OBJ output) insert assembler directives that say to the linker, "Hey, the following lines of assembly refer to line number xxx in the C source file yyy.c" However, if you go start hacking on the assembler output, I would think that it's possible to introduce subtle synchronization errors between the assembler and C source. Jon
Andy: "Perhaps it would help if the interleaved 'C'/Assembler listing were more accessible?" Jon: "I'm not sure what you mean. The .SRC file includes both the C and generated assembly code interleaved" Sorry, I was thinking of the assembler listing produced by the CODE directive. Oops! However, I note that the .SRC file duplicates the assembler code between the ASM and ENDASM - once as a comment (representing the 'C' source) and again as "real" assembler; eg,
; #pragma ASM ; ; EXTRN CODE (m_main) EXTRN CODE (m_main) ; ; MOV A,#LOW( m_main ) ; MOV A,#LOW( m_main ) ; ; MOV wait_return_address_low,Acc ; MOV wait_return_address_low,Acc ; ; MOV A,#HIGH( m_main ) ; MOV A,#HIGH( m_main ) ;
You don't call it a bug, I do. You explain me the difference between .obj and .src files. But it is your interior problem and your virtual reality - it wasn't I who chose your implementation. What I see as a user is that writing code using both C and assembler in the same file is a common practice and your simulator doesn't provide a mean to see what is going on in the controller - that is why I call it a bug. Michael.
I found a bug in my Ford Explorer. It doesn't accelerate from 0 to 60 MPH in 4 seconds. :-) Jon
You explain me the difference between .obj and .src files. Actually, I explained why you can't see C structures when you compile the C file and generate assembly source. I guess I wasn't very clear on that point. Maybe this makes more sense. Rule 1. The Keil A51 Assembler does not have a struct data type. Therefore, structures in assembly must be implemented as an array of bytes. When you use the debugger to view these assembly structures, only the first byte will be displayed. This applies EVEN IF you start with a C file and compile it using the SRC directive. The output from the C compiler is an assembler source file (.SRC) which you must then assemble using the A51 Assembler. And, Rule 1 applies. The assembler works this way by design. Jon