<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>日常笔记</title>
    <description></description>
    <link>https://www.imstatic.com/</link>
    <atom:link href="https://www.imstatic.com/feed.xml" rel="self" type="application/rss+xml"/>
    <pubDate>Fri, 06 Feb 2026 06:49:04 +0000</pubDate>
    <lastBuildDate>Fri, 06 Feb 2026 06:49:04 +0000</lastBuildDate>
    <generator>Jekyll v3.10.0</generator>
    
      <item>
        <title>LPC MCUs and ELF manipulation</title>
        <description>&lt;h2 id=&quot;01-lpcs-and-vector-checksum&quot;&gt;01. LPCs and vector checksum&lt;/h2&gt;

&lt;p&gt;After playing with NXP LPC series MCUs for some while, something has bothered me: Verification of program flash against ELF files always fail.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/2022/05/image-7.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Hmmm.. That’s strange. Tried a few different LPC models, and the failure position is always 0x1C. After digging into the user manual, I found out these MCUs uses the reserved 0x1C vector as a checksum for the first 8 vectors. The bootloader sums up the first 8 words, and if the result is zero, the flash content is considered as valid and bootloader will jump to the application reset vector.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/2022/05/image-8.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Different IDEs and tools reacts differently to this hardware feature, for example, IAR will compute this checksum by the linker during link stage, and the final image or hex files will contain correct contents. J-Link and OpenOCD process this checksum beforee flashing the image to target MCUs, regardless what the original image has.&lt;/p&gt;

&lt;p&gt;However, this checksum machnism causes a problem when verifying the flash content against original ELF files, since the original file still contains invalid value for the checksum field, which will incremential download the first flash sector even if the application has no changes.&lt;/p&gt;

&lt;h2 id=&quot;02-elf-patching&quot;&gt;02. ELF Patching&lt;/h2&gt;

&lt;p&gt;Since I already know how the checksum is computed, the next thing is to find a way patching the ELF image, writing the correct checksum into the specified offset in interrupt vector table. Instead of grepping and using some regex magic, I decided using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;libelf&lt;/code&gt; from &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;elfutils&lt;/code&gt; to manipulating the section data.&lt;/p&gt;

&lt;p&gt;The documentation for &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;libelf&lt;/code&gt; is too brief to give me the instructions on how to modify the content of a specific section. After several hours of searching between mailing lists and with the help of an old book, I finally get the library working:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-C&quot;&gt;((uint32_t *)ivt_data-&amp;gt;d_buf)[7] = checksum;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;It is important to use &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;MMAP&lt;/code&gt; commands, which will modify the data in-place without touching other section information (Since we only modify one word).&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-C&quot;&gt;Elf *e_handle = elf_begin(elf_fd, ELF_C_RDWR_MMAP, NULL);
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The ELF will be modified in-place, which can be successfully verified by J-Flash.&lt;/p&gt;

&lt;p&gt;The code is published at &lt;a href=&quot;https://github.com/imi415/lpchecksum&quot;&gt;GitHub&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/2022/05/image-9.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;h2 id=&quot;03-references&quot;&gt;03. References&lt;/h2&gt;

&lt;p&gt;[1]: &lt;a href=&quot;https://sourceforge.net/projects/elftoolchain/files/Documentation/libelf-by-example/&quot;&gt;libelf example&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;[2]: &lt;a href=&quot;https://www.iar.com/sv/knowledge/support/technical-notes/general/ielftool-checksum---when-using-lpc-device/&quot;&gt;IAR&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;[3]: &lt;a href=&quot;https://www.nxp.com/webapp/Download?colCode=UM10850&quot;&gt;User Manual&lt;/a&gt; (Sign in required)&lt;/p&gt;

</description>
        <pubDate>Sun, 15 May 2022 13:10:38 +0000</pubDate>
        <link>https://www.imstatic.com/archivers/lpc-checksum</link>
        <guid isPermaLink="true">https://www.imstatic.com/archivers/lpc-checksum</guid>
        
        <category>hardware</category>
        
        
      </item>
    
      <item>
        <title>FreeRTOS on CH32V307</title>
        <description>&lt;h2 id=&quot;01---preface&quot;&gt;01 - Preface&lt;/h2&gt;

&lt;p&gt;During my recent quarantine days, I began working on something I ordered a while ago: WCH CH32V307 RISC-V microcontroller board. The board arrived in April, at first I made a few modifications to the SDK, composed a hello world template project and literally forgot it.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/2022/05/image-5.png&quot; alt=&quot;CH32V307 Dev Kit&quot; /&gt;
&lt;em&gt;CH32V307 Dev Kit&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;After being quarantined and transferred to a hotel, I finally got some time playing with it, and the first thing came across my mind is porting some RTOSes to it (since I don’t have other gadgets with me).&lt;/p&gt;

&lt;h2 id=&quot;02---risc-v-and-wch&quot;&gt;02 - RISC-V and WCH&lt;/h2&gt;

&lt;h3 id=&quot;summary&quot;&gt;Summary&lt;/h3&gt;

&lt;p&gt;The CH32V307 is one of a series of Gerenal-Purpose MCUs produced by Nanjing Qinheng Microelectronics (a.k.a. WCH). WCH also produces CH32F20x series, which has nearly exact the same peripherals, but replaces the RISC-V core with a Cortex-M3 core. This may be another option for customers who are already familiar with Cortex-M processors.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/2022/05/1.jpg&quot; alt=&quot;The only difference between CH32F2xx and CH32V3xx&quot; /&gt;
&lt;em&gt;The only difference between CH32F2xx and CH32V3xx&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Running at 144MHz and implemented RV32IMAFC ISA, with Gigabit Ethernet, High-Speed USB and tons of low speed periperals, making this MCU fairly powerful among the budget market.&lt;/p&gt;

&lt;h3 id=&quot;arm-or-risc-v&quot;&gt;ARM or RISC-V?&lt;/h3&gt;

&lt;p&gt;Instead of building and maintaining two seperate SDKs for different CPU architectures, WCH decided to make things easier, by making an RISC-V core that much alike an ARM core, so here we are, the &lt;strong&gt;RISC-V4&lt;/strong&gt; series cores.&lt;/p&gt;

&lt;p&gt;These cores have the following unique features which make them more ARM-ish:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;A vectored interrupt controller designed by WCH, called &lt;strong&gt;PFIC&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;Hardware exception context preservation and restoration (a.k.a. hardware stack push/pop)&lt;/li&gt;
  &lt;li&gt;A memory-mapped &lt;strong&gt;SysTick&lt;/strong&gt; timer backward compatible with the same peripheral in ARM cores (counters and match registers are extended to 64bits), but not wired to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;mtime&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;mtimecmp&lt;/code&gt; CSRs.&lt;/li&gt;
  &lt;li&gt;Some non-standard features by utilizing CSRs’ reserved bits&lt;/li&gt;
  &lt;li&gt;Private peripherals located at the same PPB region(&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0xE000_0000&lt;/code&gt;)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;interrupts-or-exceptions&quot;&gt;Interrupts or Exceptions?&lt;/h3&gt;

&lt;p&gt;The vectored interrupt controller WCH has implemented in their cores replaced both CLINT and PLIC, which means it handles both internal exceptions and external interrupts. Here are some highlighted features I found from the processor’s manual:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Absolute vector table addresses utilizing a reserved &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;MODE&lt;/code&gt; &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0b11&lt;/code&gt; in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;mtvec&lt;/code&gt; CSR. In this mode, instead of setting PC to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;BASE + mcause * 4&lt;/code&gt;, the &lt;strong&gt;absolute address&lt;/strong&gt; of the exception handler will be looked up from the vector table defined in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;BASE&lt;/code&gt; and loaded to the PC, just like NVIC does.&lt;/li&gt;
  &lt;li&gt;Vector table free(VTF) interrupts, which speeds up interrupt handling by writing up to 4 handler addresses to PFIC memory mapped registers.&lt;/li&gt;
  &lt;li&gt;Hardware accelerated ISR context saving and restoring, pushes 16 caller-saved register to a &lt;em&gt;hidden dedicated hardware stack&lt;/em&gt; in one cycle (up to 3 level nested interrupts), and pops them out automatically when &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;mret&lt;/code&gt; is executed. This requires proprietary toolchain from WCH, which has a special attribute for hardware-accelerated ISR generation.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;One of the unique (and non-standard) things this PFIC does is, some processor exceptions are treated &lt;strong&gt;the same way&lt;/strong&gt; as platform interrupts:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/2022/05/image-2.png&quot; alt=&quot;RISC-V Spec&quot; /&gt;
&lt;em&gt;RISC-V Spec&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;It means some selected synchronous exceptions (like ecall exceptions) will be vectored to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;BASE + mcause * 4&lt;/code&gt; as other asynchronous interrupts does, with pre-defined priorities listed below.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/2022/05/image-4.png&quot; alt=&quot;RISC-V4 Vector Table&quot; /&gt;
&lt;em&gt;RISC-V4 Vector Table&lt;/em&gt;&lt;/p&gt;

&lt;h2 id=&quot;03---freertos-on-risc-v&quot;&gt;03 - FreeRTOS on RISC-V&lt;/h2&gt;

&lt;p&gt;FreeRTOS has basic support for RISC-V since v10.3.0, with default configuration for NXP RV32M1 Vega along with some other processors. This default port also supports custom chips with additional registers needes to be saved on stack during exception handling.&lt;/p&gt;

&lt;p&gt;The porting process is fairly simple, the official guide requires the following functions as exception entries, depends on the current &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;mtvec&lt;/code&gt; mode:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;freertos_risc_v_trap_handler()&lt;/code&gt;: For non-vectored mode&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;freertos_risc_v_exception_handler()&lt;/code&gt;: For vectored mode (ecall)&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;freertos_risc_v_mtimer_interrupt_handler()&lt;/code&gt;: For timer interrupts&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I personally prefer not touching the startup file(although I have my re-written version available), so here are the approaches I made:&lt;/p&gt;

&lt;div class=&quot;language-c highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;cp&quot;&gt;#define __IRQ_NAKED__ attribute__((naked))
&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;__IRQ_NAKED&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Ecall_M_Handler&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;cm&quot;&gt;/* Use naked function to generate a short call */&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;asm&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;j freertos_risc_v_exception_handler&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;__IRQ_NAKED&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;SysTick_Handler&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;cm&quot;&gt;/* Careful: Avoid stack unbalance. */&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;asm&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;volatile&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
        &lt;span class=&quot;s&quot;&gt;&quot;addi sp, sp, -4&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;cm&quot;&gt;/* Push */&lt;/span&gt;
        &lt;span class=&quot;s&quot;&gt;&quot;sw t0, 4(sp)&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;cm&quot;&gt;/* Save t0 on stack */&lt;/span&gt;
        &lt;span class=&quot;s&quot;&gt;&quot;li t0, 0xE000F004&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;cm&quot;&gt;/* SysTick-&amp;amp;gt;SR */&lt;/span&gt;
        &lt;span class=&quot;s&quot;&gt;&quot;sw zero, 0(t0)&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;cm&quot;&gt;/* Write 0 to clear */&lt;/span&gt;
        &lt;span class=&quot;s&quot;&gt;&quot;lw t0, 4(sp)&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;cm&quot;&gt;/* Restore t0 from stack */&lt;/span&gt;
        &lt;span class=&quot;s&quot;&gt;&quot;addi sp, sp, 4&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;cm&quot;&gt;/* Pop */&lt;/span&gt;
        &lt;span class=&quot;s&quot;&gt;&quot;j freertos_risc_v_mtimer_interrupt_handler&quot;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;blockquote class=&quot;prompt-info&quot;&gt;
  &lt;p&gt;By using naked functions, no additional instructions are generated by the compiler.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;FreeRTOS also needs to know where the exception stack top is located, this is typically defined in linker script at the end of RAM region:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;/* Place initial SP to the end of SRAM */
__stack_top = ORIGIN(RAM) + LENGTH(RAM);
PROVIDE(_eusrstack = __stack_top);
PROVIDE( __freertos_irq_stack_top =__ stack_top);
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Also, as we have additional float-point registers needs to be saved during context switches, we need to add our own chip-specific header:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;.macro portasmSAVE_ADDITIONAL_REGISTERS
	/* Push 32 FP registers to stack. */
	addi sp, sp, -(portasmADDITIONAL_CONTEXT_SIZE * portWORD_SIZE)
	fsw f0, 1 * portWORD_SIZE( sp )
	/* ...Add More FP registers here... */
	fsw f31, 32 * portWORD_SIZE( sp )
	.endm

.macro portasmRESTORE_ADDITIONAL_REGISTERS
	/* Pop 32 FP registers from stack. */
	flw f0, 1 * portWORD_SIZE( sp )
	/* ...Add More FP registers here... */
	flw f31, 32 * portWORD_SIZE( sp )
	addi sp, sp, (portasmADDITIONAL_CONTEXT_SIZE * portWORD_SIZE)
	.endm
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;blockquote class=&quot;prompt-info&quot;&gt;
  &lt;p&gt;Only show the first and last FP register here.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2 id=&quot;04---compile-and-run&quot;&gt;04 - Compile and Run&lt;/h2&gt;

&lt;h3 id=&quot;compile&quot;&gt;Compile&lt;/h3&gt;

&lt;p&gt;The &lt;a href=&quot;https://git.minori.work/Embedded_Projects/CH32V307_FreeRTOS_Hello&quot;&gt;FreeRTOS Demo&lt;/a&gt; is based on my &lt;a href=&quot;https://git.minori.work/Embedded_Projects/CH32V307_Template&quot;&gt;template&lt;/a&gt; project, which using CMake as build system and can be compiled with RISC-V baremetal toolchain. FreeRTOS has supported CMake for a while, so adding kernel to the project is fairly simple:&lt;/p&gt;

&lt;div class=&quot;language-cmake highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;# Shared libraries linked with application&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;TARGET_LIBS
    &lt;span class=&quot;s2&quot;&gt;&quot;freertos_kernel&quot;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;#...&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# Include sub directories here&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;FREERTOS_PORT &lt;span class=&quot;s2&quot;&gt;&quot;GCC_RISC_V_WCH_RISC_V4A_FPU&quot;&lt;/span&gt; CACHE STRING &lt;span class=&quot;s2&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;FREERTOS_CONFIG_FILE_DIRECTORY &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;CMAKE_SOURCE_DIR&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;/include&quot;&lt;/span&gt; CACHE STRING &lt;span class=&quot;s2&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;FREERTOS_HEAP &lt;span class=&quot;s2&quot;&gt;&quot;4&quot;&lt;/span&gt; CACHE STRING &lt;span class=&quot;s2&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;add_subdirectory&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;lib/FreeRTOS-Kernel&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;flash-download&quot;&gt;Flash Download&lt;/h3&gt;

&lt;p&gt;WCH provides their toolchain and OpenOCD along with their MounRiver IDE, but standalone toolchain archives for Linux can be downloaded seperately at &lt;a href=&quot;http://www.mounriver.com/download&quot;&gt;MounRiver.com&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The on-board WCH-Link may requires firmware update, however I did’t find a way to do it without the full Eclipse-based IDE and a working Windows OS.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nb&quot;&gt;cd &lt;/span&gt;MRS_Toolchain_Linux_x64_V1.40/OpenOCD/bin &lt;span class=&quot;c&quot;&gt;# Extracted toolchain&lt;/span&gt;
./openocd &lt;span class=&quot;nt&quot;&gt;-f&lt;/span&gt; wch-riscv.cfg &lt;span class=&quot;c&quot;&gt;# The only config needed&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;load&lt;/code&gt; the ELF file with GDB, the demo should work as intended.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/2022/05/image-6.png&quot; alt=&quot;&quot; /&gt;”
&lt;em&gt;Demo download and running&lt;/em&gt;&lt;/p&gt;
&lt;h2 id=&quot;05---fun-facts&quot;&gt;05 - Fun Facts&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;FreeRTOS only supports M mode only at this time, however WCH’s stock startup file jump to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;main()&lt;/code&gt; using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;mret&lt;/code&gt;, causing the processor switch to U mode. Modifications are required if stock startup files are used.&lt;/li&gt;
  &lt;li&gt;Somehow WCH decides to use a special way running their own FreeRTOS port, by replacing YIELD with an NVIC function, which pends a software interrupt instead of a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ecall&lt;/code&gt; instruction…&lt;/li&gt;
  &lt;li&gt;The official Dev kit has some LEDs and buttons, however they are not actually connected to the MCU, the only way is using some…jumpers.&lt;/li&gt;
  &lt;li&gt;This MCU has full SRAM backed program flash, and some part of it can be used as additional SRAM by setting the corresponding bits in option bytes.&lt;/li&gt;
  &lt;li&gt;The flash is read as &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0xe339e339&lt;/code&gt; after sucessfully erased, I have no idea why they implemented it this way..&lt;/li&gt;
  &lt;li&gt;The debug interface is SWD only, even for RISC-V MCUs. WCH-Link is definitely filled with some evil black magic…&lt;/li&gt;
  &lt;li&gt;The custom CSR &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;corecfgr (0xBC0)&lt;/code&gt; is described as “Mainly used for configuring processor pipelining and branch prediction features, and should not be operated by the user”, the default value set by startup file is &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0x1F&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;06---references&quot;&gt;06 - References:&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;http://www.wch.cn/downloads/CH32V20x_30xDS0_PDF.html&quot;&gt;Datasheet&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://www.wch.cn/downloads/CH32FV2x_V3xRM_PDF.html&quot;&gt;Reference Manual&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://riscv.org/technical/specifications/&quot;&gt;RISC-V Specs&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://git.minori.work/Embedded_Projects/riscv-openocd-wch&quot;&gt;WCH OpenOCD Source, requested under GPL&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://git.minori.work/Embedded_Projects/CH32V307_Template&quot;&gt;My Template Project&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://git.minori.work/Embedded_Projects/CH32V307_FreeRTOS_Hello&quot;&gt;FreeRTOS Demo&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Tue, 03 May 2022 13:56:23 +0000</pubDate>
        <link>https://www.imstatic.com/archivers/freertos-on-ch32v307</link>
        <guid isPermaLink="true">https://www.imstatic.com/archivers/freertos-on-ch32v307</guid>
        
        <category>hardware</category>
        
        
      </item>
    
      <item>
        <title>MIPI-DSI LCD with Zynq</title>
        <description>&lt;h2 id=&quot;01---introduction&quot;&gt;01 - Introduction&lt;/h2&gt;

