Click the above to select“Pin/Star Public Account”
Welfare and valuable content delivered first-handHello everyone, I am Mai Ge.In embedded development, especially in os-less microcontroller programs, the most common mistake is the rampant use of global variables.This phenomenon is often seen among programmers transitioning from early assembly language and beginners, who tend to treat global variables almost like function parameters.They define numerous chaotic structures in .h files, extern a bunch of globally terrifying variables, and then assign values like 123 in this module, while that module decides what to do based on the 123 branch.Every time I see such programs,I can’t help but frown and then slam the table in anger.That’s right, anger.I do not deny the importance of global variables, but I believe they should be used with extreme caution; the misuse of global variables can lead to other more serious structural system issues.Why should global variables be minimized?They can cause unnecessary constants to be used frequently, especially when these constants are not defined with macros, making the code extremely difficult to read.They can lead to unreasonable software layering; global variables act as a shortcut, easily blurring the boundaries between the “device layer” and the “application layer” for programmers.Lower-level programs can easily become overly concerned with upper-level applications.This indeed improves efficiency in the early stages of software system construction, with debugging progress advancing rapidly, but later on, it often results in a pile of bugs, with patches everywhere, and minefields abound.It would not be an exaggeration to say that it feels like a struggle to survive.Due to the unreasonable software layering, during later maintenance, even minor modifications or deletions of functions often require digging deep from top to bottom, involving most modules,while the original code comments are often forgotten to be updated.At this point, the system handed over to later maintainers increasingly resembles a “quagmire,” with comments serving only to add more fog above the quagmire.The extensive use of global variables inevitably leads to some variables lingering between interrupts and the main loop program.If not handled properly, the system’s bugs will appear randomly and irregularly, showing early signs of a terminal illness; without a strong hand to save the day, it is doomed to a slow death.No need to say more, you have successfully obtained a malformed system,which is in a mysterious state of stability!You look at this machine, and the machine looks at you, both silent, feeling uneasy.You are unsure when it will crash, nor do you know when the next complaint will arise.
While optimizing code, also upgrade your hardware knowledge base! The MPS ADC series product solution package is ready, containing architecture analysis, product guides, and application solutions, making it an excellent reference for your embedded system design.
⏬Click to download more quality embedded articles⏬What are the consequences of extensive use of global variables?“The “old man” is proud because the system cannot do without him; all the “minefields” are known only to him.When urgent bugs arise, only he can fix them.You cannot only fire him but must also give him a raise.Newcomers die upon exposure,and anyone hired to maintain this system, apart from creating more bugs, usually leaves within a month, spreading the word that the software quality of this company is terrible.As the product continues to upgrade, the original creator, who hasn’t touched this system for months, will find that he has forgotten many minefields, leading to increasingly longer maintenance cycles for product upgrades,because modifying one function will trigger many bugs, and fixing one bug will pop up even more bugs.During this period, more global variables will be generated.Finally, one day he tells the boss, it’s no good, resources are insufficient, RAM or flash space is too small, we need to upgrade.Customer complaints are incessant, after-sales support is on the verge of collapse, and salespeople dare not recommend this product anymore,leading to a shrinking market share and a deteriorating company image.To ask for countermeasures, there are only two principlesMinimize the use of global variables whenever possible; I believe that apart from system status and control parameters, communication processing, and some efficiency-critical modules, most can rely on reasonable software layering and programming techniques to solve.If it is unavoidable, hide it as deeply as possible.
- If only a certain .c file uses it, make it static to that file, and also include the structure definition;
- If only one function uses it, make it static within that function;
- If it must be exposed for reading, return it through a function, making it read-only;
- If it must be tampered with, fine, I’ll open a function interface for you to pass parameters for assignment;
- If extern must invade me, I can still strictly control the objects that include my .h file, rather than letting it be seen in the public includes.h, causing embarrassment.
Thus, you can understand how deeply I feel about global variables,unfortunately, I have had to rewrite all those cases that the “old men” handed over to me for maintenance.Final NoteGlobal variables are unavoidable; almost every device’s lower level needs them to record the current state, control timing, and manage transitions.However, they should not be used to pass parameters, which is very taboo.Try to keep the scope of variables within the module that uses them; if other modules need access, open a read or write function interface to strictly control access.This point is exactly what C++’s private attribute does,which is also beneficial for future program debugging.The reason C has a ++ version is largely to control its flexibility; if we talk about object-oriented thinking, C has long had it and can also achieve it.When the number of global variables in a module exceeds three (including), wrap them in a structure,so they can be reset together, preventing loss of track.Declaring a static global variable or global array inside a function does not occupy stack space,but some compilers may place large global arrays in a different address area than regular variables.If in Keil C51, since it is statically compiled, if the stack overflows, it will raise an alarm, so you can ride freely, just pay attention to the traffic rules.In os-less systems of microcontrollers, where there is only stack and no heap usage, those “startup.s” files that default to allocate heap space can boldly remove the heap space.Program model? How to analyze and abstract it? From which angle to build the model? I would love to hear opinions from netizens.I have always analyzed systems from two perspectives: event-state machine transition diagrams and data flow diagrams; the former analyzes control flow and improves UI, while the latter reveals the origins and fates of system data.These theories are all found in the university’s “Software Engineering” textbooks, and everyone might as well refer to them. However, those theories ultimately originate from managing large system software, so they need to be tailored for smaller applications.Material sourced from Engineer Advancement Notes, works belong to the original author, for learning reference only~—— The End ——Recommended Good Articles Click the blue text to jumpEmbedded development tips, how to accurately calculate the running time of code?Recommend a super lightweight FIFO tool for small memory MCUs!Is learning PID too painful? This open-source library doubles your efficiency!