This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

How to view variables when stepping through .src files

Hello,

I have a variable of type Nat16 (unsigned int) which is called PulseWidth.

In the function that fills the variable PulseWidth, there's some assembler code (#pragma asm/endasm included in the .c file), so I have to indicate to the compiler to generate an assembler src file and to assemble this src file too.
Because of that, I have to open the corresponding .src file to put breakpoints (apparently, I can't put breakpoints in the 'normal' .c file).

When the breakpoint is hit, I would like to see the content of this variable in the watch window #1. However, I only see the value of one byte of this variable iso the whole variable. I have to open the memory window after looking where in the memory this variable is located, and only then I can see the two bytes (so, the 'complete' variable).

My question: how to show the complete variable when you have hit a breakpoint in a .src file? Is there something like PulseWidth and PulseWidth+1 to be defined in the watch window? The example I gave just now certainly does not work, because if you put PulseWidth+1, the watch window simply adds 1 to the value of PulseWidth. Is there some other way to represent the second byte (or better, the whole variable at once)?


Rgds,

--Geert

PS.: uVision version 2.33, C-compiler version 7.03.

  • Hi Geert!
    I had the same problem a year or two ago. So, the answer was not to be so curious. And God save you to call it a bug - Jon Ward will never allow it.
    M.

  • I do not use/know about the simulator; however by emulator does not show local variables in assembly files. Glad, to hear that the problem exist in the simulator, that help me where to point the finger

    Erik

  • Mikhail???

    What do you mean: not to be so curious???

    I know, curiosity killed (sometimes) the cat... But I've always been teached that curiosity is a healthy disease, if you know what I mean.

    This phenomenon, though, is quite annoying and I should not know why Jon would not allow me to call it --at least-- a nasty thing (= synonym for bug???).

    How did you continue in your case? Also look up where the variable is located and then chase it in the memory window?

    Rgds,

    --Geert

    PS: Erik, you see IDE is not (always) the end of the world!!! Although we can't really complain (I know too we're lacking a CodeWright interface,I know...).

  • Geert,
    Unfortunately, I was forced to make a choice: either to use asm...endasm or see variables in the watch window. I've chosen the first option.
    Yes, the only way to see what's going on is the memory window - a good and probably useful exercise, anyhow.
    As for Jon - I can't answer for him, but when I called it a bug he looked frustrated and explained me two things: that I didn't understand the difference between the .src and .obj files (I never even wanted to understand it) and that his car (Ford Explorer at that time) was not sufficiently dynamic. Anyhow, no other explanation.
    Regards,
    M.

  • Sorry Geert, I fail to see the connection
    PS: Erik, you see IDE is not (always) the end of the world!!! Although we can't really complain (I know too we're lacking a CodeWright interface,I know...).
    I am referring to ICE

    Erik

  • The problem is in the way C51 does inline assembler.

    To use inline assembler, you have to specify the SRC directive. This means that the C51 Compiler does not generate any object file; since it doesn't generate an object file, it can't put any debug information into it.

    The object file is, instead, generated by the Assembler; so the only debug information you get is Assembler debug info.
    The Assembler doesn't know anything about 'C' ints, longs or anything else; all it knows about your PulseWidth symbol is that it's the address of a byte - all the work to do with 16 (or more) bit arithmetic is generated by the compiler using offets from that byte

    As has already been said: if you want to debug in 'C', you'll have to write in 'C';
    If you want to write in Assembler, then you'll have to be prepared to debug in assembler!

    Have you looked at the DEFINE debugger command?
    Perhaps you could put some DEFINEs into an initialisation file so that the debugger knows what size you want your variables?

  • The problem is that when you use the C compiler to generate an assembler SRC file, the obj file is generated by the assembler (not the C compiler). And, all the rules that apply to assembler files now apply to the object file.

    In assembler, there are no typed variables (like there are in C). In fact, there are no variables in assembler. There are only labels with either defined storage or with reserved storage (for 2 bytes in the case of an int).

    So, when you watch a "variable" in an object file that was created by the assembler, you are actually watching the label. And, the debugger has no idea how big that object is (since there is no type).

    The Keil debugger allows you to read a type from a starting address. This is done using the _R*** functions. For example, if your variable (err, label) is named xyz and it is an unsigned int, you can use the _rword function to display its value. For example:

    _rword(&xyz)

    returns the word value stored starting at the address of xyz.

    You may enter _rbyte in the command window or you may add it to the watch window. For example:

    ws 1, _rword(&xyz)

    Jon

  • What I meant by this, Erik, is that also with an IDE you can indeed have problems seeing what you want to see (or just not...).
    And I gave a kind of a 'wink' to you, because I read (and understood) on other forums that you are one of the (maybe many) developpers that would like to use another powerful editor from within the Keil environment. That's all :-)

    Rgds,

    --Geert

  • Just another example of the side effects from not accepting assembler statements as part of C source without the Texas two step, sorry, German product, der Lancier.

    Erik

  • The problem is understandable when using separate command-line tools, but one might have hoped that an Integrated (sic) Development Environment would be able to overcome this limitation from its exalted, Integrated (sic) overview position...

  • The IDE is not part of the problem. It could be made part of the solution, but only at the considerable cost of blocking out all users who want to use other IDEs than the official one from Keil from reaping the benefits.

    The correct way of handling this problem is the way Unix compilers like GNU C have been doing it for ages:

    1) The assembler must accept special statements that generate C-level debug information, as part of its input.

    2) Using inline assembly with annotation describing all its side effects for the compiler, so inline assembly doesn't have to force optimizations off.

    3) Drop direct .obj file generation by the C compiler. This creates additional load to support two different output mechanisms. I.e. it creates bugs.

  • 1)I am totally in agreement.
    2)I have used '51 compilers where this was not necessary
    3) I do not understand

    Erik

  • 3) E.g. pass the result of the compiler off to the assembler. The compiler only generates "marked up" assy. output.

  • "so inline assembly doesn't have to force optimizations off."

    it doesn't anyway:
    http://www.8052.com/forum/read.phtml?id=25467&top=

  • 3) means that currently C51 has two at least somewhat independent output generators. One outputs object code directly (including debug info), the other generates assembly text (with lots of human-readable comments, but not machine-readable debug info).

    This creates maintenance problems for Keil --- every once in a while, a modification will be made that only works for one of the output generators. In the relatively short time I've been participating here, I've already seen this kind of bug mentioned a few times, so it's for real.

    The plan I outline would drop the direct code generation completely, and rely only on assembly language output. This would make the work for Keil simpler in the long run, and kill off this type of bugs for good.

    The alternative would be to find a method that allows inline assembly code without causing the whole module to go through the assembler. But I strongly doubt this can work in a sufficiently generic way. The catch is that the tools would now have to be able to *read* assembly language and understand their every consequence.