&lt;p&gt;MIPI-DSI is the ‘latest’ standard of mobile display, with highest bandwidth and low power consumption, it was quickly adopted by nearly every hardware vendors. Recently I discovered some really cheap DSI display modules, and decided to drive them the hard way by using a Zynq-7000 SoC.&lt;/p&gt;

&lt;h2 id=&quot;02---protocol-specifications&quot;&gt;02 - Protocol Specifications&lt;/h2&gt;

&lt;p&gt;The MIPI Alliance has kept their little secrets for years, exclusive to their organization members. The documentation provided by Xilinx and LCD manufacturers, however, gave me some basic clue of the specification of these mysterious standards.&lt;/p&gt;

&lt;h3 id=&quot;d-phy&quot;&gt;D-PHY&lt;/h3&gt;

&lt;p&gt;MIPI D-PHY is the standard way which link layer protocols such as CSI-2 or DSI communicate with peripherals. A typical D-PHY transmitter or receiver has the following parts:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;PPI interface&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;High Speed&lt;/strong&gt; (HS) mode transmitter or receiver&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Low Power&lt;/strong&gt; (LP) mode transmitter or receiver&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The PPI interface is used to communicate with controllers, which provides control and data interface for the phy layer, known as the protocol side. The D-PHY also has one clock lane and one or more data lanes, each lane has a pair of HS and LP transmitters and/or receivers, which provide data and clock signals. Data lane 0 also has the capability of bus turn-around for bi-directional communication.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/2021/10/image.png&quot; alt=&quot;D-PHY overview&quot; /&gt;
&lt;em&gt;D-PHY overview&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The figure above describes the structure of the functionality of D-PHY, note the difference between HS and LP electric characteristics. HS transceivers use an differential IO standard called SLVS400, standardized by JEDEC many years ago, while LP transceivers use single-ended 1.2V LVCMOS drivers.&lt;/p&gt;

&lt;p&gt;During initialization, all lanes are in LP stop mode, to make life easier, they provided a state-code system to describe the different lane states, listed below:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/2021/10/image-1.png&quot; alt=&quot;Lane state descriptions&quot; /&gt;
&lt;em&gt;Lane state descriptions&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;To enter &lt;strong&gt;High-Speed Data Transmission&lt;/strong&gt; (HSDT) mode, the following steps are required:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Enter &lt;strong&gt;High-Speed Clock Mode&lt;/strong&gt; (HSCM)&lt;/li&gt;
  &lt;li&gt;Follow the HS request sequence to enter HSDT mode.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;mipi-dsi&quot;&gt;MIPI-DSI&lt;/h3&gt;

&lt;p&gt;The MIPI-DSI works on top of the D-PHY, provides the command and video interfaces to the host processor. There are two modes defined by the DSI specification, and panel manufacturers can select either or both modes to support.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Command Mode&lt;/li&gt;
  &lt;li&gt;Video Mode&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;DSI host communicate with panel with a packet based format, transmitted either on HS or LP mode, some packet types only support one mode. DSI packet has two formats, either the &lt;strong&gt;short packet&lt;/strong&gt; (SPa) or the &lt;strong&gt;long packet&lt;/strong&gt; (LPa), depending the length of the DS I command and parameters. Short packets can contain fixed two bytes of payload, and long packets can have maximum of 65536 bytes of payload. When multiple lanes are used, data is distributed as bytes to all data lanes. An example of a HSDT transfer are shown below, captured by DSLogic, with the lowest 40MHz clock…&lt;/p&gt;

&lt;div file=&quot;Manually parsed packet&quot; class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;LANE 0: | 11101 10100000 00000000 00010000 11110000 111...
LANE 1: | 11101 10000000 00001000 11110000 10000000 111...

          SYNC |
                1st/2nd |
                         3rd/4th |
                                  

0x05 0x01 0x00 0x10 | 0x08 0x0F 0x0F 0x01 HS-1t...
DI   PD0  PD1  ECC  | DI   PD0  PD1  ECC
DCS short write     | EoTp
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;In HSDT mode, the data samples on each change of the clock lane(DDR clock), with LSBit shifting out first. The type of the packet is determined by the first byte of the packet, called &lt;strong&gt;Data Identification&lt;/strong&gt; (DI). DI also has a &lt;strong&gt;Virtual Channel&lt;/strong&gt; (VC) field, making lane sharing possible with maximum of 4 devices. However, display modules are only support VC 0. The last byte is a ECC byte calculated from the first 3 bytes. For example, the above packet has DI value 0x05, as a DCS short write command. The second packet is a special packet called &lt;strong&gt;End of Transmission Packet&lt;/strong&gt; (EoTp), indicates the end of current transmission.&lt;/p&gt;

&lt;h3 id=&quot;dcs&quot;&gt;DCS&lt;/h3&gt;

&lt;p&gt;In DSI command mode, the host communicates with the peripheral by using different commands, including &lt;strong&gt;Display Command Set&lt;/strong&gt; (DCS). If you have experience playing with some LCD or OLED display modules, you will find out that no matter which interface are used, some initialization sequence must be written to the module before it can function normally. These sequence contain the necessary drive voltage and clock settings, the type of the panel, the internal memory layout and many other parameters. For 4-line SPI or DBI(8080/6800 MCU interface) interfaces, commands are written by using a special signal called D/CX, which indicates the data currently being transmitted is a command or data. On MIPI-DSI, this is replaced with a command called DCS. Vendor specific command can be wrapped inside DCS packets, so the panel initialization process can be carried out by host.&lt;/p&gt;

&lt;h3 id=&quot;video-mode&quot;&gt;Video Mode&lt;/h3&gt;

&lt;p&gt;Apart from traditional command based operations, DSI specification also has a Video Mode. In video mode, the host manage the display timing by sending out a stream of packets containing synchronization information and image data, then the display can retrive HSync/VSync/Blanking signal from these packets just like DPI(RGB panel interface) does. Video mode is capable of high bandwidth and smooth video, while some controllers without internal graphics RAM only supports this mode.&lt;/p&gt;

&lt;h2 id=&quot;03---the-hardware&quot;&gt;03 - The Hardware&lt;/h2&gt;

&lt;p&gt;As mentioned above, MIPI D-PHY needs two IO standards working on the same lane, in order to achieve the AC characteristics by FPGA only, we needs some sort of emulation. Luckily, Xilinx provided with an AppNote describing a low-cost way of emulating D-PHY by using FPGA IO and resistors (XAPP894).&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/2021/10/image-2.png&quot; alt=&quot;D-PHY Equivalent Solution&quot; /&gt;
&lt;em&gt;D-PHY Equivalent Solution&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;This design utilizing four IOs, two for LP mode and one diff pair for HS mode. the resistor network is designed to shift LVCMOS18 to 1.2V standard for LP mode and shift HSTL_1_18 to SLVS400 for HS mode.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/2021/10/image-7.png&quot; alt=&quot;Implemented PCB&quot; /&gt;
&lt;em&gt;Implemented PCB&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The board I planned to use is a Zynq-7020 board produced by QMTech, with the shunt resistors removed, external VCCO power can be provided by 2.54mm headers (Not every Zynq board has that) . I implemented the transmitter on a PCB, with power supplies for IOBANK and LCD, as well as the most common RaspberryPi compatible FPC socket. The impedance requirement for D-PHY is 100Ω differential and 50Ω single ended.&lt;/p&gt;

&lt;h2 id=&quot;04---block-design&quot;&gt;04 - Block Design&lt;/h2&gt;

&lt;p&gt;I planned to use the MIPI-DSI subsystem provided by Xilinx for free in Vivado 2020.2, So the standard video pipeline looks like the following.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/2021/10/image-4.png&quot; alt=&quot;Vivado Block Design&quot; /&gt;
&lt;em&gt;Vivado Block Design&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The key components of the design are:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;AXI Video Framebuffer Read&lt;/li&gt;
  &lt;li&gt;MIPI-DSI Tx Subsystem&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;As this LCD controller (NovaTek NT35516) does not support command in HSDT mode, since Xilinx IP does not support &lt;strong&gt;Low Power Data Transmission&lt;/strong&gt; (LPDT) either, I had to add an AXI GPIO and some glue logic to take over the bus for my bit-bang LPDT implementation.&lt;/p&gt;

&lt;h2 id=&quot;05---software&quot;&gt;05 - Software&lt;/h2&gt;

&lt;p&gt;The software part is quite routine, initialize a framebuffer in DDR, configure AXI framebuffer read IP to read from it and send the pixels through AXI Stream to MIPI DSI subsystem. Also, I implemented a bit-bang LPDT driver for the initialization process.&lt;/p&gt;

&lt;p&gt;After everything wired up and initialization code ran, I could see some garbage data on the screen, which proven the setup works. I also wrote some bitmap by using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;xsct&lt;/code&gt; command line tool to the framebuffer, the results are as follows.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;mwr &lt;span class=&quot;nt&quot;&gt;-bin&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-file&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;BITMAP_FILE&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;.bin 0x&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;FRAMEBUFFER_ADDR&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;WORDCOUNT&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This LCD I used is a AUO panel with NT35516 controller, with resolution of 960x540@8bpp. The timing for video mode requires more elaborated calculation, as described by the MIPI DSI Tx subsystem documentation (PG238).&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/2021/10/image-3.png&quot; alt=&quot;Example Timing Calculation&quot; /&gt;
&lt;em&gt;Example Timing Calculation&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The timing information I used:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Lane rate: 500Mb/s x2&lt;/li&gt;
  &lt;li&gt;HActive: 540 * 3(24bits), VActive: 960, frame rate 60Hz&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;After calculation described by the documentation, the final timing looks like:&lt;/p&gt;

&lt;div class=&quot;language-c highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;XDsi_VideoTiming&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;timing&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;HActive&lt;/span&gt;     &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;540&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;HFrontPorch&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;83&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;HBackPorch&lt;/span&gt;  &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;360&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;HSyncWidth&lt;/span&gt;  &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;7&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;VActive&lt;/span&gt;     &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;960&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;VFrontPorch&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;15&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;VBackPorch&lt;/span&gt;  &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;15&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;VSyncWidth&lt;/span&gt;  &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;BLLPBurst&lt;/span&gt;   &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;06---misc&quot;&gt;06 - Misc&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;Signal integrity is heavily influenced by my probe.&lt;/li&gt;
  &lt;li&gt;I might update a future version to address mis-calculated trace widths.&lt;/li&gt;
  &lt;li&gt;LP mode requires 50-75ns period, however 200ns bit-bang IO seems work just fine.&lt;/li&gt;
  &lt;li&gt;Not all commands listed in NovaTek’s command set is capable of HSDT.&lt;/li&gt;
  &lt;li&gt;RaspberryPi DSI display uses DPI panel with DSI-DPI bridge, no initialization required.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/2021/10/IMG_20211003_192332.jpg&quot; alt=&quot;&quot; /&gt;
&lt;em&gt;Adapter board&lt;/em&gt;&lt;/p&gt;

&lt;h2 id=&quot;07---references&quot;&gt;07 - References&lt;/h2&gt;

&lt;p&gt;Software code repository: &lt;a href=&quot;https://git.minori.work/Embedded_Projects/QM_Zynq_DSI_SW&quot;&gt;Embedded_Projects/QM_Zynq_DSI_SW&lt;/a&gt;&lt;/p&gt;
</description>
        <pubDate>Tue, 19 Oct 2021 12:20:02 +0000</pubDate>
        <link>https://www.imstatic.com/archivers/dsi-lcd-with-zynq</link>
        <guid isPermaLink="true">https://www.imstatic.com/archivers/dsi-lcd-with-zynq</guid>
        
        <category>hardware</category>
        
        
      </item>
    
      <item>
        <title>STM32H7-QUADSPI XIP及优化</title>
        <description>&lt;h2 id=&quot;0-简介&quot;&gt;0. 简介&lt;/h2&gt;

&lt;p&gt;新款STM32的QUADSPI外设具有多种功能，配置也相当灵活，同时支持XIP功能。本文以STM32H750为例介绍STM32中的QUADSPI外设以及通过内置Flash执行位于QSPI Flash中的程序，并实现一个简易的USB DFU bootloader。&lt;/p&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;1-qspi及qspi-flash&quot;&gt;1. QSPI及QSPI Flash&lt;/h2&gt;

&lt;p&gt;QSPI（Quad SPI）是在原有SPI的总线结构上增加了两条数据线（IO2，IO3），在数据传输时四条数据线按需切换数据方向，理论可实现4倍于SPI的传输速率，通常用于存储器件的连接。&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/2020/12/image.png&quot; alt=&quot;Quad SPI连接示例&quot; /&gt;
&lt;em&gt;Quad SPI连接示例&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;QSPI Flash是NOR Flash的一种，通信接口兼容SPI，Dual SPI及Quad SPI。在3.3V下可以实现133MHz的最大时钟频率。&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/2020/12/image-1.png&quot; alt=&quot;QSPI Flash系统框图&quot; /&gt;
&lt;em&gt;QSPI Flash系统框图&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;QSPI存储器件访问会经过以下五个阶段：&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;指令阶段（Instruction Phase）&lt;/li&gt;
  &lt;li&gt;地址阶段（Address Phase）&lt;/li&gt;
  &lt;li&gt;Alternate-byte Phase&lt;/li&gt;
  &lt;li&gt;等待周期阶段（Dummy cycle Phase）&lt;/li&gt;
  &lt;li&gt;数据阶段（Data Phase）&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;11-指令阶段&quot;&gt;1.1. 指令阶段&lt;/h3&gt;

&lt;p&gt;该阶段主机发送8位的操作指令到Flash，用于指定将要进行的操作。根据Flash模式的不同，指令可以通过单线（IO0）发送（SPI/QSPI模式）或四线发送（QPI模式）。&lt;/p&gt;

&lt;h3 id=&quot;12-地址阶段&quot;&gt;1.2. 地址阶段&lt;/h3&gt;

&lt;p&gt;该阶段主机发送24或32位的地址，根据命令和模式的不同，地址可能不需要发送，或通过单线、双线、四线模式发送。&lt;/p&gt;

&lt;h3 id=&quot;13-alternate-byte-阶段&quot;&gt;1.3. Alternate-byte 阶段&lt;/h3&gt;

&lt;p&gt;QSPI Flash可通过Alternate byte设置额外参数，如连续读命令。该Alternate byte根据命令也可通过1/2/4线发送。在Quad模式下，Alternate-byte &lt;strong&gt;也计入&lt;/strong&gt; dummy cycle。&lt;/p&gt;

&lt;h3 id=&quot;14-等待周期阶段&quot;&gt;1.4. 等待周期阶段&lt;/h3&gt;

&lt;p&gt;该阶段用于等待Flash内部同步状态，根据Flash读写时钟的不同设置。通常来讲，在高频率下需要更多dummy cycles，同时也取决于Flash配置（命令C0H）。&lt;/p&gt;

&lt;h3 id=&quot;15-数据阶段&quot;&gt;1.5. 数据阶段&lt;/h3&gt;

&lt;p&gt;在数据阶段中，数据从主机传输到Flash或者从Flash传输到主机，在该模式下所有IO的状态被确定，输入侧为High-Z，输出侧写入数据。IO方向的切换发生在dummy phase结束的下降沿。&lt;/p&gt;

&lt;p&gt;一个完整的操作时序如下图所示：&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/2020/12/image-4.png&quot; alt=&quot;QSPI操作时序&quot; /&gt;
&lt;em&gt;QSPI操作时序&lt;/em&gt;&lt;/p&gt;

&lt;h2 id=&quot;2-tm32-quadspi外设&quot;&gt;2. TM32 QUADSPI外设&lt;/h2&gt;

&lt;p&gt;STM32H7中的QUADSPI外设位于D1域中，其位置如下&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/2020/12/image-2.png&quot; alt=&quot;STM32H7 QUADSPI外设&quot; /&gt;
&lt;em&gt;STM32H7 QUADSPI外设&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;QUADSPI外设有三种工作模式，分别为&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;间接（Indirect）模式&lt;/li&gt;
  &lt;li&gt;状态轮询（Status-flag polling）模式&lt;/li&gt;
  &lt;li&gt;XIP（Memory-Mapped）模式&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;21-间接模式&quot;&gt;2.1. 间接模式&lt;/h3&gt;

&lt;p&gt;间接模式下QUADSPI外设操作类似于SPI外设，通过设置传输模式和寄存器收发数据，通过这种方式写入或擦除Flash后需要轮询状态寄存器判断操作完成。&lt;/p&gt;

&lt;h3 id=&quot;22-状态轮询模式&quot;&gt;2.2. 状态轮询模式&lt;/h3&gt;

&lt;p&gt;该模式下，QUADSPI外设通过设置轮询命令和超时，在操作结束后由硬件自动轮询状态寄存器，通过中断指示CPU传输完成。&lt;/p&gt;

&lt;p&gt;XIP模式&lt;/p&gt;

&lt;p&gt;在XIP模式下，Flash的内容会被Map进地址空间，可以通过直接访问地址的方式读取Flash内容，XIP模式下Flash不可被写入。&lt;/p&gt;

&lt;h2 id=&quot;23-hal配置qspi-xip模式&quot;&gt;2.3. HAL配置QSPI XIP模式&lt;/h2&gt;

