<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <title>AngieAn7</title>
  
  
  <link href="https://angiean7.github.io/atom.xml" rel="self"/>
  
  <link href="https://angiean7.github.io/"/>
  <updated>2024-06-05T07:14:21.282Z</updated>
  <id>https://angiean7.github.io/</id>
  
  <author>
    <name>angieAn7</name>
    
  </author>
  
  <generator uri="https://hexo.io/">Hexo</generator>
  
  <entry>
    <title>use shell to push to main</title>
    <link href="https://angiean7.github.io/2024/06/05/push_to_main_shell/"/>
    <id>https://angiean7.github.io/2024/06/05/push_to_main_shell/</id>
    <published>2024-06-05T07:13:13.648Z</published>
    <updated>2024-06-05T07:14:21.282Z</updated>
    
    <content type="html"><![CDATA[<h1 id="use-shell-to-push-to-git"><a href="#use-shell-to-push-to-git" class="headerlink" title="use shell to push to git"></a>use shell to push to git</h1><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line">$cat push_to_main.sh</span><br><span class="line"></span><br><span class="line">current_date=$(date +&quot;%Y-%m-%d&quot;)</span><br><span class="line">arg=$1</span><br><span class="line">commitment=$&#123;current_date&#125;$&#123;arg&#125;</span><br><span class="line"></span><br><span class="line">git add .</span><br><span class="line">git commit -m $commitment</span><br><span class="line">git push origin main</span><br></pre></td></tr></table></figure>]]></content>
    
    
      
      
    <summary type="html">&lt;h1 id=&quot;use-shell-to-push-to-git&quot;&gt;&lt;a href=&quot;#use-shell-to-push-to-git&quot; class=&quot;headerlink&quot; title=&quot;use shell to push to git&quot;&gt;&lt;/a&gt;use shell to p</summary>
      
    
    
    
    <category term="环境" scheme="https://angiean7.github.io/categories/%E7%8E%AF%E5%A2%83/"/>
    
    
  </entry>
  
  <entry>
    <title>Run Vitis AI Examples on KV260</title>
    <link href="https://angiean7.github.io/2024/04/17/Kria%20KV260%20setup/"/>
    <id>https://angiean7.github.io/2024/04/17/Kria%20KV260%20setup/</id>
    <published>2024-04-17T02:22:05.130Z</published>
    <updated>2024-06-01T03:44:48.906Z</updated>
    
    <content type="html"><![CDATA[<h1 id="Use-board-image-provided-by-Xilinx"><a href="#Use-board-image-provided-by-Xilinx" class="headerlink" title="Use board image provided by Xilinx"></a>Use board image provided by Xilinx</h1><p><a class="link"   href="https://xilinx.github.io/Vitis-AI/3.0/html/docs/quickstart/mpsoc.html" >Quick Start Guide for Zynq™ UltraScale+™<i class="fas fa-external-link-alt"></i></a></p><p><a class="link"   href="https://github.com/Xilinx/Vitis-AI/tree/2.5/setup/mpsoc#step2-setup-the-target" >Vitis-AI/setup/mpsoc/README<i class="fas fa-external-link-alt"></i></a></p><p>To improve the user experience, the Vitis AI Runtime packages, VART samples, Vitis-AI-Library samples and models have been built into the board image. </p><ol><li><p>Installing a Board Image.</p><p>Download the SD card system image files from the following links:</p><p><a class="link"   href="https://www.xilinx.com/member/forms/download/design-license-xef.html?filename=xilinx-kv260-dpu-v2022.1-v2.5.0.img.gz" >KV260<i class="fas fa-external-link-alt"></i></a></p></li><li><p>(Optional) Running <code>zynqmp_dpu_optimize.sh</code> to optimize the board setting.</p><p><img src="https://raw.githubusercontent.com/angiean7/wsl_test/main/image-20240417112324296.png" alt="image-20240417112324296"></p></li><li><p>Download the <a class="link"   href="https://www.xilinx.com/bin/public/openDownload?filename=vitis_ai_runtime_r2.5.0_image_video.tar.gz" >vitis_ai_runtime_r2.5.x_image_video.tar.gz<i class="fas fa-external-link-alt"></i></a>  to the target. </p></li><li><p>Unzip the <code>vitis_ai_runtime_r2.5.x_image_video.tar.gz</code> package on the target.</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">tar -xzvf vitis_ai_runtime_r*2.5*_image_video.tar.gz -C Vitis-AI/examples/VART</span><br></pre></td></tr></table></figure></li><li><p>Enter the directory of samples in the target board. Take <code>resnet50</code> as an example.</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">cd ~/Vitis-AI/examples/VART/resnet50</span><br></pre></td></tr></table></figure></li><li><p>Run the example.</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">./resnet50 /usr/share/vitis_ai_library/models/resnet50/resnet50.xmodel</span><br></pre></td></tr></table></figure><p><img src="https://raw.githubusercontent.com/angiean7/pictures/main/image-20240417155914181.png" alt="image-20240417155914181"></p><p><strong>Launching Commands for VART Samples on edge</strong></p><table><thead><tr><th>No.</th><th>Example Name</th><th>Command</th></tr></thead><tbody><tr><td>1</td><td>resnet50</td><td>./resnet50 /usr/share/vitis_ai_library/models/resnet50/resnet50.xmodel</td></tr><tr><td>2</td><td>resnet50_pt</td><td>./resnet50_pt /usr/share/vitis_ai_library/models/resnet50_pt/resnet50_pt.xmodel ../images/001.jpg</td></tr><tr><td>3</td><td>resnet50_ext</td><td>./resnet50_ext /usr/share/vitis_ai_library/models/resnet50/resnet50.xmodel ../images/001.jpg</td></tr><tr><td>4</td><td>resnet50_mt_py</td><td>python3 resnet50.py 1 /usr/share/vitis_ai_library/models/resnet50/resnet50.xmodel</td></tr><tr><td>5</td><td>inception_v1_mt_py</td><td>python3 inception_v1.py 1 /usr/share/vitis_ai_library/models/inception_v1_tf/inception_v1_tf.xmodel</td></tr><tr><td>6</td><td>pose_detection</td><td>./pose_detection video/pose.webm /usr/share/vitis_ai_library/models/sp_net/sp_net.xmodel /usr/share/vitis_ai_library/models/ssd_pedestrian_pruned_0_97/ssd_pedestrian_pruned_0_97.xmodel</td></tr><tr><td>7</td><td>video_analysis</td><td>./video_analysis video/structure.webm /usr/share/vitis_ai_library/models/ssd_traffic_pruned_0_9/ssd_traffic_pruned_0_9.xmodel</td></tr><tr><td>8</td><td>adas_detection</td><td>./adas_detection video/adas.webm /usr/share/vitis_ai_library/models/yolov3_adas_pruned_0_9/yolov3_adas_pruned_0_9.xmodel</td></tr><tr><td>9</td><td>segmentation</td><td>./segmentation video/traffic.webm /usr/share/vitis_ai_library/models/fpn/fpn.xmodel</td></tr><tr><td>10</td><td>squeezenet_pytorch</td><td>./squeezenet_pytorch /usr/share/vitis_ai_library/models/squeezenet_pt/squeezenet_pt.xmodel</td></tr></tbody></table></li></ol><h1 id="2022-1-Vitis™-Platform-Creation-Tutorials"><a href="#2022-1-Vitis™-Platform-Creation-Tutorials" class="headerlink" title="2022.1 Vitis™ Platform Creation Tutorials"></a>2022.1 Vitis™ Platform Creation Tutorials</h1><p>We’ll introduce the platform creation steps in the following pages. Each page describes one major step in the platform creation process.</p><ul><li><a class="link"   href="https://github.com/Xilinx/Vitis-Tutorials/blob/2022.1/Vitis_Platform_Creation/Design_Tutorials/01-Edge-KV260/step1.md" >Step 1: Create the Vivado Hardware Design and Generate XSA<i class="fas fa-external-link-alt"></i></a></li><li><a class="link"   href="https://github.com/Xilinx/Vitis-Tutorials/blob/2022.1/Vitis_Platform_Creation/Design_Tutorials/01-Edge-KV260/step2.md" >Step 2: Create the Vitis Platform<i class="fas fa-external-link-alt"></i></a></li><li><a class="link"   href="https://github.com/Xilinx/Vitis-Tutorials/blob/2022.1/Vitis_Platform_Creation/Design_Tutorials/01-Edge-KV260/step3.md" >Step 3: Test the Platform<i class="fas fa-external-link-alt"></i></a></li></ul><p><strong><em>Let’s start from <a class="link"   href="https://github.com/Xilinx/Vitis-Tutorials/blob/2022.1/Vitis_Platform_Creation/Design_Tutorials/01-Edge-KV260/step1.md" >step 1: Vivado Design<i class="fas fa-external-link-alt"></i></a>.</em></strong></p><p>When i do step2, there were 1 issue. </p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br></pre></td><td class="code"><pre><span class="line">xsct% createdts -hw ./kv260_hardware_platform.xsa -zocl -platform-name mydevice -git-branch xlnx_rel_v2022.1 -overlay -compile -out mydevice</span><br><span class="line">INFO: DTG repo already exists at /mnt/hdd8t/anqi/work/kv260_vitis_platform/mydevice/device-tree-xlnx</span><br><span class="line">INFO: [Hsi 55-2053] elapsed time for repository (/tools/Xilinx/Vitis/2023.2/data/embeddedsw) loading 0 seconds</span><br><span class="line">INFO: Creating platform mydevice at mydevice</span><br><span class="line">Opening the hardware design, this may take few seconds.</span><br><span class="line">INFO: Populating the default qemu data for the domain &quot;device_tree_domain&quot; from the install location /tools/Xilinx/Vitis/2023.2/data/emulation/platforms/zynqmp/sw/a53_standalone/qemu/</span><br><span class="line">zocl:true</span><br><span class="line">ext_platform:</span><br><span class="line">Failed to find overlay2 node !!!</span><br><span class="line"></span><br><span class="line">ERROR: [Hsi 55-1545] Problem running tcl command ::sw_device_tree::generate : Failed to find overlay2 node !!!</span><br><span class="line">    while executing</span><br><span class="line">&quot;error &quot;Failed to find $lu_node node !!!&quot;&quot;</span><br><span class="line">    (procedure &quot;get_node_object&quot; line 31)</span><br><span class="line">    invoked from within</span><br><span class="line">&quot;get_node_object overlay2 pl.dtsi&quot;</span><br><span class="line">    invoked from within</span><br><span class="line">&quot;create_dt_node  -name zyxclmm_drm -objects [get_node_object overlay2 pl.dtsi]&quot;</span><br><span class="line">    (&quot;eval&quot; body line 1)</span><br><span class="line">    invoked from within</span><br><span class="line">&quot;eval &quot;create_dt_node $&#123;cmd&#125;&quot;&quot;</span><br><span class="line">    (procedure &quot;add_or_get_dt_node&quot; line 187)</span><br><span class="line">    invoked from within</span><br><span class="line">&quot;add_or_get_dt_node -n &quot;zyxclmm_drm&quot; -d $&#123;default_dts&#125; -p $bus_node&quot;</span><br><span class="line">    (procedure &quot;gen_zocl_node&quot; line 21)</span><br><span class="line">    invoked from within</span><br><span class="line">&quot;gen_zocl_node&quot;</span><br><span class="line">    (procedure &quot;::sw_device_tree::generate&quot; line 23)</span><br><span class="line">    invoked from within</span><br><span class="line">&quot;::sw_device_tree::generate device_tree&quot;</span><br><span class="line"></span><br><span class="line">ERROR: [Hsi 55-1442] Error(s) while running TCL procedure generate()</span><br><span class="line"></span><br><span class="line">Could not create platform for device_tree and null</span><br><span class="line"> Failed to generate the bsp sources for domain.device_tree_domain</span><br><span class="line"></span><br><span class="line">Details: Failed to find overlay2 node !!!</span><br><span class="line"></span><br><span class="line">ERROR: [Hsi 55-1545] Problem running tcl command ::sw_device_tree::generate : Failed to find overlay2 node !!!</span><br><span class="line">    while executing</span><br><span class="line">&quot;error &quot;Failed to find $lu_node node !!!&quot;&quot;</span><br><span class="line">    (procedure &quot;get_node_object&quot; line 31)</span><br><span class="line">    invoked from within</span><br><span class="line">&quot;get_node_object overlay2 pl.dtsi&quot;</span><br><span class="line">    invoked from within</span><br><span class="line">&quot;create_dt_node  -name zyxclmm_drm -objects [get_node_object overlay2 pl.dtsi]&quot;</span><br><span class="line">    (&quot;eval&quot; body line 1)</span><br><span class="line">    invoked from within</span><br><span class="line">&quot;eval &quot;create_dt_node $&#123;cmd&#125;&quot;&quot;</span><br><span class="line">    (procedure &quot;add_or_get_dt_node&quot; line 187)</span><br><span class="line">    invoked from within</span><br><span class="line">&quot;add_or_get_dt_node -n &quot;zyxclmm_drm&quot; -d $&#123;default_dts&#125; -p $bus_node&quot;</span><br><span class="line">    (procedure &quot;gen_zocl_node&quot; line 21)</span><br><span class="line">    invoked from within</span><br><span class="line">&quot;gen_zocl_node&quot;</span><br><span class="line">    (procedure &quot;::sw_device_tree::generate&quot; line 23)</span><br><span class="line">    invoked from within</span><br><span class="line">&quot;::sw_device_tree::generate device_tree&quot;</span><br><span class="line"></span><br><span class="line">ERROR: [Hsi 55-1442] Error(s) while running TCL procedure generate()</span><br></pre></td></tr></table></figure><p>I switched to the xlnx_rel_v2022.2 branch then it succeed.</p><p><img src="https://raw.githubusercontent.com/angiean7/pictures/main/image-20240530170830787.png" alt="image-20240530170830787"></p><p><img src="https://raw.githubusercontent.com/angiean7/pictures/main/image-20240530181354042.png" alt="image-20240530181354042"></p><p><img src="https://raw.githubusercontent.com/angiean7/pictures/main/image-20240530183531292.png" alt="image-20240530183531292"></p><h1 id="Use-petalinux-to-build-a-board-image"><a href="#Use-petalinux-to-build-a-board-image" class="headerlink" title="Use petalinux to build a board image"></a>Use petalinux to build a board image</h1><h2 id="Install-Petalinux-SDK-and-BSP"><a href="#Install-Petalinux-SDK-and-BSP" class="headerlink" title="Install Petalinux SDK and BSP"></a>Install Petalinux SDK and BSP</h2><p>Get <code>PetaLinux Tools - Installer - 2023.2 Full Product Installation</code> from the following links, and install it:</p><p><a class="link"   href="https://www.xilinx.com/support/download/index.html/content/xilinx/en/downloadNav/embedded-design-tools.html" >Xilinx Petalinux Downloads<i class="fas fa-external-link-alt"></i></a></p><p>Download Kria K26 SOM Board Support Package from the following link: </p><p><a class="link"   href="https://www.xilinx.com/support/download/index.html/content/xilinx/en/downloadNav/embedded-design-tools.html" >Downloads<i class="fas fa-external-link-alt"></i></a></p><p><img src="https://raw.githubusercontent.com/angiean7/pictures/main/image-20240417170035187.png" alt="image-20240417170035187"></p><h2 id="Build-Board-Image"><a href="#Build-Board-Image" class="headerlink" title="Build Board Image"></a>Build Board Image</h2><h3 id="Creating-a-Project-Using-PetaLinux-BSP"><a href="#Creating-a-Project-Using-PetaLinux-BSP" class="headerlink" title="Creating a Project Using PetaLinux BSP"></a>Creating a Project Using PetaLinux BSP</h3><p>Try to create a project from BSP use the following command:</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">petalinux-create -t project --template zynqMP --force -n kv260 -s ../BSPs/xilinx-kv260-starterkit-v2023.2-10140544.bsp</span><br></pre></td></tr></table></figure><p><img src="https://raw.githubusercontent.com/angiean7/wsl_test/main/image-20240417171646566.png" alt="image-20240417171646566"></p><h3 id="Building-the-Linux-Image-With-Petalinux-Using-recipes-vitis-ai"><a href="#Building-the-Linux-Image-With-Petalinux-Using-recipes-vitis-ai" class="headerlink" title="Building the Linux Image With Petalinux Using recipes-vitis-ai"></a>Building the Linux Image With Petalinux Using recipes-vitis-ai</h3><p>REF: <a class="link"   href="https://xilinx.github.io/Vitis-AI/3.5/html/docs/workflow-system-integration#rebuilding-the-linux-image-with-petalinux" >Integrating the DPU - Rebuilding the Linux Image With Petalinu<i class="fas fa-external-link-alt"></i></a></p><ol><li><p>Copy the <code>recipes-vitis-ai</code> folder to <code>&lt;petalinux project&gt;/project-spec/meta-user/</code></p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">cp -r /home/anq/workspace/Vitis-AI/src/vai_petalinux_recipes/recipes-vitis-ai /home/anq/workspace/kv260/kv260/project-spec/meta-user/</span><br></pre></td></tr></table></figure><p> <img src="https://raw.githubusercontent.com/angiean7/pictures/main/image-20240418172641480.png" alt="image-20240418172641480"></p></li><li><p>Delete either <code>recipes-vitis-ai/vart/vart_3.5.bb</code> or <code>recipes-vitis-ai/vart/vart_3.5_vivado.bb</code> depending on workflow that you have selected for your design. If you use <code>recipes-vitis-ai/vart/vart_3.5_vivado.bb</code> please rename it <code>recipes-vitis-ai/vart/vart_3.5.bb</code>.</p><p><img src="https://raw.githubusercontent.com/angiean7/wsl_test/main/image-20240418172812012.png" alt=""></p></li><li><p>Edit <code>&lt;petalinux project&gt;/project-spec/meta-user/conf/user-rootfsconfig</code> file, appending the following lines:</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">CONFIG_vitis-ai-library</span><br><span class="line">CONFIG_vitis-ai-library-dev</span><br><span class="line">CONFIG_vitis-ai-library-dbg</span><br></pre></td></tr></table></figure><p><img src="https://raw.githubusercontent.com/angiean7/pictures/main/image-20240418172927993.png" alt="image-20240418172927993"></p><p><img src="https://raw.githubusercontent.com/angiean7/pictures/main/image-20240418172954404.png" alt="image-20240418172954404"></p></li><li><p>Source PetaLinux tool and run <code>petalinux-config -c rootfs</code> command. Select the follo wing option. Save and exit. </p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">Select user packages ---&gt;</span><br><span class="line">Select [*] vitis-ai-library</span><br><span class="line"></span><br><span class="line">Select [Filesystem packages]  ---&gt; [libs]</span><br><span class="line">Select [*] xrt</span><br><span class="line"></span><br></pre></td></tr></table></figure><p><img src="https://raw.githubusercontent.com/angiean7/pictures/main/image-20240418173057029.png" alt="image-20240418173057029"></p><p><img src="https://raw.githubusercontent.com/angiean7/pictures/main/image-20240418173132238.png" alt="image-20240418173132238"></p></li><li><p>Run <code>petalinux-build</code>.</p><p>When i was building project, there were 2 issues. </p><p>a. <strong>0001-glog-enable-fatal-throw-exception.patch is already applied.</strong>  </p><p><img src="https://raw.githubusercontent.com/angiean7/pictures/main/image-20240424130711333.png" alt="image-20240424130711333"></p><p>As i checked how many times the patch is used, i found 2 results. </p><p><img src="https://raw.githubusercontent.com/angiean7/pictures/main/image-20240424131500405.png" alt="image-20240424131500405"></p><p>Therefore, i commented out one of them in glog_0.5.0.bbappend. </p><p><img src="https://raw.githubusercontent.com/angiean7/pictures/main/image-20240424131528466.png" alt="image-20240424131528466"></p><p>Then rebuild project, this issue seems to be resolved. </p><p>b. <strong>cpio: cannot seek on output: Invalid argument</strong></p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">| cpio: cannot seek on output: Invalid argument</span><br><span class="line">| WARNING: exit code 2 from a shell command.</span><br></pre></td></tr></table></figure><p><img src="https://raw.githubusercontent.com/angiean7/pictures/main/image-20240424132120109.png" alt="image-20240424132120109"></p><p>I found the solution in the Petalinux manual:</p><p><a class="link"   href="https://docs.amd.com/r/ja-JP/ug1144-petalinux-tools-reference-guide/do_image_cpio-Function-Failed-%E3%81%A8%E3%81%84%E3%81%86%E3%82%A8%E3%83%A9%E3%83%BC-%E3%83%A1%E3%83%83%E3%82%BB%E3%83%BC%E3%82%B8%E3%81%8C%E8%A1%A8%E7%A4%BA%E3%81%95%E3%82%8C%E3%82%8B" >「do_image_cpio: Function Failed」というエラー メッセージが表示される<i class="fas fa-external-link-alt"></i></a></p><p><img src="https://raw.githubusercontent.com/angiean7/pictures/main/image-20240424132326769.png" alt="image-20240424132326769"></p></li></ol><h3 id="Generate-Boot-Image"><a href="#Generate-Boot-Image" class="headerlink" title="Generate Boot Image"></a>Generate Boot Image</h3><p>The boot image can be put into Flash or SD card. When you power on the board, it can boot from the boot image. A boot image usually contains a <strong>first stage boot loader image, FPGA bitstream, PMU firmware, TF-A, and U-Boot.</strong></p><p>Execute the following command to generate the boot image in <code>.BIN</code> format.</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">petalinux-package --boot --u-boot</span><br></pre></td></tr></table></figure><p><img src="https://raw.githubusercontent.com/angiean7/pictures/main/image-20240424133208907.png" alt="image-20240424133208907"></p><h3 id="Booting-PetaLinux-Image-on-Hardware-with-an-SD-Card"><a href="#Booting-PetaLinux-Image-on-Hardware-with-an-SD-Card" class="headerlink" title="Booting PetaLinux Image on Hardware with an SD Card"></a>Booting PetaLinux Image on Hardware with an SD Card</h3><p>You can boot a PetaLinux image on hardware using an SD card by copying the required images manually.</p><p>Copy the following files from <code>&lt;plnx-proj-root&gt;/images/linux or &lt;plnx-proj-root&gt;/pre-built/linux/images/</code> into the boot directory of the first partition, which is in FAT32 format in the SD card:</p><ul><li>BOOT.BIN</li><li>image.ub</li><li>boot.scr</li></ul><p>Set the boot mode of the board to SD boot. </p><p>Plug the SD card into the board.</p><p>Power on the board.</p>]]></content>
    
    
      
      
    <summary type="html">&lt;h1 id=&quot;Use-board-image-provided-by-Xilinx&quot;&gt;&lt;a href=&quot;#Use-board-image-provided-by-Xilinx&quot; class=&quot;headerlink&quot; title=&quot;Use board image provided</summary>
      
    
    
    
    <category term="Linux" scheme="https://angiean7.github.io/categories/Linux/"/>
    
    
  </entry>
  
  <entry>
    <title>Typora+PicGo+Github to make image hosting easier</title>
    <link href="https://angiean7.github.io/2024/04/03/Typora+picgo+githubrepo/"/>
    <id>https://angiean7.github.io/2024/04/03/Typora+picgo+githubrepo/</id>
    <published>2024-04-03T04:08:01.565Z</published>
    <updated>2024-04-03T05:03:59.066Z</updated>
    
    <content type="html"><![CDATA[<h6 id="Introduce"><a href="#Introduce" class="headerlink" title="Introduce"></a>Introduce</h6><p>This article introduces the process of using Typora and PicGo to edit Markdown documents and upload images to GitHub. The specific steps are as follows:</p><ol><li><strong>Download Typora</strong></li><li><strong>Create a new GitHub repository</strong>: To upload images, you need to create a new repository on GitHub.</li><li><strong>Generate a token</strong>: Access the GitHub token generation page, and generate a token for PicGo. </li><li><strong>Download PicGo</strong>: PicGo is a tool for uploading images and getting URL links.</li><li><strong>Configure PicGo</strong>: Configure PicGo, set parameters such as the repository name and branch to ensure that uploaded images are stored on GitHub.</li><li><strong>Configure Typora</strong>: In Typora’s preferences, configure the image upload options, and test the upload function to ensure that it is set up correctly.</li></ol><h6 id="Download-Typora"><a href="#Download-Typora" class="headerlink" title="Download Typora"></a>Download Typora</h6><p>Here’s the version I use. I use Typora to edit my markdown documents. </p><p><img src="https://raw.githubusercontent.com/angiean7/pictures/main/image-20240403131340404.png" alt="image-20240403131340404"></p><h6 id="Create-a-new-Github-repository-to-upload-pictures"><a href="#Create-a-new-Github-repository-to-upload-pictures" class="headerlink" title="Create a new Github repository to upload pictures"></a>Create a new Github repository to upload pictures</h6><h6 id="Generate-a-token-for-PicGo-to-manipulate-your-repository"><a href="#Generate-a-token-for-PicGo-to-manipulate-your-repository" class="headerlink" title="Generate a token for PicGo to manipulate your repository"></a>Generate a token for PicGo to manipulate your repository</h6><p>Access <a class="link"   href="https://github.com/settings/tokens" >https://github.com/settings/tokens<i class="fas fa-external-link-alt"></i></a> and click Generate token.</p><p><strong>Note:</strong> This token will only be displayed once after it is generated. You’ll want to make a copy of this token and save it somewhere else in case you want to use it later.</p><h6 id="Download-Pico"><a href="#Download-Pico" class="headerlink" title="Download Pico"></a>Download Pico</h6><p>PicGo is a tool for quickly uploading images and getting URL links to them. </p><p>Github: <a class="link"   href="https://github.com/Molunerfinn/PicGo?tab=readme-ov-file" >https://github.com/Molunerfinn/PicGo?tab=readme-ov-file<i class="fas fa-external-link-alt"></i></a></p><p>Documents: <a class="link"   href="https://picgo.github.io/PicGo-Core-Doc/" >https://picgo.github.io/PicGo-Core-Doc/<i class="fas fa-external-link-alt"></i></a></p><h6 id="Configuring-PicGo"><a href="#Configuring-PicGo" class="headerlink" title="Configuring PicGo"></a>Configuring PicGo</h6><p><img src="https://raw.githubusercontent.com/angiean7/pictures/main/image-20240403133023276.png" alt="image-20240403133023276"></p><p><img src="https://raw.githubusercontent.com/angiean7/wsl_test/main/image-20240403133058781.png" alt="image-20240403133058781"></p><p><strong>Note:</strong> The format of the repository name is username/repository</p><p>For example, if I create a repository called test, the repository name I want to set in PicGo is Molunerfinn/test.</p><p>Usually we just select the main branch. Then remember to click OK to take effect, and then you can click Set as Default Beds to make sure the uploaded bed is GitHub.</p><p>At this point the configuration is complete and it’s ready to use. When you upload by PicGo, you’ll notice that new images will be added to your repository as well.</p><p><img src="https://raw.githubusercontent.com/angiean7/pictures/main/image-20240403133254926.png" alt="image-20240403133254926"></p><h6 id="Configure-Typora"><a href="#Configure-Typora" class="headerlink" title="Configure Typora"></a>Configure Typora</h6><p>Click on the Preferences option for Typora, then select Image and configure the options for the following image: </p><p><img src="https://raw.githubusercontent.com/angiean7/pictures/main/image-20240403133740975.png" alt="image-20240403133740975"></p><p>And click Test Uploader button, If you see the successful result in the image below, it means that you can automatically upload the image and convert it to a link by pasting the image into the edit box when using Typora. </p><p><img src="https://raw.githubusercontent.com/angiean7/pictures/main/image-20240403133830877.png" alt="image-20240403133830877"></p>]]></content>
    
    
      
      
    <summary type="html">&lt;h6 id=&quot;Introduce&quot;&gt;&lt;a href=&quot;#Introduce&quot; class=&quot;headerlink&quot; title=&quot;Introduce&quot;&gt;&lt;/a&gt;Introduce&lt;/h6&gt;&lt;p&gt;This article introduces the process of usi</summary>
      
    
    
    
    <category term="环境" scheme="https://angiean7.github.io/categories/%E7%8E%AF%E5%A2%83/"/>
    
    
  </entry>
  
  <entry>
    <title>Device Tree Memo</title>
    <link href="https://angiean7.github.io/2024/04/01/Device%20Tree%20Memo/"/>
    <id>https://angiean7.github.io/2024/04/01/Device%20Tree%20Memo/</id>
    <published>2024-04-01T06:39:03.806Z</published>
    <updated>2024-04-17T02:22:32.278Z</updated>
    
    <content type="html"><![CDATA[<p>Device tree allows the  operating system or bootloader to know things like:</p><p>this system-on-chip has:</p><ul><li>2 Cortex-A9 CPU cores</li><li>2 memory-mapped UART controllers of this variant, one with registers at 0xF1000000 and IRQ 23, and another with registers at 0xF1001000 and IRQ 24</li><li>3 I2C controllers of that variant, with  registers at those memory-mapped address, those IRQs and taking their input clock from this source</li></ul><p>simplified example of i2c controller and it’s sub node (eeprom0): </p><p><img src="https://raw.githubusercontent.com/angiean7/wsl_test/main/image-20240401161154891.png" alt="image-20240401161154891"></p><p>simplified example of spi controller and it’s sub node (flash0): </p><p><img src="https://raw.githubusercontent.com/angiean7/pictures/main/image-20240405163920782.png" alt="image-20240405163920782"></p><p>there is no need to describe usb devices in the device tree as sub node, the usb controller will discover them at runtime. </p><p><img src="https://raw.githubusercontent.com/angiean7/pictures/main/image-20240402182135124.png" alt="image-20240402182135124"></p><p>The linux kernel sources can be considered as the canonical(非常によく似た) location for device tree source files</p><p><u>arch/<ARCH>/boot/dts</u></p>]]></content>
    
    
      
      
    <summary type="html">&lt;p&gt;Device tree allows the  operating system or bootloader to know things like:&lt;/p&gt;
&lt;p&gt;this system-on-chip has:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;2 Cortex-A9 CPU </summary>
      
    
    
    
    <category term="Linux Kernel" scheme="https://angiean7.github.io/categories/Linux-Kernel/"/>
    
    
  </entry>
  
  <entry>
    <title>Linux-PCI网络设备驱动</title>
    <link href="https://angiean7.github.io/2023/12/15/Linux-PCI%E7%BD%91%E7%BB%9C%E8%AE%BE%E5%A4%87%E9%A9%B1%E5%8A%A8/"/>
    <id>https://angiean7.github.io/2023/12/15/Linux-PCI%E7%BD%91%E7%BB%9C%E8%AE%BE%E5%A4%87%E9%A9%B1%E5%8A%A8/</id>
    <published>2023-12-15T02:21:29.658Z</published>
    <updated>2022-07-28T07:09:53.215Z</updated>
    
    <content type="html"><![CDATA[<h1 id="Linux-PCI网络设备驱动"><a href="#Linux-PCI网络设备驱动" class="headerlink" title="Linux-PCI网络设备驱动"></a>Linux-PCI网络设备驱动</h1><h4 id="1-驱动模块的加载和卸载"><a href="#1-驱动模块的加载和卸载" class="headerlink" title="1, 驱动模块的加载和卸载"></a>1, 驱动模块的加载和卸载</h4><p>​    如果网络设备（包括wireless）是PCI规范的，则先是向内核注册该PCI设备(pci_register_driver)，然后由pci_driver数据结构中的probe函数指针所指向的侦测函数来初始化该PCI设备，并且同时注册和初始化该网络设备。<br>​    如果网络设备（包括wireless）是PCMCIA规范的，则先是向内核注册该PCMCIA设备(register_pccard_driver)，然后 driver_info_t数据结构中的attach函数指针所指向的侦测函数来初始化该PCMCIA设备，并且同时注册和初始化该网络设备。</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="type">static</span> <span class="type">int</span> __init <span class="title function_">tg3_init</span><span class="params">(<span class="type">void</span>)</span></span><br><span class="line">&#123;</span><br><span class="line">    <span class="comment">//先注册成PCI设备，并初始化，如果是其他的ESIA，PCMCIA，用其他函数</span></span><br><span class="line">    <span class="keyword">return</span> pci_module_init(&amp;tg3_driver);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="type">static</span> <span class="type">void</span> __exit <span class="title function_">tg3_cleanup</span><span class="params">(<span class="type">void</span>)</span></span><br><span class="line">&#123;</span><br><span class="line">pci_unregister_driver(&amp;tg3_driver);<span class="comment">//注销PCI设备</span></span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">module_init(tg3_init); <span class="comment">//驱动模块的加载</span></span><br><span class="line">module_exit(tg3_cleanup); <span class="comment">//驱动模块的卸载</span></span><br></pre></td></tr></table></figure><p>申明为PCI设备：</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="type">static</span> <span class="class"><span class="keyword">struct</span> <span class="title">pci_driver</span> <span class="title">tg3_driver</span> =</span> &#123;</span><br><span class="line">    .name = DRV_MODULE_NAME,</span><br><span class="line">    .id_table = tg3_pci_tbl, <span class="comment">//此驱动所支持的网卡系列，vendor_id, device_id</span></span><br><span class="line">    .probe = tg3_init_one, <span class="comment">//初始化网络设备的回调函数</span></span><br><span class="line">    .remove = __devexit_p(tg3_remove_one), <span class="comment">//注销网络设备的回调函数</span></span><br><span class="line">    .suspend = tg3_suspend, <span class="comment">//设备挂起函数</span></span><br><span class="line">    .resume = tg3_resume <span class="comment">//设备恢复函数</span></span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><h4 id="2，PCI设备探测函数probe，初始化网络设备"><a href="#2，PCI设备探测函数probe，初始化网络设备" class="headerlink" title="2，PCI设备探测函数probe，初始化网络设备"></a>2，PCI设备探测函数probe，初始化网络设备</h4><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br></pre></td><td class="code"><pre><span class="line"><span class="type">static</span> <span class="type">int</span> __devinit <span class="title function_">tg3_init_one</span><span class="params">(<span class="keyword">struct</span> pci_dev *pdev, <span class="type">const</span> <span class="keyword">struct</span> pci_device_id *ent)</span></span><br><span class="line">&#123;</span><br><span class="line">    <span class="comment">//初始化设备，使I/O，memory可用，唤醒设备</span></span><br><span class="line">    pci_enable_device(pdev);</span><br><span class="line">    <span class="comment">//申请内存空间，配置网卡的I/O，memory资源</span></span><br><span class="line">    pci_request_regions(pdev, DRV_MODULE_NAME);</span><br><span class="line">    pci_set_master(pdev);</span><br><span class="line">    <span class="comment">//设置DMA属性</span></span><br><span class="line">    pci_set_dma_mask(pdev, (u64) <span class="number">0xffffffffffffffff</span>);</span><br><span class="line">    <span class="comment">//网卡 I/O,memory资源的启始地址</span></span><br><span class="line">    tg3reg_base = pci_resource_start(pdev, <span class="number">0</span>);</span><br><span class="line">    <span class="comment">//网卡I/O,memory资源的大小</span></span><br><span class="line">    tg3reg_len = pci_resource_len(pdev, <span class="number">0</span>);</span><br><span class="line">    <span class="comment">//分配并设置网络设备</span></span><br><span class="line">    dev = alloc_etherdev(<span class="keyword">sizeof</span>(*tp));</span><br><span class="line">    <span class="comment">//申明为内核设备模块</span></span><br><span class="line">    SET_MODULE_OWNER(dev);</span><br><span class="line">    <span class="comment">//初始化私有结构中的各成员值</span></span><br><span class="line">    tp = dev-&gt;priv;</span><br><span class="line">    tp-&gt;pdev = pdev;</span><br><span class="line">    tp-&gt;dev = dev;</span><br><span class="line">    ……</span><br><span class="line">    <span class="comment">//锁的初始化</span></span><br><span class="line">    spin_lock_init(&amp;tp-&gt;lock);</span><br><span class="line">    <span class="comment">//映射I/O,memory地址到私有域中的寄存器结构</span></span><br><span class="line">    tp-&gt;regs = (<span class="type">unsigned</span> <span class="type">long</span>) ioremap(tg3reg_base, tg3reg_len);</span><br><span class="line">    dev-&gt;irq = pdev-&gt;irq;</span><br><span class="line">    <span class="comment">//网络设备回调函数赋值</span></span><br><span class="line">    dev-&gt;open = tg3_open;</span><br><span class="line">    dev-&gt;stop = tg3_close;</span><br><span class="line">    dev-&gt;get_stats = tg3_get_stats;</span><br><span class="line">    dev-&gt;set_multicast_list = tg3_set_rx_mode;</span><br><span class="line">    dev-&gt;set_mac_address = tg3_set_mac_addr;</span><br><span class="line">    dev-&gt;do_ioctl = tg3_ioctl;</span><br><span class="line">    dev-&gt;tx_timeout = tg3_tx_timeout;</span><br><span class="line">    dev-&gt;hard_start_xmit= tg3_start_xmit;</span><br><span class="line">    <span class="comment">//网卡的MAC地址赋值dev-&gt;addr</span></span><br><span class="line">    tg3_get_device_address(tp);</span><br><span class="line">    <span class="comment">//注册网络设备</span></span><br><span class="line">    register_netdev(dev);</span><br><span class="line">    <span class="comment">//把网络设备指针地址放入PCI设备中的设备指针中</span></span><br><span class="line">    pci_set_drvdata(pdev, dev);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h4 id="3，注销网络设备"><a href="#3，注销网络设备" class="headerlink" title="3，注销网络设备"></a>3，注销网络设备</h4><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line"><span class="type">static</span> <span class="type">void</span> __devexit <span class="title function_">tg3_remove_one</span><span class="params">(<span class="keyword">struct</span> pci_dev *pdev)</span></span><br><span class="line">&#123;</span><br><span class="line">    <span class="class"><span class="keyword">struct</span> <span class="title">net_device</span> *<span class="title">dev</span> =</span> pci_get_drvdata(pdev);</span><br><span class="line">    <span class="comment">//注销网络设备</span></span><br><span class="line">    unregister_netdev(dev);</span><br><span class="line">    <span class="comment">//取消地址映射</span></span><br><span class="line">    iounmap((<span class="type">void</span> *) ((<span class="keyword">struct</span> tg3 *)(dev-&gt;priv))-&gt;regs);</span><br><span class="line">    <span class="comment">//释放网络设备</span></span><br><span class="line">    kfree(dev);</span><br><span class="line">    <span class="comment">//释放PCI资源</span></span><br><span class="line">    pci_release_regions(pdev);</span><br><span class="line">    <span class="comment">//停用PCI设备</span></span><br><span class="line">    pci_disable_device(pdev);</span><br><span class="line">    <span class="comment">//PCI设备中的设备指针赋空</span></span><br><span class="line">    pci_set_drvdata(pdev, <span class="literal">NULL</span>);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h4 id="4，打开网络设备"><a href="#4，打开网络设备" class="headerlink" title="4，打开网络设备"></a>4，打开网络设备</h4><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br></pre></td><td class="code"><pre><span class="line"><span class="type">static</span> <span class="type">int</span> <span class="title function_">tg3_open</span><span class="params">(<span class="keyword">struct</span> net_device *dev)</span></span><br><span class="line">&#123;</span><br><span class="line">    <span class="comment">//分配一个中断</span></span><br><span class="line">    request_irq(dev-&gt;irq, tg3_interrupt, SA_SHIRQ, dev-&gt;name, dev);</span><br><span class="line">    <span class="comment">/* int request_irq(unsigned int irq,</span></span><br><span class="line"><span class="comment">    void (*handler)(int irq, void *dev_id, struct pt_regs *regs),</span></span><br><span class="line"><span class="comment">    unsigned long irqflags,</span></span><br><span class="line"><span class="comment">    const char * devname,</span></span><br><span class="line"><span class="comment">    void *dev_id);</span></span><br><span class="line"><span class="comment">    irq 是要申请的硬件中断号。在Intel平台，范围0--15。</span></span><br><span class="line"><span class="comment">    handler是向系统登记的中断处理函数。这是一个回调函数，中断发生时，系统调用这个函数，传入的参数包括硬件中断号，device id，寄存器值。</span></span><br><span class="line"><span class="comment">    dev_id就是下面的request_irq时传递给系统的参数dev_id。irqflags是中断处理的一些属性。</span></span><br><span class="line"><span class="comment">    比较重要的有 SA_INTERRUPT，标明中断处理程序是快速处理程序(设置SA_INTERRUPT)还是慢速处理程序(不设置SA_INTERRUPT)。快速处理程序被调用时屏蔽所有中断。慢速处理程序不屏蔽。还有一个SA_SHIRQ属性，设置了以后运行多个设备共享中断。dev_id在中断共享时会用到。 一般设置为这个设备的device结构本身或者NULL。中断处理程序可以用dev_id找到相应的控制这个中断的设备，或者用rq2dev_map找到 中断对应的设备。*/</span></span><br><span class="line">    <span class="comment">//初始化硬件</span></span><br><span class="line">    tg3_init_hw(tp);</span><br><span class="line">    <span class="comment">//初始化收包和发包的缓冲区</span></span><br><span class="line">    tg3_init_rings(tp);</span><br><span class="line">    <span class="comment">//初始化定时器</span></span><br><span class="line">    init_timer(&amp;tp-&gt;timer);</span><br><span class="line">    tp-&gt;timer.expires = jiffies + tp-&gt;timer_offset;</span><br><span class="line">    tp-&gt;timer.data = (<span class="type">unsigned</span> <span class="type">long</span>) tp;</span><br><span class="line">    tp-&gt;timer.function = tg3_timer; <span class="comment">//超时回调函数</span></span><br><span class="line">    add_timer(&amp;tp-&gt;timer);</span><br><span class="line">    <span class="comment">//允许网卡开始传输包</span></span><br><span class="line">    netif_start_queue(dev);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h4 id="5，关闭网络设备"><a href="#5，关闭网络设备" class="headerlink" title="5，关闭网络设备"></a>5，关闭网络设备</h4><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="type">static</span> <span class="type">int</span> <span class="title function_">tg3_close</span><span class="params">(<span class="keyword">struct</span> net_device *dev)</span></span><br><span class="line">&#123;</span><br><span class="line">    <span class="comment">//停止网卡传输包</span></span><br><span class="line">    netif_stop_queue(dev);</span><br><span class="line">    netif_carrier_off(tp-&gt;dev);</span><br><span class="line">    <span class="comment">//去除定时器</span></span><br><span class="line">    del_timer_sync(&amp;tp-&gt;timer);</span><br><span class="line">    <span class="comment">//释放收包和发包的缓冲区</span></span><br><span class="line">    tg3_free_rings(tp);</span><br><span class="line">    <span class="comment">//释放中断</span></span><br><span class="line">    free_irq(dev-&gt;irq, dev);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h4 id="6，硬件处理数据包发送"><a href="#6，硬件处理数据包发送" class="headerlink" title="6，硬件处理数据包发送"></a>6，硬件处理数据包发送</h4><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="type">static</span> <span class="type">int</span> <span class="title function_">tg3_start_xmit</span><span class="params">(<span class="keyword">struct</span> sk_buff *skb, <span class="keyword">struct</span> net_device *dev)</span></span><br><span class="line">&#123;</span><br><span class="line">    len = (skb-&gt;len - skb-&gt;data_len);</span><br><span class="line">    <span class="comment">//以DMA方式向网卡物理设备传输包。如果是wireless的话，需要根据802.11协议及硬件的规范从新填充</span></span><br><span class="line">    <span class="comment">//硬件帧头，然后提交给硬件发送。</span></span><br><span class="line">    mapping = pci_map_single(tp-&gt;pdev, skb-&gt;data, len, PCI_DMA_TODEVICE);</span><br><span class="line">    tp-&gt;tx_buffers[entry].skb = skb;</span><br><span class="line">    pci_unmap_addr_set(&amp;tp-&gt;tx_buffers[entry], mapping, mapping);</span><br><span class="line">    <span class="comment">//硬件发送</span></span><br><span class="line">    tg3_set_txd(tp, entry, mapping, len, base_flags, mss_and_is_end);</span><br><span class="line">    <span class="comment">//记录发包开始时间</span></span><br><span class="line">    dev-&gt;trans_start = jiffies;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h4 id="7，中断处理收包，发包"><a href="#7，中断处理收包，发包" class="headerlink" title="7，中断处理收包，发包"></a>7，中断处理收包，发包</h4><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="type">static</span> <span class="type">void</span> <span class="title function_">tg3_interrupt</span><span class="params">(<span class="type">int</span> irq, <span class="type">void</span> *dev_id, <span class="keyword">struct</span> pt_regs *regs)</span></span><br><span class="line">&#123;</span><br><span class="line">    <span class="comment">//如果要收包</span></span><br><span class="line">    tg3_rx(tp);</span><br><span class="line">    <span class="comment">//如果要发包</span></span><br><span class="line">    tg3_tx(tp);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h4 id="8，发包"><a href="#8，发包" class="headerlink" title="8，发包"></a>8，发包</h4><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="type">static</span> <span class="type">void</span> <span class="title function_">tg3_tx</span><span class="params">(<span class="keyword">struct</span> tg3 *tp)</span></span><br><span class="line">&#123;</span><br><span class="line">    <span class="class"><span class="keyword">struct</span> <span class="title">tx_ring_info</span> *<span class="title">ri</span> =</span> &amp;tp-&gt;tx_buffers[sw_idx];</span><br><span class="line">    <span class="class"><span class="keyword">struct</span> <span class="title">sk_buff</span> *<span class="title">skb</span> =</span> ri-&gt;skb;</span><br><span class="line">    <span class="comment">//以DMA方式向网卡传输包完毕</span></span><br><span class="line">    pci_unmap_single(tp-&gt;pdev, pci_unmap_addr(ri, mapping),</span><br><span class="line">    (skb-&gt;len - skb-&gt;data_len), PCI_DMA_TODEVICE);</span><br><span class="line">    ri-&gt;skb = <span class="literal">NULL</span>;</span><br><span class="line">    dev_kfree_skb_irq(skb);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h4 id="9，收包"><a href="#9，收包" class="headerlink" title="9，收包"></a>9，收包</h4><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><span class="line"><span class="type">static</span> <span class="type">int</span> <span class="title function_">tg3_rx</span><span class="params">(<span class="keyword">struct</span> tg3 *tp, <span class="type">int</span> budget)</span></span><br><span class="line">&#123;</span><br><span class="line">    <span class="class"><span class="keyword">struct</span> <span class="title">sk_buff</span> *<span class="title">copy_skb</span>;</span></span><br><span class="line">    <span class="comment">//分配一个包</span></span><br><span class="line">    copy_skb = dev_alloc_skb(len + <span class="number">2</span>);</span><br><span class="line">    copy_skb-&gt;dev = tp-&gt;dev;</span><br><span class="line">    <span class="comment">//修改包头空间</span></span><br><span class="line">    skb_reserve(copy_skb, <span class="number">2</span>);</span><br><span class="line">    <span class="comment">//加入数据到包中</span></span><br><span class="line">    skb_put(copy_skb, len);</span><br><span class="line">    <span class="comment">//以DMA方式从网卡传输回数据</span></span><br><span class="line">    pci_dma_sync_single(tp-&gt;pdev, dma_addr, len, PCI_DMA_FROMDEVICE);</span><br><span class="line">    <span class="built_in">memcpy</span>(copy_skb-&gt;data, skb-&gt;data, len);</span><br><span class="line">    skb = copy_skb;</span><br><span class="line">    <span class="comment">//解析包的协议</span></span><br><span class="line">    skb-&gt;protocol = eth_type_trans(skb, tp-&gt;dev);</span><br><span class="line">    <span class="comment">//把包送到协议层</span></span><br><span class="line">    netif_rx(skb);</span><br><span class="line">    <span class="comment">//记录收包时间</span></span><br><span class="line">    tp-&gt;dev-&gt;last_rx = jiffies;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h4 id="10-读取包的网卡收发包的状态，统计数据"><a href="#10-读取包的网卡收发包的状态，统计数据" class="headerlink" title="10, 读取包的网卡收发包的状态，统计数据"></a>10, 读取包的网卡收发包的状态，统计数据</h4><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="type">static</span> <span class="keyword">struct</span> net_device_stats *<span class="title function_">tg3_get_stats</span><span class="params">(<span class="keyword">struct</span> net_device *dev)</span></span><br><span class="line">&#123;</span><br><span class="line">    <span class="comment">//从硬件相关的寄存器读取数据，累加</span></span><br><span class="line">    <span class="comment">//stats-&gt;rx_packets, stats-&gt;tx_packets, stats-&gt;rx_bytes, stats-&gt;tx_bytes等</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h4 id="11-用户的ioctl命令系统调用"><a href="#11-用户的ioctl命令系统调用" class="headerlink" title="11, 用户的ioctl命令系统调用"></a>11, 用户的ioctl命令系统调用</h4><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line"><span class="type">static</span> <span class="type">int</span> <span class="title function_">tg3_ioctl</span><span class="params">(<span class="keyword">struct</span> net_device *dev, <span class="keyword">struct</span> ifreq *ifr, <span class="type">int</span> cmd)</span></span><br><span class="line">&#123;</span><br><span class="line">    <span class="class"><span class="keyword">struct</span> <span class="title">mii_ioctl_data</span> *<span class="title">data</span> =</span> (<span class="keyword">struct</span> mii_ioctl_data *)&amp;ifr-&gt;ifr_data;</span><br><span class="line">    <span class="keyword">switch</span>(cmd) &#123;</span><br><span class="line">        <span class="comment">//ethtool程序命令的调用</span></span><br><span class="line">        <span class="keyword">case</span> SIOCETHTOOL:</span><br><span class="line">        <span class="keyword">return</span> tg3_ethtool_ioctl(dev, (<span class="type">void</span> *) ifr-&gt;ifr_data);</span><br><span class="line">        <span class="comment">//mii程序命令的调用</span></span><br><span class="line">        <span class="keyword">case</span> SIOCGMIIREG: &#123;</span><br><span class="line">            err = tg3_readphy(tp, data-&gt;reg_num &amp; <span class="number">0x1f</span>, &amp;mii_regval)</span><br><span class="line">            data-&gt;val_out = mii_regval;</span><br><span class="line">            <span class="keyword">return</span> err;</span><br><span class="line">    &#125;</span><br><span class="line">    ……</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h4 id="12-PCI设备的挂起和恢复函数"><a href="#12-PCI设备的挂起和恢复函数" class="headerlink" title="12, PCI设备的挂起和恢复函数"></a>12, PCI设备的挂起和恢复函数</h4><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="type">static</span> <span class="type">int</span> <span class="title function_">tg3_suspend</span><span class="params">(<span class="keyword">struct</span> pci_dev *pdev, u32 state)</span></span><br><span class="line">&#123;</span><br><span class="line">    <span class="comment">//停用网卡的中断寄存器</span></span><br><span class="line">    tg3_disable_ints(tp);</span><br><span class="line">    <span class="comment">//停止网卡收发包</span></span><br><span class="line">    netif_device_detach(dev);</span><br><span class="line">    <span class="comment">//停止网卡某些硬件，fireware的一些功能</span></span><br><span class="line">    tg3_halt(tp);</span><br><span class="line">    <span class="comment">//设置网卡的电源状态</span></span><br><span class="line">    tg3_set_power_state(tp, state);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="type">static</span> <span class="type">int</span> <span class="title function_">tg3_resume</span><span class="params">(<span class="keyword">struct</span> pci_dev *pdev)</span></span><br><span class="line">&#123;</span><br><span class="line">    <span class="comment">//恢复网卡电源</span></span><br><span class="line">    tg3_set_power_state(tp, <span class="number">0</span>);</span><br><span class="line">    <span class="comment">//允许网卡收发包</span></span><br><span class="line">    netif_device_attach(dev);</span><br><span class="line">    <span class="comment">//初始化收发包的缓冲区</span></span><br><span class="line">    tg3_init_rings(tp);</span><br><span class="line">    <span class="comment">//初始化网卡硬件</span></span><br><span class="line">    tg3_init_hw(tp);</span><br><span class="line">    <span class="comment">//打开网卡中断寄存器</span></span><br><span class="line">    tg3_enable_ints(tp);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h4 id="13，参数设置"><a href="#13，参数设置" class="headerlink" title="13，参数设置"></a>13，参数设置</h4><p>在驱动程序里还提供一些方法供系统对设备的参数进行设置和读取信息。一般只有超级用户(root)权限才能对设备参数进行设置。设置方法有：<br>    tg3_set_mac_addr (dev-&gt;set_mac_address)<br>当用户调用ioctl类型为SIOCSIFHWADDR时是要设置这个设备的mac地址。一般对mac地址的设置没有太大意义的。</p><p>dev-&gt;set_config()<br>当用户调用ioctl时类型为SIOCSIFMAP时，系统会调用驱动程序的set_config方法<br>用户会传递一个ifmap结构包含需要的I/O、中断等参数。</p><p>总结：<br>所有的Linux网络驱动程序遵循通用的接口。设计时采用的是<strong>面向对象</strong>的方法。一个设备就是一个对象(net_device 结构)，它内部有自己的数据和方法。一个网络设备最基本的方法有<strong>初始化</strong>,<strong>发送</strong>和<strong>接收</strong>。</p><p>Linux网络驱动程序的体系结构可以划分为四层：<br>网络协议接口，网络设备接口，设备驱动功能，网络设备和网络媒介层<br>网络驱动程序，最主要的工作就是完成设备驱动功能层。在Linux中所有网络设备都抽象为一个接口，这个接口提供了对所有网络设备的操作集合。由数据结构 struct net_device来表示网络设备在内核中的运行情况，即网络设备接口。它既包括纯软件网络设备接口，如环路（Loopback），也包括硬件网络设备 接口，如以太网卡。而由以dev_base为头指针的设备链表来集体管理所有网络设备，该设备链表中的每个元素代表一个网络设备接口。数据结构 net_device中有很多供系统访问和协议层调用的设备方法，包括初始化,打开和关闭网络设备的open和stop函数，处理数据包发送的 hard_start_xmit函数，以及中断处理函数等。</p><p>网络设备在Linux里做专门的处理。Linux的网络系统主要是基于BSD unix的socket机制。在系统和驱动程序之间定义有专门的数据结构(sk_buff)进行数据的传递。系统里支持对发送数据和接收数据的缓存，提供流量控制机制，提供对多协议的支持。</p>]]></content>
    
    
      
      
    <summary type="html">&lt;h1 id=&quot;Linux-PCI网络设备驱动&quot;&gt;&lt;a href=&quot;#Linux-PCI网络设备驱动&quot; class=&quot;headerlink&quot; title=&quot;Linux-PCI网络设备驱动&quot;&gt;&lt;/a&gt;Linux-PCI网络设备驱动&lt;/h1&gt;&lt;h4 id=&quot;1-驱动模块的加载和卸载&quot;</summary>
      
    
    
    
    <category term="Linux drv" scheme="https://angiean7.github.io/categories/Linux-drv/"/>
    
    
  </entry>
  
  <entry>
    <title>Linux-基本原子操作 atomic</title>
    <link href="https://angiean7.github.io/2023/12/15/Linux-%E5%8E%9F%E5%AD%90%E6%93%8D%E4%BD%9C/"/>
    <id>https://angiean7.github.io/2023/12/15/Linux-%E5%8E%9F%E5%AD%90%E6%93%8D%E4%BD%9C/</id>
    <published>2023-12-15T02:21:29.658Z</published>
    <updated>2022-07-28T07:09:07.870Z</updated>
    
    <content type="html"><![CDATA[<p>原子操作主要用于实现资源计数，很多引用计数(refcnt)就是通过原子操作实现的。原子类型定义如下：</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">typedef</span> <span class="class"><span class="keyword">struct</span> </span></span><br><span class="line"><span class="class">&#123;</span> </span><br><span class="line">   <span class="keyword">volatile</span> <span class="type">int</span> counter; </span><br><span class="line">&#125; </span><br><span class="line"><span class="type">atomic_t</span>;</span><br></pre></td></tr></table></figure><p>volatile修饰字段告诉gcc不要对该类型的数据做优化处理，对它的访问都是对内存的访问，而不是对寄存器的访问。</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br></pre></td><td class="code"><pre><span class="line"><span class="type">atomic_inc</span>(&amp;v)对变量v用锁定总线的单指令进行不可分解的<span class="string">&quot;原子&quot;</span>级增量操作，避免v的值由于中断或多处理器同时操作造成不确定状态。</span><br><span class="line"></span><br><span class="line">原子操作API包括： </span><br><span class="line"> </span><br><span class="line"><span class="type">int</span> <span class="title function_">atomic_read</span><span class="params">(<span class="type">atomic_t</span> * v)</span>;</span><br><span class="line"> </span><br><span class="line">　　该函数对原子类型的变量进行原子读操作，它返回原子类型的变量v的值。 </span><br><span class="line"> </span><br><span class="line"> </span><br><span class="line"><span class="type">void</span> <span class="title function_">atomic_set</span><span class="params">(<span class="type">atomic_t</span> * v, <span class="type">int</span> i)</span>;</span><br><span class="line"> </span><br><span class="line">　　该函数设置原子类型的变量v的值为i。 </span><br><span class="line"> </span><br><span class="line"> </span><br><span class="line"><span class="type">void</span> <span class="title function_">atomic_add</span><span class="params">(<span class="type">int</span> i, <span class="type">atomic_t</span> *v)</span>;</span><br><span class="line"> </span><br><span class="line">　　该函数给原子类型的变量v增加值i。 </span><br><span class="line"> </span><br><span class="line"> </span><br><span class="line"><span class="type">void</span> <span class="title function_">atomic_sub</span><span class="params">(<span class="type">int</span> i, <span class="type">atomic_t</span> *v)</span>;</span><br><span class="line"> </span><br><span class="line">　　该函数从原子类型的变量v中减去i。 </span><br><span class="line"> </span><br><span class="line"> </span><br><span class="line"><span class="type">int</span> <span class="title function_">atomic_sub_and_test</span><span class="params">(<span class="type">int</span> i, <span class="type">atomic_t</span> *v)</span>;</span><br><span class="line"> </span><br><span class="line">　　该函数从原子类型的变量v中减去i，并判断结果是否为<span class="number">0</span>，如果为<span class="number">0</span>，返回真，否则返回假。 </span><br><span class="line"> </span><br><span class="line"> </span><br><span class="line"><span class="type">void</span> <span class="title function_">atomic_inc</span><span class="params">(<span class="type">atomic_t</span> *v)</span>;</span><br><span class="line"> </span><br><span class="line">　　该函数对原子类型变量v原子地增加<span class="number">1</span>。 </span><br><span class="line"> </span><br><span class="line"> </span><br><span class="line"><span class="type">void</span> <span class="title function_">atomic_dec</span><span class="params">(<span class="type">atomic_t</span> *v)</span>;</span><br><span class="line"> </span><br><span class="line">　　该函数对原子类型的变量v原子地减<span class="number">1</span>。 </span><br><span class="line"> </span><br><span class="line"> </span><br><span class="line"><span class="type">int</span> <span class="title function_">atomic_dec_and_test</span><span class="params">(<span class="type">atomic_t</span> *v)</span>;</span><br><span class="line"> </span><br><span class="line">　　该函数对原子类型的变量v原子地减<span class="number">1</span>，并判断结果是否为<span class="number">0</span>，如果为<span class="number">0</span>，返回真，否则返回假。 </span><br><span class="line"> </span><br><span class="line"> </span><br><span class="line"><span class="type">int</span> <span class="title function_">atomic_inc_and_test</span><span class="params">(<span class="type">atomic_t</span> *v)</span>;</span><br><span class="line"> </span><br><span class="line">　　该函数对原子类型的变量v原子地增加<span class="number">1</span>，并判断结果是否为<span class="number">0</span>，如果为<span class="number">0</span>，返回真，否则返回假。 </span><br><span class="line"> </span><br><span class="line"> </span><br><span class="line"><span class="type">int</span> <span class="title function_">atomic_add_negative</span><span class="params">(<span class="type">int</span> i, <span class="type">atomic_t</span> *v)</span>;</span><br><span class="line"> </span><br><span class="line">　　该函数对原子类型的变量v原子地增加I，并判断结果是否为负数，如果是，返回真，否则返回假。 </span><br><span class="line"> </span><br><span class="line"> </span><br><span class="line"><span class="type">int</span> <span class="title function_">atomic_add_return</span><span class="params">(<span class="type">int</span> i, <span class="type">atomic_t</span> *v)</span>;</span><br><span class="line"> </span><br><span class="line">　　该函数对原子类型的变量v原子地增加i，并且返回指向v的指针。 </span><br><span class="line"> </span><br><span class="line"> </span><br><span class="line"><span class="type">int</span> <span class="title function_">atomic_sub_return</span><span class="params">(<span class="type">int</span> i, <span class="type">atomic_t</span> *v)</span>;</span><br><span class="line"> </span><br><span class="line">　　该函数从原子类型的变量v中减去i，并且返回指向v的指针。 </span><br><span class="line"> </span><br><span class="line"> </span><br><span class="line"><span class="type">int</span> <span class="title function_">atomic_inc_return</span><span class="params">(<span class="type">atomic_t</span> * v)</span>;</span><br><span class="line"> </span><br><span class="line">　　该函数对原子类型的变量v原子地增加<span class="number">1</span>并且返回指向v的指针。 </span><br><span class="line"> </span><br><span class="line"> </span><br><span class="line"><span class="type">int</span> <span class="title function_">atomic_dec_return</span><span class="params">(<span class="type">atomic_t</span> * v)</span>;</span><br><span class="line">　　该函数对原子类型的变量v原子地减<span class="number">1</span>并且返回指向v的指针。 </span><br><span class="line"></span><br></pre></td></tr></table></figure><p> 基本操作：</p><table><thead><tr><th>宏或者函数</th><th>说明</th></tr></thead><tbody><tr><td>atomic_read</td><td>返回原子变量的值</td></tr><tr><td>atomic_set</td><td>设置原子变量的值。</td></tr><tr><td>atomic_add</td><td>增加计数的值。(+i)</td></tr><tr><td>atomic_sub</td><td>减少计数的值。(-i)</td></tr><tr><td>atomic_inc</td><td>递增计数的值。(++)</td></tr><tr><td>atomic_dec</td><td>递减计数的值。(–)</td></tr></tbody></table>]]></content>
    
    
      
      
    <summary type="html">&lt;p&gt;原子操作主要用于实现资源计数，很多引用计数(refcnt)就是通过原子操作实现的。原子类型定义如下：&lt;/p&gt;
&lt;figure class=&quot;highlight c&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;</summary>
      
    
    
    
    <category term="Linux C" scheme="https://angiean7.github.io/categories/Linux-C/"/>
    
    
  </entry>
  
  <entry>
    <title>Linux中断子系统笔记</title>
    <link href="https://angiean7.github.io/2023/12/15/Linux%E4%B8%AD%E6%96%AD%E5%AD%90%E7%B3%BB%E7%BB%9F%E7%AC%94%E8%AE%B0/"/>
    <id>https://angiean7.github.io/2023/12/15/Linux%E4%B8%AD%E6%96%AD%E5%AD%90%E7%B3%BB%E7%BB%9F%E7%AC%94%E8%AE%B0/</id>
    <published>2023-12-15T02:21:29.658Z</published>
    <updated>2022-07-28T07:10:48.094Z</updated>
    
    <content type="html"><![CDATA[<p>在linux kernel中，对于每一个外设的IRQ都用struct irq_desc来描述，我们称之中断描述符（struct irq_desc）。</p><p>linux kernel中会有一个数据结构保存了关于所有IRQ的中断描述符信息，我们称之中断描述符DB（图中红色框图内）。</p><p>当发生中断后，首先获取触发中断的HW interupt ID，然后通过irq domain翻译成IRQ nuber，然后通过IRQ number就可以获取对应的中断描述符。</p><p><img src="https://s2.loli.net/2022/07/22/7LlN6ob2VReZ4xn.gif" alt="img"></p><p>当外设触发一次中断后，一个大概的处理过程是：</p><p>1、具体CPU architecture相关的模块会进行现场保护，然后调用machine driver对应的中断处理handler</p><p>2、machine driver对应的中断处理handler中会根据硬件的信息获取HW interrupt ID，并且通过irq domain模块翻译成IRQ number</p><p>3、调用该IRQ number对应的high level irq event handler，在这个high level的handler中，会通过和interupt controller交互，进行中断处理的flow control（处理中断的嵌套、抢占等），当然最终会遍历该中断描述符的IRQ action list，调用外设的specific handler来处理该中断</p><p>4、具体CPU architecture相关的模块会进行现场恢复。</p><h2 id="驱动申请中断API"><a href="#驱动申请中断API" class="headerlink" title="驱动申请中断API"></a>驱动申请中断API</h2><h4 id="非抢占式linux内核的实时性"><a href="#非抢占式linux内核的实时性" class="headerlink" title="非抢占式linux内核的实时性"></a>非抢占式linux内核的实时性</h4><p><img src="https://s2.loli.net/2022/07/22/E1KYn9ipasFXkxm.gif" alt="sxw"></p><ul><li><p>高优先级任务（橘色block）由于要等待外部事件（例如网络数据）而进入睡眠，调度器调度了某个低优先级的任务（紫色block）执行。</p></li><li><p>该低优先级任务欢畅的执行，直到触发了一次系统调用（例如通过read()文件接口读取磁盘上的文件等）而进入了内核态，从user space切换到了kernel space。</p></li><li><p>T0时刻，高优先级任务等待的那个中断事件发生了。</p></li><li><p>中断虽然发生了，但软件不一定立刻响应，可能由于在内核态执行的某些操作（在临界区内）不希望被外部事件打断而主动关闭了中断，这时候，中断信号没有立刻得到响应，软件仍然在内核态执行低优先级任务系统调用的代码。</p></li><li><p>在T1时刻，内核态代码由于退出临界区而打开中断，中断一旦打开，立刻跳转到了异常向量地址，interrupt handler抢占了低优先级任务的执行，进入中断上下文。</p></li><li><p>从CPU开始处理中断到具体中断服务程序被执行还需要一个分发的过程。这个期间系统要做的主要操作包括确定HW interrupt ID，确定IRQ Number，ack或者mask中断，调用中断服务程序等。</p><p>T0到T2之间的delay被称为中断延迟（Interrupt Latency），主要包括两部分，一部分是HW造成的delay（硬件的中断系统识别外部的中断事件并signal到CPU），另外一部分是软件原因（内核代码中由于要保护临界区而关闭中断引起的）。</p></li><li><p>该中断的服务程序执行完毕（在其执行过程中，T3时刻，会唤醒高优先级任务，让它从sleep状态进入runable状态），返回低优先级任务的系统调用现场，这时候并不存在一个抢占点，低优先级任务要完成系统调用之后，在返回用户空间的时候才出现抢占点。</p><p>漫长的等待之后，T4时刻，调度器调度高优先级任务执行。有一个术语叫做任务响应时间（Task Response Time）用来描述T3到T4之间的delay。</p></li></ul><h4 id="抢占式linux内核的实时性"><a href="#抢占式linux内核的实时性" class="headerlink" title="抢占式linux内核的实时性"></a>抢占式linux内核的实时性</h4><p>2.6内核和2.4内核显著的不同是提供了一个CONFIG_PREEMPT的选项，打开该选项后，linux kernel就支持了内核代码的抢占（当然不能在临界区），其行为如下：</p><p><img src="https://s2.loli.net/2022/07/22/phzSRCqKfo9NAru.gif" alt="pre"></p><p>0到T3的操作都是和上一节的描述一样的，不同的地方是在T4。</p><p>对于2.4内核，只有返回用户空间的时候才有抢占点出现，但是对于抢占式内核而言，即便是从中断上下文返回内核空间的进程上下文，只要内核代码不在临界区内，就可以发生调度，让最高优先级的任务调度执行。</p><p>在Linux kernel中，一个外设的中断处理被分成top half和bottom half，top half进行最关键，最基本的处理，而比较耗时的操作被放到bottom half（softirq、tasklet）中延迟执行。虽然bottom half被延迟执行，但始终都是先于进程执行的。为何不让这些耗时的bottom half和普通进程公平竞争呢？因此，linux kernel借鉴了RTOS的某些特性，对那些耗时的驱动interrupt handler进行线程化处理，在内核的抢占点上，让线程（无论是内核线程还是用户空间创建的线程，还是驱动的interrupt thread）在一个舞台上竞争CPU。</p><p>参考： <a class="link"   href="http://www.wowotech.net/irq_subsystem/request_threaded_irq.html" >http://www.wowotech.net/irq_subsystem/request_threaded_irq.html<i class="fas fa-external-link-alt"></i></a></p>]]></content>
    
    
      
      
    <summary type="html">&lt;p&gt;在linux kernel中，对于每一个外设的IRQ都用struct irq_desc来描述，我们称之中断描述符（struct irq_desc）。&lt;/p&gt;
&lt;p&gt;linux kernel中会有一个数据结构保存了关于所有IRQ的中断描述符信息，我们称之中断描述符DB（图中红</summary>
      
    
    
    
    <category term="Linux Kernel" scheme="https://angiean7.github.io/categories/Linux-Kernel/"/>
    
    
  </entry>
  
  <entry>
    <title>Linux-中断上下部分(top half、bottom half)</title>
    <link href="https://angiean7.github.io/2023/12/15/Linux-%E4%B8%AD%E6%96%AD%E4%B8%8A%E4%B8%8B%E6%96%87/"/>
    <id>https://angiean7.github.io/2023/12/15/Linux-%E4%B8%AD%E6%96%AD%E4%B8%8A%E4%B8%8B%E6%96%87/</id>
    <published>2023-12-15T02:21:29.658Z</published>
    <updated>2022-07-28T07:09:43.101Z</updated>
    
    <content type="html"><![CDATA[<p>问题：linux系统中对中断的处理为什么会有上下部之分呢？</p><p>中断处理程序处于中断上下文，而<strong>中断上下文是不参与调度的</strong>，这样中断上下文不能出现可能休眠的操作，因为中断上下文一旦休眠就会交出cpu，而中断上下文不参与调度，也就是交出cpu时不会保存上下文，这样一旦交出cpu就永远不会回来了。这也就决定了<strong>在中断中不能和用户空间进行数据交互</strong>，因为这种交互可能会引起休眠。</p><p>还有一点，为了尽量提高系统的响应速度，<strong>中断程序运行的时间应该尽可能短</strong>。比如说中断来临后系统在处理中断服务程序，此时有一个事件发生，如果这个事件的优先级没有此时的中断优先级高，这个事件就会等待中断处理完成，而中断处理的时间越长，该事件等待的时间就越长，因为中断是不能被调度的，这样就会导致事件的响应速度很差，也就是响应性能不好。</p><p><strong>出于对以上的考虑，linux操作系统才实现了中断的上下文。</strong></p><p>中断上下文具体有两种实现方式：</p><ul><li><strong>tasklet(小任务)</strong></li><li><strong>workqueue(工作队列)</strong></li></ul><p><strong>tasklet</strong><u>上下半部全部工作在中断上下文</u>，在执行完上半部后不会立即执行下半部，此时的空隙可以被系统调度，但一旦执行了下半部就不能被调度了；</p><p><strong>workqueue</strong>的<u>上半部工作在中断上下文，下半部工作在进程上下文</u>，进程上下文是可以被调度的。这样这两种机制就可以解决上面的响应性问题。</p><p>问题：我们在看linux中驱动的实现时对中断的处理有时候没有用到中断的上下文，有时候是通过tasklet实现的中断上下文，有时候是通过workqueue实现的中断上下文，而我们<strong>中断上下部处理的原则</strong>又是什么呢？</p><p>必须立即进行的紧急处理的极少数任务应该放在中断的上半部中，此时是屏蔽了与自己同类型的中断的，任务量少，可以迅速的完成紧急任务。</p><p>需要较少时间的中等数量的急迫任务放在tasklet的下半部，tasklet的下半部工作在中断上下文，不会被调度，但是<strong>其不会屏蔽任何中断</strong>（包括与自己上半部同类型的中断），所以并不影响其他上半部对紧急任务的处理，同时自己不会被调度也能保证自己的急迫任务被迅速完成。</p><p>需要较多时间且不急迫的大量任务放在workqueue的下半部，workqueue的下半部工作在进程上下文，参与调度。其调度优先级比较高，操作系统会尽量先完成其任务，但是当其任务时间太长，操作系统也会调度去执行其他的用户进程，从而保证其他用户进程不至于死掉</p><p><strong>总结：可能引起休眠的任务放在workqueue的下半部，因为其他的都工作在中断上下文，是不能被休眠的；在需要获得大量内存时、需要获取信号量时、阻塞操作时放在workqueue的下半部，因为获取大量内存时、获取信号量与阻塞操作时都可能会引起休眠。</strong></p>]]></content>
    
    
      
      
    <summary type="html">&lt;p&gt;问题：linux系统中对中断的处理为什么会有上下部之分呢？&lt;/p&gt;
&lt;p&gt;中断处理程序处于中断上下文，而&lt;strong&gt;中断上下文是不参与调度的&lt;/strong&gt;，这样中断上下文不能出现可能休眠的操作，因为中断上下文一旦休眠就会交出cpu，而中断上下文不参与调度，也就是交出</summary>
      
    
    
    
    <category term="Linux C" scheme="https://angiean7.github.io/categories/Linux-C/"/>
    
    
  </entry>
  
  <entry>
    <title>Linux-自旋锁与互斥锁</title>
    <link href="https://angiean7.github.io/2023/12/15/Linux-%E8%87%AA%E6%97%8B%E9%94%81%E4%B8%8E%E4%BA%92%E6%96%A5%E9%94%81/"/>
    <id>https://angiean7.github.io/2023/12/15/Linux-%E8%87%AA%E6%97%8B%E9%94%81%E4%B8%8E%E4%BA%92%E6%96%A5%E9%94%81/</id>
    <published>2023-12-15T02:21:29.658Z</published>
    <updated>2022-07-28T07:37:21.758Z</updated>
    
    <content type="html"><![CDATA[<h1 id="自旋锁和互斥锁的区别"><a href="#自旋锁和互斥锁的区别" class="headerlink" title="自旋锁和互斥锁的区别"></a>自旋锁和互斥锁的区别</h1><p>POSIX threads(简称Pthreads)是在多核平台上进行并行编程的一套API。线程同步是并行编程中非常重要的通讯手段，其中最典型的应用就是用Pthreads提供的锁机制(lock)来对多个线程之间的共享临界区(Critical Section)进行保护(另一种常用的同步机制是barrier)。</p><p>Pthreads提供了多种锁机制：</p><ul><li>Mutex(互斥量)：pthread_mutex_t</li><li>Spin lock(自旋锁): pthread_spin_t</li><li>Condition Variable(条件变量): pthread_cond_t</li><li>Read/Write lock(读写锁)：pthread_rwlock_t</li></ul><p>Pthreads提供的Mutex锁操作相关的API主要有：</p><ul><li>pthread_mutex_lock(pthread_mutex_t *mutex);</li><li>pthread_mutex_trylock(pthread_mutex_t *mutex);</li><li>pthread_mutex_unlock(pthread_mutex_t *mutex);</li></ul><p>Pthreads提供的Spin Lock锁操作相关的API主要有：</p><ul><li>pthread_spin_lock(pthread_spinlock_t *lock);</li><li>pthread_spin_trylock(pthread_spinlock_t *lock);</li><li>pthread_spin_unlock(pthread_spinlock_t *lock);</li></ul><p>从实现原理上来讲，<strong>Mutex（互斥锁）属于sleep-waiting类型的锁</strong>。例如在一个双核的机器上有两个线程（线程A和线程B）,它们分别运行在Core0和Core1上。假设线程A想要通过pthread_mutex_lock操作去得到一个临界区的锁，而此时这个锁正被线程B所持有，那么线程A就会被阻塞，</p><p>Core0会在此时进行上下文切换(Context Switch)将线程A置于等待队列中，此时Core0就可以运行其它的任务而不必进行忙等待。而<strong>Spin lock（自旋锁）</strong>则不然，它属于<strong>busy-waiting类型的锁</strong>，如果线程A是使用pthread_spin_lock操作去请求锁，那么线程A就会一直在Core0上进行忙等待并不停的进行锁请求，直到得到这个锁为止。</p><p><strong>自旋锁（Spin lock）</strong></p><p>自旋锁与<a class="link"   href="https://so.csdn.net/so/search?q=互斥锁&spm=1001.2101.3001.7020" >互斥锁<i class="fas fa-external-link-alt"></i></a>有点类似，只是自旋锁不会引起调用者睡眠，如果自旋锁已经被别的执行单元保持，调用者就一直循环在那里看是否该自旋锁的保持者已经释放了锁，<strong>“自旋锁”的作用是为了解决某项资源的互斥使用。因为自旋锁不会引起调用者睡眠，所以自旋锁的效率远高于互斥锁。</strong></p><p>自旋锁的不足之处：</p><p><strong>自旋锁一直占用着CPU，他在未获得锁的情况下，一直运行（自旋），所以占用着CPU，如果不能在很短的时间内获得锁，这无疑会使CPU效率降低。</strong></p><p>在用自旋锁时有可能造成死锁，当递归调用时有可能造成死锁，调用有些其他函数也可能造成死锁，如 copy_to_user()、copy_from_user()、kmalloc()等。</p><p>因此我们要慎重使用自旋锁，自旋锁只有在内核可抢占式或SMP的情况下才真正需要，在单CPU且不可抢占式的内核下，自旋锁的操作为空操作。自旋锁适用于锁使用者保持锁时间比较短的情况下。</p><h2 id="自旋锁-原理"><a href="#自旋锁-原理" class="headerlink" title="自旋锁-原理"></a>自旋锁-原理</h2><p>跟<a class="link"   href="https://baike.so.com/doc/6150631-6363825.html" >互斥锁<i class="fas fa-external-link-alt"></i></a>一样，一个执行单元要想访问被自旋锁保护的共享资源，必须<strong>先得到锁，在访问完共享资源后，必须释放锁</strong>。如果在获取自旋锁时，没有任何执行单元保持该锁，那么将立即得到锁;如果在获取自旋锁时锁已经有保持者，那么获取锁操作将自旋在那里，直到该自旋锁的保持者释放了锁。由此我们可以看出，自旋锁是一种比较低级的保护数据结构或代码片段的原始方式，这种锁可能存在两个问题:</p><p>1、<a class="link"   href="https://baike.so.com/doc/414521-439063.html" >死锁<i class="fas fa-external-link-alt"></i></a>。<strong>试图递归地获得自旋锁必然会引起死锁</strong>:递归程序的持有实例在第二个实例循环，以试图获得相同自旋锁时，不会释放此自旋锁。</p><p>在递归程序中使用自旋锁应遵守下列策略:</p><p>递归程序决不能在持有自旋锁时调用它自己，也决不能在<a class="link"   href="https://baike.so.com/doc/6115126-6328268.html" >递归调用<i class="fas fa-external-link-alt"></i></a>时试图获得相同的自旋锁。此外如果一个进程已经将资源锁定，那么，即使其它申请这个资源的进程不停地疯狂”自旋”,也无法获得资源，从而进入死循环。</p><p>2、过多占用cpu资源。如果不加限制，由于申请者一直在循环等待，因此自旋锁在锁定的时候,如果不成功,不会睡眠,会持续的尝试,单cpu的时候自旋锁会让其它process动不了. 因此，一般自旋锁实现会有一个参数限定最多持续尝试次数. 超出后, 自旋锁放弃当前time slice. 等下一次机会</p><p>由此可见，<strong>自旋锁</strong>比较<strong>适用于</strong>锁使用者<strong>保持锁时间比较短</strong>的情况。正是由于自旋锁使用者一般保持锁时间非常短，因此选择自旋而不是睡眠是非常必要的，自旋锁的效率远高于<a class="link"   href="https://baike.so.com/doc/6150631-6363825.html" >互斥锁<i class="fas fa-external-link-alt"></i></a>。<a class="link"   href="https://baike.so.com/doc/6799211-7016022.html" >信号量<i class="fas fa-external-link-alt"></i></a>和读写信号量适合于保持时间较长的情况，它们会导致调用者睡眠，因此只能在<a class="link"   href="https://baike.so.com/doc/2315046-2448796.html" >进程上下文<i class="fas fa-external-link-alt"></i></a>使用，而自旋锁适合于保持时间非常短的情况，它可以在任何上下文使用。如果被保护的共享资源只在进程上下文访问，使用信号量保护该共享资源非常合适，如果对共享资源的访问时间非常短，自旋锁也可以。但是如果被保护的共享资源需要在中断上下文访问(包括底半部即<a class="link"   href="https://baike.so.com/doc/4973549-5196235.html" >中断处理<i class="fas fa-external-link-alt"></i></a>句柄和顶半部即<a class="link"   href="https://baike.so.com/doc/7715429-7989524.html" >软中断<i class="fas fa-external-link-alt"></i></a>)，就必须使用自旋锁。<strong>自旋锁保持期间是抢占失效的，而信号量和读写信号量保持期间是可以被抢占的</strong>。自旋锁只有在<a class="link"   href="https://baike.so.com/doc/665564-704577.html" >内核<i class="fas fa-external-link-alt"></i></a>可抢占或<a class="link"   href="https://baike.so.com/doc/4522250-4732301.html" >SMP<i class="fas fa-external-link-alt"></i></a>(多处理器)的情况下才真正需要，在单CPU且不可抢占的内核下，自旋锁的所有操作都是空操作，</p><h4 id="互斥锁与自旋锁的区别"><a href="#互斥锁与自旋锁的区别" class="headerlink" title="互斥锁与自旋锁的区别"></a>互斥锁与自旋锁的区别</h4><p>(1)、互斥锁mutex：独占锁；开销大</p><p>pthread_mutex_lock(pthread_mutex_t *mutex);</p><p>pthread_mutex_unlock(pthread_mutex_t *mutex);</p><p>(2)、自旋锁spin lock：轻量级的锁，开销小；适用于短时间内对锁的使用。</p><p>如果自旋锁已经被其他的执行单元保持，调用者就一直循环在那里判断该自旋锁是否被释放</p><p>pthread_spin_lock(pthread_spinlock_t *lock);</p><p>pthread_spin_unlock(pthread_spinlock_t *lock);</p><p>注意：对于spin lock，如果递归调用过深，会导致死锁。</p>]]></content>
    
    
      
      
    <summary type="html">&lt;h1 id=&quot;自旋锁和互斥锁的区别&quot;&gt;&lt;a href=&quot;#自旋锁和互斥锁的区别&quot; class=&quot;headerlink&quot; title=&quot;自旋锁和互斥锁的区别&quot;&gt;&lt;/a&gt;自旋锁和互斥锁的区别&lt;/h1&gt;&lt;p&gt;POSIX threads(简称Pthreads)是在多核平台上进行并行编程</summary>
      
    
    
    
    <category term="Linux C" scheme="https://angiean7.github.io/categories/Linux-C/"/>
    
    
  </entry>
  
  <entry>
    <title>Linux-create a countdown timer thread</title>
    <link href="https://angiean7.github.io/2023/12/15/Linux%E5%BB%BA%E7%AB%8B%E8%AE%A1%E6%97%B6%E5%99%A8%E7%BA%BF%E7%A8%8B/"/>
    <id>https://angiean7.github.io/2023/12/15/Linux%E5%BB%BA%E7%AB%8B%E8%AE%A1%E6%97%B6%E5%99%A8%E7%BA%BF%E7%A8%8B/</id>
    <published>2023-12-15T02:21:29.658Z</published>
    <updated>2022-07-28T07:09:57.277Z</updated>
    
    <content type="html"><![CDATA[<h1 id="Linux-create-a-countdown-timer-thread"><a href="#Linux-create-a-countdown-timer-thread" class="headerlink" title="Linux create a countdown timer thread"></a>Linux create a countdown timer thread</h1><p>Create an independent countdown timer thread, the program ends automatically when the countdown is over. </p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br></pre></td><td class="code"><pre><span class="line"><span class="type">void</span> *<span class="title function_">check_timeout</span><span class="params">(<span class="type">void</span> *arg)</span></span><br><span class="line">&#123;</span><br><span class="line"><span class="type">int</span> second_now = <span class="number">0</span>;</span><br><span class="line"><span class="type">int</span> count = <span class="number">0</span>;</span><br><span class="line"></span><br><span class="line"><span class="comment">//Get current time and second</span></span><br><span class="line"><span class="keyword">while</span> (<span class="number">1</span>)</span><br><span class="line">&#123;</span><br><span class="line">count++;</span><br><span class="line">sleep(<span class="number">1</span>);</span><br><span class="line"><span class="keyword">if</span>(count &gt;= TIMEOUT_CNT)</span><br><span class="line">&#123;</span><br><span class="line"><span class="built_in">printf</span>(<span class="string">&quot;Timeout!\r\n&quot;</span>);</span><br><span class="line">            <span class="comment">// kill specific proccess</span></span><br><span class="line">system(<span class="string">&quot;ps | grep busybox | grep -v grep | awk &#x27;&#123;print $1&#125;&#x27; | xargs kill -s 9&quot;</span>);</span><br><span class="line"><span class="built_in">exit</span>(<span class="number">0</span>);</span><br><span class="line">&#125;</span><br><span class="line">        </span><br><span class="line">        <span class="comment">// if websocket received data, clear count</span></span><br><span class="line"><span class="keyword">if</span>((<span class="built_in">strlen</span>(idata) &gt;= <span class="number">1</span>))</span><br><span class="line">&#123;</span><br><span class="line">count = <span class="number">0</span>;</span><br><span class="line">&#125;</span><br><span class="line">&#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">//creat pthread to check time</span></span><br><span class="line"><span class="type">pthread_t</span> thread_check_time;</span><br><span class="line">pthread_create(&amp;thread_check_time, <span class="literal">NULL</span>, &amp;check_timeout, <span class="literal">NULL</span>);</span><br><span class="line"></span><br></pre></td></tr></table></figure>]]></content>
    
    
      
      
    <summary type="html">&lt;h1 id=&quot;Linux-create-a-countdown-timer-thread&quot;&gt;&lt;a href=&quot;#Linux-create-a-countdown-timer-thread&quot; class=&quot;headerlink&quot; title=&quot;Linux create a cou</summary>
      
    
    
    
    <category term="Linux C" scheme="https://angiean7.github.io/categories/Linux-C/"/>
    
    
  </entry>
  
  <entry>
    <title>Linux使用串口工具minicom</title>
    <link href="https://angiean7.github.io/2023/12/15/Linux%E4%BD%BF%E7%94%A8%E4%B8%B2%E5%8F%A3%E5%B7%A5%E5%85%B7/"/>
    <id>https://angiean7.github.io/2023/12/15/Linux%E4%BD%BF%E7%94%A8%E4%B8%B2%E5%8F%A3%E5%B7%A5%E5%85%B7/</id>
    <published>2023-12-15T02:21:29.658Z</published>
    <updated>2022-07-28T07:12:32.446Z</updated>
    
    <content type="html"><![CDATA[<h1 id="Linux使用串口工具"><a href="#Linux使用串口工具" class="headerlink" title="Linux使用串口工具"></a>Linux使用串口工具</h1><p>sudo apt-get install minicom</p><p>安装好之后minicom运行软件</p><p>按下ctrl+a然后再按z打开帮助</p><p>按O进入配置页面</p><p>A serial port setup中设置/dev/ttyS0</p><p>E 115200 8N1</p><p>F No（不设置这个的话输入不了）</p><p>G No</p><p>设置好之后返回，选择Save setup as dfl</p><p>然后重启minicom</p>]]></content>
    
    
      
      
    <summary type="html">&lt;h1 id=&quot;Linux使用串口工具&quot;&gt;&lt;a href=&quot;#Linux使用串口工具&quot; class=&quot;headerlink&quot; title=&quot;Linux使用串口工具&quot;&gt;&lt;/a&gt;Linux使用串口工具&lt;/h1&gt;&lt;p&gt;sudo apt-get install minicom&lt;/p&gt;
&lt;</summary>
      
    
    
    
    <category term="环境" scheme="https://angiean7.github.io/categories/%E7%8E%AF%E5%A2%83/"/>
    
    
  </entry>
  
  <entry>
    <title>QT-个人笔记</title>
    <link href="https://angiean7.github.io/2023/12/15/QT%E7%AC%94%E8%AE%B0/"/>
    <id>https://angiean7.github.io/2023/12/15/QT%E7%AC%94%E8%AE%B0/</id>
    <published>2023-12-15T02:21:29.658Z</published>
    <updated>2022-07-28T07:13:05.108Z</updated>
    
    <content type="html"><![CDATA[<h1 id="QT-个人笔记"><a href="#QT-个人笔记" class="headerlink" title="QT-个人笔记"></a>QT-个人笔记</h1><ol><li>使combobox選項失效ui-&gt;comboBox_ddr_select-&gt;setItemData(offset, 0, Qt::UserRole - 1);</li></ol>]]></content>
    
    
      
      
    <summary type="html">&lt;h1 id=&quot;QT-个人笔记&quot;&gt;&lt;a href=&quot;#QT-个人笔记&quot; class=&quot;headerlink&quot; title=&quot;QT-个人笔记&quot;&gt;&lt;/a&gt;QT-个人笔记&lt;/h1&gt;&lt;ol&gt;
&lt;li&gt;使combobox選項失效ui-&amp;gt;comboBox_ddr_select-&amp;gt;</summary>
      
    
    
    
    <category term="QT" scheme="https://angiean7.github.io/categories/QT/"/>
    
    
  </entry>
  
  <entry>
    <title>Xilinx 中断函数配置</title>
    <link href="https://angiean7.github.io/2023/12/15/Xilinx%20%E4%B8%AD%E6%96%AD%E5%87%BD%E6%95%B0%E9%85%8D%E7%BD%AE/"/>
    <id>https://angiean7.github.io/2023/12/15/Xilinx%20%E4%B8%AD%E6%96%AD%E5%87%BD%E6%95%B0%E9%85%8D%E7%BD%AE/</id>
    <published>2023-12-15T02:21:29.658Z</published>
    <updated>2022-08-31T09:02:07.683Z</updated>
    
    <content type="html"><![CDATA[<h1 id="Xilinx-中断函数配置"><a href="#Xilinx-中断函数配置" class="headerlink" title="Xilinx 中断函数配置"></a>Xilinx 中断函数配置</h1><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br><span class="line">122</span><br><span class="line">123</span><br><span class="line">124</span><br><span class="line">125</span><br><span class="line">126</span><br><span class="line">127</span><br><span class="line">128</span><br><span class="line">129</span><br><span class="line">130</span><br><span class="line">131</span><br><span class="line">132</span><br><span class="line">133</span><br><span class="line">134</span><br><span class="line">135</span><br><span class="line">136</span><br><span class="line">137</span><br><span class="line">138</span><br><span class="line">139</span><br><span class="line">140</span><br><span class="line">141</span><br><span class="line">142</span><br><span class="line">143</span><br><span class="line">144</span><br><span class="line">145</span><br><span class="line">146</span><br><span class="line">147</span><br><span class="line">148</span><br><span class="line">149</span><br><span class="line">150</span><br><span class="line">151</span><br><span class="line">152</span><br><span class="line">153</span><br><span class="line">154</span><br><span class="line">155</span><br><span class="line">156</span><br><span class="line">157</span><br><span class="line">158</span><br><span class="line">159</span><br><span class="line">160</span><br><span class="line">161</span><br><span class="line">162</span><br><span class="line">163</span><br><span class="line">164</span><br><span class="line">165</span><br><span class="line">166</span><br><span class="line">167</span><br><span class="line">168</span><br><span class="line">169</span><br><span class="line">170</span><br><span class="line">171</span><br><span class="line">172</span><br><span class="line">173</span><br><span class="line">174</span><br><span class="line">175</span><br><span class="line">176</span><br><span class="line">177</span><br><span class="line">178</span><br><span class="line">179</span><br><span class="line">180</span><br><span class="line">181</span><br><span class="line">182</span><br><span class="line">183</span><br><span class="line">184</span><br><span class="line">185</span><br><span class="line">186</span><br><span class="line">187</span><br><span class="line">188</span><br><span class="line">189</span><br><span class="line">190</span><br><span class="line">191</span><br><span class="line">192</span><br><span class="line">193</span><br><span class="line">194</span><br><span class="line">195</span><br><span class="line">196</span><br><span class="line">197</span><br><span class="line">198</span><br><span class="line">199</span><br><span class="line">200</span><br><span class="line">201</span><br><span class="line">202</span><br><span class="line">203</span><br><span class="line">204</span><br><span class="line">205</span><br><span class="line">206</span><br><span class="line">207</span><br><span class="line">208</span><br><span class="line">209</span><br><span class="line">210</span><br><span class="line">211</span><br><span class="line">212</span><br><span class="line">213</span><br><span class="line">214</span><br><span class="line">215</span><br><span class="line">216</span><br><span class="line">217</span><br><span class="line">218</span><br><span class="line">219</span><br><span class="line">220</span><br><span class="line">221</span><br><span class="line">222</span><br><span class="line">223</span><br><span class="line">224</span><br><span class="line">225</span><br><span class="line">226</span><br><span class="line">227</span><br><span class="line">228</span><br><span class="line">229</span><br><span class="line">230</span><br><span class="line">231</span><br><span class="line">232</span><br><span class="line">233</span><br><span class="line">234</span><br><span class="line">235</span><br><span class="line">236</span><br><span class="line">237</span><br><span class="line">238</span><br><span class="line">239</span><br><span class="line">240</span><br><span class="line">241</span><br><span class="line">242</span><br><span class="line">243</span><br><span class="line">244</span><br><span class="line">245</span><br><span class="line">246</span><br><span class="line">247</span><br><span class="line">248</span><br><span class="line">249</span><br><span class="line">250</span><br><span class="line">251</span><br><span class="line">252</span><br><span class="line">253</span><br><span class="line">254</span><br><span class="line">255</span><br><span class="line">256</span><br><span class="line">257</span><br><span class="line">258</span><br><span class="line">259</span><br><span class="line">260</span><br><span class="line">261</span><br><span class="line">262</span><br><span class="line">263</span><br><span class="line">264</span><br><span class="line">265</span><br><span class="line">266</span><br><span class="line">267</span><br><span class="line">268</span><br><span class="line">269</span><br><span class="line">270</span><br><span class="line">271</span><br><span class="line">272</span><br><span class="line">273</span><br><span class="line">274</span><br><span class="line">275</span><br><span class="line">276</span><br><span class="line">277</span><br><span class="line">278</span><br><span class="line">279</span><br><span class="line">280</span><br><span class="line">281</span><br><span class="line">282</span><br><span class="line">283</span><br><span class="line">284</span><br><span class="line">285</span><br><span class="line">286</span><br><span class="line">287</span><br><span class="line">288</span><br><span class="line">289</span><br><span class="line">290</span><br><span class="line">291</span><br><span class="line">292</span><br><span class="line">293</span><br><span class="line">294</span><br><span class="line">295</span><br><span class="line">296</span><br><span class="line">297</span><br><span class="line">298</span><br><span class="line">299</span><br><span class="line">300</span><br><span class="line">301</span><br><span class="line">302</span><br><span class="line">303</span><br><span class="line">304</span><br><span class="line">305</span><br><span class="line">306</span><br><span class="line">307</span><br><span class="line">308</span><br><span class="line">309</span><br><span class="line">310</span><br><span class="line">311</span><br><span class="line">312</span><br><span class="line">313</span><br><span class="line">314</span><br><span class="line">315</span><br><span class="line">316</span><br><span class="line">317</span><br><span class="line">318</span><br><span class="line">319</span><br><span class="line">320</span><br><span class="line">321</span><br><span class="line">322</span><br><span class="line">323</span><br><span class="line">324</span><br><span class="line">325</span><br><span class="line">326</span><br><span class="line">327</span><br><span class="line">328</span><br><span class="line">329</span><br><span class="line">330</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/****************************************************************************</span></span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment">* Copyright (C) 2010 - 2020 Xilinx, Inc.  All rights reserved.</span></span><br><span class="line"><span class="comment">* SPDX-License-Identifier: MIT</span></span><br><span class="line"><span class="comment">  ******************************************************************************/</span></span><br><span class="line"></span><br><span class="line"><span class="comment">/******************************************************************************/</span></span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment">*</span></span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment">* @file xscugic_example.c</span></span><br><span class="line"><span class="comment">  *</span></span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment">* This file contains a design example using the Interrupt Controller driver</span></span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment">* (XScuGic) and hardware device. Please reference other device driver examples</span></span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment">* to see more examples of how the intc and interrupts can be used by a software</span></span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment">* application.</span></span><br><span class="line"><span class="comment">  *</span></span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment">* @note</span></span><br><span class="line"><span class="comment">  *</span></span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment">* None</span></span><br><span class="line"><span class="comment">  *</span></span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment">* &lt;pre&gt;</span></span><br><span class="line"><span class="comment">  *</span></span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment">* MODIFICATION HISTORY:</span></span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment">* Ver   Who  Date     Changes</span></span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment">* ----- ---- -------- ----------------------------------------------------</span></span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment">* 1.00a drg  01/18/10 First release</span></span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment">* &lt;/pre&gt;</span></span><br><span class="line"><span class="comment">  ******************************************************************************/</span></span><br><span class="line"></span><br><span class="line"><span class="comment">/***************************** Include Files *********************************/</span></span><br><span class="line"></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;stdio.h&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;stdlib.h&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&quot;xil_io.h&quot;</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&quot;xil_exception.h&quot;</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&quot;xparameters.h&quot;</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&quot;xil_cache.h&quot;</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&quot;xil_printf.h&quot;</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&quot;xil_types.h&quot;</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&quot;xscugic.h&quot;</span></span></span><br><span class="line"></span><br><span class="line"><span class="comment">/************************** Constant Definitions *****************************/</span></span><br><span class="line"></span><br><span class="line"><span class="comment">/*</span></span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment"> * The following constants map to the XPAR parameters created in the</span></span><br><span class="line"><span class="comment"> * xparameters.h file. They are defined here such that a user can easily</span></span><br><span class="line"><span class="comment"> * change all the needed parameters in one place.</span></span><br><span class="line"><span class="comment">   */</span></span><br><span class="line">   <span class="meta">#<span class="keyword">define</span> INTC_DEVICE_IDXPAR_SCUGIC_0_DEVICE_ID</span></span><br><span class="line">   <span class="meta">#<span class="keyword">define</span> INTC_DEVICE_INT_ID0x0E</span></span><br><span class="line"></span><br><span class="line"><span class="comment">/**************************** Type Definitions *******************************/</span></span><br><span class="line"></span><br><span class="line"><span class="comment">/***************** Macros (Inline Functions) Definitions *********************/</span></span><br><span class="line"></span><br><span class="line"><span class="comment">/************************** Function Prototypes ******************************/</span></span><br><span class="line"><span class="type">int</span> <span class="title function_">ScuGicExample</span><span class="params">(u16 DeviceId)</span>;</span><br><span class="line"><span class="type">int</span> <span class="title function_">SetUpInterruptSystem</span><span class="params">(XScuGic *XScuGicInstancePtr)</span>;</span><br><span class="line"><span class="type">void</span> <span class="title function_">DeviceDriverHandler</span><span class="params">(<span class="type">void</span> *CallbackRef)</span>;</span><br><span class="line"></span><br><span class="line"><span class="comment">/************************** Variable Definitions *****************************/</span></span><br><span class="line"></span><br><span class="line">XScuGic InterruptController;      <span class="comment">/* Instance of the Interrupt Controller */</span></span><br><span class="line"><span class="type">static</span> XScuGic_Config *GicConfig;    <span class="comment">/* The configuration parameters of the</span></span><br><span class="line"><span class="comment">                                       controller */</span></span><br><span class="line"></span><br><span class="line"><span class="comment">/*</span></span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment"> * Create a shared variable to be used by the main thread of processing and</span></span><br><span class="line"><span class="comment"> * the interrupt processing</span></span><br><span class="line"><span class="comment">   */</span></span><br><span class="line">   <span class="keyword">volatile</span> <span class="type">static</span> <span class="type">int</span> InterruptProcessed = FALSE;</span><br><span class="line"></span><br><span class="line"><span class="type">static</span> <span class="type">void</span> <span class="title function_">AssertPrint</span><span class="params">(<span class="type">const</span> char8 *FilenamePtr, s32 LineNumber)</span>&#123;</span><br><span class="line">xil_printf(<span class="string">&quot;ASSERT: File Name: %s &quot;</span>, FilenamePtr);</span><br><span class="line">xil_printf(<span class="string">&quot;Line Number: %d\r\n&quot;</span>,LineNumber);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">/*****************************************************************************/</span></span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment">*</span></span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment">* This is the main function for the Interrupt Controller example.</span></span><br><span class="line"><span class="comment">  *</span></span><br><span class="line"><span class="comment">* @paramNone.</span></span><br><span class="line"><span class="comment">  *</span></span><br><span class="line"><span class="comment">* @returnXST_SUCCESS to indicate success, otherwise XST_FAILURE.</span></span><br><span class="line"><span class="comment">  *</span></span><br><span class="line"><span class="comment">* @noteNone.</span></span><br><span class="line"><span class="comment">  *</span></span><br><span class="line"><span class="comment">  ****************************************************************************/</span></span><br><span class="line">  <span class="type">int</span> <span class="title function_">main</span><span class="params">(<span class="type">void</span>)</span></span><br><span class="line">  &#123;</span><br><span class="line">  <span class="type">int</span> Status;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment">/*</span></span><br><span class="line"><span class="comment"> * Setup an assert call back to get some info if we assert.</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line">Xil_AssertSetCallback(AssertPrint);</span><br><span class="line"></span><br><span class="line">xil_printf(<span class="string">&quot;GIC Example Test\r\n&quot;</span>);</span><br><span class="line"></span><br><span class="line"><span class="comment">/*</span></span><br><span class="line"><span class="comment"> *  Run the Gic example , specify the Device ID generated in xparameters.h</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line">Status = ScuGicExample(INTC_DEVICE_ID);</span><br><span class="line"><span class="keyword">if</span> (Status != XST_SUCCESS) &#123;</span><br><span class="line">xil_printf(<span class="string">&quot;GIC Example Test Failed\r\n&quot;</span>);</span><br><span class="line"><span class="keyword">return</span> XST_FAILURE;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">xil_printf(<span class="string">&quot;Successfully ran GIC Example Test\r\n&quot;</span>);</span><br><span class="line"><span class="keyword">return</span> XST_SUCCESS;</span><br><span class="line"></span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">/*****************************************************************************/</span></span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment">*</span></span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment">* This function is an example of how to use the interrupt controller driver</span></span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment">* (XScuGic) and the hardware device.  This function is designed to</span></span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment">* work without any hardware devices to cause interrupts. It may not return</span></span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment">* if the interrupt controller is not properly connected to the processor in</span></span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment">* either software or hardware.</span></span><br><span class="line"><span class="comment">  *</span></span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment">* This function relies on the fact that the interrupt controller hardware</span></span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment">* has come out of the reset state such that it will allow interrupts to be</span></span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment">* simulated by the software.</span></span><br><span class="line"><span class="comment">  *</span></span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment">* @paramDeviceId is Device ID of the Interrupt Controller Device,</span></span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment">* typically XPAR_&lt;INTC_instance&gt;_DEVICE_ID value from</span></span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment">* xparameters.h</span></span><br><span class="line"><span class="comment">  *</span></span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment">* @returnXST_SUCCESS to indicate success, otherwise XST_FAILURE</span></span><br><span class="line"><span class="comment">  *</span></span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment">* @noteNone.</span></span><br><span class="line"><span class="comment">  *</span></span><br><span class="line"><span class="comment">  ******************************************************************************/</span></span><br><span class="line">  <span class="type">int</span> <span class="title function_">ScuGicExample</span><span class="params">(u16 DeviceId)</span></span><br><span class="line">  &#123;</span><br><span class="line">  <span class="type">int</span> Status;</span><br><span class="line"></span><br><span class="line">  <span class="comment">/*</span></span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment">   * Initialize the interrupt controller driver so that it is ready to</span></span><br><span class="line"><span class="comment">   * use.</span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line">     GicConfig = XScuGic_LookupConfig(DeviceId);</span><br><span class="line">     <span class="keyword">if</span> (<span class="literal">NULL</span> == GicConfig) &#123;</span><br><span class="line">     <span class="keyword">return</span> XST_FAILURE;</span><br><span class="line">     &#125;</span><br><span class="line"></span><br><span class="line">  Status = XScuGic_CfgInitialize(&amp;InterruptController, GicConfig,</span><br><span class="line">  GicConfig-&gt;CpuBaseAddress);</span><br><span class="line">  <span class="keyword">if</span> (Status != XST_SUCCESS) &#123;</span><br><span class="line">  <span class="keyword">return</span> XST_FAILURE;</span><br><span class="line">  &#125;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment">/*</span></span><br><span class="line"><span class="comment"> * Perform a self-test to ensure that the hardware was built</span></span><br><span class="line"><span class="comment"> * correctly</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line">Status = XScuGic_SelfTest(&amp;InterruptController);</span><br><span class="line"><span class="keyword">if</span> (Status != XST_SUCCESS) &#123;</span><br><span class="line"><span class="keyword">return</span> XST_FAILURE;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment">/*</span></span><br><span class="line"><span class="comment"> * Setup the Interrupt System</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line">Status = SetUpInterruptSystem(&amp;InterruptController);</span><br><span class="line"><span class="keyword">if</span> (Status != XST_SUCCESS) &#123;</span><br><span class="line"><span class="keyword">return</span> XST_FAILURE;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">/*</span></span><br><span class="line"><span class="comment"> * Connect a device driver handler that will be called when an</span></span><br><span class="line"><span class="comment"> * interrupt for the device occurs, the device driver handler performs</span></span><br><span class="line"><span class="comment"> * the specific interrupt processing for the device</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line">Status = XScuGic_Connect(&amp;InterruptController, INTC_DEVICE_INT_ID,</span><br><span class="line">   (Xil_ExceptionHandler)DeviceDriverHandler,</span><br><span class="line">   (<span class="type">void</span> *)&amp;InterruptController);</span><br><span class="line"></span><br><span class="line"><span class="keyword">if</span> (Status != XST_SUCCESS) &#123;</span><br><span class="line"><span class="keyword">return</span> XST_FAILURE;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">/*</span></span><br><span class="line"><span class="comment"> * Enable the interrupt for the device and then cause (simulate) an</span></span><br><span class="line"><span class="comment"> * interrupt so the handlers will be called</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line">XScuGic_Enable(&amp;InterruptController, INTC_DEVICE_INT_ID);</span><br><span class="line"></span><br><span class="line"><span class="comment">/*</span></span><br><span class="line"><span class="comment"> *  Simulate the Interrupt</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line">Status = XScuGic_SoftwareIntr(&amp;InterruptController,</span><br><span class="line">INTC_DEVICE_INT_ID,</span><br><span class="line">XSCUGIC_SPI_CPU0_MASK);</span><br><span class="line"><span class="keyword">if</span> (Status != XST_SUCCESS) &#123;</span><br><span class="line"><span class="keyword">return</span> XST_FAILURE;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">/*</span></span><br><span class="line"><span class="comment"> * Wait for the interrupt to be processed, if the interrupt does not</span></span><br><span class="line"><span class="comment"> * occur this loop will wait forever</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">while</span> (<span class="number">1</span>) &#123;</span><br><span class="line"><span class="comment">/*</span></span><br><span class="line"><span class="comment"> * If the interrupt occurred which is indicated by the global</span></span><br><span class="line"><span class="comment"> * variable which is set in the device driver handler, then</span></span><br><span class="line"><span class="comment"> * stop waiting</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">if</span> (InterruptProcessed) &#123;</span><br><span class="line"><span class="keyword">break</span>;</span><br><span class="line">&#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">return</span> XST_SUCCESS;</span><br><span class="line"></span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">/******************************************************************************/</span></span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment">*</span></span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment">* This function connects the interrupt handler of the interrupt controller to</span></span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment">* the processor.  This function is separate to allow it to be customized for</span></span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment">* each application.  Each processor or RTOS may require unique processing to</span></span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment">* connect the interrupt handler.</span></span><br><span class="line"><span class="comment">  *</span></span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment">* @paramXScuGicInstancePtr is the instance of the interrupt controller</span></span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment">* that needs to be worked on.</span></span><br><span class="line"><span class="comment">  *</span></span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment">* @returnNone.</span></span><br><span class="line"><span class="comment">  *</span></span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment">* @noteNone.</span></span><br><span class="line"><span class="comment">  *</span></span><br><span class="line"><span class="comment">  ****************************************************************************/</span></span><br><span class="line">  <span class="type">int</span> <span class="title function_">SetUpInterruptSystem</span><span class="params">(XScuGic *XScuGicInstancePtr)</span></span><br><span class="line">  &#123;</span><br><span class="line"></span><br><span class="line">  <span class="comment">/*</span></span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment">   * Connect the interrupt controller interrupt handler to the hardware</span></span><br><span class="line"><span class="comment">   * interrupt handling logic in the ARM processor.</span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line">     Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT,</span><br><span class="line">     (Xil_ExceptionHandler) XScuGic_InterruptHandler,</span><br><span class="line">     XScuGicInstancePtr);</span><br><span class="line"></span><br><span class="line">  <span class="comment">/*</span></span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment">   * Enable interrupts in the ARM</span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line">     Xil_ExceptionEnable();</span><br><span class="line"></span><br><span class="line">  <span class="keyword">return</span> XST_SUCCESS;</span><br><span class="line">  &#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">/******************************************************************************/</span></span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment">*</span></span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment">* This function is designed to look like an interrupt handler in a device</span></span><br><span class="line"><span class="comment">* driver. This is typically a 2nd level handler that is called from the</span></span><br><span class="line"><span class="comment">* interrupt controller interrupt handler.  This handler would typically</span></span><br><span class="line"><span class="comment">* perform device specific processing such as reading and writing the registers</span></span><br><span class="line"><span class="comment">* of the device to clear the interrupt condition and pass any data to an</span></span><br><span class="line"><span class="comment">* application using the device driver.  Many drivers already provide this</span></span><br><span class="line"><span class="comment">* handler and the user is not required to create it.</span></span><br><span class="line"><span class="comment">  *</span></span><br><span class="line"><span class="comment">* @paramCallbackRef is passed back to the device driver&#x27;s interrupt</span></span><br><span class="line"><span class="comment">* handler by the XScuGic driver.  It was given to the XScuGic</span></span><br><span class="line"><span class="comment">* driver in the XScuGic_Connect() function call.  It is typically</span></span><br><span class="line"><span class="comment">* a pointer to the device driver instance variable.</span></span><br><span class="line"><span class="comment">* In this example, we do not care about the callback</span></span><br><span class="line"><span class="comment">* reference, so we passed it a 0 when connecting the handler to</span></span><br><span class="line"><span class="comment">* the XScuGic driver and we make no use of it here.</span></span><br><span class="line"><span class="comment">  *</span></span><br><span class="line"><span class="comment">* @returnNone.</span></span><br><span class="line"><span class="comment">  *</span></span><br><span class="line"><span class="comment">* @noteNone.</span></span><br><span class="line"><span class="comment">  *</span></span><br><span class="line"><span class="comment">  ****************************************************************************/</span></span><br><span class="line">  <span class="type">void</span> <span class="title function_">DeviceDriverHandler</span><span class="params">(<span class="type">void</span> *CallbackRef)</span></span><br><span class="line">  &#123;</span><br><span class="line">  <span class="comment">/*</span></span><br><span class="line"><span class="comment">   * Indicate the interrupt has been processed using a shared variable</span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line">     InterruptProcessed = TRUE;</span><br><span class="line">     &#125;</span><br></pre></td></tr></table></figure>]]></content>
    
    
      
      
    <summary type="html">&lt;h1 id=&quot;Xilinx-中断函数配置&quot;&gt;&lt;a href=&quot;#Xilinx-中断函数配置&quot; class=&quot;headerlink&quot; title=&quot;Xilinx 中断函数配置&quot;&gt;&lt;/a&gt;Xilinx 中断函数配置&lt;/h1&gt;&lt;figure class=&quot;highlight c&quot;&gt;&lt;</summary>
      
    
    
    
    <category term="Xilinx" scheme="https://angiean7.github.io/categories/Xilinx/"/>
    
    
  </entry>
  
  <entry>
    <title>Xilinx-Vitis建立工程</title>
    <link href="https://angiean7.github.io/2023/12/15/Xilinx-Vitis%E5%BB%BA%E7%AB%8B%E5%B7%A5%E7%A8%8B/"/>
    <id>https://angiean7.github.io/2023/12/15/Xilinx-Vitis%E5%BB%BA%E7%AB%8B%E5%B7%A5%E7%A8%8B/</id>
    <published>2023-12-15T02:21:29.658Z</published>
    <updated>2022-08-31T09:00:25.040Z</updated>
    
    <content type="html"><![CDATA[<h1 id="Xilinx-Vitis建立工程"><a href="#Xilinx-Vitis建立工程" class="headerlink" title="Xilinx-Vitis建立工程"></a>Xilinx-Vitis建立工程</h1><p>本次使用处理器：ARM coatex-A53    裸机</p><p>xsa文件（硬件描述文件）、bit文件由FPGA提供。</p><p>Xilinx提供的简介</p>]]></content>
    
    
      
      
    <summary type="html">&lt;h1 id=&quot;Xilinx-Vitis建立工程&quot;&gt;&lt;a href=&quot;#Xilinx-Vitis建立工程&quot; class=&quot;headerlink&quot; title=&quot;Xilinx-Vitis建立工程&quot;&gt;&lt;/a&gt;Xilinx-Vitis建立工程&lt;/h1&gt;&lt;p&gt;本次使用处理器：ARM co</summary>
      
    
    
    
    <category term="Xilinx" scheme="https://angiean7.github.io/categories/Xilinx/"/>
    
    
  </entry>
  
  <entry>
    <title>Windows OpenBoard流程</title>
    <link href="https://angiean7.github.io/2023/12/15/WindowsOpenBoard%E6%B5%81%E7%A8%8B/"/>
    <id>https://angiean7.github.io/2023/12/15/WindowsOpenBoard%E6%B5%81%E7%A8%8B/</id>
    <published>2023-12-15T02:21:29.658Z</published>
    <updated>2022-07-28T07:11:26.448Z</updated>
    
    <content type="html"><![CDATA[<h1 id="Windows-OpenBoard流程"><a href="#Windows-OpenBoard流程" class="headerlink" title="Windows OpenBoard流程"></a>Windows OpenBoard流程</h1><p>which means 打开driver获得句柄的流程。</p><figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">HDEVINFO             hDevInfo;</span><br><span class="line">SP_INTERFACE_DEVICE_DATA     IfDevData;</span><br><span class="line">SP_INTERFACE_DEVICE_DETAIL_DATA *IfDevDetail=<span class="literal">NULL</span>;</span><br><span class="line">DWORD              ReqLen;</span><br></pre></td></tr></table></figure><h2 id="1-SetupDiGetClassDevs函数"><a href="#1-SetupDiGetClassDevs函数" class="headerlink" title="1. SetupDiGetClassDevs函数"></a>1. SetupDiGetClassDevs函数</h2><p>​    SetupDiGetClassDevs函数返回设备信息集的句柄，该<strong>设备</strong><a class="link"   href="https://docs.microsoft.com/en-us/windows-hardware/drivers/install/device-information-sets" >信息集<i class="fas fa-external-link-alt"></i></a>包含本地计算机请求的设备信息元素。</p><figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="function">WINSETUPAPI HDEVINFO <span class="title">SetupDiGetClassDevsW</span><span class="params">(</span></span></span><br><span class="line"><span class="params"><span class="function">  [in, optional] <span class="type">const</span> GUID *ClassGuid,</span></span></span><br><span class="line"><span class="params"><span class="function">  [in, optional] PCWSTR     Enumerator,</span></span></span><br><span class="line"><span class="params"><span class="function">  [in, optional] HWND       hwndParent,</span></span></span><br><span class="line"><span class="params"><span class="function">  [in]           DWORD      Flags</span></span></span><br><span class="line"><span class="params"><span class="function">)</span></span>;</span><br></pre></td></tr></table></figure><figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">hDevInfo = <span class="built_in">SetupDiGetClassDevs</span>(pGuid,</span><br><span class="line">                  <span class="literal">NULL</span>, *<span class="comment">// Enumerator*</span></span><br><span class="line">                  <span class="literal">NULL</span>, *<span class="comment">//* </span></span><br><span class="line">                  DIGCF_PRESENT | DIGCF_INTERFACEDEVICE );</span><br></pre></td></tr></table></figure><h2 id="2-SetupDiEnumDeviceInterfaces函数"><a href="#2-SetupDiEnumDeviceInterfaces函数" class="headerlink" title="2. SetupDiEnumDeviceInterfaces函数"></a>2. SetupDiEnumDeviceInterfaces函数</h2><p>​    <strong>SetupDiEnumDeviceInterfaces</strong>函数枚举设备信息集中包含的设备接口。</p><figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="function">WINSETUPAPI BOOL <span class="title">SetupDiEnumDeviceInterfaces</span><span class="params">(</span></span></span><br><span class="line"><span class="params"><span class="function">  [in]           HDEVINFO                  DeviceInfoSet,</span></span></span><br><span class="line"><span class="params"><span class="function">  [in, optional] PSP_DEVINFO_DATA          DeviceInfoData,</span></span></span><br><span class="line"><span class="params"><span class="function">  [in]           <span class="type">const</span> GUID                *InterfaceClassGuid,</span></span></span><br><span class="line"><span class="params"><span class="function">  [in]           DWORD                     MemberIndex,</span></span></span><br><span class="line"><span class="params"><span class="function">  [out]          PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData</span></span></span><br><span class="line"><span class="params"><span class="function">)</span></span>;</span><br></pre></td></tr></table></figure><figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">SetupDiEnumDeviceInterfaces</span>(hDevInfo, <span class="literal">NULL</span>, pGuid, <span class="number">0</span>, &amp;IfDevData);</span><br></pre></td></tr></table></figure><h2 id="3-SetupDiGetDeviceInterfaceDetailW函数"><a href="#3-SetupDiGetDeviceInterfaceDetailW函数" class="headerlink" title="3. SetupDiGetDeviceInterfaceDetailW函数"></a>3. SetupDiGetDeviceInterfaceDetailW函数</h2><p><strong>SetupDiGetDeviceInterfaceDetail</strong>函数返回有关设备接口的详细信息。</p><p>另有SetupDiGetDeviceInterfaceDetailA函数。</p><figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="function">WINSETUPAPI BOOL <span class="title">SetupDiGetDeviceInterfaceDetailW</span><span class="params">(</span></span></span><br><span class="line"><span class="params"><span class="function">  [in]            HDEVINFO                           DeviceInfoSet,</span></span></span><br><span class="line"><span class="params"><span class="function">  [in]            PSP_DEVICE_INTERFACE_DATA          DeviceInterfaceData,</span></span></span><br><span class="line"><span class="params"><span class="function">  [out, optional] PSP_DEVICE_INTERFACE_DETAIL_DATA_W DeviceInterfaceDetailData,</span></span></span><br><span class="line"><span class="params"><span class="function">  [in]            DWORD                              DeviceInterfaceDetailDataSize,</span></span></span><br><span class="line"><span class="params"><span class="function">  [out, optional] PDWORD                             RequiredSize,</span></span></span><br><span class="line"><span class="params"><span class="function">  [out, optional] PSP_DEVINFO_DATA                   DeviceInfoData</span></span></span><br><span class="line"><span class="params"><span class="function">)</span></span>;</span><br></pre></td></tr></table></figure><figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">SetupDiGetDeviceInterfaceDetail</span>(hDevInfo ,&amp;IfDevData, <span class="literal">NULL</span>, <span class="number">0</span>, &amp;ReqLen, <span class="literal">NULL</span>);</span><br><span class="line"></span><br><span class="line">IfDevDetail-&gt;cbSize=<span class="built_in">sizeof</span>(SP_INTERFACE_DEVICE_DETAIL_DATA);</span><br><span class="line"></span><br><span class="line"><span class="built_in">SetupDiGetDeviceInterfaceDetail</span>(hDevInfo,&amp;IfDevData, IfDevDetail, ReqLen, <span class="literal">NULL</span>, <span class="literal">NULL</span>);</span><br></pre></td></tr></table></figure><h2 id="4-CreateFile"><a href="#4-CreateFile" class="headerlink" title="4. CreateFile"></a>4. CreateFile</h2><p>创建或打开文件或 I/O 设备。</p><p>最常用的 I/O 设备如下：文件、文件流、目录、物理磁盘、卷、控制台缓冲区、磁带驱动器、通信资源、邮槽和管道。</p><p>该函数返回一个handle，根据文件或设备以及指定的标志和属性，该句柄可用于访问文件或设备以进行各种类型的 I/O。</p><figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="function">HANDLE <span class="title">CreateFileW</span><span class="params">(</span></span></span><br><span class="line"><span class="params"><span class="function">  [in]           LPCWSTR               lpFileName,</span></span></span><br><span class="line"><span class="params"><span class="function">  [in]           DWORD                 dwDesiredAccess,</span></span></span><br><span class="line"><span class="params"><span class="function">  [in]           DWORD                 dwShareMode,</span></span></span><br><span class="line"><span class="params"><span class="function">  [in, optional] LPSECURITY_ATTRIBUTES lpSecurityAttributes,</span></span></span><br><span class="line"><span class="params"><span class="function">  [in]           DWORD                 dwCreationDisposition,</span></span></span><br><span class="line"><span class="params"><span class="function">  [in]           DWORD                 dwFlagsAndAttributes,</span></span></span><br><span class="line"><span class="params"><span class="function">  [in, optional] HANDLE                hTemplateFile</span></span></span><br><span class="line"><span class="params"><span class="function">)</span></span>;</span><br></pre></td></tr></table></figure><figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line">HANDLE m_hDevice = <span class="built_in">CreateFile</span>(</span><br><span class="line">                IfDevDetail-&gt;DevicePath, </span><br><span class="line">                GENERIC_READ | GENERIC_WRITE,</span><br><span class="line">                FILE_SHARE_READ | FILE_SHARE_WRITE,</span><br><span class="line">                <span class="literal">NULL</span>, </span><br><span class="line">                OPEN_EXISTING, </span><br><span class="line">                FILE_ATTRIBUTE_NORMAL|FILE_FLAG_OVERLAPPED, </span><br><span class="line">                <span class="literal">NULL</span></span><br><span class="line">                );</span><br></pre></td></tr></table></figure><h2 id="5-获取到handle后"><a href="#5-获取到handle后" class="headerlink" title="5. 获取到handle后"></a>5. 获取到handle后</h2><p>清理工作</p><figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">delete</span> [] IfDevDetail;</span><br><span class="line"><span class="built_in">SetupDiDestroyDeviceInfoList</span>(hDevInfo);</span><br></pre></td></tr></table></figure>]]></content>
    
    
      
      
    <summary type="html">&lt;h1 id=&quot;Windows-OpenBoard流程&quot;&gt;&lt;a href=&quot;#Windows-OpenBoard流程&quot; class=&quot;headerlink&quot; title=&quot;Windows OpenBoard流程&quot;&gt;&lt;/a&gt;Windows OpenBoard流程&lt;/h1&gt;&lt;p&gt;wh</summary>
      
    
    
    
    <category term="Windows" scheme="https://angiean7.github.io/categories/Windows/"/>
    
    
  </entry>
  
  <entry>
    <title>Linux运行app带参数 [getopt]</title>
    <link href="https://angiean7.github.io/2023/12/15/Linux%E8%BF%90%E8%A1%8Capp%E5%B8%A6%E5%8F%82%E6%95%B0%20getopt/"/>
    <id>https://angiean7.github.io/2023/12/15/Linux%E8%BF%90%E8%A1%8Capp%E5%B8%A6%E5%8F%82%E6%95%B0%20getopt/</id>
    <published>2023-12-15T02:21:29.658Z</published>
    <updated>2022-07-28T07:10:22.089Z</updated>
    
    <content type="html"><![CDATA[<h1 id="Linux运行app带参数-getopt"><a href="#Linux运行app带参数-getopt" class="headerlink" title="Linux运行app带参数 getopt"></a>Linux运行app带参数 getopt</h1><p>头文件：#include &lt;getopt.h&gt;</p><p>main函数中：</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br></pre></td><td class="code"><pre><span class="line"><span class="type">int</span> opt = <span class="number">0</span>;</span><br><span class="line"><span class="type">int</span> cmd = <span class="number">0</span>;</span><br><span class="line"><span class="type">int</span> data = <span class="number">0</span>;</span><br><span class="line"><span class="type">const</span> <span class="type">char</span> *optstring = <span class="string">&quot;a:b:c:hz&quot;</span>;</span><br><span class="line"><span class="comment">//while ((opt = getopt_long(argc, argv, optstring)) != -1)</span></span><br><span class="line"><span class="keyword">while</span> ((opt = getopt(argc, argv, optstring)) != <span class="number">-1</span>)</span><br><span class="line">&#123;</span><br><span class="line">    <span class="keyword">case</span> <span class="string">&#x27;a&#x27;</span>: <span class="comment">//analog voltage</span></span><br><span class="line">      <span class="built_in">sscanf</span>(optarg, <span class="string">&quot;%d&quot;</span>, &amp;data);</span><br><span class="line">      <span class="keyword">break</span>;</span><br><span class="line">    <span class="keyword">case</span> <span class="string">&#x27;b&#x27;</span>: <span class="comment">//set bar</span></span><br><span class="line">      <span class="built_in">sscanf</span>(optarg, <span class="string">&quot;%d&quot;</span>, &amp;data);</span><br><span class="line">      <span class="keyword">break</span>;</span><br><span class="line">    <span class="keyword">case</span> <span class="string">&#x27;c&#x27;</span>: <span class="comment">// do api func</span></span><br><span class="line">      <span class="built_in">printf</span>(<span class="string">&quot;opt is c, comand is: %s\n&quot;</span>, optarg);</span><br><span class="line">      <span class="keyword">if</span> (!<span class="built_in">strcmp</span>(optarg, <span class="string">&quot;open&quot;</span>))</span><br><span class="line">      &#123;</span><br><span class="line">        cmd = <span class="number">1</span>;</span><br><span class="line">      &#125;</span><br><span class="line">      <span class="keyword">else</span> <span class="keyword">if</span> (!<span class="built_in">strcmp</span>(optarg, <span class="string">&quot;close&quot;</span>))</span><br><span class="line">      &#123;</span><br><span class="line">        cmd = <span class="number">2</span>;</span><br><span class="line">      &#125;</span><br><span class="line">      <span class="keyword">else</span></span><br><span class="line">      &#123;</span><br><span class="line">        <span class="built_in">printf</span>(<span class="string">&quot;[ERR] command NG: %s\n&quot;</span>, optarg);</span><br><span class="line">        <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">      &#125;</span><br><span class="line">      <span class="comment">/*</span></span><br><span class="line"><span class="comment">      ret = do_api_func(cmd);</span></span><br><span class="line"><span class="comment">      if (0 != ret)</span></span><br><span class="line"><span class="comment">      &#123;</span></span><br><span class="line"><span class="comment">        printf(&quot;[ERR] errcode=%d\n&quot;, ret);</span></span><br><span class="line"><span class="comment">        return 0;</span></span><br><span class="line"><span class="comment">      &#125;</span></span><br><span class="line"><span class="comment">      else</span></span><br><span class="line"><span class="comment">      &#123;</span></span><br><span class="line"><span class="comment">        ret = check_api_result_when_ok(cmd);</span></span><br><span class="line"><span class="comment">      &#125;</span></span><br><span class="line"><span class="comment">      break;</span></span><br><span class="line"><span class="comment">      */</span></span><br><span class="line">    <span class="keyword">case</span> <span class="string">&#x27;z&#x27;</span>: <span class="comment">//dump parameters for debug</span></span><br><span class="line">      <span class="comment">//debug_dump_api_parameters();</span></span><br><span class="line">      <span class="keyword">break</span>;</span><br><span class="line">    <span class="keyword">case</span> <span class="string">&#x27;h&#x27;</span>:</span><br><span class="line">      print_usage(argv[<span class="number">0</span>]);</span><br><span class="line">      <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">    <span class="keyword">case</span> <span class="string">&#x27;?&#x27;</span>:</span><br><span class="line">      <span class="built_in">printf</span>(<span class="string">&quot;Try \&#x27;%s -h\&#x27; for more information.\n&quot;</span>, argv[<span class="number">0</span>]);</span><br><span class="line">      <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>如果想用长命令（–command）代替短命令（-c），使用转换：</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">struct</span> <span class="title">option</span> <span class="title">long_options</span>[] =</span> &#123;</span><br><span class="line">    &#123;<span class="string">&quot;cmd&quot;</span>, <span class="number">1</span>, <span class="literal">NULL</span>, <span class="string">&#x27;c&#x27;</span>&#125;,</span><br><span class="line">    &#123;<span class="string">&quot;analog-input&quot;</span>, <span class="number">1</span>, <span class="literal">NULL</span>, <span class="string">&#x27;a&#x27;</span>&#125;,</span><br><span class="line">    &#123;<span class="string">&quot;bar&quot;</span>, <span class="number">1</span>, <span class="literal">NULL</span>, <span class="string">&#x27;b&#x27;</span>&#125;,</span><br><span class="line">    &#123;<span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>&#125;,</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure>]]></content>
    
    
      
      
    <summary type="html">&lt;h1 id=&quot;Linux运行app带参数-getopt&quot;&gt;&lt;a href=&quot;#Linux运行app带参数-getopt&quot; class=&quot;headerlink&quot; title=&quot;Linux运行app带参数 getopt&quot;&gt;&lt;/a&gt;Linux运行app带参数 getopt&lt;/h1&gt;&lt;</summary>
      
    
    
    
    <category term="Linux C" scheme="https://angiean7.github.io/categories/Linux-C/"/>
    
    
  </entry>
  
  <entry>
    <title>vscode 快捷键</title>
    <link href="https://angiean7.github.io/2023/12/15/vscode%E5%BF%AB%E6%8D%B7%E9%94%AE/"/>
    <id>https://angiean7.github.io/2023/12/15/vscode%E5%BF%AB%E6%8D%B7%E9%94%AE/</id>
    <published>2023-12-15T02:21:29.658Z</published>
    <updated>2022-07-28T07:11:03.188Z</updated>
    
    <content type="html"><![CDATA[<h1 id="vscode-快捷键"><a href="#vscode-快捷键" class="headerlink" title="vscode 快捷键"></a>vscode 快捷键</h1><h2 id="基础编辑-Basic-editing"><a href="#基础编辑-Basic-editing" class="headerlink" title="基础编辑 Basic editing"></a>基础编辑 Basic editing</h2><table><thead><tr><th>按 Press</th><th>功能 Function</th></tr></thead><tbody><tr><td>Ctrl+X</td><td>剪切行（空选定） Cut line (empty selection)</td></tr><tr><td>Ctrl+C</td><td>复制行（空选定）Copy line (empty selection)</td></tr><tr><td>Alt+ ↑ / ↓</td><td>向上/向下移动行 Move line up/down</td></tr><tr><td>Shift+Alt + ↓ / ↑</td><td>向上/向下复制行 Copy line up/down</td></tr><tr><td>Ctrl+Shift+K</td><td>删除行 Delete line</td></tr><tr><td>Ctrl+Enter</td><td>在下面插入行 Insert line below</td></tr><tr><td>Ctrl+Shift+Enter</td><td>在上面插入行 Insert line above</td></tr><tr><td>Ctrl+Shift+\</td><td>跳到匹配的括号 Jump to matching bracket</td></tr><tr><td>Ctrl+] / [</td><td>缩进/缩进行 Indent/outdent line</td></tr><tr><td>Home</td><td>转到行首 Go to beginning of line</td></tr><tr><td>End</td><td>转到行尾 Go to end of line</td></tr><tr><td>Ctrl+Home</td><td>转到文件开头 Go to beginning of file</td></tr><tr><td>Ctrl+End</td><td>转到文件末尾 Go to end of file</td></tr><tr><td>Ctrl+↑ / ↓</td><td>向上/向下滚动行 Scroll line up/down</td></tr><tr><td>Alt+PgUp / PgDown</td><td>向上/向下滚动页面 Scroll page up/down</td></tr><tr><td>Ctrl+Shift+[</td><td>折叠（折叠）区域 Fold (collapse) region</td></tr><tr><td>Ctrl+Shift+]</td><td>展开（未折叠）区域 Unfold (uncollapse) region</td></tr><tr><td>Ctrl+K Ctrl+[</td><td>折叠（未折叠）所有子区域 Fold (collapse) all subregions</td></tr><tr><td>Ctrl+K Ctrl+]</td><td>展开（未折叠）所有子区域 Unfold (uncollapse) all subregions</td></tr><tr><td>Ctrl+K Ctrl+0</td><td>折叠（折叠）所有区域 Fold (collapse) all regions</td></tr><tr><td>Ctrl+K Ctrl+J</td><td>展开（未折叠）所有区域 Unfold (uncollapse) all regions</td></tr><tr><td>Ctrl+K Ctrl+C</td><td>添加行注释 Add line comment</td></tr><tr><td>Ctrl+K Ctrl+U</td><td>删除行注释 Remove line comment</td></tr><tr><td>Ctrl+/</td><td>切换行注释 Toggle line comment</td></tr><tr><td>Shift+Alt+A</td><td>切换块注释 Toggle block comment</td></tr><tr><td>Alt+Z</td><td>切换换行 Toggle word wrap</td></tr></tbody></table><h2 id="导航-Navigation"><a href="#导航-Navigation" class="headerlink" title="导航 Navigation"></a>导航 Navigation</h2><table><thead><tr><th>按 Press</th><th>功能 Function</th></tr></thead><tbody><tr><td>Ctrl + T</td><td>显示所有符号 Show all Symbols</td></tr><tr><td>Ctrl + G</td><td>转到行… Go to Line…</td></tr><tr><td>Ctrl + P</td><td>转到文件… Go to File…</td></tr><tr><td>Ctrl + Shift + O</td><td>转到符号… Go to Symbol…</td></tr><tr><td>Ctrl + Shift + M</td><td>显示问题面板 Show Problems panel</td></tr><tr><td>F8</td><td>转到下一个错误或警告 Go to next error or warning</td></tr><tr><td>Shift + F8</td><td>转到上一个错误或警告 Go to previous error or warning</td></tr><tr><td>Ctrl + Shift + Tab</td><td>导航编辑器组历史记录 Navigate editor group history</td></tr><tr><td>Alt + ←/→</td><td>返回/前进 Go back / forward</td></tr><tr><td>Ctrl + M</td><td>切换选项卡移动焦点 Toggle Tab moves focus</td></tr></tbody></table>]]></content>
    
    
      
      
    <summary type="html">&lt;h1 id=&quot;vscode-快捷键&quot;&gt;&lt;a href=&quot;#vscode-快捷键&quot; class=&quot;headerlink&quot; title=&quot;vscode 快捷键&quot;&gt;&lt;/a&gt;vscode 快捷键&lt;/h1&gt;&lt;h2 id=&quot;基础编辑-Basic-editing&quot;&gt;&lt;a href=&quot;#基础编</summary>
      
    
    
    
    <category term="环境" scheme="https://angiean7.github.io/categories/%E7%8E%AF%E5%A2%83/"/>
    
    
  </entry>
  
  <entry>
    <title>日语笔记</title>
    <link href="https://angiean7.github.io/2023/12/15/%E6%97%A5%E8%AF%AD%E7%AC%94%E8%AE%B0/"/>
    <id>https://angiean7.github.io/2023/12/15/%E6%97%A5%E8%AF%AD%E7%AC%94%E8%AE%B0/</id>
    <published>2023-12-15T02:21:29.658Z</published>
    <updated>2022-07-28T07:11:53.799Z</updated>
    
    <content type="html"><![CDATA[<h3 id="20220721"><a href="#20220721" class="headerlink" title="20220721"></a>20220721</h3><table><thead><tr><th align="left">単語</th><th></th><th></th></tr></thead><tbody><tr><td align="left">威嚇(いかく)</td><td></td><td></td></tr><tr><td align="left">絨毯(じゅうたん)</td><td></td><td></td></tr><tr><td align="left">漆喰(しっくい)</td><td>石灰</td><td></td></tr><tr><td align="left">頑な(かたくな)</td><td>自分の意見や考え、主張に固執し、変えようとしないさま。</td><td></td></tr><tr><td align="left">表沙汰(おもてざた)</td><td>内密にしたいことが世間に知れ渡ること。</td><td></td></tr><tr><td align="left">やむを得ず</td><td>どうしようもなく、仕方なく</td><td></td></tr><tr><td align="left">腰を引ける</td><td>自信がなかったり恐れたりして、積極的に振る舞うことができない。</td><td></td></tr><tr><td align="left">腰を据えて</td><td>落ち着いて、じっくり構えてことに当たることを意味する表現。</td><td></td></tr><tr><td align="left">据える</td><td>場所を設けて、その場所から動かないように物を置く。</td><td></td></tr><tr><td align="left">構えて</td><td>まちがいなく。 本当に。 必ず。</td><td></td></tr><tr><td align="left">当たる</td><td>物事や人が直面、接触する。</td><td></td></tr><tr><td align="left">相応しい(ふさわしい)</td><td>似つかわしい。ある事物が別の事物と雰囲気などの点で合っているさま。</td><td></td></tr><tr><td align="left">反目(はんもく)し合う</td><td>にらみあうこと。 対立して仲の悪いこと。</td><td></td></tr><tr><td align="left">睨む(にらむ)</td><td>目をいからしてじっと見る。鋭い目つきで見る。</td><td></td></tr></tbody></table><h3 id="20220722"><a href="#20220722" class="headerlink" title="20220722"></a>20220722</h3><table><thead><tr><th>単語</th><th></th></tr></thead><tbody><tr><td>足搔く(あがく)</td><td>苦し紛れ(まぎれ)にジタバタする。</td></tr><tr><td>足搔きが取れない</td><td>動作が自由にならない。取るべき方法がない。</td></tr><tr><td>赤ランプが点る(ともる)</td><td>危険を知らせる合図の赤ランプがつく。物事が悪い方向に緊迫している状態のたとえ。</td></tr><tr><td>嫁いびり</td><td>姑 (しゅうとめ) などが嫁をいじめて苦しめること。</td></tr><tr><td>悪女の深情け(ふかなさけ)</td><td>ありがた迷惑。</td></tr><tr><td>顎が落ちる</td><td>食物の味の非常によいことのたとえ。ほっぺたが落ちる。</td></tr><tr><td>顎を外す</td><td>大笑いをすることのたとえ。</td></tr><tr><td>みかじめ料</td><td>飲食店や小売店などが出店する地域の反社会的勢力に支払う場所代、用心棒(ようじんぼう)代。</td></tr><tr><td>みすぼらしい</td><td>外見が貧弱である。身なりが見苦しい。</td></tr><tr><td>急(いそ)がば回(まわ)れ</td><td>早く着こうと思うなら、危険な近道より遠くても安全確実な方法をとったほうが早く目的を達することができるというたとえ。</td></tr></tbody></table><h4 id="20220725"><a href="#20220725" class="headerlink" title="20220725"></a>20220725</h4><table><thead><tr><th>単語</th><th></th></tr></thead><tbody><tr><td>可能な限り</td><td></td></tr><tr><td>さなかに</td><td>最中に。途中に。</td></tr><tr><td>物ともせず</td><td>問題にもしない。何とも思わない。「周囲の反対を―ひたすら意志を通した」</td></tr><tr><td>屈する(くっする)</td><td>粘り強い。骨のある。しっかりした。我慢強い。</td></tr><tr><td>ざわつく</td><td>そわつく。そわそわする。 落ち着かない様子をする。</td></tr></tbody></table>]]></content>
    
    
      
      
    <summary type="html">&lt;h3 id=&quot;20220721&quot;&gt;&lt;a href=&quot;#20220721&quot; class=&quot;headerlink&quot; title=&quot;20220721&quot;&gt;&lt;/a&gt;20220721&lt;/h3&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th align=&quot;left&quot;&gt;単語&lt;/th&gt;
&lt;th</summary>
      
    
    
    
    <category term="日语" scheme="https://angiean7.github.io/categories/%E6%97%A5%E8%AF%AD/"/>
    
    
  </entry>
  
  <entry>
    <title>C#-wpf笔记</title>
    <link href="https://angiean7.github.io/2023/12/15/C#_wpf%E7%AC%94%E8%AE%B0/"/>
    <id>https://angiean7.github.io/2023/12/15/C#_wpf%E7%AC%94%E8%AE%B0/</id>
    <published>2023-12-15T02:21:29.642Z</published>
    <updated>2022-07-28T07:16:16.320Z</updated>
    
    <content type="html"><![CDATA[<h1 id="C-wpf-个人笔记"><a href="#C-wpf-个人笔记" class="headerlink" title="C#      wpf    个人笔记"></a>C#      wpf    个人笔记</h1><ol><li>如何在TacControl种隐藏标签页</li></ol><figure class="highlight c#"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">TabPage tp = tabControl1.TabPages[<span class="number">0</span>];<span class="comment">//在这里先保存，以便以后还要显示</span></span><br><span class="line"></span><br><span class="line">tabControl1.TabPages.Remove(tp);<span class="comment">//隐藏（删除）</span></span><br><span class="line"></span><br><span class="line">tabControl1.TabPages.Insert(<span class="number">0</span>, tp);<span class="comment">//显示（插入）</span></span><br></pre></td></tr></table></figure><ol start="2"><li><p>将两个IntPtr拼接成一个IntPtr</p><figure class="highlight c#"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"><span class="doctag">///</span> <span class="doctag">&lt;summary&gt;</span></span></span><br><span class="line"><span class="comment"><span class="doctag">///</span> 将两个IntPtr拼接成一个IntPtr</span></span><br><span class="line"><span class="comment"><span class="doctag">///</span> <span class="doctag">&lt;/summary&gt;</span></span></span><br><span class="line"><span class="comment"><span class="doctag">///</span> <span class="doctag">&lt;param name=&quot;lastPtr&quot;&gt;</span>上一次数据指<span class="doctag">&lt;/param&gt;</span></span></span><br><span class="line"><span class="comment"><span class="doctag">///</span> <span class="doctag">&lt;param name=&quot;curPtr&quot;&gt;</span>本次数据指针<span class="doctag">&lt;/param&gt;</span></span></span><br><span class="line"><span class="comment"><span class="doctag">///</span> <span class="doctag">&lt;param name=&quot;imgWidth&quot;&gt;</span>图片宽度<span class="doctag">&lt;/param&gt;</span></span></span><br><span class="line"><span class="comment"><span class="doctag">///</span> <span class="doctag">&lt;param name=&quot;imgHeight&quot;&gt;</span>图片长度<span class="doctag">&lt;/param&gt;</span></span></span><br><span class="line"><span class="comment"><span class="doctag">///</span> <span class="doctag">&lt;param name=&quot;halfSize&quot;&gt;</span>拼接行数<span class="doctag">&lt;/param&gt;</span></span></span><br><span class="line"><span class="comment"><span class="doctag">///</span> <span class="doctag">&lt;param name=&quot;outputBytes&quot;&gt;</span>输出数组<span class="doctag">&lt;/param&gt;</span></span></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">ConcatGrayIntptr</span>(<span class="params">IntPtr lastPtr, IntPtr curPtr, <span class="built_in">int</span> halfSize, <span class="keyword">out</span> IntPtr outPtr</span>)</span></span><br><span class="line">&#123;</span><br><span class="line">    outPtr = IntPtr.Zero;</span><br><span class="line">    <span class="built_in">byte</span>[] outputBytes = <span class="keyword">new</span> <span class="built_in">byte</span>[halfSize * <span class="number">2</span>];</span><br><span class="line">    IntPtr offsetLastPtr = IntPtr.Zero;</span><br><span class="line">    <span class="keyword">if</span> (lastPtr != IntPtr.Zero)</span><br><span class="line">    &#123;</span><br><span class="line">        <span class="keyword">if</span> (IntPtr.Size == <span class="keyword">sizeof</span>(Int64))</span><br><span class="line">            offsetLastPtr = <span class="keyword">new</span> IntPtr(lastPtr.ToInt64() + halfSize);</span><br><span class="line">        <span class="keyword">else</span></span><br><span class="line">            offsetLastPtr = <span class="keyword">new</span> IntPtr(lastPtr.ToInt32() + halfSize);</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">if</span> (offsetLastPtr != IntPtr.Zero)</span><br><span class="line">    &#123;</span><br><span class="line">        Marshal.Copy(offsetLastPtr, outputBytes, <span class="number">0</span>, halfSize);</span><br><span class="line">    &#125;</span><br><span class="line">    Marshal.Copy(curPtr, outputBytes, halfSize, halfSize);</span><br><span class="line">    Marshal.Copy(outputBytes, <span class="number">0</span>, outPtr, halfSize*<span class="number">2</span>);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></li></ol><p>CSVファイルの書き込みと同時にFlashの特定の位置にあるmagic numberも正しく設定され、これでnet_setで設定されたDAC値も使えるようになります。magic numberが正しくない場合はデフォルトDAC値を使いますので、net_setでの設定が効かなくなります。調べた結果としては、一旦正しいmagic numberを設定すれば、net_setでDAC値を設定できるはずなので毎回CSVファイルの書き込みを行う必要はありません。</p>]]></content>
    
    
      
      
    <summary type="html">&lt;h1 id=&quot;C-wpf-个人笔记&quot;&gt;&lt;a href=&quot;#C-wpf-个人笔记&quot; class=&quot;headerlink&quot; title=&quot;C#      wpf    个人笔记&quot;&gt;&lt;/a&gt;C#      wpf    个人笔记&lt;/h1&gt;&lt;ol&gt;
&lt;li&gt;如何在TacControl种</summary>
      
    
    
    
    <category term="Windows" scheme="https://angiean7.github.io/categories/Windows/"/>
    
    
  </entry>
  
  <entry>
    <title>C 回调函数</title>
    <link href="https://angiean7.github.io/2023/12/15/C%20%E5%9B%9E%E8%B0%83%E5%87%BD%E6%95%B0/"/>
    <id>https://angiean7.github.io/2023/12/15/C%20%E5%9B%9E%E8%B0%83%E5%87%BD%E6%95%B0/</id>
    <published>2023-12-15T02:21:29.642Z</published>
    <updated>2024-03-14T04:53:54.626Z</updated>
    
    <content type="html"><![CDATA[<h1 id="C-callback-function"><a href="#C-callback-function" class="headerlink" title="C callback function"></a>C callback function</h1><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">graph LR</span><br><span class="line">id1(main program) --- id3(callback func)</span><br><span class="line">id1(main program) --&gt;|calls| id2(Lib Func)</span><br><span class="line">id2(Lib Func) --&gt;|calls| id3(callback func)</span><br></pre></td></tr></table></figure><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span><span class="string">&lt;stdio.h&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span><span class="string">&lt;Lib.h&gt;</span> <span class="comment">// include Library function</span></span></span><br><span class="line"></span><br><span class="line"><span class="type">int</span> <span class="title function_">Callback</span><span class="params">()</span> <span class="comment">// Callback Function</span></span><br><span class="line">&#123;</span><br><span class="line">  <span class="comment">// TODO</span></span><br><span class="line">  <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br><span class="line"><span class="type">int</span> <span class="title function_">main</span><span class="params">()</span> <span class="comment">// Main program</span></span><br><span class="line">&#123;</span><br><span class="line">  <span class="comment">// TODO</span></span><br><span class="line">  Library(Callback);</span><br><span class="line">  <span class="comment">// TODO</span></span><br><span class="line">  <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>code: </p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span><span class="string">&lt;stdio.h&gt;</span></span></span><br><span class="line"></span><br><span class="line"><span class="type">int</span> <span class="title function_">Callback_1</span><span class="params">(<span class="type">int</span> x)</span> <span class="comment">// Callback Function 1</span></span><br><span class="line">&#123;</span><br><span class="line">    <span class="built_in">printf</span>(<span class="string">&quot;Hello, this is Callback_1: x = %d &quot;</span>, x);</span><br><span class="line">    <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="type">int</span> <span class="title function_">Callback_2</span><span class="params">(<span class="type">int</span> x)</span> <span class="comment">// Callback Function 2</span></span><br><span class="line">&#123;</span><br><span class="line">    <span class="built_in">printf</span>(<span class="string">&quot;Hello, this is Callback_2: x = %d &quot;</span>, x);</span><br><span class="line">    <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="type">int</span> <span class="title function_">Callback_3</span><span class="params">(<span class="type">int</span> x)</span> <span class="comment">// Callback Function 3</span></span><br><span class="line">&#123;</span><br><span class="line">    <span class="built_in">printf</span>(<span class="string">&quot;Hello, this is Callback_3: x = %d &quot;</span>, x);</span><br><span class="line">    <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="type">int</span> <span class="title function_">Handle</span><span class="params">(<span class="type">int</span> y, <span class="type">int</span> (*Callback)(<span class="type">int</span>))</span></span><br><span class="line">&#123;</span><br><span class="line">    <span class="built_in">printf</span>(<span class="string">&quot;Entering Handle Function. &quot;</span>);</span><br><span class="line">    Callback(y);</span><br><span class="line">    <span class="built_in">printf</span>(<span class="string">&quot;Leaving Handle Function. &quot;</span>);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="type">int</span> <span class="title function_">main</span><span class="params">()</span></span><br><span class="line">&#123;</span><br><span class="line">    <span class="type">int</span> a = <span class="number">2</span>;</span><br><span class="line">    <span class="type">int</span> b = <span class="number">4</span>;</span><br><span class="line">    <span class="type">int</span> c = <span class="number">6</span>;</span><br><span class="line">    <span class="built_in">printf</span>(<span class="string">&quot;Entering Main Function. &quot;</span>);</span><br><span class="line">    Handle(a, Callback_1);</span><br><span class="line">    Handle(b, Callback_2);</span><br><span class="line">    Handle(c, Callback_3);</span><br><span class="line">    <span class="built_in">printf</span>(<span class="string">&quot;Leaving Main Function. &quot;</span>);</span><br><span class="line">    <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>]]></content>
    
    
      
      
    <summary type="html">&lt;h1 id=&quot;C-callback-function&quot;&gt;&lt;a href=&quot;#C-callback-function&quot; class=&quot;headerlink&quot; title=&quot;C callback function&quot;&gt;&lt;/a&gt;C callback function&lt;/h1&gt;&lt;figu</summary>
      
    
    
    
    <category term="Linux C" scheme="https://angiean7.github.io/categories/Linux-C/"/>
    
    
  </entry>
  
</feed>
