keil+stm32+jlink uses swd to output printf

Publisher:VolareLatest update time:2016-12-16 Source: eefocusKeywords:keil  stm32  jlink Reading articles on mobile phones Scan QR code
Read articles on your mobile phone anytime, anywhere

Use ITM mechanism to debug stm32 microcontroller, implement printf and scanf.

1. Introduction to ITM
ITM mechanism is a debugging mechanism, a new generation of debugging method. Before this, there was a more famous debugging method called semihosting.

Anyone who has written C language on a PC knows that printf can output to the console and scanf can get input from the console. Here, printf/scanf are standard library functions. Using these functions of the operating system, we can debug the program very conveniently. On embedded devices (such as stm32 microcontroller platform), development tools (such as MDK/IAR) also provide standard library functions, and naturally also provide printf/scanf functions. So can these functions be used? The question is, where does printf output? And in most cases, there is no keyboard, so how to use scanf to input?

We all know that embedded devices generally use emulators, such as the common Jlink/ulink, which can realize burning, single-stepping, breakpoints, viewing variables, etc. The emulator connects the PC and the microcontroller. Smart designers are considering whether it is possible to use an emulator to enable the microcontroller to use the PC screen and PC keyboard to achieve printf output and scanf key acquisition.
In other words, the following hello, world program

  1. #include   

  2. int main()  

  3. {  

  4.         //Hardware initialization  

  5.         //....  

  6.         printf("hello, world");  

  7.         for(;;);  

  8. }  


After the program is burned into the MCU, the emulator connects the MCU to the PC, and the online debugging starts, the program will output "Hello, world" to the PC and display it in a window of the development tool (MDK/IAR, etc.).

This is equivalent to the MCU using the display/input devices of the PC to realize its own output/input. This method is undoubtedly convenient for program developers to debug.

There are many ways to implement this mechanism, the more famous ones are semihosting (semihosting mechanism) and ITM mechanism.
ITM is a new generation of debugging mechanism launched by ARM after the launch of semihosting. Now let's try this debugging method.

2. STM32 uses ITM to debug
MCU: stm32f207VG
Emulator: Jlink V8
IDE: MDK4.50

2.1 Hardware connection
The ITM mechanism requires the use of the SWD interface and the connection of the SWO line. The general four-wire SWD method (VCC SDCLK, SDIO, GND) is not acceptable. The standard 20-pin JTAG interface is OK. You just need to set up the SWD interface in MDK.

2.2 Add redirection file
Save the following file as any C file and add it to the project. Here is a brief explanation of this file. You should know that our program is running on the microcontroller. Why can printf be output to the MDK window? This is because printf in the standard library actually calls fputc to achieve output, so we need to write an fputc function ourselves. This function will use the registers provided by ITM (similar to USART) to achieve data transmission. The emulator will receive this data and send it to the PC.

In fact, if your microcontroller is connected to an LCD, then you only need to re-implement the fputc function and output it to the LCD, so when you call printf, it will be output to the LCD. This mechanism is the so-called redirection mechanism.

  1. #include   

  2.   

  3. #define ITM_Port8(n)    (*((volatile unsigned char *)(0xE0000000+4*n)))  

  4. #define ITM_Port16(n)   (*((volatile unsigned short*)(0xE0000000+4*n)))  

  5. #define ITM_Port32(n)   (*((volatile unsigned long *)(0xE0000000+4*n)))  

  6. #define DEMCR           (*((volatile unsigned long *)(0xE000EDFC)))  

  7. #define TRCENA          0x01000000  

  8.   

  9. struct __FILE { int handle; /* Add whatever you need here */ };  

  10.     FILE __stdout;  

  11.     FILE __stdin;  

  12.       

  13. int fputc(int ch, FILE *f)   

  14. {  

  15.     if (DEMCR & TRCENA)   

  16.     {  

  17.         while (ITM_Port32(0) == 0);  

  18.         ITM_Port8(0) = ch;  

  19.     }  

  20.     return(ch);  

  21. }  


2.2 Configure JLINK's initialization configuration file.