&lt;p&gt;CubeMX不直接支持配置为XIP模式，需要在用户代码中配置。本文中使用的Flash型号为华邦的W25Q128FVSIG，其配置示例如下：&lt;/p&gt;

&lt;div class=&quot;language-c highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;QSPI_CommandTypeDef&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sCommand&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;QSPI_MemoryMappedTypeDef&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sMemMappedCfg&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;sCommand&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;InstructionMode&lt;/span&gt;        &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;QSPI_INSTRUCTION_1_LINE&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;sCommand&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;AddressMode&lt;/span&gt;            &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;QSPI_ADDRESS_4_LINES&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;sCommand&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;AddressSize&lt;/span&gt;            &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;QSPI_ADDRESS_24_BITS&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;sCommand&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;DataMode&lt;/span&gt;               &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;QSPI_DATA_4_LINES&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;sCommand&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;AlternateByteMode&lt;/span&gt;      &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;QSPI_ALTERNATE_BYTES_4_LINES&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;sCommand&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;AlternateBytesSize&lt;/span&gt;     &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;QSPI_ALTERNATE_BYTES_8_BITS&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;sCommand&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;AlternateBytes&lt;/span&gt;         &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0xFF&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;sCommand&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;DdrMode&lt;/span&gt;                &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;QSPI_DDR_MODE_DISABLE&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;sCommand&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;DdrHoldHalfCycle&lt;/span&gt;       &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;QSPI_DDR_HHC_ANALOG_DELAY&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;sCommand&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;SIOOMode&lt;/span&gt;               &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;QSPI_SIOO_INST_EVERY_CMD&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;sCommand&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Instruction&lt;/span&gt;            &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0xEB&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;sCommand&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;DummyCycles&lt;/span&gt;            &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;sMemMappedCfg&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;TimeOutActivation&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;QSPI_TIMEOUT_COUNTER_DISABLE&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;sMemMappedCfg&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;TimeOutPeriod&lt;/span&gt;     &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;该参数配置QUADSPI外设为四线快速读模式，会产生如下图所示的操作时序：&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/2020/12/image-3.png&quot; alt=&quot;四线快速读（0xEB）命令&quot; /&gt;
&lt;em&gt;四线快速读（0xEB）命令&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;关键参数解释：&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;InstructionMode&lt;/code&gt; ：命令的发送方式，这里选择单线模式发送&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;AddressMode&lt;/code&gt; ：地址的发送方式，该命令需要通过四线发送24bit地址&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;AddressSize&lt;/code&gt; ：地址长度，24bit&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;AlternateByteMode&lt;/code&gt; ：Alternate-byte的发送方式，四线方式发送&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Instruction&lt;/code&gt; ：指令字，1个字节。这里为四线快速读（0xEB）指令&lt;/li&gt;
  &lt;li&gt;其余参数暂时保持默认即可&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;设置参数后，执行&lt;/p&gt;

&lt;div class=&quot;language-c highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;HAL_QSPI_MemoryMapped&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;hqspi&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sCommand&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sMemMappedCfg&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;操作返回成功后，即可在总线 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0x90000000&lt;/code&gt; 访问到QSPI Flash中的内容。&lt;/p&gt;

&lt;div file=&quot;OpenOCD读取QSPI内容&quot; class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;Open On-Chip Debugger
&amp;gt; mdw 0x90000000 128                                                                       
0x90000000: 20020000 90004ccd 900006f1 900006f9 900006fb 900006fd 900006ff 00000000 
0x90000020: 00000000 00000000 00000000 90004a01 90000701 00000000 90004aa1 90004b05 
0x90000040: 90004d1d 90000703 90004d1d 90004d1d 9000070b 90000713 90004d1d 90004d1d 
0x90000060: 90004d1d 90004d1d 90004d1d 90004d1d 90004d1d 90004d1d 90004d1d 90004d1d 
0x90000080: 90004d1d 90004d1d 90004d1d 90004d1d 90004d1d 90004d1d 90004d1d 90004d1d 
0x900000a0: 90004d1d 90004d1d 90004d1d 90004d1d 90004d1d 90004d1d 90004d1d 90004d1d 
0x900000c0: 90004d1d 90004d1d 90004d1d 90004d1d 90004d1d 90004d1d 90004d1d 90004d1d 
0x900000e0: 90004d1d 90004d1d 00000000 90004d1d 90004d1d 90004d1d 90004d1d 90004d1d 
0x90000100: 90004d1d 90004d1d 90004d1d 90004d1d 90004d1d 90004d1d 90004d1d 90000715 
0x90000120: 90004d1d 90004d1d 90004d1d 90004d1d 90004d1d 90004d1d 90004d1d 90004d1d 
0x90000140: 00000000 00000000 00000000 00000000 90004d1d 90004d1d 90004d1d 90004d1d 
0x90000160: 90004d1d 90004d1d 90004d1d 90004d1d 90004d1d 90004d1d 90004d1d 90004d1d 
0x90000180: 90004d1d 90000725 90004d1d 90004d1d 90004d1d 90004d1d 90004d1d 90004d1d 
0x900001a0: 90004d1d 90004d1d 90004d1d 90004d1d 90000729 90004d1d 90004d1d 90004d1d 
0x900001c0: 90004d1d 90004d1d 90004d1d 90004d1d 90004d1d 90004d1d 90004d1d 90004d1d 
0x900001e0: 90004d1d 90004d1d 90004d1d 90004d1d 90004d1d 90004d1d 90004d1d 90004d1d 

&amp;gt; 
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;usb-dfu-bootloaderwip&quot;&gt;USB DFU Bootloader（WIP）&lt;/h2&gt;

&lt;h2 id=&quot;修改hal工程以xip方式执行wip&quot;&gt;修改HAL工程以XIP方式执行（WIP）&lt;/h2&gt;

&lt;h2 id=&quot;性能优化wip&quot;&gt;性能优化（WIP）&lt;/h2&gt;

&lt;h2 id=&quot;需注意的问题wip&quot;&gt;需注意的问题（WIP）&lt;/h2&gt;

&lt;p&gt;参考文献&lt;/p&gt;

&lt;p&gt;[1] AXI Quad SPI v3.2 LogiCORE IP Product Guide (PG153)&lt;/p&gt;

&lt;p&gt;[2] W25Q128FV Datasheet&lt;/p&gt;

</description>
        <pubDate>Sun, 20 Dec 2020 12:03:05 +0000</pubDate>
        <link>https://www.imstatic.com/archivers/stm32h7-qspi</link>
        <guid isPermaLink="true">https://www.imstatic.com/archivers/stm32h7-qspi</guid>
        
        <category>hardware</category>
        
        
      </item>
    
      <item>
        <title>STM32H7中的DMA</title>
        <description>&lt;h2 id=&quot;1-概述&quot;&gt;1. 概述&lt;/h2&gt;

&lt;p&gt;STM32H7相比其他系列性能有着不小的提升，同时结构也有了较大的变化。这些变化如果不加注意则会影响DMA等功能的使用。本文通过对STM32H7的Bus Matrix及Cache/MPU两方面尝试分析不同点及对应的解决方案。&lt;/p&gt;

&lt;h2 id=&quot;2硬件平台&quot;&gt;2.硬件平台&lt;/h2&gt;

&lt;p&gt;本文中使用的硬件是STM32H750开发板，属于STM32H7 Value Line产品线，代码位于QSPI Flash中，通过XIP方式执行。&lt;/p&gt;

&lt;h2 id=&quot;3-stm32h7的总线结构和访问规则&quot;&gt;3. STM32H7的总线结构和访问规则&lt;/h2&gt;

&lt;p&gt;STM32H7拥有三个不同的Bus Matrix，分别为D1，D2与D3。&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;D1区域为AXI  Interconnect Matrix，与CPU通过AXI总线相连，高速外设如Flash，QSPI，FMC等通过此AXI Bus连接到CPU，速度最快。&lt;/li&gt;
  &lt;li&gt;D2区域为AHB Multi-layer Bus Matrix，连接了大部分低速外设及另一部分SRAM，通过CPU的AHBP接口连接到CPU，速度其次。&lt;/li&gt;
  &lt;li&gt;D3区域为另一个AHB Bus Matrix，与前两个区域不同的是，它不与CPU直接连接，而是通过D2区域的一个AHB Master连接到D3区域。D3区域速度最慢，同时也连接了一部分低功耗外设，速度最慢。&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;三个区域的时钟及门控可独立控制，以实现低功耗与高性能间的平衡。&lt;/p&gt;

&lt;p&gt;在H7的架构中，部分高速外设通过AXI总线连接到Master，相比只有Flash存储器连接到AXI接口的F7系列，外设访问速度也有了提升。&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/2020/05/image-2.png&quot; alt=&quot;STM32H7的总线互联架构&quot; /&gt;
&lt;em&gt;STM32H7的总线互联架构&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;从上图我们可以发现以下访问规律：&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;D1区域的Bus Master可以通过D1-to-D2 AHB Bus访问D2域的地址范围，也可以通过D2-to-D3 AHB Bus访问D3的地址范围。&lt;/li&gt;
  &lt;li&gt;D2区域的Bus Master可以通过D2-to-D3 AHB Bus访问D3域的地址范围，也可以通过D2-to-D1 AHB Bus反向访问D1域的地址范围。&lt;/li&gt;
  &lt;li&gt;D3区域没有连接到其他区域的Bus Master，因此只能访问D3区域的地址范围。&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;总结一下就是：&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;D1与D2中的Bus Master可以互访对方Slave， &lt;strong&gt;D3中的Master不能访问D1与D2 Slave&lt;/strong&gt; 。&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2 id=&quot;4-stm32h7中的dma与存储器&quot;&gt;4. STM32H7中的DMA与存储器&lt;/h2&gt;

&lt;p&gt;STM32H7中有三种不同的DMA，分别为MDMA，DMA（DMA1/DMA2）以及BDMA，其特点如下所示：&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;MDMA可以通过AXI Interconnect的接口访问D1域，同时 &lt;strong&gt;能通过专用的AHBS接口访问CPU中的I/DTCM存储器&lt;/strong&gt; ，速度最高。&lt;/li&gt;
  &lt;li&gt;DMA1/2位于D2域中，通过AHB接口访问D2域。由于D2域存在着连接到D1域的通路，因此DMA1/2依然可以访问D1域中的存储器及外设。&lt;/li&gt;
  &lt;li&gt;BDMA则位于D3域中，仅可以访问D3SRAM及对应的D3域外设，同时功能上也相对有限。&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;相似的，STM32H7中的存储器也分为了以下几种：&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;AXI SRAM（D1_RAM)，QUADSPI，FMC，Flash：这些存储器连接到AXI Interconnect，可被能访问D1域的Bus Master访问。&lt;/li&gt;
  &lt;li&gt;AHB SRAM1/2 ：这些存储器连接到D2域 AHB Bus Matrix，可被能访问D2域的Bus Master访问。&lt;/li&gt;
  &lt;li&gt;AHB SRAM3：这些存储器连接到D3域 AHB Bus Matrix，可被能访问D3域的Bus Master访问。&lt;/li&gt;
  &lt;li&gt;特殊的，位于CPU内部的I/DTCM（指令/数据紧耦合存储器）在可被CPU访问的同时也可通过专用接口被 &lt;strong&gt;MDMA&lt;/strong&gt; 访问。&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;由此，我们可以得出以下几点规则：&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;MDMA能访问 &lt;strong&gt;包含TCM在内&lt;/strong&gt; 的所有存储器（几乎和CPU范围类似），DMA1/2不能访问TCM，BDMA仅可访问AHB SRAM3以及D3域外设。&lt;/p&gt;
&lt;/blockquote&gt;

&lt;blockquote&gt;
  &lt;p&gt;特别需要注意的是，这些规则 &lt;strong&gt;不仅&lt;/strong&gt; 应用于DMA控制器， &lt;strong&gt;同时也适用于其他Bus Master&lt;/strong&gt; ，如DMA2D，LTDC，Ethernet，SDMMC，USB等等拥有内部DMA的外设，使用时同样要保证用户buffer位于可访问区域内。&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ol&gt;
  &lt;li&gt;关于L1 Cache及MPU&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Cortex-M7相比于其他核心，增加了单独的L1 I/D Cache，为了保证DMA访问的内存不出现一致性问题，需要通过配置MPU的方式控制指定区域的缓存策略。&lt;/p&gt;

&lt;p&gt;Cortex-M7的MPU通过Region的形式定义访问规则，这里通过STM32CubeMX的配置工具提供简单的缓存配置示例。&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/2020/05/image-3.png&quot; alt=&quot;CubeMX的MPU配置界面&quot; /&gt;
&lt;em&gt;CubeMX的MPU配置界面&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;MPU的配置最好按照粒度从粗到细的顺序配置，示例中的默认配置是禁用缓存，允许全部访问，在QSPI Flash区域启用读缓存，并允许指令访问及共享。&lt;/p&gt;

&lt;h2 id=&quot;6-代码实现&quot;&gt;6. 代码实现&lt;/h2&gt;

&lt;p&gt;在默认的Linker Script中，数据代码被放置在了DTCM中，如果想要通过DMA访问这部分数据，我们就只能通过MDMA访问，或者修改LDS使得数据放置在AXI SRAM或者AHB SRAM中。以下的修改可以将用户的buffer放置在D2域SRAM中：&lt;/p&gt;

&lt;div file=&quot;Linker Script&quot; class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;_SI_D2SRAM = LOADADDR(.d2_sram);
.d2_sram :
{
  . = ALIGN(4);
  _DMA_Buffer_Start = .;
  *(.d2_sram_buffer)
  . = ALIGN(4);
  _DMA_Buffer_End = .;
} &amp;gt;RAM_D2 AT&amp;gt; FLASH /* Note: Not actually init, we need to copy manually before use */
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;然后我们即可初始化这部分数据：&lt;/p&gt;

&lt;div class=&quot;language-c highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kt&quot;&gt;uint32_t&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;bytes_to_copy&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_DMA_Buffer_End&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_DMA_Buffer_Start&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;bytes_to_copy&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;memcpy&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_DMA_Buffer_Start&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_SI_D2SRAM&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;bytes_to_copy&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;之后通过DMA1或DMA2即可正确实现DMA传输。&lt;/p&gt;

</description>
        <pubDate>Thu, 07 May 2020 13:19:08 +0000</pubDate>
        <link>https://www.imstatic.com/archivers/stm32h7-dma</link>
        <guid isPermaLink="true">https://www.imstatic.com/archivers/stm32h7-dma</guid>
        
        <category>hardware</category>
        
        
      </item>
    
      <item>
        <title>使用SystemView分析FreeRTOS应用</title>
        <description>&lt;h2 id=&quot;1前言&quot;&gt;1.前言&lt;/h2&gt;

&lt;p&gt;       在使用&lt;a href=&quot;https://freertos.org/&quot;&gt;FreeRTOS&lt;/a&gt;进行应用开发时经常会遇到普通的方式难以调试的问题，如栈内存不足等等，同时也希望对运行的多个Task进行实时的性能及资源占用的分析，通常的调试手段在这里就变的心有余而力不足了。以FreeRTOS为例，如何在长时间的运行过程中收集调试数据进行分析，以及如何调试不同的组件（如Queue，Notification，Semaphore等等）？这个时候就需要Trace工具帮忙了。针对RTOS的Trace需求，有多种商业工具可供选择，但其中可供免费使用的产品则寥寥无几。本文将针对SEGGER开发的SystemView Trace工具进行介绍。&lt;/p&gt;

&lt;h2 id=&quot;2-systemview&quot;&gt;2. SystemView&lt;/h2&gt;

&lt;p&gt;       &lt;a href=&quot;https://www.segger.com/products/development-tools/systemview/&quot;&gt;SystemView&lt;/a&gt;是SEGGER开发的针对嵌入式系统的trace工具，支持多种RTOS，也支持自定义OS的移植（需实现trace API，参见User Manual）。其核心基于SEGGER RTT，一个Host-Target间的通信框架，可通过多种方式连接，除J-LINK之外还可以使用串口及TCP-IP协议，对非商业用途免费且无功能限制。&lt;/p&gt;

&lt;h2 id=&quot;3-环境准备&quot;&gt;3. 环境准备&lt;/h2&gt;

&lt;p&gt;       我们使用的测试环境是STM32H750VB开发板，CPU为Cortex-M7，最高主频480MHz，程序位于QSPI Flash中，通过XIP方式运行。FreeRTOS为STM32CubeMX配置的未修改版本。运行一个自定义Task，Toggle开发板上的一个LED灯。&lt;/p&gt;

&lt;div class=&quot;language-c highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;//测试Task&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;TaskHandle_t&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;xTaskHelloHandle&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;NULL&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;vTaskHello&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;pvParameters&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(;;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;HAL_GPIO_TogglePin&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;GPIOA&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;GPIO_PIN_1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;SEGGER_SYSVIEW_PrintfTarget&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Hello world @%lu&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;HAL_GetTick&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;());&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;//这里使用了SystemView系统库提供的输出函数，向主机输出Message&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;vTaskDelay&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1000&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;vTaskDelete&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;NULL&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;在启动时自动创建该Task：&lt;/p&gt;

&lt;div class=&quot;language-c highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;xTaskCreate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;vTaskHello&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;hello_task&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1024&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;NULL&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;7&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;NULL&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;栈深度为1024字，优先级为7&lt;/p&gt;

&lt;h2 id=&quot;4-systemview-trace库移植&quot;&gt;4. SystemView trace库移植&lt;/h2&gt;

&lt;p&gt;首先下载&lt;a href=&quot;https://www.segger.com/downloads/systemview/systemview_target_src&quot;&gt;目标板源码&lt;/a&gt;，将其中的 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;SEGGER&lt;/code&gt; 目录下代码以及 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Sample&lt;/code&gt; 中的FreeRTOS代码添加到项目。&lt;/p&gt;

