zoukankan      html  css  js  c++  java
  • QEMU Trace

    Trace

    semihosting    itm    segger-rtt

    https://github.com/pokitoz/qemu-lm3s6965evb

    https://github.com/pokitoz/qemu-lm3s6965evb/blob/master/start.c

    https://github.com/iNvEr7/qemu-learn

    Cortex-M3

    链接参数中需要加入 -specs=nano.specs -specs=rdimon.specs

    #include <stdarg.h>
    #include <stdio.h>
    #include <stdlib.h>

    /*
    Static functions and constant data */ const int SYS_WRITE0 = 0x04; void semihost(int sys_id, const void *arg) { register int r0 __asm__ ("r0") = sys_id; register const void *r1 __asm__ ("r1") = arg; __asm__ volatile ("bkpt 0xab"); (void) r0; (void) r1; } void logPrint(const char* format, ...) { char buffer[256] = {''}; int bufferPos = 0; unsigned int hex; va_list arg; va_start(arg, format); for(const char* nextChar = format; *nextChar != ''; nextChar++) { while ((*nextChar != '%') && (*nextChar != '')) { sprintf(buffer + bufferPos, "%c", *nextChar); bufferPos++; nextChar++; } if (*nextChar == '') { break; } nextChar++; switch (*nextChar) { case 'x': hex = va_arg(arg, unsigned int); int written = 0; written = sprintf(buffer + bufferPos, "%x", hex); bufferPos = bufferPos + written; break; } } buffer[bufferPos] = ''; va_end(arg); semihost(SYS_WRITE0, buffer); } int main(void) { uint8_t i; uint8_t str[] = "hello world! "; semihost(SYS_WRITE0, str); for(i = 0; i < 8; i++) { logPrint("hello world! 0x%x ", i); } return 0; }
    /*
     * This file is part of the µOS++ distribution.
     *   (https://github.com/micro-os-plus)
     * Copyright (c) 2015 Liviu Ionescu.
     *
     * Permission is hereby granted, free of charge, to any person
     * obtaining a copy of this software and associated documentation
     * files (the "Software"), to deal in the Software without
     * restriction, including without limitation the rights to use,
     * copy, modify, merge, publish, distribute, sublicense, and/or
     * sell copies of the Software, and to permit persons to whom
     * the Software is furnished to do so, subject to the following
     * conditions:
     *
     * The above copyright notice and this permission notice shall be
     * included in all copies or substantial portions of the Software.
     *
     * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
     * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
     * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
     * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
     * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
     * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
     * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
     * OTHER DEALINGS IN THE SOFTWARE.
     */
    
    #ifndef CMSIS_PLUS_ARM_SEMIHOSTING_H_
    #define CMSIS_PLUS_ARM_SEMIHOSTING_H_
    
    // ----------------------------------------------------------------------------
    
    // Semihosting operations.
    enum OperationNumber
    {
      // Regular operations
      SEMIHOSTING_EnterSVC = 0x17,
      SEMIHOSTING_ReportException = 0x18,
      SEMIHOSTING_SYS_CLOSE = 0x02,
      SEMIHOSTING_SYS_CLOCK = 0x10,
      SEMIHOSTING_SYS_ELAPSED = 0x30,
      SEMIHOSTING_SYS_ERRNO = 0x13,
      SEMIHOSTING_SYS_FLEN = 0x0C,
      SEMIHOSTING_SYS_GET_CMDLINE = 0x15,
      SEMIHOSTING_SYS_HEAPINFO = 0x16,
      SEMIHOSTING_SYS_ISERROR = 0x08,
      SEMIHOSTING_SYS_ISTTY = 0x09,
      SEMIHOSTING_SYS_OPEN = 0x01,
      SEMIHOSTING_SYS_READ = 0x06,
      SEMIHOSTING_SYS_READC = 0x07,
      SEMIHOSTING_SYS_REMOVE = 0x0E,
      SEMIHOSTING_SYS_RENAME = 0x0F,
      SEMIHOSTING_SYS_SEEK = 0x0A,
      SEMIHOSTING_SYS_SYSTEM = 0x12,
      SEMIHOSTING_SYS_TICKFREQ = 0x31,
      SEMIHOSTING_SYS_TIME = 0x11,
      SEMIHOSTING_SYS_TMPNAM = 0x0D,
      SEMIHOSTING_SYS_WRITE = 0x05,
      SEMIHOSTING_SYS_WRITEC = 0x03,
      SEMIHOSTING_SYS_WRITE0 = 0x04,
    
      // Codes returned by SEMIHOSTING_ReportException
      ADP_Stopped_ApplicationExit = ((2 << 16) + 38),
      ADP_Stopped_RunTimeError = ((2 << 16) + 35),
    
    };
    
    // ----------------------------------------------------------------------------
    
    // SWI numbers and reason codes for RDI (Angel) monitors.
    #define AngelSWI_ARM                    0x123456
    #ifdef __thumb__
    #define AngelSWI                        0xAB
    #else
    #define AngelSWI                        AngelSWI_ARM
    #endif
    // For thumb only architectures use the BKPT instruction instead of SWI.
    #if defined(__ARM_ARCH_7M__)     
        || defined(__ARM_ARCH_7EM__) 
        || defined(__ARM_ARCH_6M__)
    #define AngelSWIInsn                    "bkpt"
    #define AngelSWIAsm                     bkpt
    #else
    #define AngelSWIInsn                    "swi"
    #define AngelSWIAsm                     swi
    #endif
    
    #if defined(OS_DEBUG_SEMIHOSTING_FAULTS)
    // Testing the local semihosting handler cannot use another BKPT, since this
    // configuration cannot trigger HaedFault exceptions while the debugger is
    // connected, so we use an illegal op code, that will trigger an
    // UsageFault exception.
    #define AngelSWITestFault       "setend be"
    #define AngelSWITestFaultOpCode (0xB658)
    #endif
    
    static inline int
    __attribute__ ((always_inline))
    call_host (int reason, void* arg)
    {
      int value;
      asm volatile (
    
          " mov r0, %[rsn]  
    "
          " mov r1, %[arg]  
    "
    #if defined(OS_DEBUG_SEMIHOSTING_FAULTS)
          " " AngelSWITestFault " 
    "
    #else
          " " AngelSWIInsn " %[swi] 
    "
    #endif
          " mov %[val], r0"
    
          : [val] "=r" (value) /* Outputs */
          : [rsn] "r" (reason), [arg] "r" (arg), [swi] "i" (AngelSWI) /* Inputs */
          : "r0", "r1", "r2", "r3", "ip", "lr", "memory", "cc"
          // Clobbers r0 and r1, and lr if in supervisor mode
      );
    
      // Accordingly to page 13-77 of ARM DUI 0040D other registers
      // can also be clobbered. Some memory positions may also be
      // changed by a system call, so they should not be kept in
      // registers. Note: we are assuming the manual is right and
      // Angel is respecting the APCS.
      return value;
    }
    
    // ----------------------------------------------------------------------------
    
    // Function used in _exit() to return the status code as Angel exception.
    static inline void
    __attribute__ ((always_inline,noreturn))
    report_exception (int reason)
    {
      call_host (SEMIHOSTING_ReportException, (void*) reason);
    
      for (;;)
        ;
    }
    
    // ----------------------------------------------------------------------------
    
    #endif /* CMSIS_PLUS_ARM_SEMIHOSTING_H_ */
    View Code

    https://github.com/micro-os-plus/semihosting-xpack

    https://github.com/micro-os-plus/micro-os-plus-iii/blob/1ea30f65acfc9b25e8bf6558035e5dd1bc3b9127/include/cmsis-plus/arm/semihosting.h

    ITM

     /*
      * This file is part of the µOS++ distribution.
      *   (https://github.com/micro-os-plus)
      * Copyright (c) 2015 Liviu Ionescu.
      *
      * Permission is hereby granted, free of charge, to any person
      * obtaining a copy of this software and associated documentation
      * files (the "Software"), to deal in the Software without
      * restriction, including without limitation the rights to use,
      * copy, modify, merge, publish, distribute, sublicense, and/or
      * sell copies of the Software, and to permit persons to whom
      * the Software is furnished to do so, subject to the following
      * conditions:
      *
      * The above copyright notice and this permission notice shall be
      * included in all copies or substantial portions of the Software.
      *
      * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
      * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
      * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
      * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
      * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
      * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
      * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
      * OTHER DEALINGS IN THE SOFTWARE.
      */
     
     #if defined(__ARM_EABI__)
     
     // ----------------------------------------------------------------------------
     
     #if defined(TRACE)
     
     #include <cmsis-plus/os-app-config.h>
     
     #if defined(OS_USE_TRACE_ITM)
     
     #include <cmsis-plus/diag/trace.h>
     
     // TODO: Find a better way to include the ITM definitions (including
     // the entire vendor header is averkill).
     #include <cmsis_device.h>
     
     // ----------------------------------------------------------------------------
     
     namespace os
     {
         namespace trace
         {
           // ------------------------------------------------------------------------
     
           void
           initialize (void)
           {
             // For ITM no inits required.
             // The debug registers are set the JTAG software.
           }
     
           // ----------------------------------------------------------------------
     
     #if defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__)
     
           // ITM is the ARM standard mechanism, running over SWD/SWO on Cortex-M3/M4
           // devices, and is the recommended setting, if available.
           //
           // The JLink probe and the GDB server fully support SWD/SWO
           // and the JLink Debugging plug-in enables it by default.
           // The current OpenOCD does not include support to parse the SWO stream,
           // so this configuration will not work on OpenOCD (will not crash, but
           // nothing will be displayed in the output console).
     
     #if !defined(OS_INTEGER_TRACE_ITM_STIMULUS_PORT)
     #define OS_INTEGER_TRACE_ITM_STIMULUS_PORT     (0)
     #endif
     
           ssize_t
           write (const void* buf, std::size_t nbyte)
           {
             if (buf == nullptr || nbyte == 0)
               {
                 return 0;
               }
     
             const char* cbuf = (const char*) buf;
     
             for (size_t i = 0; i < nbyte; i++)
               {
                 // Check if ITM or the stimulus port are not enabled.
                 if (((ITM->TCR & ITM_TCR_ITMENA_Msk) == 0)
                     || ((ITM->TER & (1UL << OS_INTEGER_TRACE_ITM_STIMULUS_PORT))
                         == 0))
                   {
                     // Return the number of sent characters (may be 0).
                     return (ssize_t) i;
                   }
     
                 // Wait until STIMx is ready...
                 while (ITM->PORT[OS_INTEGER_TRACE_ITM_STIMULUS_PORT].u32 == 0)
                   ;
                 // then send data, one byte at a time
                 ITM->PORT[OS_INTEGER_TRACE_ITM_STIMULUS_PORT].u8 =
                     (uint8_t) (*cbuf++);
               }
     
             // All characters successfully sent.
             return (ssize_t) nbyte;
           }
     
     #else
     
     #error "ITM available only on ARCH 7M"
     
     #endif /* defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__) */
     
         } /* namespace trace */
     } /* namespace os */
     
     #endif /* defined(OS_USE_TRACE_ITM) */
     #endif /* defined(TRACE) */
     
     // ----------------------------------------------------------------------------
     
     #endif /* defined(__ARM_EABI__) */
     
    View Code

    http://micro-os-plus.github.io/reference/cmsis-plus/trace-itm_8cpp_source.html

    http://micro-os-plus.github.io/reference/cmsis-plus/trace-semihosting_8cpp_source.html

    https://wiki.segger.com/Semihosting

    https://www.keil.com/support/man/docs/armcc/armcc_pge1358787045051.htm

    https://bbs.pediy.com/thread-266324.htm

    https://github.com/iNvEr7/qemu-learn/tree/master/semihosting-newlib

    https://github.com/OP-TEE/build/blob/637c7863d7e428d673b18bae21ac1db52b2a9b8d/qemu.mk#L179

    QEMU Bug

    https://bugs.launchpad.net/qemu/+bug/1915925

    https://bugs.launchpad.net/qemu/+bug/1918302

    不是newlib的bug

    https://sourceware.org/pipermail/newlib/2021/018261.html

    patch

    https://github.com/qemu/qemu/tree/c95bd5ff1660883d15ad6e0005e4c8571604f51a

    diff --git a/semihosting/arm-compat-semi.c b/semihosting/arm-compat-semi.c
    index 94950b6c56..d8181c972c 100644
    --- a/semihosting/arm-compat-semi.c
    +++ b/semihosting/arm-compat-semi.c
    @@ -1232,7 +1232,11 @@ target_ulong do_common_semihosting(CPUState *cs)
                 for (i = 0; i < ARRAY_SIZE(retvals); i++) {
                     bool fail;
     
    -                fail = SET_ARG(i, retvals[i]);
    +                if (is_a64(env)) {
    +                    fail = put_user_u64(retvals[i], arg0 + i * 8);
    +                } else {
    +                    fail = put_user_u32(retvals[i], arg0 + i * 4);
    +                }
     
                     if (fail) {
                         /* Couldn't write back to argument block */

     或者使用下面这个

    diff --git a/semihosting/arm-compat-semi.c b/semihosting/arm-compat-semi.c
    index 94950b6c56..1028e19133 100644
    --- a/semihosting/arm-compat-semi.c
    +++ b/semihosting/arm-compat-semi.c
    @@ -789,6 +789,11 @@ static const GuestFDFunctions guestfd_fns[] = {
         (is_a64(env) ?                                      
          put_user_u64(val, args + (n) * 8) :                
          put_user_u32(val, args + (n) * 4))
    +
    +#define SET_ARG0(n, val)                                 
    +    (is_a64(env) ?                                      
    +     put_user_u64(val, arg0 + (n) * 8) :                
    +     put_user_u32(val, arg0 + (n) * 4))
     #endif
     
     #ifdef TARGET_RISCV
    @@ -1232,7 +1237,7 @@ target_ulong do_common_semihosting(CPUState *cs)
                 for (i = 0; i < ARRAY_SIZE(retvals); i++) {
                     bool fail;
     
    -                fail = SET_ARG(i, retvals[i]);
    +                fail = SET_ARG0(i, retvals[i]);
     
                     if (fail) {
                         /* Couldn't write back to argument block */

    github上最新commit的代码已经修复该问题

    https://github.com/qemu/qemu/commit/35e3f029a966845e090dc8b295312751524df967

    xPack QEMU ARM (qemu-system-gnuarmeclipse)已经修复该问题

    https://github.com/xpack-dev-tools/qemu

    https://github.com/xpack-dev-tools/qemu/blob/xpack/target-arm/arm-semi.c

    https://github.com/xpack-dev-tools/qemu/commit/f5666418c449b49917ea24cdb0bed76a602a3c74

                for (i = 0; i < ARRAY_SIZE(retvals); i++) {
                    bool fail;
    
                    if (is_a64(env)) {
                        fail = put_user_u64(retvals[i], arg0 + i * 8);
                    } else {
                        fail = put_user_u32(retvals[i], arg0 + i * 4);
                    }
    
                    if (fail) {
                        /* Couldn't write back to argument block */
                        return -1;
                    }
                }
                return 0;
            }

    https://www.bahutou.cn/2018/04/11/RTOS-dev-env/

    https://github.com/beckus/stm32_p103_demos

    https://logiase.github.io/The-Embedded-Rust-Book-CN/start/qemu.html

    https://rustcc.com/article?id=88c8ac37-c31c-495c-8b17-7e12b51a618a

    https://github.com/rust-embedded/cortex-m-quickstart

    https://docs.rust-embedded.org/book/start/qemu.html

    https://github.com/cbhust/STM32F429_Discovery_FreeRTOS_9

    https://www.cnblogs.com/wall-f/p/7615943.html

    https://github.com/SuYouge/stm32f4-vscode/tree/ucos/cube/UCOSIII

  • 相关阅读:
    mysql 5.5多实例部署【图解】
    mysql多实例的配置和管理
    Xtrabackup数据全备份与快速搭建从服务器
    REST API设计指导——译自Microsoft REST API Guidelines(四)
    REST API设计指导——译自Microsoft REST API Guidelines(三)
    REST API设计指导——译自Microsoft REST API Guidelines(二)
    REST API设计指导——译自Microsoft REST API Guidelines(一)
    【活动提示】免费帮你做系统,请点击!
    程序员最大的悲哀是什么?
    工欲善其事必先利其器——产品篇
  • 原文地址:https://www.cnblogs.com/sinferwu/p/14565703.html
Copyright © 2011-2022 走看看