Place the following file under your project and give it any name. Here I named it STM32DBG.ini

  1. /******************************************************************************/  

  2. /* STM32DBG.INI: STM32 Debugger Initialization File                           */  

  3. /******************************************************************************/  

  4. // <<< Use Configuration Wizard in Context Menu >>>                           //   

  5. /******************************************************************************/  

  6. /* This file is part of the uVision/ARM development tools.                    */  

  7. /* Copyright (c) 2005-2007 Keil Software. All rights reserved.                */  

  8. /* This software may only be used under the terms of a valid, current,        */  

  9. /* end user licence from KEIL for a compatible version of KEIL software       */  

  10. /* development tools. Nothing else gives you the right to use this software.  */  

  11. /******************************************************************************/  

  12.   

  13.   

  14. FUNC void DebugSetup (void) {  

  15. //  Debug MCU Configuration  

  16. //       DBG_SLEEP      Debug Sleep Mode  

  17. //       DBG_STOP       Debug Stop Mode  

  18. //       DBG_STANDBY    Debug Standby Mode  

  19. //       TRACE_IOEN     Trace I/O Enable   

  20. //    TRACE_MODE     Trace Mode  

  21. //             <0=> Asynchronous  

  22. //             <1=> Synchronous: TRACEDATA Size 1  

  23. //             <2=> Synchronous: TRACEDATA Size 2  

  24. //             <3=> Synchronous: TRACEDATA Size 4  

  25. //       DBG_IWDG_STOP  Independant Watchdog Stopped when Core is halted  

  26. //       DBG_WWDG_STOP  Window Watchdog Stopped when Core is halted  

  27. //      DBG_TIM1_STOP  Timer 1 Stopped when Core is halted  

  28. //      DBG_TIM2_STOP  Timer 2 Stopped when Core is halted  

  29. //      DBG_TIM3_STOP  Timer 3 Stopped when Core is halted  

  30. //      DBG_TIM4_STOP  Timer 4 Stopped when Core is halted  

  31. //      DBG_CAN_STOP   CAN Stopped when Core is halted  

  32. //   

  33. _WDWORD(0xE0042004, 0x00000027);  // DBGMCU_CR  

  34. _WDWORD(0xE000ED08, 0x20000000);   // Setup Vector Table Offset Register  

  35. }  

  36.   

  37. DebugSetup();                       // Debugger Setup  


Here is a brief explanation of this file,
_WDWORD(0xE0042004, 0x00000027); // DBGMCU_CR
This sentence means that you want to write 0x000000027 to the address 0xE0042004. The meaning of each bit of this register is explained in detail in the comments. 0x27 means
        BIT0 DBG_SLEEP
        BIT1 DBG_STOP
        BIT2 DBG_STANDBY
        BIT5 TRACE_IOEN
Note that to use the ITM mechanism, BIT5 must be turned on.

Open the MDK project and modify it according to the figure below.

2.3 Configuration of JLINK in MDK

Note two points in the figure below:
1). The CoreClock here is 120M, because the author uses the stm32F207VG chip, and the clock is configured to 120M, so fill in 120M here. If you use stm32F10x, the clock is configured to 72M, then you need to fill in 72M here. That is, it needs to be consistent with the actual situation.
2). Finally, be sure to check 0 and remove the check marks on other bits. It is best to keep it consistent with this figure, except for CoreClock.

2.4 Burn the program and start debugging. As you can see, I inserted a printf statement in the program source code, and then you can see the output of the program according to the figure below.

3. Comprehensive version uses scanf and printf
3.1 Add retarget file
Save the following code as retarget.c and add it to the project.

  1. #pragma import(__use_no_semihosting_swi)  

  2.   

  3. struct __FILE { int handle; /* Add whatever you need here */ };  

  4.     FILE __stdout;  

  5.     FILE __stdin;  

  6.       

  7. int fputc(int ch, FILE *f)   

  8. {  

  9.     return ITM_SendChar(ch);  

  10. }  

  11.   

  12. volatile int32_t ITM_RxBuffer;  

  13. int fgetc(FILE *f)  

  14. {  

  15.   while (ITM_CheckChar() != 1) __NOP();  

  16.   return (ITM_ReceiveChar());  

  17. }  

  18.   

  19. int ferror(FILE *f)  

  20. {  

  21.     /* Your implementation of ferror */  

  22.     return EOF;  

  23. }  

  24.   

  25. void _ttywrch(int c)  

  26. {  

  27.     fputc(c, 0);  

  28. }  

  29.   

  30. int __backspace()  

  31. {  

  32.     return 0;  

  33. }  

  34. void _sys_exit(int return_code)  

  35. {  

  36. label:  

  37.     goto label;  /* endless loop */  

  38. }  


3.2 Compile and run
Compile, burn, run, open the Debug (printf) viewer, and you can see the input, see the figure below

Here are some explanations about the retarget.c file.
1). The above code is actually modified from X:\Keil\ARM\Startup\Retarget.c. There are two functions that scanf depends on, fgetc and __backspace, which need to be implemented. If the __backespace function is missing, scanf cannot get input from the Debug Viewer Dialog window. In addition, the code provided above is just a demo to demonstrate the effect. It should be processed more perfectly when used in production. See reference [1].

2). The functions ITM_SendChar, ITM_CheckChar, and ITM_ReceiveChar are in the library file CMSIS\Include\core_cm3.h.

3) To view the symbolic reference relationship of the function, you can generate a detailed map file. Add the --verbose --list rtt.map option to the command line to generate a file named rtt.map.

4. Combining ITM and RTT (to be implemented)
grissiom wrote:
I suddenly thought that maybe we can make this semihost into a device, and then rt_console_set_device("semi") can directly use semihost to do finsh/rt_kprintf... I don't know if it is feasible...

prife: I don't know whether ITM reception supports interrupts. Currently, the reception of characters uses polling. It only makes sense if it is an interrupt. In this way, the ITM device can be made into an rtt device, and finsh can run in the Debug printf Viewer window. In the future, you only need to connect a jtag/SWD port to debug, and you don't need to connect a serial port line.