&lt;div file=&quot;tree&quot; class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;SystemView
├── Config
│   ├── Global.h
│   ├── SEGGER_RTT_Conf.h
│   ├── SEGGER_SYSVIEW_Conf.h
│   └── SEGGER_SYSVIEW_Config_FreeRTOS.c
└── SEGGER
    ├── SEGGER.h
    ├── SEGGER_RTT.c
    ├── SEGGER_RTT.h
    ├── SEGGER_RTT_ASM_ARMv7M.s
    ├── SEGGER_RTT_printf.c
    ├── SEGGER_SYSVIEW.c
    ├── SEGGER_SYSVIEW.h
    ├── SEGGER_SYSVIEW_ConfDefaults.h
    ├── SEGGER_SYSVIEW_FreeRTOS.c
    ├── SEGGER_SYSVIEW_FreeRTOS.h
    ├── SEGGER_SYSVIEW_Int.h
    └── Syscalls
        └── SEGGER_RTT_Syscalls_GCC.c
    
    3 directories, 16 files
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;接下来我们需要实现通过串口的RTT数据收发，这里使用一个额外的Task实现这个操作。&lt;/p&gt;

&lt;div class=&quot;language-c highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;cp&quot;&gt;#define SYSVIEW_COMM_APP_HELLO_SIZE 32
#define SYSVIEW_COMM_TARGET_HELLO_SIZE 32
&lt;/span&gt;
&lt;span class=&quot;cp&quot;&gt;#define SYSVIEW_SINGLE_TX 256
&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;U8&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;hello_message&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;SYSVIEW_COMM_TARGET_HELLO_SIZE&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;sc&quot;&gt;&apos;S&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;sc&quot;&gt;&apos;E&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;sc&quot;&gt;&apos;G&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;sc&quot;&gt;&apos;G&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;sc&quot;&gt;&apos;E&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;sc&quot;&gt;&apos;R&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;sc&quot;&gt;&apos; &apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;sc&quot;&gt;&apos;S&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;sc&quot;&gt;&apos;y&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;sc&quot;&gt;&apos;s&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;sc&quot;&gt;&apos;t&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;sc&quot;&gt;&apos;e&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;sc&quot;&gt;&apos;m&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;sc&quot;&gt;&apos;V&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;sc&quot;&gt;&apos;i&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;sc&quot;&gt;&apos;e&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;sc&quot;&gt;&apos;w&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;sc&quot;&gt;&apos; &apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;sc&quot;&gt;&apos;V&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;sc&quot;&gt;&apos;0&apos;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;SEGGER_SYSVIEW_MAJOR&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;sc&quot;&gt;&apos;.&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;sc&quot;&gt;&apos;0&apos;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;SEGGER_SYSVIEW_MINOR&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
    &lt;span class=&quot;sc&quot;&gt;&apos;0&apos;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;SEGGER_SYSVIEW_MINOR&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
    &lt;span class=&quot;sc&quot;&gt;&apos;.&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;sc&quot;&gt;&apos;0&apos;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;SEGGER_SYSVIEW_REV&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
    &lt;span class=&quot;sc&quot;&gt;&apos;0&apos;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;SEGGER_SYSVIEW_REV&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
    &lt;span class=&quot;sc&quot;&gt;&apos;\0&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt; 
&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;TaskHandle_t&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;xTaskTraceCommHandle&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;NULL&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;vTaskTraceComm&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;pvParameters&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;//获取Channel ID&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;channel_id&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;SEGGER_SYSVIEW_GetChannelID&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;//发送HELLO包&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;HAL_UART_Transmit&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;huart1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;hello_message&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;SYSVIEW_COMM_TARGET_HELLO_SIZE&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1000&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

    &lt;span class=&quot;kt&quot;&gt;uint8_t&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rx_buf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;uint8_t&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tx_buf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;SYSVIEW_SINGLE_TX&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;//启动记录&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;SEGGER_SYSVIEW_Start&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;//等待通过串口中断接收数据&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;HAL_UART_Receive_IT&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;huart1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rx_buf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0x01&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(;;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;xTaskNotifyWait&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x00&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0x01&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;NULL&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pdMS_TO_TICKS&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;400&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pdTRUE&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;c1&quot;&gt;//接收到数据，写入到RTT缓存&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;SEGGER_RTT_WriteDownBufferNoLock&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;channel_id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rx_buf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0x01&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;HAL_UART_Receive_IT&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;huart1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rx_buf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0x01&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;//获取上行缓存数据长度&lt;/span&gt;
        &lt;span class=&quot;kt&quot;&gt;unsigned&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tx_length&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;SEGGER_RTT_GetBytesInBuffer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;channel_id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tx_length&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;SYSVIEW_SINGLE_TX&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; 
            &lt;span class=&quot;c1&quot;&gt;//STM32 HAL代码有最大长度限制，这里默认设置为256字节，可调整&lt;/span&gt;
            &lt;span class=&quot;c1&quot;&gt;//从RTT缓存中读出数据&lt;/span&gt;
            &lt;span class=&quot;kt&quot;&gt;uint32_t&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;num&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;SEGGER_RTT_ReadUpBufferNoLock&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;channel_id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tx_buf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;SYSVIEW_SINGLE_TX&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
            &lt;span class=&quot;c1&quot;&gt;//通过串口发送，此处可使用中断方式发送，尚未实现。&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;HAL_UART_Transmit&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;huart1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tx_buf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;num&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tx_length&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;){&lt;/span&gt;
            &lt;span class=&quot;c1&quot;&gt;// 同上&lt;/span&gt;
            &lt;span class=&quot;kt&quot;&gt;uint32_t&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;num&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;SEGGER_RTT_ReadUpBufferNoLock&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;channel_id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tx_buf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tx_length&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;HAL_UART_Transmit&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;huart1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tx_buf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;num&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;vTaskDelete&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;NULL&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;//串口ISR&lt;/span&gt;
&lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;HAL_UART_RxCpltCallback&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;UART_HandleTypeDef&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;huart&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;huart&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Instance&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;USART1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;//向Task发送通知，收到数据&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;BaseType_t&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;higher_woken&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pdFALSE&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;xTaskNotifyFromISR&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;xTaskTraceCommHandle&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0x01&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;eSetBits&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;higher_woken&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;portYIELD_FROM_ISR&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;higher_woken&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;创建Task：&lt;/p&gt;

&lt;div class=&quot;language-c highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;xTaskCreate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;vTaskTraceComm&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;trace_task&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1024&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;NULL&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;6&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;xTaskTraceCommHandle&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;在RTOS调度器启动之前执行 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;SEGGER_SYSVIEW_Conf()&lt;/code&gt; 。&lt;/p&gt;

&lt;p&gt;默认情况下SystemView会从DWT的Cycle counter获取系统当前周期数用于生成时间戳：&lt;/p&gt;

&lt;div class=&quot;language-c highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;cm&quot;&gt;/*********************************************************************
*
* SystemView timestamp configuration
*/&lt;/span&gt;
&lt;span class=&quot;cp&quot;&gt;#if !defined(SEGGER_SYSVIEW_GET_TIMESTAMP) &amp;amp;&amp;amp; !defined(SEGGER_SYSVIEW_TIMESTAMP_BITS)
&lt;/span&gt;  &lt;span class=&quot;cp&quot;&gt;#if SEGGER_SYSVIEW_CORE == SEGGER_SYSVIEW_CORE_CM3
&lt;/span&gt;    &lt;span class=&quot;cp&quot;&gt;#define SEGGER_SYSVIEW_GET_TIMESTAMP() (*(U32 *)(0xE0001004)) // Retrieve a system timestamp. Cortex-M cycle counter.
&lt;/span&gt;    &lt;span class=&quot;cp&quot;&gt;#define SEGGER_SYSVIEW_TIMESTAMP_BITS 32 // Define number of valid bits low-order delivered by clock source
&lt;/span&gt;  &lt;span class=&quot;cp&quot;&gt;#else
&lt;/span&gt;    &lt;span class=&quot;cp&quot;&gt;#define SEGGER_SYSVIEW_GET_TIMESTAMP() SEGGER_SYSVIEW_X_GetTimestamp() // Retrieve a system timestamp via user-defined function
&lt;/span&gt;    &lt;span class=&quot;cp&quot;&gt;#define SEGGER_SYSVIEW_TIMESTAMP_BITS 32 // Define number of valid bits low-order delivered by SEGGER_SYSVIEW_X_GetTimestamp()
&lt;/span&gt;  &lt;span class=&quot;cp&quot;&gt;#endif
#endif
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;在STM32CubeMX的初始化代码中该计数器默认未启用，在这里手工启用。&lt;/p&gt;

&lt;div class=&quot;language-c highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;CoreDebug&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;DEMCR&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;CoreDebug_DEMCR_TRCENA_Msk&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;DWT&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;CYCCNT&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;DWT&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;CTRL&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;DWT_CTRL_CYCCNTENA_Msk&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;修改 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;FreeRTOSConfig.h&lt;/code&gt; 引入SystemView的trace宏：&lt;/p&gt;

&lt;div class=&quot;language-c highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;cm&quot;&gt;/* USER CODE BEGIN Defines */&lt;/span&gt;   	      
&lt;span class=&quot;cm&quot;&gt;/* Section where parameter definitions can be added (for instance, to override default ones in FreeRTOS.h) */&lt;/span&gt;
    
&lt;span class=&quot;cp&quot;&gt;#define INCLUDE_xTaskGetIdleTaskHandle 1
&lt;/span&gt;    
&lt;span class=&quot;cp&quot;&gt;#include&lt;/span&gt; &lt;span class=&quot;cpf&quot;&gt;&quot;SEGGER_SYSVIEW_FreeRTOS.h&quot;&lt;/span&gt;&lt;span class=&quot;cp&quot;&gt;
&lt;/span&gt;    
&lt;span class=&quot;cm&quot;&gt;/* USER CODE END Defines */&lt;/span&gt; 
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;至此，我们的移植过程基本结束。&lt;/p&gt;

&lt;p&gt;注：在SEGGER代码中， &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;_write&lt;/code&gt; 部分的实现存在签名不兼容的问题，此函数是用于将stdout通过RTT输出到SystemView，可直接删除 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;SEGGER/Syscalls/SEGGER_RTT_Syscalls_GCC.c&lt;/code&gt; ，也可修改函数签名使其与系统库一致。&lt;/p&gt;

&lt;p&gt;注2：在初始化时使用了 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;strcpy()&lt;/code&gt; 函数，在测试环境中出现Hardfault问题，可在 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;SEGGER/SEGGER_RTT.c&lt;/code&gt; 中将&lt;/p&gt;

&lt;div file=&quot;SEGGER/SEGGER_RTT.c&quot; class=&quot;language-c highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;cp&quot;&gt;#ifndef STRCPY
&lt;/span&gt;  &lt;span class=&quot;cp&quot;&gt;#define STRCPY(pDest, pSrc, NumBytes) strcpy((pDest), (pSrc))
#endif
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;替换为&lt;/p&gt;

&lt;div file=&quot;SEGGER/SEGGER_RTT.c&quot; class=&quot;language-c highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;cp&quot;&gt;#ifndef STRCPY
&lt;/span&gt;  &lt;span class=&quot;cp&quot;&gt;#define STRCPY(pDest, pSrc, NumBytes) strncpy((pDest), (pSrc), (NumBytes))
#endif
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;初步推测为Null-Terminated的问题，有头绪欢迎联系指正。&lt;/p&gt;

&lt;p&gt;2020-05-07更新：使用DMA传输以减少CPU开销&lt;/p&gt;

&lt;p&gt;更新部分代码如下&lt;/p&gt;

&lt;div file=&quot;void vTaskTraceComm(void *pvParameters)&quot; class=&quot;language-c highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;for&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(;;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;xTaskNotifyWait&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x00&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0x03&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;amp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;notify_flag&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pdMS_TO_TICKS&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;400&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pdTRUE&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;notify_flag&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;amp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0x01&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;SEGGER_RTT_WriteDownBufferNoLock&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;channel_id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;amp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rx_buf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0x01&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;HAL_UART_Receive_IT&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;amp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;huart1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;amp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rx_buf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0x01&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;notify_flag&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;amp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0x02&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dma_in_progress&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;dma_in_progress&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;prev_send&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;xTaskGetTickCount&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dma_in_progress&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;amp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;amp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;xTaskGetTickCount&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;prev_send&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;gt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pdMS_TO_TICKS&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;400&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;kt&quot;&gt;unsigned&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tx_length&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;SEGGER_RTT_GetBytesInBuffer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;channel_id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tx_length&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;gt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;SYSVIEW_SINGLE_TX&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;kt&quot;&gt;uint32_t&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;num&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;SEGGER_RTT_ReadUpBufferNoLock&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;channel_id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tx_buf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;SYSVIEW_SINGLE_TX&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;HAL_UART_Transmit_DMA&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;amp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;huart1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tx_buf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;num&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tx_length&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;){&lt;/span&gt;
            &lt;span class=&quot;kt&quot;&gt;uint32_t&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;num&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;SEGGER_RTT_ReadUpBufferNoLock&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;channel_id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tx_buf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tx_length&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;HAL_UART_Transmit_DMA&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;amp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;huart1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tx_buf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;num&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;dma_in_progress&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;同时添加DMA传输完成中断&lt;/p&gt;

&lt;div class=&quot;language-c highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;HAL_UART_TxCpltCallback&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;UART_HandleTypeDef&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;huart&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;huart&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Instance&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;USART1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;BaseType_t&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;higher_woken&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pdFALSE&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;xTaskNotifyFromISR&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;xTaskTraceCommHandle&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0x02&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;eSetBits&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;higher_woken&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;portYIELD_FROM_ISR&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;higher_woken&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;即可实现DMA传输&lt;/p&gt;

&lt;h2 id=&quot;5-软件使用&quot;&gt;5. 软件使用&lt;/h2&gt;

&lt;p&gt;启动SystemView，在Target-&amp;gt;Recorder Configuration中指定串口及波特率，连接后RESET目标板即可接收事件。如下图。&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/2020/05/image-4.png&quot; alt=&quot;&quot; /&gt;
&lt;em&gt;SystemView主界面&lt;/em&gt;&lt;/p&gt;

&lt;h2 id=&quot;6-patch&quot;&gt;6. Patch&lt;/h2&gt;

&lt;p&gt;默认的FreeRTOS trace宏不足以收集足够的参数，因此需要Patch FreeRTOS。提供参考Patch如下，来自SEGGER的Sample目录&lt;/p&gt;

&lt;div class=&quot;language-patch highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;gh&quot;&gt;diff -ur Middlewares/Third_Party/FreeRTOS/Source/include/FreeRTOS.h ../FreeRTOS/Source/include/FreeRTOS.h
&lt;/span&gt;&lt;span class=&quot;gd&quot;&gt;--- Middlewares/Third_Party/FreeRTOS/Source/include/FreeRTOS.h	2020-05-07 22:43:33.533067758 +0800
&lt;/span&gt;&lt;span class=&quot;gi&quot;&gt;+++ ../FreeRTOS/Source/include/FreeRTOS.h	2020-05-07 22:41:30.520012215 +0800
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;@@ -156,6 +156,10 @@&lt;/span&gt;
 	#define INCLUDE_uxTaskGetStackHighWaterMark 0
 #endif
 
&lt;span class=&quot;gi&quot;&gt;+#ifndef INCLUDE_pxTaskGetStackStart
+	#define INCLUDE_pxTaskGetStackStart 0
+#endif
+
&lt;/span&gt; #ifndef INCLUDE_uxTaskGetStackHighWaterMark2
 	#define INCLUDE_uxTaskGetStackHighWaterMark2 0
 #endif
&lt;span class=&quot;p&quot;&gt;@@ -400,6 +404,25 @@&lt;/span&gt;
 	#define tracePOST_MOVED_TASK_TO_READY_STATE( pxTCB )
 #endif
 
&lt;span class=&quot;gi&quot;&gt;+#ifndef traceREADDED_TASK_TO_READY_STATE
+ #define traceREADDED_TASK_TO_READY_STATE( pxTCB ) traceMOVED_TASK_TO_READY_STATE( pxTCB )
+#endif
+
+#ifndef traceMOVED_TASK_TO_DELAYED_LIST
+ #define traceMOVED_TASK_TO_DELAYED_LIST()
+#endif
+
+#ifndef traceMOVED_TASK_TO_OVERFLOW_DELAYED_LIST
+ #define traceMOVED_TASK_TO_OVERFLOW_DELAYED_LIST()
+#endif
+
+#ifndef traceMOVED_TASK_TO_SUSPENDED_LIST
+ #define traceMOVED_TASK_TO_SUSPENDED_LIST( pxTCB )
+#endif
+
+
+
+
&lt;/span&gt; #ifndef traceQUEUE_CREATE
 	#define traceQUEUE_CREATE( pxNewQueue )
 #endif
&lt;span class=&quot;p&quot;&gt;@@ -644,6 +667,18 @@&lt;/span&gt;
 	#define traceTASK_NOTIFY_GIVE_FROM_ISR()
 #endif
 
&lt;span class=&quot;gi&quot;&gt;+#ifndef traceISR_EXIT_TO_SCHEDULER
+	#define traceISR_EXIT_TO_SCHEDULER()
+#endif
+
+#ifndef traceISR_EXIT
+	#define traceISR_EXIT()
+#endif
+
+#ifndef traceISR_ENTER
+	#define traceISR_ENTER()
+#endif
+
&lt;/span&gt; #ifndef traceSTREAM_BUFFER_CREATE_FAILED
 	#define traceSTREAM_BUFFER_CREATE_FAILED( xIsMessageBuffer )
 #endif
&lt;span class=&quot;gh&quot;&gt;diff -ur Middlewares/Third_Party/FreeRTOS/Source/include/task.h ../FreeRTOS/Source/include/task.h
&lt;/span&gt;&lt;span class=&quot;gd&quot;&gt;--- Middlewares/Third_Party/FreeRTOS/Source/include/task.h	2020-05-07 22:43:33.529734437 +0800
&lt;/span&gt;&lt;span class=&quot;gi&quot;&gt;+++ ../FreeRTOS/Source/include/task.h	2020-05-07 22:41:30.516678886 +0800
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;@@ -1438,6 +1438,25 @@&lt;/span&gt;
 
 /**
  * task.h
&lt;span class=&quot;gi&quot;&gt;+ * &amp;lt;PRE&amp;gt;uint8_t* pxTaskGetStackStart( TaskHandle_t xTask);&amp;lt;/PRE&amp;gt;
+ *
+ * INCLUDE_pxTaskGetStackStart must be set to 1 in FreeRTOSConfig.h for
+ * this function to be available.
+ *
+ * Returns the start of the stack associated with xTask. That is,
+ * the highest stack memory address on architectures where the stack grows down
+ * from high memory, and the lowest memory address on architectures where the
+ * stack grows up from low memory.
+ *
+ * @param xTask Handle of the task associated with the stack returned.
+ * Set xTask to NULL to return the stack of the calling task.
+ *
+ * @return A pointer to the start of the stack.
+ */
+uint8_t* pxTaskGetStackStart( TaskHandle_t xTask) PRIVILEGED_FUNCTION;
+
+/**
+ * task.h
&lt;/span&gt;  * &amp;lt;PRE&amp;gt;configSTACK_DEPTH_TYPE uxTaskGetStackHighWaterMark2( TaskHandle_t xTask );&amp;lt;/PRE&amp;gt;
  *
  * INCLUDE_uxTaskGetStackHighWaterMark2 must be set to 1 in FreeRTOSConfig.h for
&lt;span class=&quot;gh&quot;&gt;diff -ur Middlewares/Third_Party/FreeRTOS/Source/portable/GCC/ARM_CM4F/port.c ../FreeRTOS/Source/portable/GCC/ARM_CM4F/port.c
&lt;/span&gt;&lt;span class=&quot;gd&quot;&gt;--- Middlewares/Third_Party/FreeRTOS/Source/portable/GCC/ARM_CM4F/port.c	2020-05-07 22:43:33.533067758 +0800
&lt;/span&gt;&lt;span class=&quot;gi&quot;&gt;+++ ../FreeRTOS/Source/portable/GCC/ARM_CM4F/port.c	2020-05-07 22:41:30.536678867 +0800
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;@@ -492,14 +492,20 @@&lt;/span&gt;
 	save and then restore the interrupt mask value as its value is already
 	known. */
 	portDISABLE_INTERRUPTS();
&lt;span class=&quot;gi&quot;&gt;+	traceISR_ENTER();
&lt;/span&gt; 	{
 		/* Increment the RTOS tick. */
 		if( xTaskIncrementTick() != pdFALSE )
 		{
&lt;span class=&quot;gi&quot;&gt;+ traceISR_EXIT_TO_SCHEDULER();
&lt;/span&gt; 			/* A context switch is required. Context switching is performed in
 			the PendSV interrupt. Pend the PendSV interrupt. */
 			portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT;
 		}
&lt;span class=&quot;gi&quot;&gt;+ else
+ {
+ traceISR_EXIT();
+ }
&lt;/span&gt; 	}
 	portENABLE_INTERRUPTS();
 }
