且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

Qemu裸机仿真-如何查看UART输出?

更新时间:2023-10-12 23:44:58

在尝试输出任何字符之前,您需要初始化UART. 例如,通过使用UART0仿真可以很好地工作. >此程序:

You need to initialize the UART prior to attempt outputing any characters. The UART0 emulation is working fine for example by using a slightly modified version of this program:

/opt/qemu-4.2.0/bin/qemu-system-arm -semihosting --semihosting-config enable=on,target=native -nographic -serial mon:stdio -machine xilinx-zynq-a9 -m 768M -cpu cortex-a9 -kernel hello05.elf

Hello number 1

git diff命令的修改后的输出为:

The output of the git diff command after modifications were made was:

diff --git a/Hello01/Makefile b/Hello01/Makefile
index 4a1b512..8d6d12a 100644
--- a/Hello01/Makefile
+++ b/Hello01/Makefile
@@ -1,10 +1,10 @@
 ARMGNU ?= arm-linux-gnueabihf
-COPS    =   
+COPS    = -g -O0  
 ARCH    = -mcpu=cortex-a9 -mfpu=vfpv3 

 gcc : hello01.bin

-all : gcc clang
+all : gcc 

 clean :
    rm -f *.o
@@ -15,8 +15,6 @@ clean :
    rm -f *.img
    rm -f *.bc

-clang: hello02.bin
-
 startup.o : startup.s
    $(ARMGNU)-as $(ARCH) startup.s -o startup.o

diff --git a/Hello01/hello01.c b/Hello01/hello01.c
index 20cb4a4..14ed2a0 100644
--- a/Hello01/hello01.c
+++ b/Hello01/hello01.c
@@ -10,16 +10,16 @@
 */


-#define UART1_BASE 0xe0001000
-#define UART1_TxRxFIFO0 ((unsigned int *) (UART1_BASE + 0x30))
+#define UART0_BASE 0xe0000000
+#define UART0_TxRxFIFO0 ((unsigned int *) (UART0_BASE + 0x30))

-volatile unsigned int * const TxRxUART1 = UART1_TxRxFIFO0;
+volatile unsigned int * const TxRxUART0 = UART0_TxRxFIFO0;

 void print_uart1(const char *s) 
 {
     while(*s != '\0') 
     {     /* Loop until end of string */
-    *TxRxUART1 = (unsigned int)(*s); /* Transmit char */
+    *TxRxUART0 = (unsigned int)(*s); /* Transmit char */
     s++; /* Next char */
     }
 }
@@ -28,4 +28,4 @@ void c_entry()
 {
    print_uart1("\r\nHello world!");
    while(1) ; /*dont exit the program*/
-}
\ No newline at end of file
+}
diff --git a/Hello05/Makefile b/Hello05/Makefile
index 9d3ca23..bc9bb61 100644
--- a/Hello05/Makefile
+++ b/Hello05/Makefile
@@ -1,5 +1,5 @@
 ARMGNU ?= arm-linux-gnueabihf
-COPS    =   
+COPS    =  -g -O0
 ARCH    = -mcpu=cortex-a9 -mfpu=vfpv3 

 gcc : hello05.bin
diff --git a/Hello05/hello05.c b/Hello05/hello05.c
index 1b92dde..01ce7ee 100644
--- a/Hello05/hello05.c
+++ b/Hello05/hello05.c
@@ -26,7 +26,7 @@

 void c_entry() 
 {
-   init_uart1_RxTx_115200_8N1();
+   init_uart0_RxTx_115200_8N1();
    printf("\nHello number %d\n",1);
    while(1) ; /*dont exit the program*/
 }
diff --git a/Hello05/xuartps.c b/Hello05/xuartps.c
index bdf7ad1..74f68bd 100644
--- a/Hello05/xuartps.c
+++ b/Hello05/xuartps.c
@@ -16,42 +16,42 @@
 void putc(int *p ,char c);

 /*
-* Initiate UART1  ( /dev/ttyACM0 on host computer )
+* Initiate UART0  ( /dev/ttyACM0 on host computer )
 *   115,200 Baud 8-bit No-Parity 1-stop-bit
 */
-void init_uart1_RxTx_115200_8N1()
+void init_uart0_RxTx_115200_8N1()
 {
   /* Disable the transmitter and receiver before writing to the Baud Rate Generator */
-  UART1->control_reg0=0; 
+  UART0->control_reg0=0; 

   /* Set Baudrate to 115,200 Baud */
-  UART1->baud_rate_divider =XUARTPS_BDIV_CD_115200;
-  UART1->baud_rate_gen=     XUARTPS_BRGR_CD_115200;
+  UART0->baud_rate_divider =XUARTPS_BDIV_CD_115200;
+  UART0->baud_rate_gen=     XUARTPS_BRGR_CD_115200;

   /*Set 8-bit NoParity 1-StopBit*/
-  UART1->mode_reg0   =   XUARTPS_MR_PAR_NONE;  
+  UART0->mode_reg0   =   XUARTPS_MR_PAR_NONE;  

   /*Enable Rx & Tx*/
-  UART1->control_reg0=   XUARTPS_CR_TXEN | XUARTPS_CR_RXEN | XUARTPS_CR_TXRES | XUARTPS_CR_RXRES ;      
+  UART0->control_reg0=   XUARTPS_CR_TXEN | XUARTPS_CR_RXEN | XUARTPS_CR_TXRES | XUARTPS_CR_RXRES ;      


 }