References
[1] MDK help. Indirect semihosting C library function dependencies
[2] MDK help ARM Development Tools.
         Debugger Adapter User's Guides
             J-Link/J-Trace User's Guide
         Libraries and Floating Point Support Referencee
         Libraries and Floating Point Support Guide

         Linker Reference Guide


Keywords:keil  stm32  jlink Reference address:keil+stm32+jlink uses swd to output printf

Previous article:The USART interrupt of STM32 is in an infinite loop, resulting in a system crash.
Next article:Doubts in STM32 timer output comparison mode

Recommended ReadingLatest update time:2024-11-16 15:00

stm32_timer basic timer configuration and light flashing
There are a total of 11 timers in STM32, including 2 advanced control timers, 4 ordinary timers and 2 basic timers, as well as 2 watchdog timers and 1 system tick timer. TIM1 and TIM8 are advanced timers that can generate three pairs of PWM complementary outputs, and are commonly used to drive three-phase motors. The
[Microcontroller]
stm32_timer basic timer configuration and light flashing
Three compilation modes in KEIL and their impact on variable space
There are three compilation mode control commands: SMALL, COMPACT, and LARGE. Their effects on variable memory space are as follows. SMALL: All variables are defined in the on-chip RAM of the 8051 microcontroller, and the access speed to such variables is the fastest. In addition, the stack must also be locat
[Microcontroller]
stm32.cube (I)——System architecture and directory structure
I. Introduction The application scenarios of Arm are often much more complex than those of 51 MCUs. If the development of an advanced application requires the reconstruction of even the underlying structural code, there will be huge risks in terms of cost and R&D cycle. In order to simplify the coding process, chip ma
[Microcontroller]
A brief analysis of STM32's CANTTCAN mode
1 Introduction             Traditional CAN uses event-triggered message transmission mechanism, CSMA/CD+AMP (Carrier-Sense Multiple Access with Collision Detection and Arbitration on Message Priorities) media access control mechanism, that is, when multiple messages are sent at the same time, low-priority messages a
[Microcontroller]
A brief analysis of STM32's CANTTCAN mode
Coexistence of Keil C51 and Keil MDK
keil c51 version c51v959, the latest version in 2018 is C51V960A.EXE keil mdk 5.29, the latest version After the two are installed, they both have green icons. The old version before was mdk4.74 c51v906, and they both have blue icons. During the installation process, remember not to instal
[Microcontroller]
Keil accurately measures code execution time
In the project settings, under "Debug", select Hardware Simulation on the right, click the drop-down box to select "J-LINK/J-TRACE", and then click "Setting" In the pop-up window, under "Debug", select "JTAG" or "SW", and then select the download rate. Click on the Trace tab, if you select SW Check the "En
[Microcontroller]
Keil accurately measures code execution time
Xintang N76E003 MCU downloads program and downloads pin multiplexing in Keil
1. Install other drivers related to the downloader, and then download them using the download tool. 2. Open Keil and plug in the downloader. You will be prompted to upgrade the firmware. Just agree to it. Finally, you need to unplug and plug it in again, and then select in Keil: 3. Click "Settings" and set as shown
[Microcontroller]
Xintang N76E003 MCU downloads program and downloads pin multiplexing in Keil
Design of LF RFID identification system based on STM32
Radio Frequency Identification (RFID) is an automatic identification technology that has matured since the 1980s. RFID uses radio frequency to conduct non-contact two-way communication to achieve identification purposes and exchange data. It mainly achieves contactless information transmission through spatial coupling
[Microcontroller]
Design of LF RFID identification system based on STM32
Latest Microcontroller Articles
  • Download from the Internet--ARM Getting Started Notes
    A brief introduction: From today on, the ARM notebook of the rookie is open, and it can be regarded as a place to store these notes. Why publish it? Maybe you are interested in it. In fact, the reason for these notes is ...
  • Learn ARM development(22)
    Turning off and on interrupts Interrupts are an efficient dialogue mechanism, but sometimes you don't want to interrupt the program while it is running. For example, when you are printing something, the program suddenly interrupts and another ...
  • Learn ARM development(21)
    First, declare the task pointer, because it will be used later. Task pointer volatile TASK_TCB* volatile g_pCurrentTask = NULL;volatile TASK_TCB* vol ...
  • Learn ARM development(20)
    With the previous Tick interrupt, the basic task switching conditions are ready. However, this "easterly" is also difficult to understand. Only through continuous practice can we understand it. ...
  • Learn ARM development(19)
    After many days of hard work, I finally got the interrupt working. But in order to allow RTOS to use timer interrupts, what kind of interrupts can be implemented in S3C44B0? There are two methods in S3C44B0. ...
  • Learn ARM development(14)
  • Learn ARM development(15)
  • Learn ARM development(16)
  • Learn ARM development(17)
Change More Related Popular Components

EEWorld
subscription
account

EEWorld
service
account

Automotive
development
circle

About Us Customer Service Contact Information Datasheet Sitemap LatestNews


Room 1530, 15th Floor, Building B, No.18 Zhongguancun Street, Haidian District, Beijing, Postal Code: 100190 China Telephone: 008610 8235 0740

Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号