Hi, everyone. My name is Yang Song. Today, we'll be discussing the Armv8-M mainline debug. In this module, we will start by introducing some basic arm debug and trace theory. In the theory, we will list some of the differences between invasive and non-invasive debug actions. We will then cover the various debug and trace components in the course site debug architecture that are available to the Armv8-M mainline. By the end of this module, you will also be able to list the various debug events that can halt the processor, as well as distinguish a standard breakpoint versus a semi-hosting call. Lastly, we will also look into some of the new profiling features added as part of the Armv8.1-M architecture update, the performance monitoring unit. Let's start with the basic introduction to Armv8-M debug and trace. In order to debug our application running on a microprocessor, we expect to be able to start and stop the processor's execution as we please. At a bare minimum, we would like a debugger to be able to run, stop, single-step into, or out of instruction or code. We would also like to set triggers to halt the processor automatically by setting breakpoints and watchpoints. A breakpoint monitors a particular instruction to be executed, whereas a watchpoint monitors the data access to an address. More on both of these later. When the processor is halted, we will also want to look at the various states within the system, such as the processor state, i.e, general purpose registers and system control registers, and the system state i.e, contents of memory, status of peripherals, etc. Perhaps the microcontroller has been executing for a bit of time and we are interested in the uninterrupted execution history, which can also be collected through trace, more on trace later as well. But how do we achieve these various debug actions? The actions are achieved by programming the various hardware debug and trace components within the microcontroller design. From a user's perspective, we debug the code running on our target using a software debugger such as the Armds or covermdk. The debug actions we want to achieve are then sent from the software debugger to the hardware debug probe, such as the DStream or the U-link Pro. The probe then connects to a target via the debug access port, the dapp, through either serial wire or J tag protocols, which then send instructions or data to the processor via its debug transfer registers. Now with control of the processor, we can access and program the other various components in the system and can now set breakpoints through the FPB, the flesh patch, and breakpoint unit, watchpoints, and enable trace through the DWT data watchpoint and trace unit, which can then signal trace sources like the MTB, micro trace buffer, the ETM, embedded trace macrocells and ITN instrumentation trace macrocells to start generating trace. The generator trace packets can then flow to various tracings, like some of the on-chip buffers, system memory, or TPIU, the trace port interface unit, which can then be read by the debugger to view the processor's execution history. Arm debug mostly falls into two categories; invasive and non-invasive. An invasive debugging is any debug method that potentially severely affects the state of the system, such as stopping and restarting the processor, modifying the core registers and or memory. It can be very intrusive to the execution of our program since we already essentially just hijacking control from the core. Non-invasive debugging, on the other hand, is any debug method that does not potentially severely affects the state of the system, such as enabling trace to capture execution history, or enabling performance monitoring unit to capture various performance metrics. Not all non-invasive debug is completely non-intrusive. However, there may be a bit of software overhead that are needed to program up the probe PMU counters. Routing trace to system memory could take the bus and interconnect bandwidth, and PMU counters can optionally overflow and generate interrupts just to list a few examples. Ultimately, the type of debugging actions to perform depends on the state of our software development. Are we testing for the correctness of our application running up the target? In this case, we do want to hold the processor every once in a while and peek and poke at the registers and the memory. Or, are we mostly certain of the correctness of our code and now wants to just to capture some performance benchmarks. Then collecting trace and programming the PMU counters may be the better way to go. Falling under the invasive category is halting debug. When halting debug is enabled in the processor, in the debug halting control and status register, and a qualifying debug event occurs, the processor enters the debug state and is then halted. In this halting state, no instruction will execute and no interrupts are serviced. The CPU clock is essentially stopped. At this point, the processor is solely controlled to the external debug interface by our debugger. The qualifying debug events for halting debug is any of those listed on this page. When the processor is halted, we can look at the debug fault status register to see the cause. The cause could be one of the below, such as the PMU counter has overflowed, or some component on the SOC has asserted the core input signal external debug request. Or it could be an exception triggered our vector catch settings, or we have hit a watchpoint, a breakpoint, or the user has issued a halt request with the external debugger. The alternative, less invasive but still intrusive counterpart to halting debug is the exception-based self-hosted debug, or known to previous architectures as the monitor mode debug. The processor can be configured to take debug monitor exceptions instead of a halting when reaching one of those qualifying debug events. Essentially, the core never enters the debug state, but just taken debug exception and the user-created exception handler will read the DFSR to determine what to do. Self-hosted debug is much better suited for systems that are deployed the field in which attaching an external debugger is difficult, or system with hard real time requirements that does not permit to halt, such as in a motor or a disc control device. Debug monitor may also be used to handle PMU counter overflows where the exception handler can simply record the result and then reset the counter for the PMU counters to continue. The method to enable self-hosted debug is always implemented at any processor which implements the Armv8-M mainline extension, such as the Cortex M33, but never implemented in the baseline implementations, such as the Cortex M23.