-void sendUART1char(char s)
+void sendUART0char(char s)
 {
   /*Make sure that the uart is ready for new char's before continuing*/
-  while ((( UART1->channel_sts_reg0 ) & UART_STS_TXFULL) > 0) ;
+  while ((( UART0->channel_sts_reg0 ) & UART_STS_TXFULL) > 0) ;

   /* Loop until end of string */
-  UART1->tx_rx_fifo= (unsigned int) s; /* Transmit char */
+  UART0->tx_rx_fifo= (unsigned int) s; /* Transmit char */
 }

 /* "print.h" uses this function for is's printf implementation */
 void putchar(char c)
 {
   if(c=='\n')
-    sendUART1char('\r');
-  sendUART1char(c);
+    sendUART0char('\r');
+  sendUART0char(c);
 }

 /* <stdio.h>'s printf uses puts to send chars
@@ -61,9 +61,9 @@ int puts(const char *s)
     while(*s != '\0') 
     { 
      if(*s=='\n')
-         sendUART1char('\r');
+         sendUART0char('\r');

-      sendUART1char(*s); /*Send char to the UART1*/       
+      sendUART0char(*s); /*Send char to the UART0*/       
       s++; /* Next char */
     }
     return 0;
diff --git a/Hello05/xuartps.h b/Hello05/xuartps.h
index fc5008f..64e3b88 100644
--- a/Hello05/xuartps.h
+++ b/Hello05/xuartps.h
@@ -13,7 +13,7 @@
    #define u32 unsigned int
 #endif

-#define UART1_BASE 0xe0001000
+#define UART0_BASE 0xe0000000
 // Register Description as found in
 //    B.33 UART Controller (UART) p.1626
 struct XUARTPS{
@@ -34,7 +34,7 @@ struct XUARTPS{
         u32 Flow_delay_reg0;            /* Flow Control Delay Register  def=0*/
         u32 Tx_FIFO_trigger_level;};    /* Transmitter FIFO Trigger Level Register */

-static struct XUARTPS *UART1=(struct XUARTPS*) UART1_BASE;        
+static struct XUARTPS *UART0=(struct XUARTPS*) UART0_BASE;        

 /*
     Page 496
@@ -87,11 +87,11 @@ static struct XUARTPS *UART1=(struct XUARTPS*) UART1_BASE;
 #define XUARTPS_MR_CLKS_REF_CLK 0       /*  0: clock source is uart_ref_clk*/

 /*
-* Initiate UART1  ( /dev/ttyACM0 on host computer )
+* Initiate UART0  ( /dev/ttyACM0 on host computer )
 *   115,200 Baud 8-bit No-Parity 1-stop-bit
 */
-void init_uart1_RxTx_115200_8N1();
-void sendUART1char(char s);
+void init_uart0_RxTx_115200_8N1();
+void sendUART0char(char s);
 int puts(const char *s);
 //void putc((void*), char);

ZedBoard-BareMetal-Examples/Hello05目录执行的用于构建修改后的Hello05示例的命令为:

The command executed from the ZedBoard-BareMetal-Examples/Hello05 directory for building the modified Hello05 example was:

make ARMGNU=/opt/arm/9/gcc-arm-9.2-2019.12-x86_64-arm-none-eabi/bin/arm-none-eabi clean all 

这就是您的上一篇文章的最后评论使我认为您可能只希望能够看到程序的输出,但不一定必须使用UART0.

This being said, the last comment from your previous post made me think that you may just want to be able to see the output of your program, but not necessarily by using UART0.

在这种情况下,使用天使/半主机接口可以工作-我了解您可能尝试过这种方式.

If this is the case, using the Angel/Semihosting interface would do the job - I understand you may have attempted to go this way.

示例:

// hello.c:

#include <stdlib.h>

int main(int argc, char** argv)
{
    printf("Hello, World!\n");
    return EXIT_SUCCESS;
}

gcc命令:

/opt/arm/9/gcc-arm-9.2-2019.12-x86_64-arm-none-eabi/bin/arm-none-eabi-gcc -g -O0 --specs=rdimon.specs -o hello.elf hello.c

qemu命令:

/opt/qemu-4.2.0/bin/qemu-system-arm -semihosting --semihosting-config enable=on,target=native -nographic -serial mon:stdio -machine xilinx-zynq-a9 -m 768M -cpu cortex-a9 -kernel hello.elf

结果:

Hello, World!

使用半主机界面将允许您读取/写入文件,读取用户输入以及使用某些 CppUnit QEMU以及半主机界面..

Using the semihosting interface would allow you to read/write files, read user input, and to use some of the xUnit testing frameworks available for either C or C++ - I have been for example successfully be using CppUnit with QEMU and the Semihosting interface. at several occasions.

我希望有帮助.