&lt;span class=&quot;gh&quot;&gt;diff -ur Middlewares/Third_Party/FreeRTOS/Source/portable/GCC/ARM_CM4F/portmacro.h ../FreeRTOS/Source/portable/GCC/ARM_CM4F/portmacro.h
&lt;/span&gt;&lt;span class=&quot;gd&quot;&gt;--- Middlewares/Third_Party/FreeRTOS/Source/portable/GCC/ARM_CM4F/portmacro.h	2020-05-07 22:43:33.533067758 +0800
&lt;/span&gt;&lt;span class=&quot;gi&quot;&gt;+++ ../FreeRTOS/Source/portable/GCC/ARM_CM4F/portmacro.h	2020-05-07 22:41:30.536678867 +0800
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;@@ -89,7 +89,7 @@&lt;/span&gt;
 
 #define portNVIC_INT_CTRL_REG ( * ( ( volatile uint32_t * ) 0xe000ed04 ) )
 #define portNVIC_PENDSVSET_BIT ( 1UL &amp;lt;&amp;lt; 28UL )
&lt;span class=&quot;gd&quot;&gt;-#define portEND_SWITCHING_ISR( xSwitchRequired ) if( xSwitchRequired != pdFALSE ) portYIELD()
&lt;/span&gt;&lt;span class=&quot;gi&quot;&gt;+#define portEND_SWITCHING_ISR( xSwitchRequired ) { if( xSwitchRequired ) { traceISR_EXIT_TO_SCHEDULER(); portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; } else { traceISR_EXIT(); } }
&lt;/span&gt; #define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x )
 /*-----------------------------------------------------------*/
 
&lt;span class=&quot;gh&quot;&gt;diff -ur Middlewares/Third_Party/FreeRTOS/Source/tasks.c ../FreeRTOS/Source/tasks.c
&lt;/span&gt;&lt;span class=&quot;gd&quot;&gt;--- Middlewares/Third_Party/FreeRTOS/Source/tasks.c	2020-05-07 22:43:33.549734367 +0800
&lt;/span&gt;&lt;span class=&quot;gi&quot;&gt;+++ ../FreeRTOS/Source/tasks.c	2020-05-07 22:41:30.546678856 +0800
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;@@ -220,6 +220,17 @@&lt;/span&gt;
 	taskRECORD_READY_PRIORITY( ( pxTCB )-&amp;gt;uxPriority ); \
 	vListInsertEnd( &amp;amp;( pxReadyTasksLists[( pxTCB )-&amp;gt;uxPriority] ), &amp;amp;( ( pxTCB )-&amp;gt;xStateListItem ) ); \
 	tracePOST_MOVED_TASK_TO_READY_STATE( pxTCB )
&lt;span class=&quot;gi&quot;&gt;+
+/*
+ * Place the task represented by pxTCB which has been in a ready list before
+ * into the appropriate ready list for the task.
+ * It is inserted at the end of the list.
+ */
+#define prvReaddTaskToReadyList( pxTCB ) \
+ traceREADDED_TASK_TO_READY_STATE( pxTCB ); \
+ taskRECORD_READY_PRIORITY( ( pxTCB )-&amp;gt;uxPriority ); \
+ vListInsertEnd( &amp;amp;( pxReadyTasksLists[( pxTCB )-&amp;gt;uxPriority] ), &amp;amp;( ( pxTCB )-&amp;gt;xStateListItem ) ); \
+ tracePOST_MOVED_TASK_TO_READY_STATE( pxTCB )
&lt;/span&gt; /*-----------------------------------------------------------*/
 
 /*
&lt;span class=&quot;p&quot;&gt;@@ -1126,7 +1137,7 @@&lt;/span&gt;
 		#endif /* configUSE_TRACE_FACILITY */
 		traceTASK_CREATE( pxNewTCB );
 
&lt;span class=&quot;gd&quot;&gt;- prvAddTaskToReadyList( pxNewTCB );
&lt;/span&gt;&lt;span class=&quot;gi&quot;&gt;+ prvReaddTaskToReadyList( pxNewTCB );
&lt;/span&gt; 
 		portSETUP_TCB( pxNewTCB );
 	}
&lt;span class=&quot;p&quot;&gt;@@ -1726,6 +1737,8 @@&lt;/span&gt;
 				mtCOVERAGE_TEST_MARKER();
 			}
 
&lt;span class=&quot;gi&quot;&gt;+ traceMOVED_TASK_TO_SUSPENDED_LIST(pxTCB);
+
&lt;/span&gt; 			vListInsertEnd( &amp;amp;xSuspendedTaskList, &amp;amp;( pxTCB-&amp;gt;xStateListItem ) );
 
 			#if( configUSE_TASK_NOTIFICATIONS == 1 )
&lt;span class=&quot;p&quot;&gt;@@ -3821,6 +3834,20 @@&lt;/span&gt;
 #endif /* INCLUDE_uxTaskGetStackHighWaterMark */
 /*-----------------------------------------------------------*/
 
&lt;span class=&quot;gi&quot;&gt;+#if (INCLUDE_pxTaskGetStackStart == 1)
+ uint8_t* pxTaskGetStackStart( TaskHandle_t xTask)
+ {
+ TCB_t *pxTCB;
+ UBaseType_t uxReturn;
+ (void)uxReturn;
+
+ pxTCB = prvGetTCBFromHandle( xTask );
+ return ( uint8_t * ) pxTCB-&amp;gt;pxStack;
+ }
+
+#endif /* INCLUDE_pxTaskGetStackStart */
+/*-----------------------------------------------------------*/
+
&lt;/span&gt; #if ( INCLUDE_vTaskDelete == 1 )
 
 	static void prvDeleteTCB( TCB_t *pxTCB )
&lt;span class=&quot;p&quot;&gt;@@ -3990,7 +4017,7 @@&lt;/span&gt;
 
 					/* Inherit the priority before being moved into the new list. */
 					pxMutexHolderTCB-&amp;gt;uxPriority = pxCurrentTCB-&amp;gt;uxPriority;
&lt;span class=&quot;gd&quot;&gt;- prvAddTaskToReadyList( pxMutexHolderTCB );
&lt;/span&gt;&lt;span class=&quot;gi&quot;&gt;+ prvReaddTaskToReadyList( pxMutexHolderTCB );
&lt;/span&gt; 				}
 				else
 				{
&lt;span class=&quot;p&quot;&gt;@@ -4080,7 +4107,7 @@&lt;/span&gt;
 					any other purpose if this task is running, and it must be
 					running to give back the mutex. */
 					listSET_LIST_ITEM_VALUE( &amp;amp;( pxTCB-&amp;gt;xEventListItem ), ( TickType_t ) configMAX_PRIORITIES - ( TickType_t ) pxTCB-&amp;gt;uxPriority ); /*lint !e961 MISRA exception as the casts are only redundant for some ports. */
&lt;span class=&quot;gd&quot;&gt;- prvAddTaskToReadyList( pxTCB );
&lt;/span&gt;&lt;span class=&quot;gi&quot;&gt;+ prvReaddTaskToReadyList( pxTCB );
&lt;/span&gt; 
 					/* Return true to indicate that a context switch is required.
 					This is only actually required in the corner case whereby
&lt;span class=&quot;p&quot;&gt;@@ -5112,6 +5139,7 @@&lt;/span&gt;
 			/* Add the task to the suspended task list instead of a delayed task
 			list to ensure it is not woken by a timing event. It will block
 			indefinitely. */
&lt;span class=&quot;gi&quot;&gt;+ traceMOVED_TASK_TO_SUSPENDED_LIST(pxCurrentTCB);
&lt;/span&gt; 			vListInsertEnd( &amp;amp;xSuspendedTaskList, &amp;amp;( pxCurrentTCB-&amp;gt;xStateListItem ) );
 		}
 		else
