Change Location EUR
 
Mouser Europe - Flag Mouser Europe

Incoterms: DDP is available to customers in EU Member States.
All prices include duty and customs fees on select shipping methods.

Incoterms: DDU applies to most non-EU customers.
Duty, customs fees and taxes are collected at time of delivery.


Please confirm your currency selection:

Euros
Euros are accepted for payment only in EU member states these countries.

US Dollars
USD is accepted in all countries.

Other currency options may also be available - see
Mouser Worldwide.

Bench Talk for Design Engineers

Bench Talk

rss

Bench Talk for Design Engineers | The Official Blog of Mouser Electronics


Optimizing Software for Multicore Arm Microcontrollers Mike Parks

(Source: Virtual Art Studio / stock.adobe.com; generated with AI)

Multicore Arm® microcontrollers represent a significant advancement in embedded systems technology, offering the ability to perform more complex tasks, improve application performance, and reduce power consumption. In this blog, we will explore/outline the different multicore Arm microcontroller configurations and explore optimization strategies to maximize the capabilities of multicore Arm MCUs in embedded systems.

Arm Cortex Architecture Profiles

The Arm architecture, known for its efficiency and performance, is widely used in applications from smartphones to industrial control systems. Arm cores come in a variety of architecture configurations, including the Cortex-A, Cortex-R, and Cortex-M series, each tailored for different applications:

  • Cortex-A (application processors): Cortex-A processors are designed for high-performance and rich operating systems like Android or Linux. Typical applications include smartphones, tablets, networking equipment, and high-end industrial systems.
  • Cortex-R (real-time processors): Cortex-R processors prioritize deterministic response times and predictability for real-time applications. They are often used in industrial automation, motor control, robotics, and safety-critical systems like automotive and avionics.
  • Cortex-M (microcontrollers): Cortex-M processors emphasize low power consumption, cost efficiency, and flexibility, making them suitable for a wide range of embedded applications. Examples include wearable devices, sensors, smart home devices, and Internet of Things (IoT) applications.

Multicore configurations can enhance performance by allowing parallel processing and efficient data handling. A multicore processor can be externally viewed in two ways: as a single unit or cluster—either by the system designer or by an operating system—that can abstract the underlying resources from the application layer, or as multiple clusters in which each cluster contains multiple cores.

High-performance Cortex-A series may use clusters for improved performance and power efficiency. For example, some systems-on-chips (SoCs) based on Cortex-A cores might cluster several cores with shared caches and memory controllers. Cortex-R and Cortex-M series primarily focus on real-time performance and low power consumption, respectively, and typically do not implement clusters in the traditional sense. They may have multicore configurations, but these cores operate independently without the shared resources associated with clustered architectures.

Today, even low-cost microcontroller platforms, such as the Raspberry Pi RP2040, contain two M0+ cores. This means multicore hardware is increasingly prevalent and not restricted to more expensive products. However, multicore hardware is not without its challenges. Regardless of how well the hardware is designed, poorly written code can still adversely impact the system during operations.

Programming Strategies

The following sections offer tips for programming efficient software for multicore Arm microcontrollers.

Identify Task Parallelism

The foundation of successful multicore programming lies in identifying opportunities for parallel execution within your application. Look for tasks that are independent and can be run concurrently without data dependencies. This might involve the following:

  • Sensor data processing: Multiple cores can simultaneously handle data from different sensors.
  • Signal processing: Filtering, fast Fourier transform (FFT) calculations, and other algorithms can be divided among multiple cores to separate the hardware-intense calculations into more manageable chunks.
  • User interface tasks: One core can manage user interactions while another handles background processing.

Choose a Parallel Programming Model

Once you've identified parallelism, select a suitable programming model to coordinate tasks across cores. Common models include:

  • Primary/subordinate: One core (primary) distributes tasks to other cores (subordinates) and manages communication. This is simple but can become a bottleneck for the master core.
  • Multithreading: Each core runs its own thread, allowing for finer-grained parallelism. Requires careful synchronization to avoid race conditions.
  • Message passing: Cores communicate by sending messages, enabling flexible task distribution and dynamic workload balancing.

Practice Efficient Coding

Some software operations are dependent on which core the code is running on. For example, global initialization is typically performed by code running on a single core, followed by local initialization on all cores. There are two possible locations for identifying which core is executing the code:

  • Multi-Processor Affinity Register (MPIDR_EL1): This register shows which core is executing code, both within a cluster and in a multi-cluster system.
  • U-bit: Some processor configurations indicate whether this is a single-core or a multicore cluster.

Also consider these design elements for optimizing software:

  • Code modularity: Writing modular code is crucial. It enhances readability, makes the codebase more straightforward to manage, and simplifies debugging and maintenance.
  • Memory management: Efficient use of memory is key in embedded systems. Developers should be mindful of stack and heap usage, avoid memory leaks, and use direct memory access (DMA) for data-intensive operations.
  • Power efficiency: Optimizing code for power efficiency is essential for battery-powered devices. Techniques include utilizing sleep modes, minimizing clock speeds, and optimizing interrupt handling.

Leverage Concurrency

