Compilation optimization: I can't remember these pots!

When using KEIL to debug, you may encounter many inexplicable things, such as some locations that cannot be debugged with breakpoints, and some variables cannot be viewed. Many people's first reaction is: Is it because the compiler optimization level is too high?

But when you actually check the compilation level, you find that it is already the lowest optimization level.

Compiler optimization said: I don't take this pot back!

So what is going on here?

Question 1: Why can't break points in some places?

To clarify this problem, the first thing we need to know is, what does the debugger use to determine where breakpoints can be interrupted, and where cannot breakpoints?

I believe that experienced Taoists have already thought of it, that is, through the axf file.

A lot of information will tell you that in addition to the code, the axf file also contains debugging information. So what is this debugging information?

One point is the correspondence between C source code and assembly.

Only when the debugger (MDK) loads the axf file, can it know where the breakpoints can be broken, and how the breakpoints are related to the C language and assembly.

Therefore, each time MDK enters the debugging mode, it will not only download the code to the MCU, but also load the axf file to the debugger to debug at the source code level.

So back to the original question, where can I interrupt?

You can see the gray part on the left. Only the gray part is the breakpoint position. The debugger in other places does not recognize the execution code.

Therefore, we can determine whether a macro is in the open state by this point.

For example, if a macro prints LOG(), if printing is enabled, it must be dark gray next to it, otherwise it means that there is no code to execute in this line.

At the same time, we can also determine whether your current axf file is the latest.

For example, a piece of code is modified, but after you enter the debugging mode, you find that the gray part is inconsistent with the actual one, such as this:

The first thing you need to do is to compile -> download. The second is to check whether your compilation optimization level is correct.

Compilation is to update the modification to the axf file, and download is to update the code of the single-chip microcomputer. After entering the debug mode, the code of the single-chip microcomputer corresponds to the newly loaded axf file.

Of course, for the sake of simplicity, the general approach of Osprey is to directly compile -> debug. When the compilation is completed, because MDK detects that the axf file has been updated, it will automatically re-download the new code to the microcontroller (this function is the default configuration, of course, it does not need to download), and then automatically load the new axf file to the debugger, and enter Debug mode.

Sometimes, you will find that you can quickly enter the debugging mode because the debugger detects that the axf file has not been updated, so it will not be downloaded automatically, which saves a lot of time.

So this pot is probably because you forgot to compile because you modified the code. You should recite it yourself.

Question 2: Why can't some variables be viewed through watch?

Is it really because the optimization level is too high?

In this case, first see if your code is too simple.

Because this function code is very simple, the local variable has only one temp (and there is no need to take the address of this variable), and there are many free registers, so the compiler directly allocates this variable to the register, so this temp variable is the R4 register. This can speed up the running speed.

Therefore, this pot cannot be backed by compilation optimization, it can only be said to be the normal behavior of the compiler, but you don't understand it.

And when your function is very complicated (or explicitly addressing local variables), the compiler has to store some local variables in the stack, so that you can get the address of local variables just like global variables Up.

But MDK is still very smart. In this example, the watch window can view the value of temp, but if the program leaves this function, the value must be no longer available. If you don't believe it, you can try.

The above are the knowledge points that Osprey wants to share. I hope it will be helpful to all fellow Taoists. See you next time.


1. Make a reminder | Don’t miss the GD32 Arm MCU Internet of Things developer online course!

2. Should I participate in training when learning embedded?

3. Apple M1 heralds the rise of RISC-V?

4. Thinking about the startup part of RISC-V~

5. You may not understand how ARM handles exceptions!

6. Some people say that these languages ​​are going to be eliminated!

Disclaimer: This article is reproduced online, and the copyright belongs to the original author. If you are involved in copyright issues, please contact us, we will confirm the copyright based on the copyright certification materials you provide and pay the author's remuneration or delete the content.

Guess you like

Origin blog.csdn.net/DP29syM41zyGndVF/article/details/111877802