During this period of time, I have been debugging the Flash program of DSP6713, and now I am still confused about the Flash program.
On that day, I was very Happy to find that the Flash LED was successfully written to Flash, and then I thought everything was okay ......
On that day, I successfully wrote a program of more than kb, and thought that this time should be OK ......
That day, I wrote a Timer interrupt program, burned it to Flash, but it crashed ......
On that day, an algorithm that runs smoothly on RAM (the algorithm calls the atan function of CCS) and crashes after the algorithm is written to Flash ......
On that day, I began to think about what caused a program running happily in RAM to run so badly in Flash-a large number of phases.
"Keep it safe and cherish", and cherish the opportunities for discovering bugs. Therefore, I would like to sum up some discussions about the normal operation in RAM and the failure to run after Flash.
Check the interrupt vector table
The interrupt vector table contains all the interrupt entries. There are two ways to ensure that the interrupt works normally when Flash is burned. For details, see section 5th of general method for Flash writing on TMS320C6713.
Check for hidden memory errors in the program.
In many cases, programs in RAM can run normally when the array is out of bounds, but running after Flash writing will crash or the program will run.
For example, defining an array,
int x[5];
You can use statements like x [5] = 10 to run correctly in a RAM program, or on a PC. However, after writing the program to Flash, the DSP will definitely say goodbye to you!
Therefore, check carefully for Array out-of-bounds and pointer operations in the program code. In the DSP program, we are determined not to use the malloc function in the C library function. If you need to dynamically allocate memory, you can write one by yourself or use an embedded operating system such as uCOS II or DSP/BIOS.
Avoid using triangle and log functions in math. h whenever possible.
I don't know why, or maybe it is caused by incorrect methods for using the atan function. In an initial program of mine, I calculated atan (x) directly in this way,
Float x, y;... y = atan (x); // The range of x is [0, 1.7].
No problems have been detected in RAM and in PC.
After Flash writing, it is not a dead end, but when the program runs to the atan function, it will be stuck for a long time and then run down.
Is the atan operation efficiency in math. h too low? But why does it run in RAM? This is not clear yet.
So I thought of a trick. Where I want to use functions such as trigonometric function and log, I used the lookup method to replace the library function. In the case of high precision requirements and limited storage space, you can use the lookup table + interpolation method.
The following is an improvement method for computing atan,
/* Table of determine ATAN (x) */const float atan_tb [] = {// accuracy (0.020) 0.00, 1.15, 2.29, 3.43, 4.57, 5.71, 6.84, 7.97, 9.09, 10.20, 11.31, 12.41, 13.50, 14.57, 15.64, 16.70, 17.74, 18.78, 19.80, 20.81, 21.80, 22.78, 23.75, 24.70, 25.64, 26.57, 27.47, 28.37, 29.25, 30.11, 30.96, 31.80, 32.62, 33.42, 34.22, 34.99, 35.75, 36.50, 37.23, 37.95, 38.66, 39.35, 40.03, 40.70, 41.35, 41.99, 42.61, 43.23, 43.83, 44.42, 45.00, 45.57, 46.12, 46.67, 47.20, 47.73, 48.24, 48.74, 49.24, 49.72, 50.19, 50.66, 51.12, 51.56, 52.00, 52.43, 52.85, 53.27, 53.67, 54.07, 54.46, 54.85, 55.22, 55.59, 55.95, 56.31, 56.66, 57.00, 57.34, 57.67, 57.99, 58.31, 58.63, 58.93 }; y = atan_tb [(uint16_t) (x * 100)> 1];
You can use Matlab to create an atan table. In situations where interpolation is required, for example, the accuracy of atan_tb is 0.02, and we want to make atan 0.01 accurate in a few cases, if you create a table with 0.01, the data storage capacity of the table will be doubled. This is the method that we can use Interpolation on the basis of the 0.02 precision table.
For example, to calculate atan (0.03), we can find atan (0.02) and atan (0.04) in the table. If only linear interpolation is used
atan(0.03) = (atan(0.02) + atan(0.04)) / 2
Check the program logic.
I once wrote a program similar to the following,
Uint8_t dir; // encode the lower 3 bits. The switch below decodes int dist_switch (int a, int B, int c) {int max_dist; int min_dist; int result = 0; switch (dir) {case 0x00: break; case 0x01: max = a; min = B; break; case 0x02: max = a; min = c; break; case 0x03: max = B; min = a; break; case 0x04: max = B; min = c; break; case 0x05: max = c; min = a; break; case 0x06: max = c; min = B; break; case 0x07: break; default: break;} result = max * 100/(min + max); return result ;}
At first glance, there is no syntax problem, and the switch break statement is also added.
The problem is that the Code is performed at the lower three digits of dir, and the maximum number of codes is 8. In fact, only six types of codes are used, and break is used for the other two types of codes in the switch. The problem arises. What if my dir = 0x00? Of course, the switch statement is okay. The problem lies in the Next statement:
result = max * 100 / (min + max);
Dir = 0x00 does not assign values to max and min, and there is no value elsewhere. Therefore, max and min as local variables will be a random value, which can be run in RAM, but after being written to Flash, the uncertainty of such local variables directly leads to Flash downtime.
Therefore, for the logic problems of switch and if... else..., you cannot only focus on their scope. Check their context carefully.
Please take special care of Division operations in the program
In x = a/B, if B may be 0, such a program is burned to Flash, which will directly cause the DSP to crash. If possible, convert the division operation to the shift operation.
For example, to calculate y = x/0.02, the conversion method of a number is:
y=(uint32_t)(x*100)/2=((uint32_t)(x*100) >> 1);
It can also be better to replace * 100 with shift,
uint32_t tmp_x = (uint32_t)x;y = ((tmp_x<<6) + (tmp_x<<5) + (tmp_x<<2)) >> 1;
In this way, you will no longer see Division operations.