
SW Lab 7 Problem Description
Like other people reported here and there, I noticed the same problem in Experiment 2, SW Lab 7: the peripheral test application stuck at the point of showing message "Running Interrupt Test for psu_csudma..." (shown in the screenshot below).
However, we did a similar peripheral test application in Experiment 3, SW Lab 5. The only difference between them is: in lab 5, the build configuration is Debug while in lab 7 the build configuration is Release. In lab 5, the test completed successfully (as shown in the screenshot below).
What's the difference between Release configuration and Debug configuration? A couple of major differences: with and without compiler optimization AND without and with debugging information. With and without debugging information should usually NOT make any behavior change. Thus, I think the problem is due to the optimization for Release configuration and the Debug version has no problem just like Experiment 3, SW Lab 5. To confirm the problem doesn't exist in Debug configuration, I slightly modified the Create Boot Image settings regarding the folder path of application binary: before the modification, we use the binary from the release folder and then we changed it to the debug folder (Please refer the highlighted difference in the following two screenshots). The test result confirmed that the BOOT.bin using the debug version application code had successfully completed the whole test.
I didn't use the solution provided in the training materials, but in P2P: SW Lab 7 Road Block blog, nerdyupdates reported the provided solution basically hides the problem (maybe because the lab creator observed the same problem and couldn't find a solution). It is very common in embedded development that a working debug version of application code stops working after switching to a release version. Usually it's because of the compiler optimization.
A Correct SW Lab 7 Solution
Let's take a look at the highlighted line 244 shown below. What do you think the compiler optimization will do for that line? It will generate assembly code that reads the variable DsDone just once and uses this value to check the condition (i.e., DsDone == 0) forever. It will NOT update DsDone. The reason is because the compiler optimizer considers variable DsDone doesn't change at all in the context. However, as programmer, we know the variable has to change somewhere else. Otherwise, this is a dead loop which is definitely not the programmer's intention.
How can we let the optimizer know our intention? Here's the solution - adding keyword volatile before the declaration of variable DsDone (as highlighted below). Basically, the keyword tells the optimizer not do any optimization in any reference to variable DsDone.
Test result confirmed the BOOT.bin including the above modification had successfully completed the whole peripheral test. Hope I clearly explained the problem and the solution. Please comment with your feedback or questions.
Top Comments