An Overview of Microcontroller Software Development Techniques

Microcontroller technology is based on the use of chips and external devices, achieved through software and hardware development, ultimately realizing comprehensive technology for electronic products.

First, it is important to confirm that the learning and usage curve for microcontrollers is not steep. Various chip manufacturers are also providing graphical development tools, such as ST’s STM32CubeMX, Infineon’s DAVE, and Microchip’s Microchip Studio, all of which support graphical project generation, lowering the entry barrier. Currently, understanding schematics and mastering the use of graphical tools theoretically allows one to engage in application development even without familiarity with microcontrollers.

For microcontrollers, developing simple peripheral drivers is not particularly difficult. For interfaces like GPIO, RTC, Timer, UART, I2C/SPI, the graphical tools do not significantly replace the work; rather, they provide the most help in implementing complex functionalities, such as Fatfs, USB, LWIP, GUI libraries, and motor control libraries. When I first entered the embedded field, I spent a month porting and debugging uCos-II and LWIP from scratch. Later, due to occasional stuttering, I had to understand each configuration item in LWIP for debugging. However, using the STM32CubeMX graphical interface, I recently spent only 2 hours debugging and supporting FreeRTOS and LWIP applications, successfully running Ping and simple socket applications. Of course, I also spent half a day on configuration tuning, which relied on my previous debugging experience.

Graphical development can be said to simplify a lot of operations, but it does come at a cost. For developers who initially transitioned from registers and standard libraries and have ported projects and libraries, at least for me, it is easy to understand the execution flow of the generated code. If the work does not meet expectations, one can quickly know how to check and where to modify. However, if one only learns that set of graphical operations and the generated code works fine, that is great; if it does not work, sorting out the logic of the generated code and understanding the significance of each configuration item becomes more challenging. It is not that the operations are simple; the complexity does not disappear; it is just that the complexity has been hidden and implemented by the chip manufacturer’s engineers. If your application happens to be covered by the software, there is no problem; but for applications that are not covered or have incomplete support, one must understand the development thinking of the chip manufacturer’s software engineers to make modifications, which actually increases complexity.

Moreover, although the graphical tools from various manufacturers all logically involve option configurations and importing external modules, the configuration items are not the same. The underlying logic is controlled through registers to manage hardware functions, which has its consistency. Only by mastering the underlying chip operation and functional execution logic, with chip applications as the main focus and graphical development as a supplement, can one adapt to various development environments and functional requirements. Graphical development mainly includes creating projects, selecting functions, configuring parameters, and finally generating functionalities, which is logically clear and simple. After selecting a platform, downloading the corresponding graphical tool to generate the project is straightforward; however, adapting hardware, integrating applications, and realizing specific functionalities is not simple, involving various types of technologies.

Microcontroller technology is quite complex, and the software part includes the following content.

Building Microcontroller Software Projects

The approach to building a complete microcontroller project is as follows.

  1. Establish the project’s compilation scheme, such as MDK, IAR, Makefile, and cmake, etc.

  2. Files required for the project, including startup files, entry functions, support libraries (HAL, LL, etc.), drivers, application files, etc.

  3. Configure download items, to implement debugging and downloading actions. For MDK and IAR, this means configuring the downloader and FLASH operation files; Makefile and cmake involve gdb and openocd, etc.

  4. Debugging print interfaces are powerful tools during development, crucial for analyzing issues and viewing execution flow, and must be mastered.

Understanding Peripheral Module Functions and Configurations

Peripheral modules are the most encountered parts during the learning phase, primarily concentrated in the early board-level solution verification stage, and are rarely modified once matured. This part requires joint debugging of hardware and software to truly master. Encountering and solving problems is essential to understand the design principles and avoid errors. Peripheral modules include the following content.

  1. Functions and usage methods of peripheral modules. Common peripherals include RCC, GPIO, EXTI, I2C, SPI, ADC/DAC, Timer, SDIO, IWDG/WWDG, DMA, USART, RTC, LTDC, USB, ETH, etc. Some complex modules also require corresponding libraries and protocol codes to be used together.

  2. Register function descriptions for peripheral modules. Each peripheral has registers for functions, states, etc., which need to be adapted for operation during hardware debugging.

  3. Interconnections and cooperative use between peripherals. For example, most modules support working with DMA, and Timer modules can serve as trigger signals for many modules.

External Device Driver Functions

External devices are key modules that expand the functionality of microcontrollers, enabling detection and control in applications. Examples include sensors for detecting temperature, humidity, and light, serial conversion modules for Bluetooth and Wi-Fi communication, adjustable DC-DC chips for controlling voltage output, and SPI-ADC chips for expanding sampling channels. External devices serve as the eyes and arms of the entire microcontroller system, executing tasks under the command of the MCU as the brain. External devices mainly include the following content.

  1. Various sensors accessed via I2C/SPI.

  2. SD-Card devices accessed via SDIO.

  3. ETH PHY devices accessed via network.

  4. CMOS for image capture and LCD screens for image display.

  5. Various power driver chips.

