But what happened today proved me wrong.
I have a product code on hand, and the code volume is very large. The program does not run well, so I plan to optimize the code. The larger the code volume, the more areas that can be optimized. For 8051, the memory access speed of the data area (0~7FH) inside the chip is the fastest. Direct access can read and write with one instruction. Although the idata area (80H~FFH) is still a memory area, it can only be accessed indirectly because the address allocation overlaps with the special register SFR. It can only be read and written with two instructions, and the speed is slightly slower. The external memory xdata area (0~7FFFH) must be accessed using the DPTR pointer, and the speed is the slowest. Obviously, the principle of optimization is to try to prioritize the variables that are frequently read and written in the data area, then the idata area, and finally the xdata area.
8051 has 4 physical memory spaces
On-chip ROM and off-chip ROM. On-chip RAM and off-chip RAM.
The address space of the off-chip program memory ROM is 64kB, and the off-chip data memory RAM also has a 64kB addressing area, which overlaps with the ROM in address.
The 8051 microcontroller uses different signals to select ROM or RAM. When fetching instructions from the external ROM, the selection signal PSEN is used, and when reading and writing data from the external RAM, the selection signal PSEN is used.
The read RD and write WR signals are used to select, so there will be no confusion due to address overlap. [page]
On-chip data memory RAM
The on-chip RAM has 256 bytes, of which the address space from 00H to 7FH is the direct addressing area, and the address from 00H to 1FH in this area is the working register area.
There are 4 groups of working registers, each group is R0~R7. At a certain moment, the CPU can only use any one group of working registers, which is determined by the program status word.
Determined by the status of RS0 and RS1 in PSW.
The address units 20H to 2FH of the on-chip RAM are bit addressable areas, where each bit of each byte specifies a bit address.
In addition to section operations, bit operations can also be performed.
The address space 80H to FFH of the on-chip RAM is the special function register SFR area. For the 51 series, 21 special function registers are arranged in this area. For the 52 series,
26 special function registers are arranged in this area, and 128 bytes of indirect addressing on-chip RAM are expanded at the same time, and the address is also 80~FFH, overlapping with the SFR area address.
After I finished manually optimizing the variables, I set the compilation mode to SMALL. In this way, the C51 compiler will automatically prioritize the variables that I did not manually specify to be stored in the data area. If they exceed the valid address range, it will report an error, so I can rest assured. After pressing the rebuild all button, the compiler prompts:
Program Size: data=236.2 xdata=19321 code=43372
"ipphone_main" - 0 Error(s), 0Warning(s).
The data area prompted by the compiler includes idata. According to past experience, the data area has 256 bytes, and the program has only used 236.2 of them, leaving 19 bytes without overflow. The xdata area has 32k, and only 19k has been used, which is far from overflow. The compilation results are all normal.
After burning the code into the chip and running it, the result was unexpected. From the phenomenon, it restarted automatically about 1 second after power-on, and restarted again 1 second after the restart, which was a very regular restart.
I didn't suspect that it was the compiler. My first thought was that it was the watchdog. The code turned on the watchdog after power-on. Maybe some subroutine code took too long to execute and the watchdog was reset. So I inserted the watchdog feeding code in the suspected place, recompiled and tested it again, and it still restarted automatically. So I simply commented out the watchdog code and didn't use the watchdog, thinking that there would be no problem this time. Unexpectedly, it still restarted.
I thought about it carefully and there are not many reasons that can cause the 8051 to restart. One is the restart caused by the watchdog, which can be ruled out. Second, some 8051s support restart instructions. Although the one I use supports it, I have never used that instruction, so this can also be ruled out. Third, the 8051 is strongly interfered with, and the content of the instruction fetch register PC is changed to 0, so it restarts. This can also be ruled out, because if there is strong interference on site, it should restart before optimization.
Since I couldn't figure out the reason, I started to tinker with it, restoring the optimized variables one by one to the unoptimized state, and retesting each time I restored them. Finally, when I restored a 16-byte array, I found that the program was normal. After a closer look, I found that the program was completely normal when the array was defined in the xdata area, but it was reset when it was defined in the idata area. Although it was strange that the compiler did not report a memory overflow when it was defined in the idata area. Tracing the assembly instructions did not find any abnormalities. Whether it was defined in idata or xdata, the addresses assigned by the compiler to the array proved to be valid addresses, and there was indeed no overflow. The compiler's arrangement was still correct.
Although I haven't found the root cause, since the problem is in the memory, I decided to check the memory allocation when the array is specified as idata type. Keil C51 will output an M51 file when compiling. This file contains a lot of memory allocation information, which is very detailed, including which variable is assigned to which memory address by the compiler, how many bytes it occupies, which variables are local variables, and which variables can be reused... This M51 file has a detailed list.
Looking down the variable allocation addresses in the list, everything is correct. I was amazed at how accurately the compiler arranged the variable allocation. But when I saw the arrangement of the last stack pointer, I finally found the problem. It is arranged like this:
TYPE BASE LENGTH RELOCATION SEGMENT NAME
----------------------------------------------------------------------------------------------
IDATA 0080H 0034H UNIT _IDATA_GROUP_
IDATA 00B4H 0022H UNIT ?ID?IPPHONE_MAIN
IDATA 00D6H 001FH UNIT ?ID?DNS_NICRCV?IPPHONE_DNS
IDATA 00F5H 0004H UNIT ?ID?DISP
IDATA 00F9H 0001H UNIT ?STACK
The segment marked with STACK is the stack allocation. The data above shows that the SP stack pointer is arranged at the address F9H, and the stack space is 1 byte! On the surface, there is no overflow, but my program uses interrupt service. When entering the interrupt service, at least 8 bytes of stack space (to save R0~R7 registers) are required to protect the scene. 8051 uses an incremental stack design. The stack pointer is often arranged in the available part of the memory space at the back. Every time a byte is pushed, the SP pointer is increased by 1. When entering the interrupt service, at least 8 bytes are pushed, F9H+8, which exceeds FFH. The stack pointer cannot exceed FFH, which means the stack overflows! It turns out that this is the reason why the program keeps restarting, not the variable memory overflow, but the stack overflow!
When I specify the array as xdata type, since the array no longer occupies the idata area, IDATA suddenly has 16 bytes of available space. The recompiled M51 is arranged like this:
IDATA 0080H 0024H UNIT _IDATA_GROUP_
IDATA 00A4H 0022H UNIT ?ID?IPPHONE_MAIN
IDATA 00C6H 001FH UNIT ?ID?DNS_NICRCV?IPPHONE_DNS
IDATA 00E5H 0004H UNIT ?ID?DISP
IDATA 00E9H 0001H UNIT ?STACK
From this set of data, we can see that the SP pointer is arranged at the address E9H, and the stack space has FFH-E9H+1=23 bytes, which is enough for the program, so the program runs normally.
The compilation results of adjusting the variable type multiple times show that C51 does not calculate the required size of the stack space. Any code is allocated based on the requirement of only 1 byte of stack space (this is obviously nonsense in my opinion. It is impossible for a slightly complex subroutine call to complete the field protection with only 1 byte). Since the stack can only be allocated in the data area and idata area, when a program occupies too much data area for optimization, although the compiler can compile successfully, the SP stack pointer is often allocated at the end of the data area, which can easily cause insufficient stack space and overflow. To be on the safe side, it is best to ensure that the compiled SP value is arranged before F0H, so that there are at least 16 bytes of stack space to maximize the guarantee that the program will not run away.
It seems that we cannot trust Keil C51 too much. After compiling, we will have to check M51 to ensure the quality of the program. I don't know if this is a bug of Keil C51.
Previous article:51 MCU voice + temperature control source code
Next article:AT89S52 and DS18B20 digital temperature sensor testing completed
Recommended ReadingLatest update time:2024-11-16 14:59
- Popular Resources
- Popular amplifiers
- Wireless Sensor Network Technology and Applications (Edited by Mou Si, Yin Hong, and Su Xing)
- Principles and Applications of Single Chip Microcomputers and C51 Programming (3rd Edition) (Xie Weicheng, Yang Jiaguo)
- Foundations of ARM64 Linux Debugging, Disassembling, and Reversing Analyze Code, Understand Stack Me
- 智能化测量控制仪表原理与设计(第3版) (徐爱钧,徐阳编著)
Professor at Beihang University, dedicated to promoting microcontrollers and embedded systems for over 20 years.
- Innolux's intelligent steer-by-wire solution makes cars smarter and safer
- 8051 MCU - Parity Check
- How to efficiently balance the sensitivity of tactile sensing interfaces
- What should I do if the servo motor shakes? What causes the servo motor to shake quickly?
- 【Brushless Motor】Analysis of three-phase BLDC motor and sharing of two popular development boards
- Midea Industrial Technology's subsidiaries Clou Electronics and Hekang New Energy jointly appeared at the Munich Battery Energy Storage Exhibition and Solar Energy Exhibition
- Guoxin Sichen | Application of ferroelectric memory PB85RS2MC in power battery management, with a capacity of 2M
- Analysis of common faults of frequency converter
- In a head-on competition with Qualcomm, what kind of cockpit products has Intel come up with?
- Dalian Rongke's all-vanadium liquid flow battery energy storage equipment industrialization project has entered the sprint stage before production
- Allegro MicroSystems Introduces Advanced Magnetic and Inductive Position Sensing Solutions at Electronica 2024
- Car key in the left hand, liveness detection radar in the right hand, UWB is imperative for cars!
- After a decade of rapid development, domestic CIS has entered the market
- Aegis Dagger Battery + Thor EM-i Super Hybrid, Geely New Energy has thrown out two "king bombs"
- A brief discussion on functional safety - fault, error, and failure
- In the smart car 2.0 cycle, these core industry chains are facing major opportunities!
- The United States and Japan are developing new batteries. CATL faces challenges? How should China's new energy battery industry respond?
- Murata launches high-precision 6-axis inertial sensor for automobiles
- Ford patents pre-charge alarm to help save costs and respond to emergencies
- New real-time microcontroller system from Texas Instruments enables smarter processing in automotive and industrial applications
- Has anyone used ads7844?
- CPU card programming system main frequency setting
- EEWORLD University ---- Automotive eCall Power Solution
- Because he mastered the company's "core technology", the boss hired several strong men to kidnap people on the street after leaving the company
- It's time to test your eyesight
- How to not set a password in AP mode
- LCD Segment Screen Screen Printing Notes
- hfss18 version 3D image setting problem
- The network transformer output does not connect to RJ45, but uses a custom interface!
- EEWORLD University Hall----Live Replay: TI Sitara? Multi-protocol Industrial Communication Optimization Solution, PLC Demo Real-time Demonstration