Upward posture, 7 tips for embedded system development, how many do you know?

Become a formal embedded development engineer. It's a tough process that requires developers to maintain and manage every bit and byte of the system. There are many techniques for developing highly reliable embedded systems, from well-developed development cycles to strict implementation and system checks. Today, I will introduce you to 7 easy-to-use and long-lasting tips that will help ensure that the system runs more reliably and captures anomalous behavior.

Tip 1 - Fill the ROM with a known value

Software developers are often very optimistic people, just let their code run faithfully for a long time, and that's it. It seems quite rare for a microcontroller to jump out of the application space and execute it in an unintended code space. However, the chances of this happening are no less than the buffer overflow or the wrong pointer loses the reference. It does happen! The behavior of the system after this happens will be undefined, because the memory space is 0xFF by default, or because the memory area is usually not written, the value may only be known to God.

涨姿势,嵌入式系统开发的7大技巧 ,你了解几个?

However, there are fairly comprehensive linker or IDE tricks that can be used to help identify such events and recover from them. The trick is to use the FILL command to fill a known bit pattern with unused ROM. To populate unused memory, there are many different possible combinations to use, but if you want to build a more reliable system, the most obvious option is to place the ISR fault handler at these locations. If something goes wrong with the system and the processor begins executing code outside of program space, it triggers the ISR and provides an opportunity to store the processor, registers, and system state before deciding to correct the action.

Tip 2 - Check the application's CRC

A big benefit for embedded engineers is that our IDE and toolchain can automatically generate an application or memory checksum (Checksum) to verify that the application is intact based on this checksum. Interestingly, in many of these cases, the checksum is only used when the program code is loaded into the device.

However, if the CRC or checksum remains in memory, then verifying that the application is still intact at startup (or even for a long-running system) is an excellent way to ensure that unexpected things don't happen. The probability of a programmed application changing now is small, but considering the billions of microcontrollers delivered each year and potentially poor work environments, the chances of an application crash are not zero. More likely, a defect in the system can cause flash writes or flash erases in a sector, thereby damaging the integrity of the application.

Tip 3 - Perform a RAM check at startup

In order to build a more reliable and solid system, it is very important to ensure that the system hardware is working properly. After all, the hardware will fail. (Fortunately, the software never fails, the software only does what the code wants it to do, whether it is correct or wrong). Verifying that there is no problem inside or outside of the RAM at startup is a good way to ensure that the hardware can function as expected.
There are many different ways to perform a RAM check, but the usual method is to write a known pattern and wait for a short time before reading back. The result should be what you read is written. The truth is that in most cases the RAM check is passed, which is what we want. However, there is also a very small possibility that the inspection will not pass, which provides an excellent opportunity for the system to indicate hardware problems.

Tip 4 - Using a Stack Monitor

For many embedded developers, the stack seems to be a pretty mysterious force. When strange things started to happen, the engineers were finally stumped, and they started thinking, maybe something happened on the stack. The result is blindly adjusting the size and position of the stack, and so on. But the error is often unrelated to the stack, but how can it be so determined? After all, how many engineers actually did the worst-case stack size analysis?

The stack size is statically allocated at compile time, but the stack is used dynamically. As the code executes, the variables, returned addresses, and other information the application needs are continuously stored on the stack. This mechanism causes the stack to grow in its allocated memory. However, this growth sometimes exceeds the capacity limit determined at compile time, causing the stack to corrupt data in adjacent memory regions.

One way to absolutely ensure that the stack works properly is to implement the stack monitor as part of the system's "health" code (how many engineers will do this?). The stack monitor creates a buffer area between the stack and the "other" memory area and fills in the known bit pattern. The monitor then constantly monitors the pattern for any changes. If this bit pattern changes, it means that the stack is growing too much, and the system is about to be pushed to the dark hell! At this point the monitor can record the occurrence of the event, the system status, and any other useful data for later diagnosis of the problem.

A stack monitor is provided in most real-time operating systems (RTOS) or microcontroller systems that implement a memory protection unit (MPU). The scary thing is that these features are turned off by default, or are often intentionally closed by developers. A quick search on the network reveals that many people recommend turning off the stack monitor in the real-time operating system to save 56 bytes of flash space, etc., which is not worth the effort!

Tip 5 - Using MPU

In the past, it was difficult to find a Memory Protection Unit (MPU) in a small, inexpensive microcontroller, but this has begun to change. MPUs are now available from high-end to low-end microcontrollers, and these MPUs offer embedded software developers an opportunity to dramatically increase their firmware robustness.

The MPU has gradually been coupled to the operating system to create memory space where the processing is separate, or tasks can execute their code without worrying about being stomped on. If there really happen, uncontrolled process will be canceled, also performs other protective measures. Please pay attention to the microcontroller with this component, if any, please take advantage of this feature.

Tip 6 - Build a powerful watchdog system

One of the most popular watchdog implementations you'll often find is where the watchdog is enabled (this is a good start), but it can also be done with a periodic timer. The watchdog is cleared; the timer is enabled to be completely isolated from anything that occurs in the program. The purpose of using the watchdog is to help ensure that if an error occurs, the watchdog will not be cleared, ie when the work is suspended, the system will be forced to perform a hardware reset to recover. Using a timer independent of system activity keeps the watchdog clear, even if the system has failed.

Embedded developers need to think carefully and design how application tasks are integrated into the watchdog system. For example, there is a technique that allows each task that runs within a certain period of time to indicate that they can successfully complete their tasks. In this event, the watchdog is not cleared and forced to be reset. There are also some more advanced techniques, such as using an external watchdog processor, which can be used to monitor how the main processor behaves and vice versa. For a reliable system, it is important to build a powerful watchdog system.

Tip 7 - Avoid volatile memory allocation

Engineers who are not accustomed to working in resource-constrained environments may attempt to use the features of their programming language, which allows them to use volatile memory allocation. After all, this is a technique often used in calculator systems where memory is only allocated when necessary. For example, when developing in C, engineers may prefer to use malloc to allocate space on the heap. There is an operation to execute, once completed, you can use free to return the allocated memory for the heap to use.

In a resource-constrained system, this could be a disaster! One of the problems with using volatile memory allocation is that errors or improper techniques can cause memory leaks or memory fragmentation. If these problems occur, most embedded systems do not have the resources or knowledge to monitor the heap or handle it properly. And when they happen, what happens if the application asks for space but does not have the requested space available?

The problems caused by the use of volatile memory allocation are very complicated. It is a nightmare to properly handle these problems! An alternative approach is to simplify the allocation of memory directly in a static manner. For example, instead of simply creating a buffer that is 256 bytes long in the program, instead of requesting a memory buffer of this size via malloc. This allocated memory can be maintained throughout the life of the application without the concerns of heap or memory fragmentation issues.

in conclusion

The above embedded development tutorials allow developers of technology to get a better approach to embedded systems. All of these technologies allow designers to develop the secrets of more reliable embedded systems.

Aluminum Alloy Housing Integrator

Aluminum Alloy Housing Integrator,Metal Case Integrator,Three Phase Metal Case Integrator,Three Phase Aluminum Alloy Housing Integrator

Zibo Tongyue Electronics Co., Ltd , https://www.tongyueelectron.com