ARM7 CAN Code Compatibility Issues with ARM Cortex-A9 FlexCAN
When attempting to port a CAN (Controller Area Network) program written for an ARM7 processor to an ARM Cortex-A9 processor, such as the one found in the i.MX6 board, several architectural and peripheral differences must be considered. The ARM7 and ARM Cortex-A9 are fundamentally different in terms of their instruction sets, memory models, and peripheral interfaces. The ARM7 is based on the ARMv4T architecture, which is a 32-bit RISC processor with a relatively simple pipeline and no memory management unit (MMU). In contrast, the ARM Cortex-A9 is based on the ARMv7-A architecture, which supports a more complex pipeline, out-of-order execution, and includes an MMU, making it suitable for running full-fledged operating systems like Linux.
The CAN controllers in these processors also differ significantly. The ARM7 typically uses a basic CAN controller, while the ARM Cortex-A9 in the i.MX6 board features FlexCAN, a more advanced CAN controller with additional features such as enhanced message filtering, higher data throughput, and support for more complex network topologies. These differences mean that the CAN program written for the ARM7 cannot be directly used on the ARM Cortex-A9 without significant modifications.
The primary issue lies in the differences in the register sets, interrupt handling mechanisms, and memory addressing schemes between the two architectures. The ARM7 code may use direct register accesses and simple polling or interrupt-driven mechanisms that are not directly applicable to the ARM Cortex-A9’s FlexCAN module. Additionally, the ARM Cortex-A9’s more complex memory hierarchy, including caches and virtual memory, can introduce subtle issues related to data coherency and timing that were not present in the ARM7 implementation.
Architectural and Peripheral Differences Between ARM7 and ARM Cortex-A9 FlexCAN
The architectural differences between the ARM7 and ARM Cortex-A9 are profound and impact the way CAN programs are written and executed. The ARM7’s ARMv4T architecture is relatively simple, with a three-stage pipeline and a limited set of peripherals. The ARM Cortex-A9, on the other hand, is based on the ARMv7-A architecture, which includes features such as superscalar execution, out-of-order processing, and a more sophisticated memory system with caches and an MMU. These differences necessitate a different approach to programming, especially for real-time applications like CAN communication.
The FlexCAN module in the ARM Cortex-A9 is more advanced than the CAN controller found in typical ARM7 implementations. FlexCAN supports up to 64 message buffers, each of which can be configured as either a transmit or receive buffer. It also includes features such as individual mask registers for each buffer, which allow for more flexible message filtering. The FlexCAN module also supports higher data rates and more complex network configurations, which can be both an advantage and a challenge when porting code from an ARM7-based system.
One of the key challenges in porting the ARM7 CAN code to the ARM Cortex-A9 is the difference in interrupt handling. The ARM7 typically uses a simple interrupt controller with a fixed priority scheme, while the ARM Cortex-A9 uses a more complex interrupt controller that supports priority levels, nested interrupts, and software-triggered interrupts. This means that the interrupt service routine (ISR) for the CAN controller in the ARM7 code may need to be rewritten to accommodate the more sophisticated interrupt handling mechanisms in the ARM Cortex-A9.
Another significant difference is the memory model. The ARM7 uses a flat memory model with no MMU, meaning that all memory accesses are direct and there is no virtual memory. The ARM Cortex-A9, however, uses a virtual memory model with an MMU, which allows for memory protection, virtual address translation, and the use of caches. This can introduce issues related to data coherency, especially when dealing with DMA (Direct Memory Access) transfers, which are commonly used in CAN communication to move data between the CAN controller and memory.
Steps for Porting ARM7 CAN Code to ARM Cortex-A9 FlexCAN
Porting CAN code from an ARM7 to an ARM Cortex-A9 processor involves several steps, each of which must be carefully executed to ensure that the code works correctly on the new architecture. The first step is to analyze the existing ARM7 CAN code to identify any architecture-specific features that may need to be modified. This includes examining the register accesses, interrupt handling, and memory management code to determine how they will need to be adapted for the ARM Cortex-A9.
The next step is to familiarize yourself with the FlexCAN module in the ARM Cortex-A9. This involves studying the FlexCAN reference manual to understand the differences between the FlexCAN module and the CAN controller used in the ARM7. Pay particular attention to the register set, message buffer configuration, and interrupt handling mechanisms. You will need to map the functionality of the ARM7 CAN controller to the equivalent functionality in the FlexCAN module, which may involve reconfiguring the message buffers, adjusting the interrupt handling code, and modifying the DMA setup.
Once you have a clear understanding of the differences between the two CAN controllers, you can begin the process of rewriting the ARM7 CAN code for the ARM Cortex-A9. Start by creating a new project in your development environment and setting up the necessary configuration files for the ARM Cortex-A9. This includes configuring the memory map, setting up the interrupt controller, and initializing the FlexCAN module. You will also need to modify the linker script to account for the differences in memory layout between the ARM7 and ARM Cortex-A9.
Next, you will need to rewrite the CAN initialization code to configure the FlexCAN module according to your application’s requirements. This includes setting up the message buffers, configuring the baud rate, and enabling the necessary interrupts. You will also need to modify the ISR to handle interrupts from the FlexCAN module, taking into account the more complex interrupt handling mechanisms in the ARM Cortex-A9.
After rewriting the initialization and interrupt handling code, you can begin porting the application logic from the ARM7 code to the ARM Cortex-A9. This involves modifying the code that interacts with the CAN controller to use the FlexCAN API instead of the ARM7 CAN controller API. You will also need to update any code that deals with memory management to account for the differences in the memory model between the ARM7 and ARM Cortex-A9.
Finally, you will need to test the ported code to ensure that it works correctly on the ARM Cortex-A9. This involves running the code on the target hardware and verifying that the CAN communication works as expected. You should also perform stress testing to ensure that the code can handle high data rates and complex network configurations without issues. If you encounter any problems, you may need to revisit the earlier steps to identify and fix the issues.
In conclusion, porting a CAN program from an ARM7 to an ARM Cortex-A9 processor is a complex task that requires a deep understanding of both architectures and their respective CAN controllers. By carefully analyzing the existing code, familiarizing yourself with the FlexCAN module, and methodically rewriting and testing the code, you can successfully port the CAN program to the ARM Cortex-A9 and take advantage of its advanced features.