RTOS Porting and Application Techniques

RTOS is the foundation for building complex embedded systems. If a project only involves turning on a light or executing a command, bare metal can suffice. However, when the entire project is complex, involving networking, image capture, UI display, and various controls, while bare metal can still be implemented, it requires a complex state machine management mechanism akin to coroutines. Using RTOS is relatively simpler and more convenient.

For RTOS, the main content includes the following.

  1. Proficient in one RTOS, which can be FreeRTOS, rtthread, etc.

  2. Ability to port RTOS, create tasks, and run them.

  3. Understanding common configuration items of RTOS, trimming and controlling OS support features, such as internal heap size, hook functions, system frequency, task stack limits, etc.

  4. Mastering common inter-thread communication concepts and applications of RTOS, including critical sections, semaphores, mutexes, queues, event groups, and message buffers, etc.

  5. Other extended features, such as software timers, dynamic memory management, etc.

RTOS is an advanced knowledge area in microcontroller development and a commonly used technology in project development, making understanding and mastery necessary.

Porting and Applying Complex Libraries

For microcontroller projects, it is necessary to use some external libraries to achieve specific functional business. Here are some common applications and the modules involved.

  1. Using Fatfs to manage files, in conjunction with SDIO, SPI, etc., to manage file systems supporting fatfs format.

  2. Using USB libraries to implement applications, in conjunction with USB modules to achieve mouse, keyboard, USB drive functionalities.

  3. Local area network interface support, such as CANOPEN, Modbus protocols, etc.

  4. Network library support, in conjunction with ETH modules, porting LWIP, and integrating HTTP, MQTT, etc., libraries for network applications.

  5. Graphical library support, porting emwin, touchGFX, lvgl, etc., to implement graphical UI.

  6. Motor control libraries, based on ADC, Timer encoders to obtain position, speed, and current values, calculating control signals through the motor library and outputting them.

How to Learn Microcontrollers?

A complete microcontroller software project requires users to build projects, debug module drivers, develop and debug device drivers, port external libraries, and finally combine them with self-implemented bare metal code to form complete functionality.

As can be seen, microcontroller technology covers a wide range, and even seasoned professionals cannot be proficient in all areas. For instance, someone working on industrial bus CAN-related communications may have some knowledge of networking, but if asked about cameras or UI-related topics, they might be at a loss. Conversely, someone focused on graphical capture and processing may struggle to answer questions about USB-related interfaces and drivers. This industry requires both breadth and depth of knowledge, and a systematic learning approach is as follows.

  1. Master C language, as it remains the mainstream in the entire microcontroller industry, even though C++ and RUST can also be used. The drivers, RTOS, and third-party libraries mentioned above are primarily based on C. Without proficiency in C, further discussions become impossible. I am currently updating a series on C language, which can be referenced for related learning.

  2. Learn to manually build projects, as using STM32CubeMX to generate code is common in work and convenient to master. However, it is essential to learn manual construction to understand startup files, entry functions, driver file inclusions, header files, and downloader selections. This part is a universal skill and the foundation of the entire project; relying solely on graphical tools limits one to a single platform, leaving one confused when switching platforms.

  3. Master some basic module functions and debugging methods, including RCC, GPIO, EXTI, and serial port applications. This part not only requires the ability to debug and ensure normal operation but also to understand the underlying register configuration functions. Module usage is one aspect; the most important is to cultivate the ability to analyze problems and think critically. When discovering that functionality does not meet expectations, one should not only focus on configuration items but also be able to analyze problems in conjunction with registers and hardware. For complex modules, this approach can also be applied, where methods are more important than functionalities.

  4. Combine complex modules with external devices and libraries to form applications for learning, and summarize debugging experiences. This part is also the most challenging.

For example, constructing an application as follows: enabling a host computer to obtain temperature and humidity detected by the microcontroller via serial port and Modbus protocol, supporting alarm functions and log recording.

  • The lower computer supports temperature and humidity collection – obtaining status through I2C/SPI interface sensors.

  • The lower computer supports alarm sounds and LED notifications – controlling buzzers and LEDs through GPIO.

  • The host and lower computer communicate via serial port and Modbus protocol – controlling serial port transmission and porting Modbus protocol.

  • Logs are recorded using SDCard – porting SDIO interface and fatfs.

If in the future, there is a desire to support web interface display and management, it will require ETH drivers, RTOS porting, LWIP protocol support, and HTTP server implementation, thus completing the framework of an IoT project. Through the practice of this project, one will naturally learn and understand the corresponding modules and functionalities, making the learning process less tedious.

Although the challenges in microcontrollers are not high, those wishing to develop in this industry must continue to learn and strive. Let us encourage each other in this endeavor.

Leave a Comment