&lt;span class=&quot;p&quot;&gt;@@ -5128,12 +5156,14 @@&lt;/span&gt;
 			{
 				/* Wake time has overflowed. Place this item in the overflow
 				list. */
&lt;span class=&quot;gi&quot;&gt;+ traceMOVED_TASK_TO_OVERFLOW_DELAYED_LIST();
&lt;/span&gt; 				vListInsert( pxOverflowDelayedTaskList, &amp;amp;( pxCurrentTCB-&amp;gt;xStateListItem ) );
 			}
 			else
 			{
 				/* The wake time has not overflowed, so the current block list
 				is used. */
&lt;span class=&quot;gi&quot;&gt;+ traceMOVED_TASK_TO_OVERFLOW_DELAYED_LIST();
&lt;/span&gt; 				vListInsert( pxDelayedTaskList, &amp;amp;( pxCurrentTCB-&amp;gt;xStateListItem ) );
 
 				/* If the task entering the blocked state was placed at the
&lt;span class=&quot;p&quot;&gt;@@ -5163,11 +5193,13 @@&lt;/span&gt;
 		if( xTimeToWake &amp;lt; xConstTickCount )
 		{
 			/* Wake time has overflowed. Place this item in the overflow list. */
&lt;span class=&quot;gi&quot;&gt;+ traceMOVED_TASK_TO_OVERFLOW_DELAYED_LIST();
&lt;/span&gt; 			vListInsert( pxOverflowDelayedTaskList, &amp;amp;( pxCurrentTCB-&amp;gt;xStateListItem ) );
 		}
 		else
 		{
 			/* The wake time has not overflowed, so the current block list is used. */
&lt;span class=&quot;gi&quot;&gt;+ traceMOVED_TASK_TO_DELAYED_LIST();
&lt;/span&gt; 			vListInsert( pxDelayedTaskList, &amp;amp;( pxCurrentTCB-&amp;gt;xStateListItem ) );
 
 			/* If the task entering the blocked state was placed at the head of the
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h2 id=&quot;7-参考&quot;&gt;7. 参考&lt;/h2&gt;

&lt;p&gt;&lt;a href=&quot;https://www.segger.com/downloads/systemview/UM08027&quot;&gt;User Manual&lt;/a&gt;&lt;/p&gt;
</description>
        <pubDate>Tue, 05 May 2020 09:48:59 +0000</pubDate>
        <link>https://www.imstatic.com/archivers/systemview-freertos</link>
        <guid isPermaLink="true">https://www.imstatic.com/archivers/systemview-freertos</guid>
        
        <category>hardware</category>
        
        
      </item>
    
      <item>
        <title>Archlinux上Buildroot的基础使用</title>
        <description>&lt;h2 id=&quot;什么是buildroot好吃么&quot;&gt;什么是Buildroot？好吃么？&lt;/h2&gt;

&lt;p&gt;Buildroot是一套用于构建定制化rootfs环境的工具集，可以通过简单步骤在嵌入式系统上快速构建rootfs环境用于应用部署。&lt;/p&gt;

&lt;h2 id=&quot;为什么选择buildroot和发行版rootfs的区别是&quot;&gt;为什么选择Buildroot？和发行版rootfs的区别是？&lt;/h2&gt;

&lt;h3 id=&quot;1-架构支持广泛&quot;&gt;1. 架构支持广泛&lt;/h3&gt;

&lt;p&gt;大多数发行版rootfs只支持常见主流架构，不仅如此，发行版在架构支持方面本着兼容性原则，即便是支持的架构，最终依然会牺牲一部分性能（Hard Float，Architecture Specific的SIMD指令集支持等），Buildroot则可以自由选择工具链及编译参数，并且指定所需要的优化选项进行构建。&lt;/p&gt;

&lt;h3 id=&quot;2-体积小工作稳定&quot;&gt;2. 体积小，工作稳定&lt;/h3&gt;

&lt;p&gt;发行版为了保证易用性，通常加入了大量功能与程序便于用户使用，同时为了开箱即用的特征，在网络配置等关键环节也会使用NetworkManager等高级工具进行管理，Init系统也大多使用Systemd，增大了系统的复杂程度，同时不可避免的要产生文件写入等操作，加速Flash等存储设备寿命损耗，降低设备使用年限。Buildroot则避免了上述种种问题，单一稳定的网络配置，可选的DHCP等组件，Busybox轻量级的初始化系统及CoreUtils，可以只读的文件系统支持都使得它对于小体积Flash，低写入寿命，长时间工作的嵌入式系统极其友好。&lt;/p&gt;

&lt;h3 id=&quot;3-定制程度高配置简单&quot;&gt;3. 定制程度高，配置简单&lt;/h3&gt;

&lt;p&gt;不需要使用包管理器，基于Kconfig的编译配置系统，软件支持也很齐全，只需要选择所需工具就可以构建上机即用的rootfs。&lt;/p&gt;

&lt;h2 id=&quot;获取buildroot及工具链&quot;&gt;获取Buildroot及工具链&lt;/h2&gt;

&lt;h3 id=&quot;0-了解硬件平台&quot;&gt;0. 了解硬件平台&lt;/h3&gt;

&lt;p&gt;为了构建出我们需要的可用的rootfs，我们首先需要了解我们的硬件平台。&lt;/p&gt;

&lt;p&gt;本文来自之前为 LoRaWAN 网关设计平台的过程中，我们选用了全志V3s这款SoC，LQFP封装，内嵌512Mbit DDR2 SDRAM，单核Cortex-A7 w/ NEON+FPv4，很适合我们需要的场景使用。&lt;/p&gt;

&lt;h3 id=&quot;1-获取buildroot&quot;&gt;1. 获取Buildroot&lt;/h3&gt;

&lt;p&gt;Buildroot的最新版本可以从 &lt;a href=&quot;https://buildroot.org/download.html&quot;&gt;https://buildroot.org/download.html&lt;/a&gt; 下载tarball。&lt;/p&gt;

&lt;h3 id=&quot;2-获取工具链&quot;&gt;2. 获取工具链&lt;/h3&gt;

&lt;p&gt;Archlinux默认工具链及AUR提供的交叉工具链都是无法复制使用的，Buildroot在构建时会将工具链复制到工作目录执行，因此我们需要选择Portable的工具链二进制或者像我一样选择 The Hard Way - crosstool-NG编译工具链。&lt;/p&gt;

&lt;h3 id=&quot;21-crosstool-ng的使用及工具链构建&quot;&gt;2.1 crosstool-NG的使用及工具链构建&lt;/h3&gt;

&lt;p&gt;crosstool-NG（以下简称 ct-ng ）是一个快速简易构建工具链的工具（没错够绕嘴的），可以用于完成以下几个主要步骤&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;构建 buildutils&lt;/li&gt;
  &lt;li&gt;构建 3-Stage Cross GCC 及对应的C Library&lt;/li&gt;
  &lt;li&gt;构建 Cross-GDB&lt;/li&gt;
&lt;/ol&gt;

&lt;h3 id=&quot;211-ct-ng-获取及编译&quot;&gt;2.1.1 ct-ng 获取及编译&lt;/h3&gt;

&lt;p&gt;部分发行版可能打包了crosstool-NG，Archlinux并没有打包，而且为了使用新版本工具链及配置，推荐跟随文档使用如下的编译安装方式。&lt;/p&gt;

&lt;p&gt;首先我们需要从 &lt;a href=&quot;https://crosstool-ng.github.io/&quot;&gt;https://crosstool-ng.github.io&lt;/a&gt; 获取最新版本的ct-ng（Git/Tarball），解压后进入项目目录，跟随 &lt;a href=&quot;https://crosstool-ng.github.io/docs/install/&quot;&gt;https://crosstool-ng.github.io/docs/install/&lt;/a&gt; 的步骤，执行 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;bootstrap&lt;/code&gt; ，选择合适prefix，编译并安装（ &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;make&lt;/code&gt; 与 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;make install&lt;/code&gt; 想必你们用得比我熟）。&lt;/p&gt;

&lt;p&gt;现在我们可以使用 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ct-ng&lt;/code&gt; 命令了，不过不要急着试试，因为这东西会在当前目录创建一些配置文件，所以我们要新建一个工作目录用于 ct-ng 保存配置及文件。&lt;/p&gt;

&lt;p&gt;本次目录名叫 arm-linux-glibc ，字面意思：target 是 32-bit 的 ARM 处理器，操作系统 Linux ，C标准库使用GNU LibC实现，因为 AUR 中的工具链一样使用了 GlibC，方便日后交叉编译使用（但是其实可以完全一套工具链跑到黑）。&lt;/p&gt;

&lt;p&gt;在工作目录中，运行 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ct-ng list-samples&lt;/code&gt; 可以查看当前的所有sample列表，这里我们选用 arm-cortex_a15-linux-gnueabihf 作为我们的预设target，之后的步骤基于这个配置修改。选择这个配置的原因是，Cortex-A7与Cortex-A15都基于ARMv7-A，同时都使用FPv4浮点处理器和NEON SIMD指令。&lt;/p&gt;

&lt;p&gt;运行 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ct-ng arm-cortex_a15-linux-gnueabihf&lt;/code&gt; 配置当前工程， &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ct-ng nconfig&lt;/code&gt;  使用酷炫的 nurses 配置界面修改配置。&lt;/p&gt;

&lt;p&gt;多数配置不需要更改，可以添加tarball cache以节约下载时间。&lt;/p&gt;

&lt;div file=&quot;nconfig&quot; class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;                                    .config - crosstool-NG  Configuration
 ┌── Paths and misc options ───────────────────────────────────────────────────────────────────────────────┐
 │                                                                                                         │
 │        *** crosstool-NG behavior ***                                                                    │
 │    [ ] Use obsolete features                                                                            │
 │    [ ] Try features marked as EXPERIMENTAL                                                              │
 │    [ ] Debug crosstool-NG                                                                               │
 │        *** Paths ***                                                                                    │
 │        (${HOME}/Softwares/Crosstool-NG/tarballs) Local tarballs directory                               │
 │    [*]   Save new tarballs                                                                              │
 │    [ ] Prefer buildroot-style layout of the downloads                                                   │
 │        (${CT_TOP_DIR}/.build) Working directory                                                         │
 │        (${CT_PREFIX:-${HOME}/x-tools}/${CT_HOST:+HOST-${CT_HOST}/}${CT_TARGET}) Prefix directory        │
 │    [*]   Remove the prefix dir prior to building                                                        │
 │    [*] Remove documentation                                                                             │
 │    [*] Install licenses                                                                                 │
 │    [*] Render the toolchain read-only                                                                   │
 │    [*] Strip host toolchain executables                                                                 │
 │    [ ] Strip target toolchain executables                                                               │
 │        *** Downloading ***                                                                              │
 │        Download agent (wget)  ---&amp;gt;                                                                      │
 │    [ ] Forbid downloads                                                                                 │
 │    [ ]   Force downloads                                                                                │
 │        (10)  Connection timeout                                                                         │
 │        (--passive-ftp --tries=3 -nc --progress=dot:binary) Extra options to wget                        │
 │    [ ]   Stop after downloading tarballs                                                                │
 │    [ ]   Use a mirror                                                                                   │
 │    [*]   Verify download digests (checksums)                                                            │
 │            Digest algorithm (SHA-512)  ---&amp;gt;                                                             │
 │    [ ]   Verify detached signatures                                                                     │
 │                                                                                                         │
 │                                                                                                         │
 └F1Help─F2SymInfo─F3Help 2─F4ShowAll─F5Back─F6Save─F7Load─F8SymSearch─F9Exit──────────────────────────────┘
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;一切准备就绪就可以运行ct-ng build，在x-tools就可以拿到我们的工具链了。&lt;/p&gt;

&lt;h2 id=&quot;配置编译buildroot&quot;&gt;配置编译Buildroot&lt;/h2&gt;

&lt;p&gt;Buildroot的配置与Crosstool-NG类似，也使用了Kconfig及Kbuild。解压下载得到的tar包，进入目录运行make nconfig即可看到相似的配置界面。&lt;/p&gt;

&lt;div file=&quot;nconfig&quot; class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt; ┌── Target options ───────────────────────────────────────────────────────────────────────────────────────┐
 │                                                                                                         │
 │                             Target Architecture (ARM (little endian))  ---&amp;gt;                             │
 │                             Target Binary Format (ELF)  ---&amp;gt;                                            │
 │                             Target Architecture Variant (cortex-A7)  ---&amp;gt;                               │
 │                             Target ABI (EABIhf)  ---&amp;gt;                                                   │
 │                             Floating point strategy (NEON/VFPv4)  ---&amp;gt;                                  │
 │                             ARM instruction set (ARM)  ---&amp;gt;                                             │
 │                                                                                                         │
 │                                                                                                         │
 │                                                                                                         │
 │                                                                                                         │
 │                                                                                                         │
 │                                                                                                         │
 │                                                                                                         │
 │                                                                                                         │
 │                                                                                                         │
 │                                                                                                         │
 │                                                                                                         │
 │                                                                                                         │
 │                                                                                                         │
 │                                                                                                         │
 │                                                                                                         │
 │                                                                                                         │
 │                                                                                                         │
 │                                                                                                         │
 │                                                                                                         │
 │                                                                                                         │
 │                                                                                                         │
 │                                                                                                         │
 │                                                                                                         │
 └F1Help─F2SymInfo─F3Help 2─F4ShowAll─F5Back─F6Save─F7Load─F8SymSearch─F9Exit──────────────────────────────┘
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;我们在Target Options中选择我们CPU的类型，Cortex-A7，硬浮点，NEON/VFPv4。&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt; ┌── Toolchain ────────────────────────────────────────────────────────────────────────────────────────────┐
 │                                                                                                         │
 │     Toolchain type (External toolchain)  ---&amp;gt;                                                           │
 │     *** Toolchain External Options ***                                                                  │
 │     Toolchain (Custom toolchain)  ---&amp;gt;                                                                  │
 │     Toolchain origin (Pre-installed toolchain)  ---&amp;gt;                                                    │
 │     (/home/imi415/Softwares/Crosstool-NG/arm-cortex_a15-linux-gnueabihf/arm-cortex_a15-linux-gnueabi    │
 │     (arm-cortex_a15-linux-gnueabihf) Toolchain prefix                                                   │
 │     External toolchain gcc version (9.x)  ---&amp;gt;                                                          │
 │     External toolchain kernel headers series (5.4.x or later)  ---&amp;gt;                                     │
 │     External toolchain C library (glibc/eglibc)  ---&amp;gt;                                                   │
 │ [*] Toolchain has SSP support?                                                                          │
 │ [*] Toolchain has RPC support?                                                                          │
 │ [*] Toolchain has C++ support?                                                                          │
 │ [ ] Toolchain has D support?                                                                            │
 │ [ ] Toolchain has Fortran support?                                                                      │
 │ [ ] Toolchain has OpenMP support?                                                                       │
 │ [ ] Copy gdb server to the Target                                                                       │
 │     *** Host GDB Options ***                                                                            │
 │ [ ] Build cross gdb for the host                                                                        │
 │     *** Toolchain Generic Options ***                                                                   │
 │ [ ] Copy gconv libraries                                                                                │
 │     ()  Extra toolchain libraries to be copied to target                                                │
 │ [*] Enable MMU support                                                                                  │
 │     ()  Target Optimizations                                                                            │
 │     ()  Target linker options                                                                           │
 │ [ ] Register toolchain within Eclipse Buildroot plug-in                                                 │
 │                                                                                                         │
 │                                                                                                         │
 │                                                                                                         │
 │                                                                                                         │
 └F1Help─F2SymInfo─F3Help 2─F4ShowAll─F5Back─F6Save─F7Load─F8SymSearch─F9Exit──────────────────────────────┘
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;在工具链配置中指定我们之前编译的工具链路径，下面相关的参数如果和实际不符的话Buildroot会提示我们修改。&lt;/p&gt;

&lt;p&gt;默认配置使用Busybox作为初始化系统及核心组件，其余配置可自行摸索。&lt;/p&gt;

&lt;p&gt;配置结束后可以执行 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;make&lt;/code&gt; 启动编译，Buildroot会自动下载所需组件，最后生成的rootfs则位于 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;output/images/rootfs.tar&lt;/code&gt; 中。&lt;/p&gt;

&lt;h2 id=&quot;上电运行&quot;&gt;上电运行&lt;/h2&gt;

&lt;p&gt;使用生成的rootfs及另外编译的内核，系统即可启动。&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;[    1.255069] VFS: Mounted root (ext4 filesystem) on device 179:2.
[    1.263416] devtmpfs: mounted
[    1.267895] Freeing unused kernel memory: 1024K
[    1.272748] Run /sbin/init as init process
[    1.415171] EXT4-fs (mmcblk0p2): re-mounted. Opts: (null)
Starting syslogd: OK
Starting klogd: OK
Running sysctl: OK
Initializing random number generator: OK
Saving random seed: [    1.654797] random: dd: uninitialized urandom read (512 bytes read)
OK
Starting network: OK

Welcome to Buildroot
buildroot login: 
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
</description>
        <pubDate>Wed, 26 Feb 2020 13:10:36 +0000</pubDate>
        <link>https://www.imstatic.com/archivers/build-this-root</link>
        <guid isPermaLink="true">https://www.imstatic.com/archivers/build-this-root</guid>
        
        <category>hardware</category>
        
        
      </item>
    
      <item>
        <title>灵车IPQ4019——R619AC</title>
        <description>&lt;blockquote class=&quot;prompt-tip&quot;&gt;
  &lt;p&gt;OpenWrt主线已支持这个型号 (P&amp;amp;W R619AC)，不再需要本文内容。&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2 id=&quot;1-简介&quot;&gt;1. 简介&lt;/h2&gt;

&lt;p&gt;不多说，灵车，IPQ4019，OpenWrt没支持，国产X-Wrt不想用，拿ImageBuilder打Patch吧。&lt;/p&gt;

&lt;h2 id=&quot;2-系统&quot;&gt;2. 系统&lt;/h2&gt;

&lt;p&gt;打Patch的话参见X-Wrt的commit，&lt;a href=&quot;https://github.com/x-wrt/x-wrt/commit/c1ac0ca52a46b13a493035d08d41d32898752d4a&quot;&gt;这个&lt;/a&gt;就差不多了。&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;但是PCIe并不能开箱即用。&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;要想PCIe能用的话还存在三个问题&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;没设备树&lt;/li&gt;
  &lt;li&gt;没电&lt;/li&gt;
  &lt;li&gt;没REFCLK&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;miniPCIe接口3.3V AUX没电的问题可以看下图&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/2019/11/image.png&quot; alt=&quot;&quot; /&gt;
&lt;em&gt;miniPCIe的供电部分，缺焊元件为bypass电阻&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;恩山的方案是短路这个电阻，但是这需要一定的焊接，而且也不便使用，根据观察可以发现左侧SOP-8封装的器件为 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;IRF7416PbF&lt;/code&gt; 功率MOSFET，封装如下：&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/2019/11/image-1.png&quot; alt=&quot;&quot; /&gt;
&lt;em&gt;IRF7416PbF Datasheet&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;这个MOSFET的源极和漏极接在整板3.3V与miniPCIe的供电3.3V中间，我们可以推断该MOSFET的用途是miniPCIe的供电控制，那么栅极推断应为SoC GPIO控制。&lt;/p&gt;

&lt;p&gt;问题来了，这货有100个GPIO，我们如何找到正确的控制这个MOSFET的GPIO呢？&lt;/p&gt;

&lt;p&gt;根据实际插入PCIe模块的情况及万用表测试的结果，该IO的状态只存在是两种可能：&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;输出模式，高电平&lt;/li&gt;
  &lt;li&gt;输入模式，内部上拉&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;那么范围缩小到了状态为输出高或者输入上拉，且没被其他外设占用的GPIO，可以通过/sys/kernel/debug/gpio查看符合条件的Pin，如下：&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;root@OpenWrt:~# cat /sys/kernel/debug/gpio  | grep &quot;pull up&quot;
 gpio0   : in  high func0 2mA pull up
 gpio1   : in  high func0 2mA pull up
 gpio6   : in  high func1 2mA pull up
 gpio7   : in  high func1 2mA pull up
 gpio10  : in  high func0 2mA pull up
 gpio11  : in  high func0 2mA pull up
 gpio12  : in  high func1 2mA pull up
 gpio13  : in  high func1 2mA pull up
 gpio14  : in  low  func1 2mA pull up
 gpio15  : in  low  func1 2mA pull up
 gpio20  : in  high func0 2mA pull up
 gpio21  : in  high func0 2mA pull up
 gpio22  : in  low  func0 2mA pull up
 gpio23  : in  high func1 10mA pull up
 gpio24  : in  high func1 10mA pull up
 gpio25  : in  high func1 10mA pull up
 gpio26  : in  high func1 10mA pull up
 gpio27  : in  high func1 16mA pull up
 gpio28  : in  high func1 10mA pull up
 gpio29  : in  high func0 2mA pull up
 gpio30  : in  high func0 2mA pull up
 gpio31  : in  high func0 2mA pull up
 gpio32  : out low  func0 2mA pull up
 gpio34  : in  high func0 2mA pull up
 gpio35  : in  high func0 2mA pull up
 gpio39  : out high func0 2mA pull up
 gpio40  : in  high func0 2mA pull up
 gpio50  : out high func0 2mA pull up
 gpio52  : out high func0 2mA pull up
 gpio53  : in  high func1 2mA pull up
 gpio58  : in  low  func1 2mA pull up
 gpio59  : in  low  func1 2mA pull up
root@OpenWrt:~# cat /sys/kernel/debug/gpio  | grep &quot;out high&quot;
 gpio4   : out high func0 2mA pull down
 gpio39  : out high func0 2mA pull up
 gpio50  : out high func0 2mA pull up
 gpio52  : out high func0 2mA pull up
 gpio61  : out high func0 2mA pull down
root@OpenWrt:~# 
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;其中可以筛选出func0的IO即为GPIO function。&lt;/p&gt;

&lt;p&gt;根据依次尝试，GPIO2 即为我们要找的GPIO。&lt;/p&gt;

&lt;p&gt;之后我们需要在设备树里让kernel在配置PCIe的时候初始化好这个GPIO，如下所示&lt;/p&gt;

&lt;div class=&quot;language-patch highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;gi&quot;&gt;+&amp;amp;pcie0 {
+        status = &quot;okay&quot;;
+
+        perst-gpio = &amp;lt;&amp;amp;tlmm 4 GPIO_ACTIVE_LOW&amp;gt;;
+        wake-gpio = &amp;lt;&amp;amp;tlmm 40 GPIO_ACTIVE_HIGH&amp;gt;;
+
+       pinctrl-0 = &amp;lt;&amp;amp;pcie_pins&amp;gt;;
+       pinctrl-names = &quot;default&quot;;
+
+        bridge@0,0 {
+                reg = &amp;lt;0x00000000 0 0 0 0&amp;gt;;
+                #address-cells = &amp;lt;3&amp;gt;;
+                #size-cells = &amp;lt;2&amp;gt;;
+                ranges;
+
+                wifi2: wifi@1,0 {
+                        compatible = &quot;qcom,ath10k&quot;;
+                        reg = &amp;lt;0x00010000 0 0 0 0&amp;gt;;
+                };
+        };
+};
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;我在miniPCIe插槽里插入的是QCA9880 3x3模块，如果是其他模块可以修改或者干脆删除 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;wifi2&lt;/code&gt; 节点。&lt;/p&gt;

&lt;p&gt;其中要注意的是pinctrl字段，我们并不需要使用pinctrl初始化已经有了的perst和wake，但是由于这个电源控制并不在我们的pcie能配置的GPIO里，我们需要单独配置他。&lt;/p&gt;

&lt;p&gt;在 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&amp;amp;tlmm&lt;/code&gt; 设备节点中添加我们的GPIO2配置，配置为输出低电平，2mA（默认）和下拉。之所以在配置下拉的同时还要设置输出是为了防止下拉强度不够导致MOS工作在线性区无法正常供电。&lt;/p&gt;

&lt;div class=&quot;language-patch highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;gi&quot;&gt;+       pcie_pins: pcie_pinmux {
+               mux {
+                       pins = &quot;gpio2&quot;;
+                       function = &quot;gpio&quot;;
+                       bias-pull-down;
+                       output-low;
+               };
+       };
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;按照这种方式修改编译得到的OpenWrt就可以在加载驱动时自动配置给卡供电了。&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;回到REFCLK的问题&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;REFCLK的焊盘出厂时默认留空，补焊上即可，如下图：&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/2019/11/image-2.png&quot; alt=&quot;&quot; /&gt;
&lt;em&gt;手头没有0402的0欧电阻了，用跳线短上&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;一般大多数的miniPCIe卡只需要3.3V供电，不过板子还预留了RESERVED pin的5V供电电路，据恩山说法是为内置PA的大功率无线网卡准备的。有需求可以短掉R443和R447 。如果不清楚所用模块型号则不需要，这里不做赘述。&lt;/p&gt;

&lt;p&gt;附PCIe正常初始化日志如下：&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;[    0.051140] qcom-pcie 40000000.pci: host bridge /soc/pci@40000000 ranges:
[    0.051183] qcom-pcie 40000000.pci:    IO 0x40200000..0x402fffff -&amp;gt; 0x40200000
[    0.051210] qcom-pcie 40000000.pci:   MEM 0x40300000..0x40ffffff -&amp;gt; 0x40300000
[    0.326667] qcom-pcie 40000000.pci: Link up
[    0.326822] qcom-pcie 40000000.pci: PCI host bridge to bus 0000:00
[    0.326844] pci_bus 0000:00: root bus resource [bus 00-ff]
[    0.326860] pci_bus 0000:00: root bus resource [io  0x0000-0xfffff] (bus address [0x40200000-0x402fffff])
[    0.326874] pci_bus 0000:00: root bus resource [mem 0x40300000-0x40ffffff]
[    0.326916] pci 0000:00:00.0: [17cb:1001] type 01 class 0x060400
[    0.326953] pci 0000:00:00.0: reg 0x10: [mem 0x00000000-0x00000fff 64bit]
[    0.327013] pci 0000:00:00.0: PME# supported from D0 D3hot
[    0.328977] pci 0000:01:00.0: [168c:003c] type 00 class 0x028000
[    0.329176] pci 0000:01:00.0: reg 0x10: [mem 0x00000000-0x001fffff 64bit]
[    0.329404] pci 0000:01:00.0: reg 0x30: [mem 0x00000000-0x0000ffff pref]
[    0.329837] pci 0000:01:00.0: supports D1 D2
[    0.329845] pci 0000:01:00.0: PME# supported from D0 D1 D2 D3hot D3cold
[    0.331776] pci 0000:00:00.0: BAR 8: assigned [mem 0x40300000-0x405fffff]
[    0.331793] pci 0000:00:00.0: BAR 0: assigned [mem 0x40600000-0x40600fff 64bit]
[    0.331821] pci 0000:01:00.0: BAR 0: assigned [mem 0x40400000-0x405fffff 64bit]
[    0.331899] pci 0000:01:00.0: BAR 6: assigned [mem 0x40300000-0x4030ffff pref]
[    0.331915] pci 0000:00:00.0: PCI bridge to [bus 01-ff]
[    0.331930] pci 0000:00:00.0:   bridge window [mem 0x40300000-0x405fffff]
[    0.334340] pcieport 0000:00:00.0: AER enabled with IRQ 97
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;关于LTE模块&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;市面99.9%的LTE模块是USB通讯的，如果使用LTE模块则不需要短接REFCLK，不过上述操作依然可以实现免焊接。&lt;/p&gt;

&lt;h2 id=&quot;3-已知问题wip&quot;&gt;3. 已知问题（WIP）&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;SDHCI在USB插入的时候会出错，估计是pinmux的问题，尚未解决&lt;/li&gt;
  &lt;li&gt;USB不可用&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Sun, 24 Nov 2019 12:49:19 +0000</pubDate>
        <link>https://www.imstatic.com/archivers/drifting-ipq4019</link>
        <guid isPermaLink="true">https://www.imstatic.com/archivers/drifting-ipq4019</guid>
        
        <category>hardware</category>
        
        
      </item>
    
      <item>
        <title>Mbed OS 5的自定义开发板移植 - NRF51</title>
        <description>&lt;h1 id=&quot;前言&quot;&gt;前言&lt;/h1&gt;

&lt;p&gt;最开始看到Mbed OS5的时候没太在意，然而最近Nucleo买多了就变成了……&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;真香！&lt;/strong&gt;&lt;/p&gt;

&lt;hr /&gt;

&lt;h1 id=&quot;步骤&quot;&gt;步骤&lt;/h1&gt;

&lt;p&gt;正好手头的BLE开发板就又开始痒痒，那就上咯&lt;/p&gt;

&lt;p&gt;手头的NRF51开发板是微雪的NRF51822开发板，芯片型号为_AC，意即32KB SRAM+256KB Flash的型号。我们首先用Mbed CLI新建一个项目，起名叫nrf51_hello就好了。&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;mbed new nrf51_hello
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;会在当前目录创建工程目录，随便写一个main.cpp，包含main函数用来对付链接问题&lt;/p&gt;

&lt;div class=&quot;language-c highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;cp&quot;&gt;#include&lt;/span&gt; &lt;span class=&quot;cpf&quot;&gt;&amp;lt;mbed.h&amp;gt;&lt;/span&gt;&lt;span class=&quot;cp&quot;&gt;
&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;DigitalOut&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;led&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;LED1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;while&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;led&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;led&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;wait&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;嗯，点灯工程师。&lt;/p&gt;

&lt;p&gt;于是我们来处理板子的问题。Mbed OS 5的大致结构如下&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;.
├── [3.5K]  CONTRIBUTING.md
├── [ 254]  DOXYGEN_FRONTPAGE.md
├── [  73]  Jenkinsfile
├── [8.9K]  LICENSE
├── [2.5K]  README.md
├── [4.0K]  TESTS
├── [4.0K]  TEST_APPS
├── [4.0K]  UNITTESTS
├── [   0]  astyle-branch.out
├── [4.0K]  cmsis
├── [4.0K]  components
├── [4.0K]  docs
├── [107K]  doxyfile_options
├── [2.3K]  doxygen_options.json
├── [4.0K]  drivers
├── [4.0K]  events
├── [4.0K]  features
├── [4.0K]  hal
├── [ 36K]  logo.png
├── [2.9K]  mbed.h
├── [4.0K]  platform
├── [ 381]  requirements.txt
├── [4.0K]  rtos
├── [4.0K]  targets
└── [4.0K]  tools

14 directories, 11 files
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;添加板子定义的时候，我们需要在如下几个部分添加相应的文件&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;targets/targets.json&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;targets.json记录了所有板子的型号和特性，也是Mbed CLI寻找编译对象的入口&lt;/p&gt;

&lt;p&gt;我们在其中添加自己的板子信息（照着SoC差不多的板子抄过来即可）&lt;/p&gt;

&lt;div class=&quot;language-patch highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;gh&quot;&gt;diff --git a/targets/targets.json b/targets/targets.json
index 3d0c2bdf5..1dc765096 100755
&lt;/span&gt;&lt;span class=&quot;gd&quot;&gt;--- a/targets/targets.json
&lt;/span&gt;&lt;span class=&quot;gi&quot;&gt;+++ b/targets/targets.json
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;@@ -2709,6 +2709,24 @@&lt;/span&gt;
         &quot;extra_labels_add&quot;: [&quot;DELTA_DFCM_NNN50&quot;],
         &quot;macros_add&quot;: [&quot;TARGET_DELTA_DFCM_NNN50&quot;]
     },
&lt;span class=&quot;gi&quot;&gt;+    &quot;WAVESHARE_NRF51822&quot;: {
+        &quot;supported_form_factors&quot;: [&quot;ARDUINO&quot;],
+        &quot;inherits&quot;: [&quot;MCU_NRF51_32K_UNIFIED&quot;],
+        &quot;device_has&quot;: [&quot;USTICKER&quot;, &quot;LPTICKER&quot;, &quot;ANALOGIN&quot;, &quot;I2C&quot;, &quot;I2C_ASYNCH&quot;, &quot;INTERRUPTIN&quot;, &quot;PORTIN&quot;, &quot;PORTINOUT&quot;, &quot;PORTOUT&quot;, &quot;PWMOUT&quot;, &quot;SERIAL&quot;, &quot;SERIAL_ASYNCH&quot;, &quot;SERIAL_FC&quot;, &quot;SLEEP&quot;, &quot;SPI&quot;, &quot;SPI_ASYNCH&quot;, &quot;SPISLAVE&quot;],
+        &quot;device_name&quot;: &quot;nRF51822_xxAC&quot;
+    },
+    &quot;WAVESHARE_NRF51822_BOOT&quot;: {
+        &quot;supported_form_factors&quot;: [&quot;ARDUINO&quot;],
+        &quot;inherits&quot;: [&quot;MCU_NRF51_32K_BOOT&quot;],
+        &quot;extra_labels_add&quot;: [&quot;WAVESHARE_NRF51822&quot;],
+        &quot;macros_add&quot;: [&quot;TARGET_WAVESHARE_NRF51822&quot;]
+    },
+    &quot;WAVESHARE_NRF51822_OTA&quot;: {
+        &quot;supported_form_factors&quot;: [&quot;ARDUINO&quot;],
+        &quot;inherits&quot;: [&quot;MCU_NRF51_32K_OTA&quot;],
+        &quot;extra_labels_add&quot;: [&quot;WAVESHARE_NRF51822&quot;],
+        &quot;macros_add&quot;: [&quot;TARGET_WAVESHARE_NRF51822&quot;]
+    },
&lt;/span&gt;     &quot;NRF51_DK_LEGACY&quot;: {
         &quot;supported_form_factors&quot;: [&quot;ARDUINO&quot;],
         &quot;inherits&quot;: [&quot;MCU_NRF51_32K&quot;],
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;可以看出我们的板子叫做 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;WAVESHARE_NRF51822&lt;/code&gt; 。&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Target定义文件，上述的 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;inherits&lt;/code&gt; 已经给定了这个板子所属的厂商和型号，在对应目录里添加相应定义文件，包含引脚定义 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;PinNames.h&lt;/code&gt; 和设备定义 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;device.h&lt;/code&gt; 。根据板子的外设和引脚信息修改对应文件即可。我们正在添加的板子应位于&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;targets/TARGET_NORDIC/TARGET_NRF5x/TARGET_NRF51/TARGET_MCU_NRF51822_UNIFIED/TARGET_WAVESHARE_NRF51822&lt;/code&gt; 中。&lt;/p&gt;

&lt;div class=&quot;language-patch highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;gi&quot;&gt;+++ ../TARGET_NRF51_DK/PinNames.h	2018-10-27 12:42:18.034690786 +0800
&lt;/span&gt;&lt;span class=&quot;gd&quot;&gt;--- PinNames.h	2018-10-27 13:43:22.036980344 +0800
&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;***************&lt;/span&gt;
*** 120,134 ****
      P0_29 = p29,
      P0_30 = p30,
  
&lt;span class=&quot;gs&quot;&gt;!     LED1    = p21,
!     LED2    = p22,
!     LED3    = p23,
!     LED4    = p24,
&lt;/span&gt;  
&lt;span class=&quot;gs&quot;&gt;!     BUTTON1 = p17,
!     BUTTON2 = p18,
!     BUTTON3 = p19,
!     BUTTON4 = p20,
&lt;/span&gt;  
      RX_PIN_NUMBER  = p11,
      TX_PIN_NUMBER  = p9,
&lt;span class=&quot;gd&quot;&gt;--- 120,132 ----
&lt;/span&gt;      P0_29 = p29,
      P0_30 = p30,
  
&lt;span class=&quot;gs&quot;&gt;!     LED1    = p18,
!     LED2    = p19,
!     LED3    = p20,
!     LED4    = p21,
&lt;/span&gt;  
&lt;span class=&quot;gs&quot;&gt;!     BUTTON1 = p16,
!     BUTTON2 = p17,
&lt;/span&gt;  
      RX_PIN_NUMBER  = p11,
      TX_PIN_NUMBER  = p9,
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;本例中 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;device.h&lt;/code&gt; 无需修改。&lt;/p&gt;

&lt;p&gt;添加完板子定义我们来简单测试一下&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;mbed compile &lt;span class=&quot;nt&quot;&gt;-m&lt;/span&gt; WAVESHARE_NRF51822 &lt;span class=&quot;nt&quot;&gt;-t&lt;/span&gt; GCC_ARM &lt;span class=&quot;nt&quot;&gt;-j8&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;...
Link: nrf51_hello
Elf2Bin: nrf51_hello
| Module             |      .text |    .data |     .bss |
|--------------------|------------|----------|----------|
| [fill]             |    171(+4) |   19(+0) |   55(+0) |
| [lib]/c.a          |  22739(+0) | 2472(+0) |   56(+0) |
| [lib]/gcc.a        |   7142(+0) |    0(+0) |    0(+0) |
| [lib]/misc         |    208(+0) |   12(+0) |   25(+0) |
| [lib]/stdc++.a     |      1(+0) |    0(+0) |    0(+0) |
| main.o             |   2229(+7) |    5(+0) |   97(+0) |
| mbed-os/components |     54(+0) |    0(+0) |    0(+0) |
| mbed-os/drivers    |   787(+16) |    0(+0) |    0(+0) |
| mbed-os/events     |   1240(+0) |    0(+0) |    0(+0) |
| mbed-os/features   |  40015(+6) |    4(+0) | 1334(+0) |
| mbed-os/hal        |   1758(-2) |    8(+0) |  130(+0) |
| mbed-os/platform   |   3898(-4) |  260(+0) |  221(+0) |
| mbed-os/rtos       |  10287(-2) |  168(+0) | 6113(+0) |
| mbed-os/targets    |   9281(-3) |   20(+0) |  865(+0) |
| Subtotals          | 99810(+22) | 2968(+0) | 8896(+0) |
Total Static RAM memory (data + bss): 11864(+0) bytes
Total Flash memory (text + data): 102778(+22) bytes

Image: ./BUILD/WAVESHARE_NRF51822/GCC_ARM/nrf51_hello.hex
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;我们就可以在生成目录 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;BUILD/&lt;/code&gt; 下找到ELF和IHEX文件了。&lt;/p&gt;

&lt;p&gt;NRF51需要一个闭源静态库用来实现驱动和蓝牙，Nordic管他叫SoftDevice。我们首先需要下载SoftDevice到设备。&lt;/p&gt;

&lt;p&gt;本例中依然使用OpenOCD，调试器使用LPC11U35开发板运行DAPLink（CMSIS-DAP）固件，制作方法后述。&lt;/p&gt;

&lt;p&gt;运行&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;openocd &lt;span class=&quot;nt&quot;&gt;-f&lt;/span&gt; /usr/share/openocd/scripts/interface/cmsis-dap.cfg &lt;span class=&quot;nt&quot;&gt;-f&lt;/span&gt; /usr/share/openocd/scripts/target/nrf51.cfg
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;Open On-Chip Debugger 0.10.0+dev-00523-g2a3b709aa (2018-08-30-22:25)
Licensed under GNU GPL v2
For bug reports, read
	http://openocd.org/doc/doxygen/bugs.html
Info : auto-selecting first available session transport &quot;swd&quot;. To override use &apos;transport select &amp;lt;transport&amp;gt;&apos;.
cortex_m reset_config sysresetreq
adapter speed: 1000 kHz
Info : Listening on port 6666 for tcl connections
Info : Listening on port 4444 for telnet connections
Info : CMSIS-DAP: SWD  Supported
Info : CMSIS-DAP: FW Version = 1.10
Info : CMSIS-DAP: Interface Initialised (SWD)
Info : SWCLK/TCK = 1 SWDIO/TMS = 1 TDI = 0 TDO = 0 nTRST = 0 nRESET = 1
Info : CMSIS-DAP: Interface ready
Info : clock speed 1000 kHz
Info : SWD DPIDR 0x0bb11477
Info : nrf51.cpu: hardware has 4 breakpoints, 2 watchpoints
Info : Listening on port 3333 for gdb connections
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;一如既往，显示连接成功。&lt;/p&gt;

&lt;p&gt;运行 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;telnet localhost 4444&lt;/code&gt; 连接到OpenOCD的CLI界面，运行&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;reset init&lt;/code&gt; halt CPU，接着运行&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;flash write_image erase /path/to/softdevice/s130.hex&lt;/code&gt; 下载SoftDevice到设备。&lt;/p&gt;

&lt;p&gt;最后运行&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;flash write_image erase /path/to/nrf51_hello.elf&lt;/code&gt; 下载应用程序到设备，执行 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;reset&lt;/code&gt; 即可点灯成功（&lt;/p&gt;

&lt;p&gt;！&lt;a href=&quot;/assets/img/2018/10/IMG_9421.JPG&quot;&gt;&lt;/a&gt;
&lt;em&gt;点灯工程师&lt;/em&gt;&lt;/p&gt;

&lt;h1 id=&quot;后记&quot;&gt;后记&lt;/h1&gt;

&lt;p&gt;&lt;strong&gt;P.S. NRF51822 的串口默认流控，请确认CTS/RTS pin连接正常，否则串口会卡死目标板。&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;我们来运行一下Mbed OS的心率传感器&lt;a href=&quot;https://os.mbed.com/docs/v5.10/apis/heartrateservice.html&quot;&gt;示例&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;由于之前已经下载过SoftDevice，本次无需重新下载。直接下载应用程序到设备即可。
&lt;img src=&quot;/assets/img/2018/10/Screenshot_2018-10-27-16-02-03-1.png&quot; alt=&quot;&quot; /&gt;
&lt;em&gt;nRF Connect 应用程序&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;通过Nordic的BLE App，就可以看到心率了…… &lt;del&gt;170了，我要挂了.jpg&lt;/del&gt;&lt;/p&gt;
</description>
        <pubDate>Sat, 27 Oct 2018 08:12:12 +0000</pubDate>
        <link>https://www.imstatic.com/archivers/waveshare_mbed</link>
        <guid isPermaLink="true">https://www.imstatic.com/archivers/waveshare_mbed</guid>
        
        <category>hardware</category>
        
        
      </item>
    
      <item>
        <title>i.MX RT1050 简单上手</title>
        <description>&lt;h2 id=&quot;1-前言&quot;&gt;1. 前言&lt;/h2&gt;

&lt;p&gt;i.MX RT1050大概是能买到的比较便宜的Cortex-M7 MCU了，本文介绍从裸Linux环境开始配置完整工作环境。&lt;/p&gt;

&lt;h2 id=&quot;2-硬件准备&quot;&gt;2. 硬件准备&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;i.MX RT1050开发板&lt;/li&gt;
  &lt;li&gt;JTAG/SWD调试器&lt;/li&gt;
  &lt;li&gt;足够多的USB线和杜邦线&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;3-软件准备&quot;&gt;3. 软件准备&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;ARM GCC（任意版本，&amp;gt;= 7）&lt;/li&gt;
  &lt;li&gt;CMake&lt;/li&gt;
  &lt;li&gt;OpenOCD（越新越好）&lt;/li&gt;
  &lt;li&gt;文本编辑器（任意）&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;4-openocd调试环境准备&quot;&gt;4. OpenOCD调试环境准备&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;在任意位置保存如下target配置&lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;language-tcl highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;# NXP i.MX RT1050 family &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;Arm Cortex-M7 @ 600 MHz&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
#

if &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;info exists CHIPNAME&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        set _CHIPNAME $CHIPNAME
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; else &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        set _CHIPNAME imxrt1050
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

source &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;find target/swj-dp.tcl&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;

if &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;info exists CPU_SWD_TAPID&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        set _CPU_SWD_TAPID $CPU_SWD_TAPID
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; else &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        set _CPU_SWD_TAPID 0x0bd11477
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

if &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;using_jtag&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        set _CPU_TAPID 0
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; else &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        set _CPU_TAPID $_CPU_SWD_TAPID
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

swj_newdap $_CHIPNAME cpu -irlen 4 -expected-id $_CPU_TAPID

set _TARGETNAME $_CHIPNAME
dap create $_TARGETNAME.dap -chain-position $_TARGETNAME.cpu
target create $_TARGETNAME cortex_m -dap $_TARGETNAME.dap

if &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; !&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;using_hla&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        cortex_m reset_config sysresetreq
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

gdb_breakpoint_override hard # 调试XIP Flash应用时，见说明

adapter_khz 1000
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;ul&gt;
  &lt;li&gt;根据你的JTAG Adapter，选择合适的配置文件&lt;/li&gt;
  &lt;li&gt;运行OpenOCD，直到看到类似的消息代表识别成功&lt;/li&gt;
  &lt;li&gt;OpenOCD会自动选择断点模式，Flash区域应使用硬件断点，否则无法命中。由于i.MX RT1050 无片上Flash，Config中并未加入Flash bank的定义，而是强制全局使用硬件断点以避免这种情况。RT1050的Cortex-M7拥有8个硬件断点，这对于大多数调试情况都足够了。个人使用时也可以加入自己板子定义的Flash区域，但目前（2018.12现在）OpenOCD并不支持RT1050的Flash读写，所以仅能用来自动配置断点类型。&lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;openocd &lt;span class=&quot;nt&quot;&gt;-f&lt;/span&gt; ~/Documents/Conf/OpenOCD/interface/ft232-swd.cfg &lt;span class=&quot;nt&quot;&gt;-f&lt;/span&gt; ~/Documents/Conf/OpenOCD/target/imxrt1050.cfg
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;Open On-Chip Debugger 0.10.0+dev-00523-g2a3b709aa (2018-08-30-22:25)
Licensed under GNU GPL v2
For bug reports, read
	http://openocd.org/doc/doxygen/bugs.html
Info : FTDI SWD mode enabled
adapter speed: 2000 kHz
cortex_m reset_config sysresetreq
adapter speed: 1000 kHz
Info : Listening on port 6666 for tcl connections
Info : Listening on port 4444 for telnet connections
Info : clock speed 1000 kHz
Info : SWD DPIDR 0x0bd11477
Info : imxrt1050: hardware has 8 breakpoints, 4 watchpoints
Info : Listening on port 3333 for gdb connections
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;5-示例工程准备&quot;&gt;5. 示例工程准备&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;从 &lt;a href=&quot;https://mcuxpresso.nxp.com/en/dashboard&quot;&gt;https://mcuxpresso.nxp.com/en/dashboard&lt;/a&gt; 添加并下载i.MX RT1050的SDK，根据芯片型号选择对应的SDK。（测试中Rev.1 和Rev.2可以互换但不建议使用）&lt;/li&gt;
  &lt;li&gt;从&lt;a href=&quot;https://www.nxp.com/support/developer-resources/software-development-tools/mcuxpresso-software-and-tools/mcuxpresso-config-tools-pins-clocks-peripherals:MCUXpresso-Config-Tools&quot;&gt;NXP网站&lt;/a&gt;下载 Config Tool。&lt;/li&gt;
  &lt;li&gt;解压deb，选择合适的位置放置Config Tool，运行&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/path/to/config_tool/bin/tool&lt;/code&gt;并选择解压到SDK的位置，从示例创建新工程，类型选择ARM GCC。&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/2018/09/2018-09-09_18-03-1.png&quot; alt=&quot;2018-09-09_18-03-1&quot; /&gt;&lt;br /&gt;
&lt;img src=&quot;/assets/img/2018/09/2018-09-09_18-04-1.png&quot; alt=&quot;2018-09-09_18-04-1&quot; /&gt;&lt;/p&gt;

&lt;h2 id=&quot;6-编译示例工程&quot;&gt;6. 编译示例工程&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;在工程目录中运行&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ARMGCC_DIR=/path/to/arm_gcc ./build_debug.sh&lt;/code&gt;即可编译出ELF&lt;/li&gt;
  &lt;li&gt;在工程目录中运行&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ARMGCC_DIR=/path/to/arm_gcc ./build_flexspi_nor_debug.sh&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;由于第二步中我们选择了flexspi_nor配置，该程序将被链接进FlexSPI NOR Flash区域（&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0x60000000&lt;/code&gt;）；第一步中的ELF则被链接进SRAM区域。&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;7-调试&quot;&gt;7. 调试&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;运行GDB连接OpenOCD并加载elf，载入ELF到设备SRAM并跳转入口点即可开始调试（注：事先需要halt CPU）&lt;/li&gt;
  &lt;li&gt;以下步骤中continue位置不建议使用，应使用 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;jump *entry_point&lt;/code&gt; 跳转程序入口点开始执行。&lt;/li&gt;
  &lt;li&gt;本例中程序入口点位于 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0x468&lt;/code&gt;，即 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;jump *0x468&lt;/code&gt; 。&lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;130 imi415@imi415 ..dwares/Kinetis_Projects/freertos_hello % arm-none-eabi-gdb -ex &quot;target remote localhost:3333&quot; debug/freertos_hello.elf                                                                                                  :(
GNU gdb (GDB) 8.1.1
Copyright (C) 2018 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later &amp;lt;http://gnu.org/licenses/gpl.html&amp;gt;
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type &quot;show copying&quot;
and &quot;show warranty&quot; for details.
This GDB was configured as &quot;--host=x86_64-pc-linux-gnu --target=arm-none-eabi&quot;.
Type &quot;show configuration&quot; for configuration details.
For bug reporting instructions, please see:
&amp;lt;http://www.gnu.org/software/gdb/bugs/&amp;gt;.
Find the GDB manual and other documentation resources online at:
&amp;lt;http://www.gnu.org/software/gdb/documentation/&amp;gt;.
For help, type &quot;help&quot;.
Type &quot;apropos word&quot; to search for commands related to &quot;word&quot;...
Reading symbols from debug/freertos_hello.elf...done.
Remote debugging using localhost:3333
0x600044d6 in ?? ()
(gdb) load
Loading section .interrupts, size 0x400 lma 0x0
Loading section .text, size 0x5c08 lma 0x400
Loading section .ARM, size 0x8 lma 0x6008
Loading section .init_array, size 0x4 lma 0x6010
Loading section .fini_array, size 0x4 lma 0x6014
Loading section .data, size 0x6c lma 0x6018
Start address 0x468, load size 24708
Transfer rate: 69 KB/sec, 3529 bytes/write.
(gdb) b main
Breakpoint 1 at 0x4afa: file /home/imi415/Documents/Hardwares/Kinetis_Projects/freertos_hello/source/freertos_hello.c, line 68.
(gdb) c
Continuing.

Breakpoint 1, main () at /home/imi415/Documents/Hardwares/Kinetis_Projects/freertos_hello/source/freertos_hello.c:68
68	    BOARD_ConfigMPU();
(gdb) 
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;8-下载程序到flexspi-nor-flash-并启用xip&quot;&gt;8. 下载程序到FlexSPI NOR Flash 并启用XIP&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;根据开发板制造商的参数修改&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;xip&lt;/code&gt;目录下文件，配置XIP Header。&lt;/li&gt;
  &lt;li&gt;NOR Flash XIP Header类似下方&lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;language-c highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;cp&quot;&gt;#include&lt;/span&gt; &lt;span class=&quot;cpf&quot;&gt;&quot;fire_imxrt1050_flexspi_nor_config.h&quot;&lt;/span&gt;&lt;span class=&quot;cp&quot;&gt;
&lt;/span&gt;
&lt;span class=&quot;cm&quot;&gt;/*******************************************************************************
 * Code
 ******************************************************************************/&lt;/span&gt;
&lt;span class=&quot;cp&quot;&gt;#if defined(XIP_BOOT_HEADER_ENABLE) &amp;amp;&amp;amp; (XIP_BOOT_HEADER_ENABLE == 1)
#if defined(__CC_ARM) || defined(__GNUC__)
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;__attribute__&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;section&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;.boot_hdr.conf&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)))&lt;/span&gt;
&lt;span class=&quot;cp&quot;&gt;#elif defined(__ICCARM__)
#pragma location = &quot;.boot_hdr.conf&quot;
#endif
&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;flexspi_nor_config_t&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;spiflash_config&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;memConfig&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tag&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;FLEXSPI_CFG_BLK_TAG&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;                                   &lt;span class=&quot;cm&quot;&gt;/*标志：FCFB*/&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;version&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;FLEXSPI_CFG_BLK_VERSION&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;                           &lt;span class=&quot;cm&quot;&gt;/*版本：V1.4.0*/&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;readSampleClkSrc&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;kFlexSPIReadSampleClk_LoopbackInternally&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;cm&quot;&gt;/*内部环回*/&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;csHoldTime&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3u&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;                                             &lt;span class=&quot;cm&quot;&gt;/*保持时间*/&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;csSetupTime&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3u&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;                                            &lt;span class=&quot;cm&quot;&gt;/*建立时间*/&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;columnAddressWidth&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0u&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;                                     &lt;span class=&quot;cm&quot;&gt;/*列地址宽度*/&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;deviceModeCfgEnable&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1u&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;                                    &lt;span class=&quot;cm&quot;&gt;/*设备模式配置使能*/&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;deviceModeType&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1u&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;                                         &lt;span class=&quot;cm&quot;&gt;/*Quad 使能命令*/&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;deviceModeSeq&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;seqNum&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1u&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;                                   &lt;span class=&quot;cm&quot;&gt;/*LUT序列号*/&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;deviceModeSeq&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;seqId&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;4u&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;                                    &lt;span class=&quot;cm&quot;&gt;/*LUT序列索引*/&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;deviceModeArg&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0x000200&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;                                    &lt;span class=&quot;cm&quot;&gt;/*设置 QE=1（S9）*/&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;deviceType&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;kFlexSpiDeviceType_SerialNOR&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;                   &lt;span class=&quot;cm&quot;&gt;/*设备类型为nor flash*/&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sflashPadType&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;kSerialFlash_4Pads&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;                          &lt;span class=&quot;cm&quot;&gt;/*设备数据总线为4*/&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;serialClkFreq&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;kFlexSpiSerialClk_133MHz&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;                    &lt;span class=&quot;cm&quot;&gt;/*flash 时钟*/&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sflashA1Size&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;32u&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1024u&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1024u&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;                          &lt;span class=&quot;cm&quot;&gt;/*flash 大小32MBytes*/&lt;/span&gt;
            &lt;span class=&quot;c1&quot;&gt;//.dataValidTime = {16u, 16u},&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;lookupTable&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;
                &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
                    &lt;span class=&quot;cm&quot;&gt;/*快速读命令（四线）*/&lt;/span&gt;
                    &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;FLEXSPI_LUT_SEQ&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;CMD_SDR&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;FLEXSPI_1PAD&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0xEB&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;RADDR_SDR&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;FLEXSPI_4PAD&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0x18&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
                    &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;FLEXSPI_LUT_SEQ&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;DUMMY_SDR&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;FLEXSPI_4PAD&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0x06&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;READ_SDR&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;FLEXSPI_4PAD&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0x04&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;

                    &lt;span class=&quot;cm&quot;&gt;/*读状态命令*/&lt;/span&gt;
                    &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;FLEXSPI_LUT_SEQ&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;CMD_SDR&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;FLEXSPI_1PAD&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0x05&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;READ_SDR&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;FLEXSPI_1PAD&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0x04&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
                    &lt;span class=&quot;cm&quot;&gt;/*写使能命令*/&lt;/span&gt;
                    &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;FLEXSPI_LUT_SEQ&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;CMD_SDR&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;FLEXSPI_1PAD&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0x06&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;STOP&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;FLEXSPI_1PAD&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
                    &lt;span class=&quot;cm&quot;&gt;/*擦除扇区命令*/&lt;/span&gt;
                    &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;FLEXSPI_LUT_SEQ&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;CMD_SDR&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;FLEXSPI_1PAD&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0x20&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;RADDR_SDR&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;FLEXSPI_1PAD&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0x04&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
                    &lt;span class=&quot;cm&quot;&gt;/*页编程命令（四线）*/&lt;/span&gt;
                    &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;9&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;FLEXSPI_LUT_SEQ&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;CMD_SDR&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;FLEXSPI_1PAD&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0x32&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;RADDR_SDR&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;FLEXSPI_1PAD&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0x18&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
                    &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;9&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;FLEXSPI_LUT_SEQ&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;WRITE_SDR&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;FLEXSPI_4PAD&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0x04&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;STOP&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;FLEXSPI_1PAD&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
                    &lt;span class=&quot;cm&quot;&gt;/*整片擦除*/&lt;/span&gt;
                    &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;11&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;FLEXSPI_LUT_SEQ&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;CMD_SDR&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;FLEXSPI_1PAD&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0xc7&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;STOP&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;FLEXSPI_1PAD&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
                &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;pageSize&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;256u&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;         &lt;span class=&quot;cm&quot;&gt;/*页大小为256字节*/&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sectorSize&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;4u&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1024u&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;cm&quot;&gt;/*扇区大小为4k字节*/&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