Task concurrency is crucial for multicore microcontrollers because it allows efficient use of multiple cores, enabling parallel execution of tasks to improve overall system performance. By running tasks concurrently, the system can handle more processes simultaneously, reducing latency and increasing responsiveness for time-sensitive applications. Additionally, concurrency supports better resource management, ensuring that computational workloads are distributed evenly across cores to prevent bottlenecks and maximize efficiency.

The following are some methods to leverage concurrency in multicore microcontrollers:

  • Task parallelism: Divide the application into independent tasks that can run concurrently. This approach is practical for applications that can be broken down into distinct, parallelizable tasks.
  • Data parallelism: This involves performing the same operation on multiple data elements in parallel. This method benefits signal processing, image processing, and similar data-intensive tasks.
  • Synchronization: Proper synchronization is crucial to avoid race conditions and data corruption. Arm microcontrollers provide various mechanisms for synchronization, including semaphores, mutexes, and barriers.
  • Inter-processor communication (IPC): Efficient IPC mechanisms are vital for multicore systems. Techniques include shared memory, message passing, and interrupt signals. Concurrent execution requires mechanisms to ensure data consistency and prevent race conditions:
    • Semaphores: Control access to shared resources like memory blocks, preventing multiple cores from modifying data simultaneously.
    • Mutexes: Grant exclusive access to a critical section of code, ensuring only one core executes it at a time (Figure 1).
    • Message queues: Cores exchange data by sending and receiving messages, facilitating asynchronous communication.

 

Figure 1: Mutexes are object-based and can be thought of as passing a key to a locked shared resource. A semaphore is based on an integer counter and can be thought of as a stoplight to control access. (Source: Author)

Optimization Strategies

Software optimization is vital for multicore microcontrollers because it directly impacts performance and efficiency. Well-optimized code minimizes unnecessary instructions and efficiently uses hardware resources such as memory, enabling better parallel execution across cores that can generate significant performance benefits of multicore systems while also reducing power consumption.

Optimizing Software

Software optimization strategies for multicore microcontrollers include the following:

  • Compiler optimizations: Use compiler optimization flags to improve performance and reduce code size. Understanding the trade-offs between optimization levels is essential.
  • Profiling and benchmarking: Regularly profile the application to identify bottlenecks. Tools like Arm's Streamline performance analyzer can provide valuable insights.
  • Cache optimization: Efficient use of cache can significantly impact performance. Techniques include cache locking for critical sections and optimizing data structures for cache efficiency.

Optimizing for Cache and Memory

Multicore processors often have complex cache hierarchies, and effective use of these caches is crucial for performance.

  • Data locality: Place frequently accessed data together in memory to improve cache hit rates.
  • Cache-line alignment: Ensure data structures align with cache line boundaries for efficient access.
  • Minimize false sharing: Avoid placing unrelated data in the same cache line to prevent unnecessary invalidation.
  • Assembly optimization: For critical code sections, consider using assembly language to take complete control over the hardware for maximum performance.

Leveraging Hardware Features

Modern multicore Arm microcontrollers often provide hardware-assisted mechanisms, such as the following, for efficient communication and synchronization.

  • IPC peripherals: Dedicated hardware channels for fast data exchange between cores.
  • Memory management units (MMUs): Hardware that enables memory protection and isolation between cores, improving security and reliability.
  • Cache coherency protocols: Hardware-managed mechanisms to ensure data consistency across caches in different cores.

Debugging, Profiling, and Testing

When implemented, the previously mentioned methods of optimizing software for multicore microcontrollers should achieve significant performance increases and energy efficiency. However, implementing code for multicore systems, especially embedded systems, can be fraught with unintended consequences. Thus, code must be tested and measured to ensure that the code is running efficiently across multiple cores.

  • Multicore-aware debuggers: Inspect individual core states, communication channels, and synchronization primitives using debugging tools such as JTAG, SWD, and onboard debugging features provided by Arm microcontrollers.
  • Profiling tools: Identify performance bottlenecks and assess core utilization to optimize task distribution.
  • Unit testing: Implement unit tests for individual components to ensure reliability and facilitate maintenance before they are integrated into the larger system.
  • Integration testing: Test the interaction between different system components, which is especially important in multicore environments where task interactions can be complex.

Conclusion

Programming multicore Arm microcontrollers presents unique challenges but also offers the potential for significant performance improvements in embedded systems. By understanding Arm architecture, carefully identifying and planning parallel tasks, adopting efficient coding practices, effectively leveraging concurrency, and applying optimization strategies, developers can maximize the capabilities of these powerful multicore devices. This overview provides a foundation, but mastering multicore Arm microcontroller programming requires in-depth study, practical experience, and ongoing engagement with the latest technologies and methodologies. Arm provides an introductory programmer's guide as well as more in-depth training to help engineers optimize their programming.



« Back


Michael Parks, P.E. is the co-founder of Green Shoe Garage, a custom electronics design studio and embedded security research firm located in Western Maryland. He produces the Gears of Resistance Podcast to help raise public awareness of technical and scientific matters. Michael is also a licensed Professional Engineer in the state of Maryland and holds a Master’s degree in systems engineering from Johns Hopkins University.


All Authors

Show More Show More
View Blogs by Date

Archives