&lt;span class=&quot;cp&quot;&gt;#endif &lt;/span&gt;&lt;span class=&quot;cm&quot;&gt;/* XIP_BOOT_HEADER_ENABLE */&lt;/span&gt;&lt;span class=&quot;cp&quot;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;!--kg-card-end: html--&gt;
&lt;!--kg-card-begin: markdown--&gt;
&lt;ul&gt;
  &lt;li&gt;从&lt;a href=&quot;https://www.nxp.com/webapp/Download?colCode=IMX-RT1050-FLASHLOADER&amp;amp;appType=license&amp;amp;Parent_nodeId=1507661717567725431170&amp;amp;Parent_pageType=product&quot;&gt;NXP&lt;/a&gt;下载Flashloader并解压&lt;/li&gt;
  &lt;li&gt;通过GDB将 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Flashloader/flashloader.elf&lt;/code&gt; 下载到内存并执行（步骤同RAM调试步骤，需要跳转程序入口点开始执行。）&lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;将ELF转换为 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;srec&lt;/code&gt; 或 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ihx&lt;/code&gt;&lt;/p&gt;

    &lt;p&gt;arm-none-eabi-objcopy -O srec freertos_hello.elf freertos_hello.srec&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;连接USB OTG1，会有一个新USB HID设备连接到主机&lt;/li&gt;
  &lt;li&gt;运行下列命令初始化NOR Flash并写入程序&lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nb&quot;&gt;sudo&lt;/span&gt; ./blhost &lt;span class=&quot;nt&quot;&gt;-u&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-V&lt;/span&gt; fill-memory 0x2000 0x04 0xc0000006
&lt;span class=&quot;nb&quot;&gt;sudo&lt;/span&gt; ./blhost &lt;span class=&quot;nt&quot;&gt;-u&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-V&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-t&lt;/span&gt; 30000 configure-memory 0x09 0x2000
&lt;span class=&quot;nb&quot;&gt;sudo&lt;/span&gt; ./blhost &lt;span class=&quot;nt&quot;&gt;-u&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-V&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-t&lt;/span&gt; 30000 flash-image ~/freertos_hello.srec erase
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;blockquote class=&quot;prompt-info&quot;&gt;
  &lt;p&gt;根据Flash类型调整第一条命令的值。&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ul&gt;
  &lt;li&gt;Flash 识别状态可以通过如下命令查看。&lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nb&quot;&gt;sudo&lt;/span&gt; ./blhost &lt;span class=&quot;nt&quot;&gt;-u&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-V&lt;/span&gt; list-memory
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h2 id=&quot;9-总结&quot;&gt;9. 总结&lt;/h2&gt;

&lt;p&gt;环境是第一步，代码尚未成功，同志仍需努力：）&lt;/p&gt;
</description>
        <pubDate>Sun, 09 Sep 2018 10:16:17 +0000</pubDate>
        <link>https://www.imstatic.com/archivers/rt1050</link>
        <guid isPermaLink="true">https://www.imstatic.com/archivers/rt1050</guid>
        
        <category>hardware</category>
        
        
      </item>
    
  </channel>
</rss>
