﻿<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>程序员日志</title>
	<atom:link href="https://e673.com/feed/" rel="self" type="application/rss+xml" />
	<link>https://e673.com</link>
	<description></description>
	<lastBuildDate>Sun, 01 Mar 2026 08:10:34 +0000</lastBuildDate>
	<language>zh-Hans</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.9.1</generator>
	<item>
		<title>STM32+CubeMX 配置ADC配合DMA多通道多次采样并自动取平均</title>
		<link>https://e673.com/stm32cubemx-adc-with-dma-multiple-channel-average-oversample/</link>
		
		<dc:creator><![CDATA[ahe]]></dc:creator>
		<pubDate>Sun, 01 Mar 2026 08:10:34 +0000</pubDate>
				<category><![CDATA[应用笔记]]></category>
		<category><![CDATA[经验分享]]></category>
		<category><![CDATA[ARM]]></category>
		<category><![CDATA[嵌入程序]]></category>
		<guid isPermaLink="false">https://e673.com/?p=3096</guid>

					<description><![CDATA[一、推荐参数 先用这一组，比较稳&#46;&#46;&#46;]]></description>
										<content:encoded><![CDATA[<h2 data-start="284" data-end="305">一、推荐参数</h2>
<p data-start="307" data-end="317">先用这一组，比较稳：</p>
<ul data-start="319" data-end="374">
<li data-start="319" data-end="348">
<p data-start="321" data-end="348"><strong data-start="321" data-end="348">Oversampling Ratio = 8x</strong></p>
</li>
<li data-start="349" data-end="374">
<p data-start="351" data-end="374"><strong data-start="351" data-end="374">Right Bit Shift = 3</strong></p>
</li>
</ul>
<p data-start="376" data-end="381">这等价于：</p>
<ul data-start="383" data-end="438">
<li data-start="383" data-end="396">
<p data-start="385" data-end="396">每个通道内部采 8 次</p>
</li>
<li data-start="397" data-end="415">
<p data-start="399" data-end="415">累加后右移 3 位（即除以 8）</p>
</li>
<li data-start="416" data-end="438">
<p data-start="418" data-end="438">输出结果仍保持接近 <strong data-start="428" data-end="438">12 位量程</strong></p>
</li>
</ul>
<p data-start="440" data-end="545">也就是说，<strong data-start="445" data-end="463">你拿到的就是“8 次平均值”</strong>。STM32L4 的硬件过采样支持把输出当作 averaging function 来用。</p>
<p data-start="547" data-end="561">如果你更想抑制噪声，可改成：</p>
<ul data-start="563" data-end="582">
<li data-start="563" data-end="582">
<p data-start="565" data-end="582"><strong data-start="565" data-end="582">16x + Shift 4</strong></p>
</li>
</ul>
<p data-start="584" data-end="597">但总转换时间会进一步增加。</p>
<hr data-start="599" data-end="602" />
<h2 data-start="604" data-end="620">二、CubeMX 配置</h2>
<p data-start="622" data-end="671">下面按 <strong data-start="626" data-end="667">“软件触发一次，采完 6 个通道（每个都做过采样），DMA 搬 6 个值”</strong> 来配。</p>
<h3 data-start="673" data-end="688">1）ADC1 基本参数</h3>
<p data-start="689" data-end="723">在 <strong data-start="691" data-end="720">ADC1 &gt; Parameter Settings</strong> 里：</p>
<ul data-start="725" data-end="1113">
<li data-start="725" data-end="758">
<p data-start="727" data-end="758"><strong data-start="727" data-end="751">Scan Conversion Mode</strong>：Enable</p>
</li>
<li data-start="759" data-end="784">
<p data-start="761" data-end="784"><strong data-start="761" data-end="782">Nbr Of Conversion</strong>：6</p>
</li>
<li data-start="785" data-end="820">
<p data-start="787" data-end="820">把你的 6 个通道分别设成 <strong data-start="801" data-end="820">Rank 1 ~ Rank 6</strong></p>
</li>
<li data-start="821" data-end="845">
<p data-start="823" data-end="845"><strong data-start="823" data-end="837">Resolution</strong>：12 bits</p>
</li>
<li data-start="846" data-end="872">
<p data-start="848" data-end="872"><strong data-start="848" data-end="866">Data Alignment</strong>：Right</p>
</li>
<li data-start="873" data-end="917">
<p data-start="875" data-end="917"><strong data-start="875" data-end="905">Continuous Conversion Mode</strong>：<strong data-start="906" data-end="917">Disable</strong></p>
</li>
<li data-start="918" data-end="961">
<p data-start="920" data-end="961"><strong data-start="920" data-end="953">Discontinuous Conversion Mode</strong>：Disable</p>
</li>
<li data-start="962" data-end="1017">
<p data-start="964" data-end="1017"><strong data-start="964" data-end="1002">External Trigger Conversion Source</strong>：Software Start</p>
</li>
<li data-start="1018" data-end="1059">
<p data-start="1020" data-end="1059"><strong data-start="1020" data-end="1047">DMA Continuous Requests</strong>：<strong data-start="1048" data-end="1059">Disable</strong></p>
</li>
<li data-start="1060" data-end="1113">
<p data-start="1062" data-end="1113"><strong data-start="1062" data-end="1093">End Of Conversion Selection</strong>：<strong data-start="1094" data-end="1113">End of Sequence</strong></p>
</li>
</ul>
<p data-start="1115" data-end="1118">说明：</p>
<ul data-start="1119" data-end="1355">
<li data-start="1119" data-end="1156">
<p data-start="1121" data-end="1156">你要的是“触发一次，拿一组”，所以 <strong data-start="1139" data-end="1156">Continuous 要关</strong></p>
</li>
<li data-start="1157" data-end="1191">
<p data-start="1159" data-end="1191">DMA 用 <strong data-start="1165" data-end="1175">Normal</strong> 模式，一次搬完 6 个结果就停</p>
</li>
<li data-start="1192" data-end="1355">
<p data-start="1194" data-end="1355">EOC 选 <strong data-start="1200" data-end="1219">End of Sequence</strong>，这样一整组 6 通道完成后再作为一次完整结果处理，更省心。STM32L4 的 ADC 支持 single-shot 或 continuous 的单通道/扫描模式，规则组数据也可通过 DMA 获取。</p>
</li>
</ul>
<hr data-start="1357" data-end="1360" />
<h3 data-start="1362" data-end="1387">2）每个通道的 Sampling Time</h3>
<p data-start="1388" data-end="1421">在 6 个通道各自的 Rank 设置里，给一个相对稳妥的采样时间：</p>
<ul data-start="1423" data-end="1510">
<li data-start="1423" data-end="1467">
<p data-start="1425" data-end="1467">若信号源阻抗不高：<strong data-start="1434" data-end="1449">24.5 cycles</strong> 或 <strong data-start="1452" data-end="1467">47.5 cycles</strong></p>
</li>
<li data-start="1468" data-end="1510">
<p data-start="1470" data-end="1510">若是分压电阻较大 / 传感器阻抗高：建议 <strong data-start="1491" data-end="1506">92.5 cycles</strong> 或更长</p>
</li>
</ul>
<p data-start="1512" data-end="1585">STM32L4 允许每个通道单独设置采样时间；高阻信号需要更长采样时间。</p>
<hr data-start="1587" data-end="1590" />
<h3 data-start="1592" data-end="1613">3）打开 Oversampling</h3>
<p data-start="1614" data-end="1693">在 ADC1 的参数页里，找到 <strong data-start="1630" data-end="1669">Oversampling / Regular Oversampling</strong>（不同 CubeMX 版本位置略有不同），设置：</p>
<ul data-start="1695" data-end="1931">
<li data-start="1695" data-end="1725">
<p data-start="1697" data-end="1725"><strong data-start="1697" data-end="1718">Oversampling Mode</strong>：Enable</p>
</li>
<li data-start="1726" data-end="1757">
<p data-start="1728" data-end="1757"><strong data-start="1728" data-end="1750">Oversampling Ratio</strong>：<strong data-start="1751" data-end="1757">8x</strong></p>
</li>
<li data-start="1758" data-end="1790">
<p data-start="1760" data-end="1790"><strong data-start="1760" data-end="1779">Right Bit Shift</strong>：<strong data-start="1780" data-end="1790">3 bits</strong></p>
</li>
<li data-start="1791" data-end="1931">
<p data-start="1793" data-end="1853"><strong data-start="1793" data-end="1852">Triggered Oversampling Mode / Regular Oversampling Mode</strong>：</p>
<ul data-start="1856" data-end="1931">
<li data-start="1856" data-end="1895">
<p data-start="1858" data-end="1895">若有这个选项，建议先用 <strong data-start="1870" data-end="1895">Continued mode（连续过采样）</strong></p>
</li>
<li data-start="1898" data-end="1931">
<p data-start="1900" data-end="1931">也就是一次规则转换内，把 8 次子采样连续完成，再给出一个结果</p>
</li>
</ul>
</li>
</ul>
<p data-start="1933" data-end="1936">说明：</p>
<ul data-start="1937" data-end="2054">
<li data-start="1937" data-end="2017">
<p data-start="1939" data-end="2017">L4 的硬件过采样支持 <strong data-start="1951" data-end="1977">2/4/8/16/32/64/128/256</strong> 倍。</p>
</li>
<li data-start="2018" data-end="2054">
<p data-start="2020" data-end="2054"><strong data-start="2020" data-end="2036">8x + shift 3</strong> 是最像“硬件平均 8 次”的配置。</p>
</li>
</ul>
<hr data-start="2056" data-end="2059" />
<h3 data-start="2061" data-end="2073">4）DMA 配置</h3>
<p data-start="2074" data-end="2112">在 <strong data-start="2076" data-end="2099">ADC1 &gt; DMA Settings</strong> 添加一个 DMA 通道：</p>
<ul data-start="2114" data-end="2341">
<li data-start="2114" data-end="2150">
<p data-start="2116" data-end="2150"><strong data-start="2116" data-end="2129">Direction</strong>：Peripheral to Memory</p>
</li>
<li data-start="2151" data-end="2172">
<p data-start="2153" data-end="2172"><strong data-start="2153" data-end="2161">Mode</strong>：<strong data-start="2162" data-end="2172">Normal</strong></p>
</li>
<li data-start="2173" data-end="2207">
<p data-start="2175" data-end="2207"><strong data-start="2175" data-end="2199">Peripheral Increment</strong>：Disable</p>
</li>
<li data-start="2208" data-end="2237">
<p data-start="2210" data-end="2237"><strong data-start="2210" data-end="2230">Memory Increment</strong>：Enable</p>
</li>
<li data-start="2238" data-end="2275">
<p data-start="2240" data-end="2275"><strong data-start="2240" data-end="2265">Peripheral Data Width</strong>：Half Word</p>
</li>
<li data-start="2276" data-end="2309">
<p data-start="2278" data-end="2309"><strong data-start="2278" data-end="2299">Memory Data Width</strong>：Half Word</p>
</li>
<li data-start="2310" data-end="2341">
<p data-start="2312" data-end="2341"><strong data-start="2312" data-end="2324">Priority</strong>：Low / Medium 都可以</p>
</li>
</ul>
<p data-start="2343" data-end="2459">因为 ADC 数据寄存器是 16 位，DMA 用 <strong data-start="2368" data-end="2381">Half Word</strong> 最合适。STM32 的 ADC 结果寄存器是 16 位，数据可由 DMA 取走。</p>
<hr data-start="2461" data-end="2464" />
<h2 data-start="2466" data-end="2495">三、CubeMX 生成代码关键检查</h2>
<p data-start="2497" data-end="2525">不同 HAL 版本字段名略有差异，但核心会类似下面这样。</p>
<h3 data-start="2527" data-end="2557"><code data-start="2531" data-end="2547">MX_ADC1_Init()</code> 里关键部分（示例）</h3>
<div class="relative w-full my-4">
<div class="">
<div class="relative">
<div class="h-full min-h-0 min-w-0">
<div class="h-full min-h-0 min-w-0">
<div class="border border-token-border-light border-radius-3xl corner-superellipse/1.1 rounded-3xl">
<div class="h-full w-full border-radius-3xl bg-token-bg-elevated-secondary corner-superellipse/1.1 overflow-clip rounded-3xl lxnfua_clipPathFallback">
<div class="pointer-events-none absolute inset-x-4 top-12 bottom-4">
<div class="pointer-events-none sticky z-40 shrink-0 z-1!">
<div class="sticky bg-token-border-light"></div>
</div>
</div>
<div class="">
<div class="relative z-0 flex max-w-full">
<div id="code-block-viewer" class="q9tKkq_viewer cm-editor z-10 light:cm-light dark:cm-light flex h-full w-full flex-col items-stretch ͼ5 ͼj" dir="ltr">
<div class="cm-scroller">
<div class="cm-content q9tKkq_readonly"><span class="ͼe">hadc1</span>.<span class="ͼe">Instance</span> <span class="ͼ8">=</span> <span class="ͼe">ADC1</span>;<br />
<span class="ͼe">hadc1</span>.<span class="ͼe">Init</span>.<span class="ͼe">ClockPrescaler</span> <span class="ͼ8">=</span> <span class="ͼe">ADC_CLOCK_ASYNC_DIV2</span>; <span class="ͼ6">// 或按你的需求</span><br />
<span class="ͼe">hadc1</span>.<span class="ͼe">Init</span>.<span class="ͼe">Resolution</span> <span class="ͼ8">=</span> <span class="ͼe">ADC_RESOLUTION_12B</span>;<br />
<span class="ͼe">hadc1</span>.<span class="ͼe">Init</span>.<span class="ͼe">DataAlign</span> <span class="ͼ8">=</span> <span class="ͼe">ADC_DATAALIGN_RIGHT</span>;<br />
<span class="ͼe">hadc1</span>.<span class="ͼe">Init</span>.<span class="ͼe">ScanConvMode</span> <span class="ͼ8">=</span> <span class="ͼe">ADC_SCAN_ENABLE</span>;<br />
<span class="ͼe">hadc1</span>.<span class="ͼe">Init</span>.<span class="ͼe">EOCSelection</span> <span class="ͼ8">=</span> <span class="ͼe">ADC_EOC_SEQ_CONV</span>;<br />
<span class="ͼe">hadc1</span>.<span class="ͼe">Init</span>.<span class="ͼe">LowPowerAutoWait</span> <span class="ͼ8">=</span> <span class="ͼe">DISABLE</span>;<br />
<span class="ͼe">hadc1</span>.<span class="ͼe">Init</span>.<span class="ͼe">ContinuousConvMode</span> <span class="ͼ8">=</span> <span class="ͼe">DISABLE</span>;<br />
<span class="ͼe">hadc1</span>.<span class="ͼe">Init</span>.<span class="ͼe">NbrOfConversion</span> <span class="ͼ8">=</span> <span class="ͼb">6</span>;<br />
<span class="ͼe">hadc1</span>.<span class="ͼe">Init</span>.<span class="ͼe">DiscontinuousConvMode</span> <span class="ͼ8">=</span> <span class="ͼe">DISABLE</span>;<br />
<span class="ͼe">hadc1</span>.<span class="ͼe">Init</span>.<span class="ͼe">ExternalTrigConv</span> <span class="ͼ8">=</span> <span class="ͼe">ADC_SOFTWARE_START</span>;<br />
<span class="ͼe">hadc1</span>.<span class="ͼe">Init</span>.<span class="ͼe">ExternalTrigConvEdge</span> <span class="ͼ8">=</span> <span class="ͼe">ADC_EXTERNALTRIGCONVEDGE_NONE</span>;<br />
<span class="ͼe">hadc1</span>.<span class="ͼe">Init</span>.<span class="ͼe">DMAContinuousRequests</span> <span class="ͼ8">=</span> <span class="ͼe">DISABLE</span>;<br />
<span class="ͼe">hadc1</span>.<span class="ͼe">Init</span>.<span class="ͼe">Overrun</span> <span class="ͼ8">=</span> <span class="ͼe">ADC_OVR_DATA_OVERWRITTEN</span>;<br />
<span class="ͼe">hadc1</span>.<span class="ͼe">Init</span>.<span class="ͼe">OversamplingMode</span> <span class="ͼ8">=</span> <span class="ͼe">ENABLE</span>;</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="">
<div class=""></div>
</div>
</div>
</div>
</div>
<p data-start="3240" data-end="3278">然后还有 Oversampling 结构体（字段名按你当前 HAL 为准）：</p>
<div class="relative w-full my-4">
<div class="">
<div class="relative">
<div class="h-full min-h-0 min-w-0">
<div class="h-full min-h-0 min-w-0">
<div class="border border-token-border-light border-radius-3xl corner-superellipse/1.1 rounded-3xl">
<div class="h-full w-full border-radius-3xl bg-token-bg-elevated-secondary corner-superellipse/1.1 overflow-clip rounded-3xl lxnfua_clipPathFallback">
<div class="pointer-events-none absolute inset-x-4 top-12 bottom-4">
<div class="pointer-events-none sticky z-40 shrink-0 z-1!">
<div class="sticky bg-token-border-light"></div>
</div>
</div>
<div class="">
<div class="relative z-0 flex max-w-full">
<div id="code-block-viewer" class="q9tKkq_viewer cm-editor z-10 light:cm-light dark:cm-light flex h-full w-full flex-col items-stretch ͼ5 ͼj" dir="ltr">
<div class="cm-scroller">
<div class="cm-content q9tKkq_readonly"><span class="ͼe">hadc1</span>.<span class="ͼe">Init</span>.<span class="ͼe">Oversampling</span>.<span class="ͼe">Ratio</span> <span class="ͼ8">=</span> <span class="ͼe">ADC_OVERSAMPLING_RATIO_8</span>;<br />
<span class="ͼe">hadc1</span>.<span class="ͼe">Init</span>.<span class="ͼe">Oversampling</span>.<span class="ͼe">RightBitShift</span> <span class="ͼ8">=</span> <span class="ͼe">ADC_RIGHTBITSHIFT_3</span>;<br />
<span class="ͼe">hadc1</span>.<span class="ͼe">Init</span>.<span class="ͼe">Oversampling</span>.<span class="ͼe">TriggeredMode</span> <span class="ͼ8">=</span> <span class="ͼe">ADC_TRIGGEREDMODE_SINGLE_TRIGGER</span>;<br />
<span class="ͼe">hadc1</span>.<span class="ͼe">Init</span>.<span class="ͼe">Oversampling</span>.<span class="ͼe">OversamplingStopReset</span> <span class="ͼ8">=</span> <span class="ͼe">ADC_REGOVERSAMPLING_CONTINUED_MODE</span>;</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="">
<div class=""></div>
</div>
</div>
</div>
</div>
<blockquote data-start="3580" data-end="3682">
<p data-start="3582" data-end="3682">这里最后两个枚举名在不同 HAL 版本中可能略有差异；<strong data-start="3609" data-end="3630">CubeMX 生成什么就以什么为准</strong>。<br data-start="3631" data-end="3634" />你只需要保证逻辑上是：<strong data-start="3647" data-end="3681">一次启动后，每个规则转换会连续完成 8 次子采样并输出平均值</strong>。</p>
</blockquote>
<hr data-start="3684" data-end="3687" />
<h2 data-start="3689" data-end="3712">四、6 通道配置示例（Rank 1~6）</h2>
<p data-start="3714" data-end="3731">这个你前面已经配好了，只确认保留：</p>
<div class="relative w-full my-4">
<div class="">
<div class="relative">
<div class="h-full min-h-0 min-w-0">
<div class="h-full min-h-0 min-w-0">
<div class="border border-token-border-light border-radius-3xl corner-superellipse/1.1 rounded-3xl">
<div class="h-full w-full border-radius-3xl bg-token-bg-elevated-secondary corner-superellipse/1.1 overflow-clip rounded-3xl lxnfua_clipPathFallback">
<div class="pointer-events-none absolute inset-x-4 top-12 bottom-4">
<div class="pointer-events-none sticky z-40 shrink-0 z-1!">
<div class="sticky bg-token-border-light"></div>
</div>
</div>
<div class="">
<div class="relative z-0 flex max-w-full">
<div id="code-block-viewer" class="q9tKkq_viewer cm-editor z-10 light:cm-light dark:cm-light flex h-full w-full flex-col items-stretch ͼ5 ͼj" dir="ltr">
<div class="cm-scroller">
<div class="cm-content q9tKkq_readonly"><span class="ͼe">ADC_ChannelConfTypeDef</span> <span class="ͼe">sConfig</span> <span class="ͼ8">=</span> {<span class="ͼb">0</span>};</p>
<p><span class="ͼe">sConfig</span>.<span class="ͼe">SamplingTime</span> <span class="ͼ8">=</span> <span class="ͼe">ADC_SAMPLETIME_47CYCLES_5</span>;<br />
<span class="ͼe">sConfig</span>.<span class="ͼe">SingleDiff</span> <span class="ͼ8">=</span> <span class="ͼe">ADC_SINGLE_ENDED</span>;<br />
<span class="ͼe">sConfig</span>.<span class="ͼe">OffsetNumber</span> <span class="ͼ8">=</span> <span class="ͼe">ADC_OFFSET_NONE</span>;<br />
<span class="ͼe">sConfig</span>.<span class="ͼe">Offset</span> <span class="ͼ8">=</span> <span class="ͼb">0</span>;</p>
<p><span class="ͼ6">/* Rank 1 */</span><br />
<span class="ͼe">sConfig</span>.<span class="ͼe">Channel</span> <span class="ͼ8">=</span> <span class="ͼe">ADC_CHANNEL_1</span>;<br />
<span class="ͼe">sConfig</span>.<span class="ͼe">Rank</span> <span class="ͼ8">=</span> <span class="ͼe">ADC_REGULAR_RANK_1</span>;<br />
<span class="ͼe">HAL_ADC_ConfigChannel</span>(<span class="ͼ8">&amp;</span><span class="ͼe">hadc1</span>, <span class="ͼ8">&amp;</span><span class="ͼe">sConfig</span>);</p>
<p><span class="ͼ6">/* Rank 2 */</span><br />
<span class="ͼe">sConfig</span>.<span class="ͼe">Channel</span> <span class="ͼ8">=</span> <span class="ͼe">ADC_CHANNEL_2</span>;<br />
<span class="ͼe">sConfig</span>.<span class="ͼe">Rank</span> <span class="ͼ8">=</span> <span class="ͼe">ADC_REGULAR_RANK_2</span>;<br />
<span class="ͼe">HAL_ADC_ConfigChannel</span>(<span class="ͼ8">&amp;</span><span class="ͼe">hadc1</span>, <span class="ͼ8">&amp;</span><span class="ͼe">sConfig</span>);</p>
<p><span class="ͼ6">/* &#8230; 一直到 Rank 6 */</span></div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="">
<div class=""></div>
</div>
</div>
</div>
</div>
<p data-start="4211" data-end="4299">STM32L4 的 sequencer 可按任意顺序转换多达 16 个通道；你这里只用 6 个没问题。</p>
<hr data-start="4301" data-end="4304" />
<h2 data-start="4306" data-end="4339">五、应用代码模板（一次触发，DMA 收 6 个“已平均值”）</h2>
<h3 data-start="4341" data-end="4351">1）全局变量</h3>
<div class="relative w-full my-4">
<div class="">
<div class="relative">
<div class="h-full min-h-0 min-w-0">
<div class="h-full min-h-0 min-w-0">
<div class="border border-token-border-light border-radius-3xl corner-superellipse/1.1 rounded-3xl">
<div class="h-full w-full border-radius-3xl bg-token-bg-elevated-secondary corner-superellipse/1.1 overflow-clip rounded-3xl lxnfua_clipPathFallback">
<div class="pointer-events-none absolute inset-x-4 top-12 bottom-4">
<div class="pointer-events-none sticky z-40 shrink-0 z-1!">
<div class="sticky bg-token-border-light"></div>
</div>
</div>
<div class="">
<div class="relative z-0 flex max-w-full">
<div id="code-block-viewer" class="q9tKkq_viewer cm-editor z-10 light:cm-light dark:cm-light flex h-full w-full flex-col items-stretch ͼ5 ͼj" dir="ltr">
<div class="cm-scroller">
<div class="cm-content q9tKkq_readonly"><span class="ͼ7">#include &#8220;main.h&#8221;</span></p>
<p><span class="ͼ8">extern</span> <span class="ͼe">ADC_HandleTypeDef</span> <span class="ͼe">hadc1</span>;</p>
<p><span class="ͼ7">#define ADC_CH_NUM 6</span></p>
<p><span class="ͼe">uint16_t</span> <span class="ͼe">adc_avg_buf</span>[<span class="ͼe">ADC_CH_NUM</span>];<br />
<span class="ͼ8">volatile</span> <span class="ͼe">uint8_t</span> <span class="ͼe">adc_done</span> <span class="ͼ8">=</span> <span class="ͼb">0</span>;</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="">
<div class=""></div>
</div>
</div>
</div>
</div>
<hr data-start="4514" data-end="4517" />
<h3 data-start="4519" data-end="4537">2）初始化时先做一次校准</h3>
<p data-start="4538" data-end="4634">STM32L4 官方建议在应用中做 ADC 校准；当参考电压变化超过 10%（如复位、某些低功耗恢复）时建议重新校准。</p>
<div class="relative w-full my-4">
<div class="">
<div class="relative">
<div class="h-full min-h-0 min-w-0">
<div class="h-full min-h-0 min-w-0">
<div class="border border-token-border-light border-radius-3xl corner-superellipse/1.1 rounded-3xl">
<div class="h-full w-full border-radius-3xl bg-token-bg-elevated-secondary corner-superellipse/1.1 overflow-clip rounded-3xl lxnfua_clipPathFallback">
<div class="pointer-events-none absolute inset-x-4 top-12 bottom-4">
<div class="pointer-events-none sticky z-40 shrink-0 z-1!">
<div class="sticky bg-token-border-light"></div>
</div>
</div>
<div class="">
<div class="relative z-0 flex max-w-full">
<div id="code-block-viewer" class="q9tKkq_viewer cm-editor z-10 light:cm-light dark:cm-light flex h-full w-full flex-col items-stretch ͼ5 ͼj" dir="ltr">
<div class="cm-scroller">
<div class="cm-content q9tKkq_readonly"><span class="ͼe">void</span> <span class="ͼe">ADC1_AppInit</span>(<span class="ͼe">void</span>)<br />
{<br />
<span class="ͼe">HAL_ADCEx_Calibration_Start</span>(<span class="ͼ8">&amp;</span><span class="ͼe">hadc1</span>, <span class="ͼe">ADC_SINGLE_ENDED</span>);<br />
}</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="">
<div class=""></div>
</div>
</div>
</div>
</div>
<hr data-start="4745" data-end="4748" />
<h3 data-start="4750" data-end="4762">3）启动一次采样</h3>
<div class="relative w-full my-4">
<div class="">
<div class="relative">
<div class="h-full min-h-0 min-w-0">
<div class="h-full min-h-0 min-w-0">
<div class="border border-token-border-light border-radius-3xl corner-superellipse/1.1 rounded-3xl">
<div class="h-full w-full border-radius-3xl bg-token-bg-elevated-secondary corner-superellipse/1.1 overflow-clip rounded-3xl lxnfua_clipPathFallback">
<div class="pointer-events-none absolute inset-x-4 top-12 bottom-4">
<div class="pointer-events-none sticky z-40 shrink-0 z-1!">
<div class="sticky bg-token-border-light"></div>
</div>
</div>
<div class="">
<div class="relative z-0 flex max-w-full">
<div id="code-block-viewer" class="q9tKkq_viewer cm-editor z-10 light:cm-light dark:cm-light flex h-full w-full flex-col items-stretch ͼ5 ͼj" dir="ltr">
<div class="cm-scroller">
<div class="cm-content q9tKkq_readonly"><span class="ͼe">HAL_StatusTypeDef</span> <span class="ͼe">ADC1_ScanOnce_Oversampled_Start</span>(<span class="ͼe">void</span>)<br />
{<br />
<span class="ͼe">adc_done</span> <span class="ͼ8">=</span> <span class="ͼb">0</span>;<br />
<span class="ͼ8">return</span> <span class="ͼe">HAL_ADC_Start_DMA</span>(<span class="ͼ8">&amp;</span><span class="ͼe">hadc1</span>, (<span class="ͼe">uint32_t</span> <span class="ͼe">*</span>)<span class="ͼe">adc_avg_buf</span>, <span class="ͼe">ADC_CH_NUM</span>);<br />
}</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="">
<div class=""></div>
</div>
</div>
</div>
</div>
<p data-start="4938" data-end="4975">这里的 <code data-start="4942" data-end="4961">adc_avg_buf[0..5]</code> 不是“原始单次值”，而是：</p>
<ul data-start="4977" data-end="5051">
<li data-start="4977" data-end="4999">
<p data-start="4979" data-end="4999">Rank1 通道：内部 8 次平均后的值</p>
</li>
<li data-start="5000" data-end="5022">
<p data-start="5002" data-end="5022">Rank2 通道：内部 8 次平均后的值</p>
</li>
<li data-start="5023" data-end="5028">
<p data-start="5025" data-end="5028">&#8230;</p>
</li>
<li data-start="5029" data-end="5051">
<p data-start="5031" data-end="5051">Rank6 通道：内部 8 次平均后的值</p>
</li>
</ul>
<hr data-start="5053" data-end="5056" />
<h3 data-start="5058" data-end="5072">4）DMA 完成回调</h3>
<div class="relative w-full my-4">
<div class="">
<div class="relative">
<div class="h-full min-h-0 min-w-0">
<div class="h-full min-h-0 min-w-0">
<div class="border border-token-border-light border-radius-3xl corner-superellipse/1.1 rounded-3xl">
<div class="h-full w-full border-radius-3xl bg-token-bg-elevated-secondary corner-superellipse/1.1 overflow-clip rounded-3xl lxnfua_clipPathFallback">
<div class="pointer-events-none absolute inset-x-4 top-12 bottom-4">
<div class="pointer-events-none sticky z-40 shrink-0 z-1!">
<div class="sticky bg-token-border-light"></div>
</div>
</div>
<div class="">
<div class="relative z-0 flex max-w-full">
<div id="code-block-viewer" class="q9tKkq_viewer cm-editor z-10 light:cm-light dark:cm-light flex h-full w-full flex-col items-stretch ͼ5 ͼj" dir="ltr">
<div class="cm-scroller">
<div class="cm-content q9tKkq_readonly"><span class="ͼe">void</span> <span class="ͼe">HAL_ADC_ConvCpltCallback</span>(<span class="ͼe">ADC_HandleTypeDef</span> <span class="ͼ8">*</span><span class="ͼe">hadc</span>)<br />
{<br />
<span class="ͼ8">if</span> (<span class="ͼe">hadc</span><span class="ͼ8">-&gt;</span><span class="ͼe">Instance</span> <span class="ͼ8">==</span> <span class="ͼe">ADC1</span>)<br />
{<br />
<span class="ͼe">adc_done</span> <span class="ͼ8">=</span> <span class="ͼb">1</span>;<br />
<span class="ͼe">HAL_ADC_Stop_DMA</span>(<span class="ͼ8">&amp;</span><span class="ͼe">hadc1</span>);<br />
}<br />
}</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="">
<div class=""></div>
</div>
</div>
</div>
</div>
<hr data-start="5254" data-end="5257" />
<h3 data-start="5259" data-end="5269">5）使用方法</h3>
<div class="relative w-full my-4">
<div class="">
<div class="relative">
<div class="h-full min-h-0 min-w-0">
<div class="h-full min-h-0 min-w-0">
<div class="border border-token-border-light border-radius-3xl corner-superellipse/1.1 rounded-3xl">
<div class="h-full w-full border-radius-3xl bg-token-bg-elevated-secondary corner-superellipse/1.1 overflow-clip rounded-3xl lxnfua_clipPathFallback">
<div class="pointer-events-none absolute inset-x-4 top-12 bottom-4">
<div class="pointer-events-none sticky z-40 shrink-0 z-1!">
<div class="sticky bg-token-border-light"></div>
</div>
</div>
<div class="">
<div class="relative z-0 flex max-w-full">
<div id="code-block-viewer" class="q9tKkq_viewer cm-editor z-10 light:cm-light dark:cm-light flex h-full w-full flex-col items-stretch ͼ5 ͼj" dir="ltr">
<div class="cm-scroller">
<div class="cm-content q9tKkq_readonly"><span class="ͼ8">if</span> (<span class="ͼe">ADC1_ScanOnce_Oversampled_Start</span>() <span class="ͼ8">==</span> <span class="ͼe">HAL_OK</span>)<br />
{<br />
<span class="ͼ6">// 等待 adc_done 或在主循环里异步判断</span><br />
}</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="">
<div class=""></div>
</div>
</div>
</div>
</div>
<p data-start="5375" data-end="5380">主循环里：</p>
<div class="relative w-full my-4">
<div class="">
<div class="relative">
<div class="h-full min-h-0 min-w-0">
<div class="h-full min-h-0 min-w-0">
<div class="border border-token-border-light border-radius-3xl corner-superellipse/1.1 rounded-3xl">
<div class="h-full w-full border-radius-3xl bg-token-bg-elevated-secondary corner-superellipse/1.1 overflow-clip rounded-3xl lxnfua_clipPathFallback">
<div class="pointer-events-none absolute inset-x-4 top-12 bottom-4">
<div class="pointer-events-none sticky z-40 shrink-0 z-1!">
<div class="sticky bg-token-border-light"></div>
</div>
</div>
<div class="">
<div class="relative z-0 flex max-w-full">
<div id="code-block-viewer" class="q9tKkq_viewer cm-editor z-10 light:cm-light dark:cm-light flex h-full w-full flex-col items-stretch ͼ5 ͼj" dir="ltr">
<div class="cm-scroller">
<div class="cm-content q9tKkq_readonly"><span class="ͼ8">if</span> (<span class="ͼe">adc_done</span>)<br />
{<br />
<span class="ͼe">adc_done</span> <span class="ͼ8">=</span> <span class="ͼb">0</span>;</p>
<p><span class="ͼ6">// adc_avg_buf[0] -&gt; Rank1 通道的平均值</span><br />
<span class="ͼ6">// adc_avg_buf[1] -&gt; Rank2</span><br />
<span class="ͼ6">// &#8230;</span><br />
<span class="ͼ6">// adc_avg_buf[5] -&gt; Rank6</span><br />
}</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="">
<div class=""></div>
</div>
</div>
</div>
</div>
<hr data-start="5552" data-end="5555" />
<h2 data-start="5557" data-end="5576">六、这时“单次采样时间”会怎么变</h2>
<p data-start="5578" data-end="5589">这是你最容易忽略的点。</p>
<p data-start="5591" data-end="5609">如果你原来单通道一次转换耗时近似是：</p>
<p><span class="katex-display"><span class="katex"><span class="katex-mathml">Tone=Tsample+TconvertT_{one} = T_{sample} + T_{convert}</span><span class="katex-html" aria-hidden="true"><span class="base"><span class="mord"><span class="mord mathnormal">T</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist"><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">o</span><span class="mord mathnormal mtight">n</span><span class="mord mathnormal mtight">e</span></span></span></span><span class="vlist-s">​</span></span></span></span></span><span class="mrel">=</span></span><span class="base"><span class="mord"><span class="mord mathnormal">T</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist"><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">s</span><span class="mord mathnormal mtight">am</span><span class="mord mathnormal mtight">pl</span><span class="mord mathnormal mtight">e</span></span></span></span><span class="vlist-s">​</span></span></span></span></span><span class="mbin">+</span></span><span class="base"><span class="mord"><span class="mord mathnormal">T</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist"><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">co</span><span class="mord mathnormal mtight">n</span><span class="mord mathnormal mtight">v</span><span class="mord mathnormal mtight">er</span><span class="mord mathnormal mtight">t</span></span></span></span><span class="vlist-s">​</span></span></span></span></span></span></span></span></span></p>
<p data-start="5653" data-end="5693">那打开 <strong data-start="5657" data-end="5676">8x oversampling</strong> 后，<strong data-start="5679" data-end="5687">每个通道</strong>大致会变成：</p>
<p><span class="katex-display"><span class="katex"><span class="katex-mathml">Tone_os≈8×(Tsample+Tconvert)T_{one\_os} \approx 8 \times (T_{sample} + T_{convert})</span><span class="katex-html" aria-hidden="true"><span class="base"><span class="mord"><span class="mord mathnormal">T</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist"><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">o</span><span class="mord mathnormal mtight">n</span><span class="mord mathnormal mtight">e</span>_<span class="mord mathnormal mtight">os</span></span></span></span><span class="vlist-s">​</span></span></span></span></span><span class="mrel">≈</span></span><span class="base"><span class="mord">8</span><span class="mbin">×</span></span><span class="base"><span class="mopen">(</span><span class="mord"><span class="mord mathnormal">T</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist"><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">s</span><span class="mord mathnormal mtight">am</span><span class="mord mathnormal mtight">pl</span><span class="mord mathnormal mtight">e</span></span></span></span><span class="vlist-s">​</span></span></span></span></span><span class="mbin">+</span></span><span class="base"><span class="mord"><span class="mord mathnormal">T</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist"><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">co</span><span class="mord mathnormal mtight">n</span><span class="mord mathnormal mtight">v</span><span class="mord mathnormal mtight">er</span><span class="mord mathnormal mtight">t</span></span></span></span><span class="vlist-s">​</span></span></span></span></span><span class="mclose">)</span></span></span></span></span></p>
<p data-start="5758" data-end="5857">所以 <strong data-start="5761" data-end="5772">整组 6 通道</strong> 的总时间也大约乘以 8。STM32L4 的硬件过采样就是先做多次采样并累加，再输出给 DMA。</p>
<p data-start="5859" data-end="5866">举例（粗略）：</p>
<ul data-start="5867" data-end="5909">
<li data-start="5867" data-end="5885">
<p data-start="5869" data-end="5885">若原来 6 通道一轮约 20µs</p>
</li>
<li data-start="5886" data-end="5909">
<p data-start="5888" data-end="5909">开 8x 后，可能接近 <strong data-start="5900" data-end="5909">160µs</strong></p>
</li>
</ul>
<p data-start="5911" data-end="5947">所以如果你有“50µs 内完成”的硬限制，8x 可能就太慢了；那就改成：</p>
<ul data-start="5948" data-end="5977">
<li data-start="5948" data-end="5961">
<p data-start="5950" data-end="5961">2x + shift1</p>
</li>
<li data-start="5962" data-end="5977">
<p data-start="5964" data-end="5977">或 4x + shift2</p>
</li>
</ul>
<hr data-start="5979" data-end="5982" />
<h2 data-start="5984" data-end="5994">七、最常见的坑</h2>
<h3 data-start="5996" data-end="6030">1）开了 Oversampling，却还按“原采样速度”估算</h3>
<p data-start="6031" data-end="6089">这是最常见误判。过采样会显著拉长转换时间。</p>
<h3 data-start="6091" data-end="6112">2）DMA 长度还写成 <code data-start="6107" data-end="6112">6*N</code></h3>
<p data-start="6113" data-end="6168">模板 B 下，DMA 长度就是 <strong data-start="6129" data-end="6134">6</strong>，不是 <code data-start="6138" data-end="6143">6×8</code>。<br data-start="6144" data-end="6147" />因为多次采样在 ADC 内部已经处理完了。</p>
<h3 data-start="6170" data-end="6182">3）采样时间太短</h3>
<p data-start="6183" data-end="6290">如果前端源阻抗偏大（比如几十 kΩ 分压），哪怕开了过采样，<strong data-start="6213" data-end="6227">采样电容本身还没充稳</strong>，结果照样漂。<br data-start="6234" data-end="6237" />这时应优先增加 <strong data-start="6245" data-end="6262">Sampling Time</strong>，而不是盲目加大 Oversampling Ratio。</p>
<h3 data-start="6292" data-end="6312">4）误以为分辨率一定“真实提高”</h3>
<p data-start="6313" data-end="6438">过采样确实能改善随机噪声、实现平均/基本滤波，L4 在一定条件下可把 12 位输出扩展到 16 位表现；但这依赖噪声特性和输入信号条件，不是“无条件白捡 4 位有效精度”。</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>电容NP0、C0G、X7R、X5R、Y5V、Z5U的区别</title>
		<link>https://e673.com/capacitornp0-c0g-x7r-x5r-y5v-z5u-compare/</link>
		
		<dc:creator><![CDATA[ahe]]></dc:creator>
		<pubDate>Sat, 28 Feb 2026 04:56:18 +0000</pubDate>
				<category><![CDATA[应用笔记]]></category>
		<category><![CDATA[经验分享]]></category>
		<category><![CDATA[电路]]></category>
		<category><![CDATA[硬件]]></category>
		<guid isPermaLink="false">https://e673.com/?p=3087</guid>

					<description><![CDATA[主要是介质材料不同。不同介质种类&#46;&#46;&#46;]]></description>
										<content:encoded><![CDATA[<div class="css-1ac3ifk">
<div class="css-12o297s">
<div class="css-1ld0bim"><picture><img fetchpriority="high" decoding="async" class="alignnone size-full wp-image-3088" src="https://e673.com/wp-content/uploads/2026/02/8561390c5c274cc6c8f0a8a6e5615d39.jpg" width="576" height="334" alt="NP0、C0G、X7R、X5R、Y5V、Z5U的区别" srcset="https://e673.com/wp-content/uploads/2026/02/8561390c5c274cc6c8f0a8a6e5615d39.jpg 576w, https://e673.com/wp-content/uploads/2026/02/8561390c5c274cc6c8f0a8a6e5615d39-500x290.jpg 500w" sizes="(max-width: 576px) 100vw, 576px" /></picture></div>
</div>
</div>
<article class="Post-Main Post-NormalMain" tabindex="-1">
<header class="Post-Header">
<p data-first-child="" data-pid="1fhL8KMc">主要是介质材料不同。不同介质种类由于它的主要<a class="RichContent-EntityWord css-b7erz1" href="https://zhida.zhihu.com/search?content_id=189120689&amp;content_type=Article&amp;match_order=1&amp;q=%E6%9E%81%E5%8C%96%E7%B1%BB%E5%9E%8B&amp;zd_token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJ6aGlkYV9zZXJ2ZXIiLCJleHAiOjE3NzI0MjcwNTQsInEiOiLmnoHljJbnsbvlnosiLCJ6aGlkYV9zb3VyY2UiOiJlbnRpdHkiLCJjb250ZW50X2lkIjoxODkxMjA2ODksImNvbnRlbnRfdHlwZSI6IkFydGljbGUiLCJtYXRjaF9vcmRlciI6MSwiemRfdG9rZW4iOm51bGx9.Vlhr6H0l-ukFPtZ-RGm1Oiw253pTIwMjmR-_Bmgs6PE&amp;zhida_source=entity" target="_blank" rel="noopener" data-za-not-track-link="true" data-paste-text="true">极化类型</a>不一样，其对电场变化的响应速度和极化率亦不一样。 在相同的体积下的容量就不同，随之带来的<u><a class=" wrap external" href="https://link.zhihu.com/?target=http%3A//www.elecfans.com/tags/%25E7%2594%25B5%25E5%25AE%25B9%25E5%2599%25A8/" target="_blank" rel="nofollow noopener noreferrer" data-za-detail-view-id="1043">电容器</a></u>的介质损耗、容量稳定性等也就不同。介质材料划按容量的温度稳定性可以分为两类，即<a class="RichContent-EntityWord css-b7erz1" href="https://zhida.zhihu.com/search?content_id=189120689&amp;content_type=Article&amp;match_order=1&amp;q=%E2%85%A0%E7%B1%BB%E9%99%B6%E7%93%B7&amp;zd_token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJ6aGlkYV9zZXJ2ZXIiLCJleHAiOjE3NzI0MjcwNTQsInEiOiLihaDnsbvpmbbnk7ciLCJ6aGlkYV9zb3VyY2UiOiJlbnRpdHkiLCJjb250ZW50X2lkIjoxODkxMjA2ODksImNvbnRlbnRfdHlwZSI6IkFydGljbGUiLCJtYXRjaF9vcmRlciI6MSwiemRfdG9rZW4iOm51bGx9.P3QA2e63OWKMyGr6clpkp-I0vYZfH17i9e_52jOO6VE&amp;zhida_source=entity" target="_blank" rel="noopener" data-za-not-track-link="true" data-paste-text="true">Ⅰ类陶瓷</a><u><a class=" wrap external" href="https://link.zhihu.com/?target=http%3A//www.elecfans.com/tags/%25E7%2594%25B5%25E5%25AE%25B9/" target="_blank" rel="nofollow noopener noreferrer" data-za-detail-view-id="1043">电容</a></u>器和<a class="RichContent-EntityWord css-b7erz1" href="https://zhida.zhihu.com/search?content_id=189120689&amp;content_type=Article&amp;match_order=1&amp;q=%E2%85%A1%E7%B1%BB%E9%99%B6%E7%93%B7&amp;zd_token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJ6aGlkYV9zZXJ2ZXIiLCJleHAiOjE3NzI0MjcwNTQsInEiOiLihaHnsbvpmbbnk7ciLCJ6aGlkYV9zb3VyY2UiOiJlbnRpdHkiLCJjb250ZW50X2lkIjoxODkxMjA2ODksImNvbnRlbnRfdHlwZSI6IkFydGljbGUiLCJtYXRjaF9vcmRlciI6MSwiemRfdG9rZW4iOm51bGx9.I3DTpjYa2OE3Mjd9eIIpU9jEHgHOX4Zf_Jy0abU3sFY&amp;zhida_source=entity" target="_blank" rel="noopener" data-za-not-track-link="true" data-paste-text="true">Ⅱ类陶瓷</a>电容器， NPO属于Ⅰ类陶瓷，而其他的<a class="RichContent-EntityWord css-b7erz1" href="https://zhida.zhihu.com/search?content_id=189120689&amp;content_type=Article&amp;match_order=1&amp;q=X7R&amp;zd_token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJ6aGlkYV9zZXJ2ZXIiLCJleHAiOjE3NzI0MjcwNTQsInEiOiJYN1IiLCJ6aGlkYV9zb3VyY2UiOiJlbnRpdHkiLCJjb250ZW50X2lkIjoxODkxMjA2ODksImNvbnRlbnRfdHlwZSI6IkFydGljbGUiLCJtYXRjaF9vcmRlciI6MSwiemRfdG9rZW4iOm51bGx9.7TSKLvwzPrYdUeEx7zwL8lDnV8hbvcAseW6ZXYx2wwk&amp;zhida_source=entity" target="_blank" rel="noopener" data-za-not-track-link="true" data-paste-text="true">X7R</a>、<a class="RichContent-EntityWord css-b7erz1" href="https://zhida.zhihu.com/search?content_id=189120689&amp;content_type=Article&amp;match_order=1&amp;q=X5R&amp;zd_token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJ6aGlkYV9zZXJ2ZXIiLCJleHAiOjE3NzI0MjcwNTQsInEiOiJYNVIiLCJ6aGlkYV9zb3VyY2UiOiJlbnRpdHkiLCJjb250ZW50X2lkIjoxODkxMjA2ODksImNvbnRlbnRfdHlwZSI6IkFydGljbGUiLCJtYXRjaF9vcmRlciI6MSwiemRfdG9rZW4iOm51bGx9.Po28k12T087BN1MrQVazawfHT3zBJJJseJGOkc_MaNw&amp;zhida_source=entity" target="_blank" rel="noopener" data-za-not-track-link="true" data-paste-text="true">X5R</a>、<a class="RichContent-EntityWord css-b7erz1" href="https://zhida.zhihu.com/search?content_id=189120689&amp;content_type=Article&amp;match_order=1&amp;q=Y5V&amp;zd_token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJ6aGlkYV9zZXJ2ZXIiLCJleHAiOjE3NzI0MjcwNTQsInEiOiJZNVYiLCJ6aGlkYV9zb3VyY2UiOiJlbnRpdHkiLCJjb250ZW50X2lkIjoxODkxMjA2ODksImNvbnRlbnRfdHlwZSI6IkFydGljbGUiLCJtYXRjaF9vcmRlciI6MSwiemRfdG9rZW4iOm51bGx9.fuQxwIDUn0OGN_7Z-PGjzKL0L1Io1oCmImWo-SlvoVQ&amp;zhida_source=entity" target="_blank" rel="noopener" data-za-not-track-link="true" data-paste-text="true">Y5V</a>、<a class="RichContent-EntityWord css-b7erz1" href="https://zhida.zhihu.com/search?content_id=189120689&amp;content_type=Article&amp;match_order=1&amp;q=Z5U&amp;zd_token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJ6aGlkYV9zZXJ2ZXIiLCJleHAiOjE3NzI0MjcwNTQsInEiOiJaNVUiLCJ6aGlkYV9zb3VyY2UiOiJlbnRpdHkiLCJjb250ZW50X2lkIjoxODkxMjA2ODksImNvbnRlbnRfdHlwZSI6IkFydGljbGUiLCJtYXRjaF9vcmRlciI6MSwiemRfdG9rZW4iOm51bGx9.hOFSIbt_qFdrJyF-yybJ1Ggf_6fNjevXhfnSGdb65pk&amp;zhida_source=entity" target="_blank" rel="noopener" data-za-not-track-link="true" data-paste-text="true">Z5U</a>等都属于Ⅱ类陶瓷。</p>
<figure data-size="normal">
<div class="RichText-ConditionalImagePortal"><img decoding="async" class="alignnone size-full wp-image-3089" src="https://e673.com/wp-content/uploads/2026/02/v2-d41e5cbc8825d7c747c7e2b00463ddc9_1440w.jpg" width="506" height="125" srcset="https://e673.com/wp-content/uploads/2026/02/v2-d41e5cbc8825d7c747c7e2b00463ddc9_1440w.jpg 506w, https://e673.com/wp-content/uploads/2026/02/v2-d41e5cbc8825d7c747c7e2b00463ddc9_1440w-500x124.jpg 500w" sizes="(max-width: 506px) 100vw, 506px" /></div>
</figure>
<h2 id="h_454453669_0" data-into-catalog-status=""><b>什么是Ⅰ类陶瓷，有什么特点？</b></h2>
<p data-pid="5p1Xt4hy">
Ⅰ类陶瓷电容器（ClassⅠce<u><a class=" wrap external" href="https://link.zhihu.com/?target=http%3A//www.elecfans.com/tags/ram/" target="_blank" rel="nofollow noopener noreferrer" data-za-detail-view-id="1043">ram</a></u>ic capacitor），过去称高频陶瓷电容器（High-frequency ceramic capacitor），介质采用非铁电（顺电）配方，以<u><a class=" wrap external" href="https://link.zhihu.com/?target=http%3A//www.elecfans.com/tags/ti/" target="_blank" rel="nofollow noopener noreferrer" data-za-detail-view-id="1043">Ti</a></u>O2为主要成分（介电常数小于150），因此具有最稳定的性能；或者通过添加少量其他（铁电体）<u><a class=" wrap external" href="https://link.zhihu.com/?target=http%3A//www.hqpcb.com/zhuoluye8" target="_blank" rel="nofollow noopener noreferrer" data-za-detail-view-id="1043">氧化</a></u>物，如CaTiO3 或SrTiO3，构成“扩展型”温度补偿陶瓷，则可表现出近似线性的温度系数，介电常数增加至500。这两种介质损耗小、绝缘电阻高、温度特性好。特别适用于<u><a class=" wrap external" href="https://link.zhihu.com/?target=http%3A//www.elecfans.com/tags/%25E6%258C%25AF%25E8%258D%25A1%25E5%2599%25A8/" target="_blank" rel="nofollow noopener noreferrer" data-za-detail-view-id="1043">振荡器</a></u>、谐振回路、高频<u><a class=" wrap external" href="https://link.zhihu.com/?target=http%3A//www.hqpcb.com/zhuoluye8" target="_blank" rel="nofollow noopener noreferrer" data-za-detail-view-id="1043">电路</a></u>中的<u><a class=" wrap external" href="https://link.zhihu.com/?target=http%3A//www.elecfans.com/tags/%25E8%2580%25A6%25E5%2590%2588/" target="_blank" rel="nofollow noopener noreferrer" data-za-detail-view-id="1043">耦合</a></u>电容，以及其他要求损耗小和电容量稳定的电路，或用于温度补偿。</p>
<h2 id="h_454453669_1" data-into-catalog-status=""><b>Ⅰ类陶瓷的温度特性怎么表示</b></h2>
<p data-pid="2FL06UGT">Ⅰ类陶瓷的温度容量特性（TCC）非常小，单位往往在ppm/℃，容量较基准值的变化往往远小于1皮法。美国<u><a class=" wrap external" href="https://link.zhihu.com/?target=http%3A//www.elecfans.com/soft/special/" target="_blank" rel="nofollow noopener noreferrer" data-za-detail-view-id="1043">电子</a></u>工业协会（EIA）标准采用“字母+数字+字母” 这种代码形式来表示Ⅰ类陶瓷温度系数。比如常见的<a class="RichContent-EntityWord css-b7erz1" href="https://zhida.zhihu.com/search?content_id=189120689&amp;content_type=Article&amp;match_order=1&amp;q=C0G&amp;zd_token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJ6aGlkYV9zZXJ2ZXIiLCJleHAiOjE3NzI0MjcwNTQsInEiOiJDMEciLCJ6aGlkYV9zb3VyY2UiOiJlbnRpdHkiLCJjb250ZW50X2lkIjoxODkxMjA2ODksImNvbnRlbnRfdHlwZSI6IkFydGljbGUiLCJtYXRjaF9vcmRlciI6MSwiemRfdG9rZW4iOm51bGx9.tVzzblgXak3tQN3EZXUG3R5OnzcZc8TsQGfun5vPWUA&amp;zhida_source=entity" target="_blank" rel="noopener" data-za-not-track-link="true" data-paste-text="true">C0G</a>。</p>
<p data-pid="dD-FEgWo">C0G代表的温度系数究竟是多少？</p>
<p data-pid="1CxoCiNc">C 表示电容温度系数的有效数字为 0 ppm/℃</p>
<p data-pid="2GHcvFmg">0 表示有效数字的倍乘因数为 -1（即10的0次方）</p>
<p data-pid="KZfmnRAQ">G 表示随温度变化的容差为 ±30ppm</p>
<figure data-size="normal">
<div class="RichText-ConditionalImagePortal"><img decoding="async" class="alignnone size-full wp-image-3090" src="https://e673.com/wp-content/uploads/2026/02/v2-84482e952d41e481e36b6397d3a6cc63_1440w.jpg" width="607" height="337" srcset="https://e673.com/wp-content/uploads/2026/02/v2-84482e952d41e481e36b6397d3a6cc63_1440w.jpg 607w, https://e673.com/wp-content/uploads/2026/02/v2-84482e952d41e481e36b6397d3a6cc63_1440w-500x278.jpg 500w" sizes="(max-width: 607px) 100vw, 607px" /></div>
</figure>
<p data-pid="9gMIycL8">计算下来，C0G电容最终的TCC为：0×（-1）ppm/℃±30ppm/℃。而相应的其他Ⅰ类陶瓷的温度系数，例如U2J电容，计算下来则为：-750 ppm/℃±120 ppm/℃。</p>
<figure data-size="normal">
<div class="RichText-ConditionalImagePortal"><img loading="lazy" decoding="async" class="alignnone size-full wp-image-3091" src="https://e673.com/wp-content/uploads/2026/02/v2-a873a3920e3aff9326c0e4203dbb8209_1440w.jpg" width="588" height="338" srcset="https://e673.com/wp-content/uploads/2026/02/v2-a873a3920e3aff9326c0e4203dbb8209_1440w.jpg 588w, https://e673.com/wp-content/uploads/2026/02/v2-a873a3920e3aff9326c0e4203dbb8209_1440w-500x287.jpg 500w" sizes="(max-width: 588px) 100vw, 588px" /></div>
</figure>
<h2 id="h_454453669_2" data-into-catalog-status=""><b>NPO和C0G是同一种电容吗？</b></h2>
<p data-pid="lNScXpas">NPO是美国军用标准（<u><a class=" wrap external" href="https://link.zhihu.com/?target=http%3A//www.hqpcb.com/zhuoluye11/%3Ftid%3D26%26plan%3Dfashaoyou" target="_blank" rel="nofollow noopener noreferrer" data-za-detail-view-id="1043">MI</a></u>L）中的说法，其实应该是NP0（零），但一般大家习惯写成NPO（欧）。这是Negative-Positive-Zero的简写，用来表示的温度特性。说明NPO的电容温度特性很好，不随正负温度变化而出现容值漂移。</p>
<p data-pid="NCqnpYgD">从前面我们已经知道，C0G是I类陶瓷中温度稳定性最好的一种，温度特性近似为0，满足“负-正-零”的含义。所以C0G其实和NPO是一样的，只不过是两个标准的两种表示方法（当然，容值更小、精度略差一点的C0K、C0J等也是NPO电容）。类似的，U2J对应于MIL标准中的组别代码为N750。</p>
<p data-pid="bs3A31g8">NPO 电容器随封装形式不同其电容量和介质损耗随频率变化的特性也不同，大封装尺寸的要比小封装尺寸的频率特性好。</p>
<figure data-size="normal">
<div class="RichText-ConditionalImagePortal"><img loading="lazy" decoding="async" class="alignnone size-full wp-image-3092" src="https://e673.com/wp-content/uploads/2026/02/v2-75de4cc45374fec3c8a2a5dd12f1c74e_1440w.jpg" width="619" height="487" srcset="https://e673.com/wp-content/uploads/2026/02/v2-75de4cc45374fec3c8a2a5dd12f1c74e_1440w.jpg 619w, https://e673.com/wp-content/uploads/2026/02/v2-75de4cc45374fec3c8a2a5dd12f1c74e_1440w-500x393.jpg 500w" sizes="(max-width: 619px) 100vw, 619px" /></div>
</figure>
<h2 id="h_454453669_3" data-into-catalog-status=""><b>什么是Ⅱ类陶瓷，有什么特点？</b></h2>
<p data-pid="KPxFuq5l">Ⅱ类陶瓷电容器（Class Ⅱ ceramic capacitor）过去称为为低频陶瓷电容器（Low frequency ceramic capacitor），指用铁电陶瓷作介质的电容器，因此也称铁电陶瓷电容器。这类电容器的比电容大，电容量随温度呈非线性变化，损耗较大，常在电子设备中用于旁路、耦合或用于其它对损耗和电容量稳定性要求不高的电路中。其中Ⅱ类陶瓷电容器又分为稳定级和可用级。X5R、X7R属于Ⅱ类陶瓷的稳定级，而Y5V和Z5U属于可用级。</p>
<p data-pid="Qty64DSq">X5R、X7R、Y5V、Z5U之间的区别是什么？</p>
<p data-pid="UWHCzS1b">区别主要还在于温度范围和容值随温度的变化特性上。下表提示了这些代号的含义。</p>
<figure data-size="normal">
<div class="RichText-ConditionalImagePortal"><img loading="lazy" decoding="async" class="alignnone size-full wp-image-3093" src="https://e673.com/wp-content/uploads/2026/02/v2-a8317644e70edf931af359824a82ef79_1440w.jpg" width="576" height="326" srcset="https://e673.com/wp-content/uploads/2026/02/v2-a8317644e70edf931af359824a82ef79_1440w.jpg 576w, https://e673.com/wp-content/uploads/2026/02/v2-a8317644e70edf931af359824a82ef79_1440w-500x283.jpg 500w, https://e673.com/wp-content/uploads/2026/02/v2-a8317644e70edf931af359824a82ef79_1440w-520x293.jpg 520w" sizes="(max-width: 576px) 100vw, 576px" /></div>
</figure>
<p data-pid="aSX6N7vR">以X7R为例。</p>
<p data-pid="hsqNYynX">X 代表电容最低可工作在 -55℃</p>
<p data-pid="U-LPv4cj">7 代表电容最高可工作在 +125℃</p>
<p data-pid="9XiySm3H">R 代表容值随温度的变化为 ±15%</p>
<p data-pid="u8shGNgf">同样的，Y5V正常工作温度范围在-30℃～+85℃, 对应的电容容量变化为+22～82%；而Z5U 正常工作温度范围在+10℃～+85℃，对应的电容容量变化为+22～-56%。</p>
<figure data-size="normal">
<div class="RichText-ConditionalImagePortal"><img loading="lazy" decoding="async" class="alignnone size-full wp-image-3094" src="https://e673.com/wp-content/uploads/2026/02/v2-9dab5bd9e27f4826c7dd4ee623a43492_1440w.jpg" width="576" height="334" srcset="https://e673.com/wp-content/uploads/2026/02/v2-9dab5bd9e27f4826c7dd4ee623a43492_1440w.jpg 576w, https://e673.com/wp-content/uploads/2026/02/v2-9dab5bd9e27f4826c7dd4ee623a43492_1440w-500x290.jpg 500w" sizes="(max-width: 576px) 100vw, 576px" /></div>
</figure>
</header>
</article>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>取消新款MacBook的掀盖自动启动功能以及恢复开机音效</title>
		<link>https://e673.com/to-disable-the-lid-auto-power-on-and-restart-chime-on-new-macbooks/</link>
		
		<dc:creator><![CDATA[ahe]]></dc:creator>
		<pubDate>Wed, 25 Feb 2026 12:22:59 +0000</pubDate>
				<category><![CDATA[经验分享]]></category>
		<category><![CDATA[OS X]]></category>
		<guid isPermaLink="false">https://e673.com/?p=3085</guid>

					<description><![CDATA[去年 2016 新款 MacBo&#46;&#46;&#46;]]></description>
										<content:encoded><![CDATA[<p>去年 2016 新款 MacBook Pro 起，預設打開筆電上蓋或連接電源供應器時，電腦就會自動開機而且開機時沒有啟動聲，本文教你如何將這些東西調整回原本的樣子。</p>
<p>以下指令都是透過「工具程式」→「終端機」來達成。</p>
<p>取消自動開機：</p><pre class="crayon-plain-tag">sudo nvram AutoBoot=%00</pre><p>重新啟用自動開機：</p><pre class="crayon-plain-tag">sudo nvram AutoBoot=%03</pre><p>開啟開機音效：</p><pre class="crayon-plain-tag">sudo nvram BootAudio=%01</pre><p>取消開機音效：</p><pre class="crayon-plain-tag">sudo nvram BootAudio=%00</pre><p>輸入指令後若提示你輸入密碼，就打吧！</p>
<p>以上，提供大家參考。</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>龙芯架构软件体系中的旧世界与新世界</title>
		<link>https://e673.com/the-new-world-old-world-in-loongarch/</link>
		
		<dc:creator><![CDATA[ahe]]></dc:creator>
		<pubDate>Fri, 19 Dec 2025 05:57:44 +0000</pubDate>
				<category><![CDATA[信创环境]]></category>
		<category><![CDATA[国产系统]]></category>
		<guid isPermaLink="false">https://e673.com/?p=3077</guid>

					<description><![CDATA[我需要关心这问题吗？ 简单来讲，&#46;&#46;&#46;]]></description>
										<content:encoded><![CDATA[<div class="theme-admonition theme-admonition-info admonition_xJq3 alert alert--info">
<div class="admonitionHeading_Gvgb">我需要关心这问题吗？</div>
<div class="admonitionContent_BuS1">
<p>简单来讲，如果您不自行编译安装软件，或许就不必关心。 当然，随意浏览下这篇文章，以后见到这俩说法不至于一头雾水，或者其他同学遇到问题您可以给 tā 们指路，也是不错的。</p>
<ul>
<li>如果您目前在龙架构电脑上使用 Loongnix、麒麟或者 UOS 这些系统，几个月或一两年之后，一定会有一次全系统升级。
<ul>
<li>如果您不升级，那么本身外界如何变化也与您无关。</li>
<li>如果您升级，那么升级之后您应该也感受不到使用上的差别，这其实就是「移民新世界」了。</li>
</ul>
</li>
<li>如果您目前在龙架构电脑上使用 Arch、Gentoo 等等这些系统，那么您已经是新世界住民了，这一切也与您无关。</li>
</ul>
<p>会被坑到的情况目前来看只有：</p>
<ul>
<li>您使用 Loongnix、麒麟或者 UOS 这些系统，但自行编译了一些要用的软件。 在未来那次全系统升级之后，您自行编译的软件应该不再能工作，需要重新编译或从系统包管理器安装。</li>
<li>您是为龙架构适配或开发软件的开发者用户。 会来到这个页面，基本是已经被坑到了，那就往下读吧！</li>
</ul>
</div>
</div>
<p>截至目前（2024 年初），LoongArch 有两套不兼容的软件体系，习惯上大家把它们叫作「旧世界」和「新世界」。 龙芯中科的材料中也有「ABI1.0」、「ABI2.0」的提法（目前所见的表述均未在 ABI 与数字之间加空格）。</p>
<p><strong>旧世界</strong>是指最早在龙芯中科内部适配的、随着 LoongArch 公开一并发布的那个 LoongArch 软件生态。 <strong>新世界</strong>是指龙芯中科与社区同仁一道，以典型开源社区协作模式打造的，完全开源的 LoongArch 软件生态。</p>
<p>两个世界的产生是龙芯中科对 LoongArch 采取了秘密开发、突然全盘推出的商业策略， 由于未能预见到这一版工作有些地方不得不做不兼容修改，而使客户和自身不得不面对的无奈后果。 按照目前的趋势和一些公开消息，未来旧世界将逐渐消亡。 从龙芯 3A6000 一代产品起，相关产品的出厂配套固件都已达到兼容新、旧世界的状态， 但就 2024 年 2 月初的现状而言，可能发行版方面（Loongnix 及其他商业发行版）仍需更长时间才能完成迁移， 因此未能赶上 3A6000 的正式发布。</p>
<p>在讨论龙芯话题时，新旧世界的说法仅仅被用来区分两个不兼容的 LoongArch 生态。 MIPS 型号的龙芯既不是新世界也不是旧世界。 一般只会说「MIPS 时代的龙芯」（the MIPS-era Loongson）怎么怎么样。</p>
<p>「旧世界」、「新世界」的名词形式英译即为「the old world」、「the new world」。 作形容词时一般以连字符连接前后部分即「old-world」、「new-world」。 如果在一段话中频繁使用，有时也会用「OW」、「NW」的缩写形式。</p>
<h2 id="我在哪个世界" class="anchor anchorWithStickyNavbar_LWe7">我在哪个世界？</h2>
<p>如果符合以下任一条件，你就在用<strong>旧世界</strong>：</p>
<ul>
<li>系统是麒麟、Loongnix、UOS 其中之一</li>
<li>内核版本以 4.19 开头</li>
<li>有 WPS 用但没有安装过 <code>libLoL</code> 等旧世界兼容方案</li>
</ul>
<p>如果一条都没中，你就在用<strong>新世界</strong>。</p>
<p>这个判断方法是基于 2024 年 2 月的已知信息设计的。 后续如果没及时更新，可能会不准。</p>
<h2 id="手头这软件是哪个世界的" class="anchor anchorWithStickyNavbar_LWe7">手头这软件是哪个世界的？</h2>
<p>可以使用 <code>file</code> 工具方便地检查一个二进制程序属于哪个世界。 假设你想检查 <code>someprogram</code> 这个文件，就执行 <code>file someprogram</code>，如果输出的行含有这些字样：</p>
<div class="codeBlockContainer_Ckt0 theme-code-block">
<div class="codeBlockContent_biex">
<pre class="crayon-plain-tag">&lt;span class=&quot;token-line&quot;&gt;&lt;span class=&quot;token plain&quot;&gt;interpreter /lib64/ld.so.1, for GNU/Linux 4.15.0&lt;/span&gt;
&lt;/span&gt;</pre></p>
<div class="buttonGroup__atx"></div>
</div>
</div>
<p>就表明这是一个旧世界程序。</p>
<p>相应地，如果输出的行含有这些字样：</p>
<div class="codeBlockContainer_Ckt0 theme-code-block">
<div class="codeBlockContent_biex">
<pre class="crayon-plain-tag">&lt;span class=&quot;token-line&quot;&gt;&lt;span class=&quot;token plain&quot;&gt;interpreter /lib64/ld-linux-loongarch-lp64d.so.1, for GNU/Linux 5.19.0&lt;/span&gt;
&lt;/span&gt;</pre></p>
<div class="buttonGroup__atx"></div>
</div>
</div>
<p>就表明这是一个新世界程序。</p>
<p>以上的判断都适用于系统 libc 为 glibc 且动态链接的程序。如果程序是静态链接的，便没有 interpreter 信息； 如果程序是 Go 语言的或者使用了 musl 作为 C 库，那么文件里就没有对应到 <code>for GNU/Linux</code> 这部分信息的标记。 这种时候试着运行一下就可以了，「异世界」的程序几乎没有可能正常启动。</p>
<p>当然，如果你得到的输出类似下边几行之一：</p>
<div class="codeBlockContainer_Ckt0 theme-code-block">
<div class="codeBlockContent_biex">
<pre class="crayon-plain-tag">&lt;span class=&quot;token-line&quot;&gt;&lt;span class=&quot;token plain&quot;&gt;someprogram: Python script, Unicode text, UTF-8 text executable&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;token-line&quot;&gt;&lt;span class=&quot;token plain&quot;&gt;someprogram: Bourne-Again shell script, ASCII text executable, with escape sequences&lt;/span&gt;
&lt;/span&gt;</pre></p>
<div class="buttonGroup__atx"></div>
</div>
</div>
<p>这种情况代表你检查的程序是个脚本。 一般脚本语言的程序都无所谓新旧世界的，但它仍然有可能依赖一些二进制组件才能正常工作： 因此最靠谱的方法还是试着跑一下！</p>
<h2 id="为啥叫新旧世界" class="anchor anchorWithStickyNavbar_LWe7">为啥叫「新旧世界」？</h2>
<p>在汉语圈其他领域已有「新旧世界」的说法了，例如「旧/新世界猴」、「旧/新世界葡萄酒」： 这里的「世界」其实就是「大陆」。 LoongArch 的新世界也比旧世界出现得晚，并且也存在做事方式上的不兼容，相互之间也有一定的沟通交流， 因此这样的类比在一定程度上还比较贴切。</p>
<p>在技术领域，「新旧世界」的说法也有先例。怀旧计算（retro-computing）群体对 Macintosh 电脑的不同型号就使用 Old World、New World 来区分。 他们的「旧世界」是指系统硬件包含一块 ROM 芯片，其中搭载了 Macintosh Toolbox 这个老固件。 「新世界」硬件则没有这块芯片。 使用 Old/New World ROM 的 Macintosh 型号就被叫作 Old/New World Macs。</p>
<p>另一方面，使用 Linux 源码发行版如 Gentoo 的用户群体， 口语上也有「重做世界」（rebuild world）之类的表达。 此处的「世界」是系统上所有包的统称， 这层意义上 world 的含义类似 userland：统称在用户态运行的所有程序。 对 Gentoo 用户而言，还恰好表示 <code>@world</code> 集合。 而 LoongArch 的新旧世界区分，很大程度上正是由于内核态提供的系统调用界面有细微差别， 导致了用户态的程序相互间不兼容。</p>
<h2 id="俩世界区别在哪" class="anchor anchorWithStickyNavbar_LWe7">俩世界区别在哪？</h2>
<p><strong>源码开放程度不一样</strong>。 新世界都是开源代码，而旧世界的部分底层代码由于知识产权等原因始终没有开放，尽管其中也有一部分后来放出了。 比方说旧世界的 binutils、gcc 在最初发布之后过了几个月有了完整源码，Linux 源码直到 2023 年才有， 但 GSGPU 的 shader 编译器源码就始终没有。 放出的源码基本也比较少有完整的 Git 提交历史，因此不便基于它二次修改或者将其移植到上游新版本。</p>
<p><strong>可用的发行版不一样</strong>。 由于外界拿不到旧世界的完整源码，旧世界发行版只有几个商业公司能做。 社区制作的发行版都属于新世界。</p>
<p>目前已知的旧世界发行版（移植）有：（按英文名字母顺序排序）</p>
<ul>
<li>麒麟 (Kylin)</li>
<li>Loongnix</li>
<li>UOS</li>
</ul>
<p>目前已知的新世界发行版（移植）有：（按英文名字母顺序排序）</p>
<ul>
<li><a class="link--overseas" href="https://www.altlinux.org/Ports/loongarch64" target="_blank" rel="noopener noreferrer">ALT Linux</a></li>
<li><a class="link--overseas" href="https://aosc.io/zh-cn" target="_blank" rel="noopener noreferrer">AOSC OS</a></li>
<li><a class="link--overseas" href="https://github.com/sunhaiyong1978/CLFS-for-LoongArch" target="_blank" rel="noopener noreferrer">CLFS 手册与成品</a></li>
<li><a class="link--overseas" href="https://wiki.debian.org/Ports/loong64" target="_blank" rel="noopener noreferrer">Debian</a></li>
<li><a class="link--overseas" href="https://github.com/fedora-remix-loongarch/releases-info" target="_blank" rel="noopener noreferrer">Fedora LoongArch Remix</a></li>
<li><a class="link--overseas" href="https://wiki.gentoo.org/wiki/Project:LoongArch" target="_blank" rel="noopener noreferrer">Gentoo</a></li>
<li><a class="link--overseas" href="https://github.com/loongarchlinux" target="_blank" rel="noopener noreferrer">Loong Arch Linux</a></li>
<li><a class="link--overseas" href="https://github.com/shipujin/slackware-loongarch64" target="_blank" rel="noopener noreferrer">Slackware</a></li>
<li><a class="link--overseas" href="https://github.com/sunhaiyong1978/Yongbao" target="_blank" rel="noopener noreferrer">Yongbao</a></li>
</ul>
<div class="theme-admonition theme-admonition-warning admonition_xJq3 alert alert--warning">
<div class="admonitionHeading_Gvgb">注意</div>
<div class="admonitionContent_BuS1">
<p>有些新世界发行版是由龙芯员工制作，因此相比其他纯社区工作， 可能会额外集成一些：</p>
<ul>
<li>尚未正式合入上游的代码（如内核的二进制翻译支持）</li>
<li>授权不清晰的内容（如 LATX 没有许可协议，默认为所有权利保留，无法被龙芯中科以外的主体集成、分发等）</li>
<li>尚未开源的内容（如 libffi、LibreOffice、Chromium 等软件，在 CLFS、Loong Arch Linux 很早就有包了，比相应的开源补丁最早一版还早。它们的移植都更晚甚至仍未完全进入上游。最极端的例子是 2021 年初 LoongArch 工具链、内核源码、QEMU 移植都还没开源，硬件也很难买到，CLFS 就已经出来了。）</li>
</ul>
<p>不过随着时间推移，更多内容会进入上游或变成熟， 这种情况以后也会越来越少直至消失。</p>
</div>
</div>
<p><strong>软件版本不一样</strong>。 旧世界的基础组件版本主要跟随当初移植时基于的 Debian 或 RHEL 大版本。 因为商业公司不一定有优先级（或者能力）去关心跟进新版本的事情， 所以旧世界的基础组件版本几乎不会有大的更新。 视具体用户场景和开发、部署习惯而定，有时候这是个好事，有时候很糟心。</p>
<p>以下是一些常见软件、开发工具在两个世界的版本对比：</p>
<table>
<thead>
<tr>
<th>软件</th>
<th>旧世界版本</th>
<th>新世界版本</th>
</tr>
</thead>
<tbody>
<tr>
<td>Linux</td>
<td>4.19</td>
<td>≥ 5.19，常见 ≥ 6.1</td>
</tr>
<tr>
<td>binutils</td>
<td>2.31</td>
<td>≥ 2.38，常见 ≥ 2.40</td>
</tr>
<tr>
<td>gcc</td>
<td>8.3</td>
<td>≥ 12.1，常见 ≥ 13.1</td>
</tr>
<tr>
<td>glibc</td>
<td>2.28</td>
<td>≥ 2.36</td>
</tr>
<tr>
<td>LLVM</td>
<td>8</td>
<td>≥ 16</td>
</tr>
<tr>
<td>Node.js</td>
<td>14.16.1</td>
<td>≥ 18</td>
</tr>
<tr>
<td>Go</td>
<td>1.15、1.18、1.19</td>
<td>≥ 1.19</td>
</tr>
<tr>
<td>Rust</td>
<td>1.41、1.58</td>
<td>≥ 1.71</td>
</tr>
</tbody>
</table>
<h2 id="怎么兼容两个世界" class="anchor anchorWithStickyNavbar_LWe7">怎么兼容两个世界？</h2>
<p>鉴于新旧世界的差异可谓不大不小，想要实现完美的兼容性十分困难：一个方案无法同时具备以下的全部优势，而必须作出取舍。</p>
<ul>
<li>所需磁盘空间尽可能少，</li>
<li>性能开销尽可能低，</li>
<li>对宿主系统的侵入式修改尽可能少，</li>
<li>（尤指极端场景下）尽量保证正确性：不使原世界本应成功的操作在兼容下失败，也不使原世界本应失败的操作在兼容下成功。</li>
</ul>
<p>目前，源自 AOSC 社区的 <a class="link--overseas" href="https://liblol.aosc.io/" target="_blank" rel="noopener noreferrer"><code>libLoL</code></a> 是完成度最高的解决方案，已为许多新世界发行版所集成。 龙芯方面也表态过会开发兼容方案，但截至 2024 年 1 月，未有任何此方面的公开消息。</p>
<h2 id="常见的坑" class="anchor anchorWithStickyNavbar_LWe7">常见的坑</h2>
<h3 id="执行一个程序报没有那个文件或目录咋回事" class="anchor anchorWithStickyNavbar_LWe7">执行一个程序，报「没有那个文件或目录」，咋回事？</h3>
<p>如果您执行一个程序却被告知这个程序不存在，类似这样：</p>
<div class="language-sh-session codeBlockContainer_Ckt0 theme-code-block">
<div class="codeBlockContent_biex">
<pre class="crayon-plain-tag">&lt;span class=&quot;token-line&quot;&gt;&lt;span class=&quot;token command shell-symbol important&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;token command bash language-bash&quot;&gt;./foo&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;token-line&quot;&gt;&lt;span class=&quot;token output&quot;&gt;zsh: no such file or directory: ./foo&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;token-line&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;token-line&quot;&gt;&lt;span class=&quot;token command shell-symbol important&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;token command bash language-bash&quot;&gt;./foo&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;token-line&quot;&gt;&lt;span class=&quot;token output&quot;&gt;zsh: 没有那个文件或目录: ./foo&lt;/span&gt;
&lt;/span&gt;</pre></p>
<div class="buttonGroup__atx"></div>
</div>
</div>
<p>如果这个文件确实存在，那么大概率是您在尝试执行异世界的程序。 不存在的文件并非程序本身，而是所谓「ELF 解释器」， 即上文教你判断一个程序是新世界还是旧世界那里提到的 ELF interpreter。 请换对应您系统的程序版本，或要求软件提供者增加适配。</p>
<h3 id="我给龙架构交叉编译的-go-程序运行报段错误咋回事" class="anchor anchorWithStickyNavbar_LWe7">我给龙架构交叉编译的 Go 程序，运行报段错误，咋回事？</h3>
<p>可能是由于未使用正确的 Go 工具链，导致不经意间构建了与您预期 ABI 相异的二进制。</p>
<ul>
<li>为旧世界发行版构建，必须搭配使用龙芯提供的 Go 工具链与 goproxy 源（所谓「龙芯源」；见下）。</li>
<li>为新世界发行版构建，必须搭配使用上游版本的 Go 工具链，不可使用「龙芯源」。</li>
</ul>
<p>具体而言，Go 程序在异世界运行时，初始化过程中必须的一次 <code>rt_sigprocmask</code> 系统调用会由于它使用的 <code>NSIG</code> 常量定义与当前运行内核不同而失败， 此时 Go 会故意访问一个非法地址直接崩溃： 此时从程序视角看，必然成功的系统调用居然失败，这说明内核服务已经不再可靠，继续下去没有意义。</p>
<h3 id="龙芯提供了很多镜像源龙芯源我能用吗" class="anchor anchorWithStickyNavbar_LWe7">龙芯提供了很多镜像源（「龙芯源」），我能用吗？</h3>
<p>龙芯确实提供了很多「龙芯源」。<strong>旧世界开发者必须使用（系统可能已默认加载了相应的配置修改），新世界开发者不可使用。</strong></p>
<p>出于 SEO 以及行侠仗义（天下开发者是一家）的精神，此处破例提供相应的旧世界文档。</p>
<table>
<thead>
<tr>
<th>种类</th>
<th>典型地址</th>
<th>备注</th>
</tr>
</thead>
<tbody>
<tr>
<td>Go</td>
<td><code>http://goproxy.loongnix.cn:3000</code></td>
<td><a href="https://docs.loongnix.cn/golang/goproxy.html" target="_blank" rel="noopener noreferrer">文档</a></td>
</tr>
<tr>
<td>PyPI</td>
<td><code>https://pypi.loongnix.cn/loongson/pypi</code></td>
<td><a href="https://docs.loongnix.cn/python/python.html" target="_blank" rel="noopener noreferrer">文档</a></td>
</tr>
<tr>
<td>npm</td>
<td><code>https://registry.loongnix.cn:4873</code></td>
<td><a href="http://docs.loongnix.cn/nodejs/doc/list/03.%E9%BE%99%E8%8A%AFnpm%E7%9A%84%E5%AE%89%E8%A3%85%E5%92%8C%E4%BB%93%E5%BA%93%E9%85%8D%E7%BD%AE%E4%BD%BF%E7%94%A8.html" target="_blank" rel="noopener noreferrer">文档</a></td>
</tr>
<tr>
<td>NuGet</td>
<td><code>https://nuget.loongnix.cn</code></td>
<td><a href="https://docs.loongnix.cn/dotnet/support/list/01.%E5%B8%B8%E8%A7%81%E9%97%AE%E9%A2%98-FAQ.html" target="_blank" rel="noopener noreferrer">文档</a></td>
</tr>
<tr>
<td>Rust<br />
(crates.io)</td>
<td><code>https://crates.loongnix.cn</code></td>
<td><a href="https://docs.loongnix.cn/rust/" target="_blank" rel="noopener noreferrer">文档</a></td>
</tr>
<tr>
<td>Harbor<br />
(容器镜像)</td>
<td><code>https://cr.loongnix.cn</code></td>
<td><a class="link--overseas" href="https://loongson-cloud-community.github.io/Loongson-Cloud-Community" target="_blank" rel="noopener noreferrer">文档</a></td>
</tr>
</tbody>
</table>
<p>由于旧世界 ABI、API 并未上游，也不会被上游，那些需要关心系统底层 ABI、API 细节的包， 其正式版本——也就是从上游或常规镜像站下到的版本——在旧世界不可能正常工作：要么没适配过龙架构，要么适配的是新世界。 因此为了方便为旧世界适配软件，龙芯搭建了这些源：那些会受影响的包和相应版本，在这些源里被针对旧世界改过了。</p>
<p>这就是为何新世界开发者不可贪图方便使用它们：从这些软件源中下载的有些包，对新世界而言反而是坏的，更何况完整性校验不会通过——龙芯提供魔改代码的行为与「中间人攻击」没有外观上的差别。 换个角度看，这也是旧世界开发者必须开启它们，并且关闭相应的完整性校验的原因。</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Nuget 生成本地包源v3 feed的自动批处理脚本</title>
		<link>https://e673.com/nuget-create-local-v3-feed-batch-script/</link>
		
		<dc:creator><![CDATA[ahe]]></dc:creator>
		<pubDate>Fri, 05 Dec 2025 00:29:44 +0000</pubDate>
				<category><![CDATA[应用笔记]]></category>
		<category><![CDATA[.Net]]></category>
		<guid isPermaLink="false">https://e673.com/?p=3074</guid>

					<description><![CDATA[[crayon-69a7c9c0&#46;&#46;&#46;]]></description>
										<content:encoded><![CDATA[<p></p><pre class="crayon-plain-tag">@echo off
setlocal enabledelayedexpansion

:: ========================================
:: 配置区 —— 请按需修改
:: ========================================
set RAW_ROOT=F:\third_ext\NAPS2
set LOCAL_FEED=F:\third_ext\LocalFeed
set NUGET_EXE=F:\Tools\nuget.exe
:: ========================================


echo.
echo ======= 自动 NuGet Feed 更新（安全版） =======
echo RAW_ROOT = %RAW_ROOT%
echo LOCAL_FEED = %LOCAL_FEED%
echo NUGET_EXE = %NUGET_EXE%
echo ================================================
echo.

:: ===== 检查路径是否存在 =====
if not exist "%RAW_ROOT%" (
echo [错误] RAW_ROOT 路径不存在：
echo %RAW_ROOT%
pause
exit /b 1
)

if not exist "%NUGET_EXE%" (
echo [错误] 未找到 nuget.exe：
echo %NUGET_EXE%
pause
exit /b 1
)

:: ===== 创建本地 Feed 目录 =====
if not exist "%LOCAL_FEED%" (
echo [Info] LOCAL_FEED 不存在，正在创建...
mkdir "%LOCAL_FEED%"
)

:: ===== 初始化 feed =====
if not exist "%LOCAL_FEED%\index.json" (
echo [Info] 正在初始化 NuGet V3 feed...
"%NUGET_EXE%" init "%RAW_ROOT%" "%LOCAL_FEED%"
echo 初始化完成！
)

echo.
echo [Info] 开始扫描子目录...
echo.

:: ===== 递归扫描所有 .nupkg（必须加引号） =====
for /R "%RAW_ROOT%" %%f in (*.nupkg) do (
echo [Add] %%f

:: 强制使用引号，避免路径非法
"%NUGET_EXE%" add "%%f" -Source "%LOCAL_FEED%"
echo.
)

echo ================================================
echo 所有包已成功导入！
echo 本地源： "%LOCAL_FEED%"
echo ================================================
echo.

pause
exit /b 0</pre><p>&nbsp;</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>.Net Core web项目“检测到URL存在 http host 头攻击漏洞”的修复及验证</title>
		<link>https://e673.com/net-core-web-fix-http-host-header-attack-vulnerabilities/</link>
		
		<dc:creator><![CDATA[ahe]]></dc:creator>
		<pubDate>Wed, 26 Nov 2025 00:34:02 +0000</pubDate>
				<category><![CDATA[应用笔记]]></category>
		<category><![CDATA[.Net]]></category>
		<category><![CDATA[运维]]></category>
		<guid isPermaLink="false">https://e673.com/?p=3066</guid>

					<description><![CDATA[基于.Net 6.0的SSO认证&#46;&#46;&#46;]]></description>
										<content:encoded><![CDATA[<p>基于.Net 6.0的SSO认证小应用，交付后进行web安全扫描，提示“检测到URL存在 http host 头攻击漏洞”，验证过程：</p>
<p>Chrome浏览器安装ModHeader插件，启用插件后，在ModHeader中添加Host  abcdexxx.com，此时刷新目标网址，如果能正常显示或试图跳转至abcdexxx.com ，则证明漏洞存在。修复后应提示400 host invalid，无法正常访问。</p>
<p>ModHeader插件下载<a href="https://e673.com/wp-content/uploads/2025/11/modheader_idgpnmonknjnojddfkpgkljpfnnfcklj.zip">modheader_idgpnmonknjnojddfkpgkljpfnnfcklj</a></p>
<p>以下是修复过程：</p>
<h1 data-start="116" data-end="143"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2705.png" alt="✅" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Host Header Attack 是什么？</h1>
<p data-start="144" data-end="177">攻击者通过伪造 <code data-start="152" data-end="159">Host:</code> 请求头，使应用产生错误行为，例如：</p>
<ul data-start="178" data-end="235">
<li data-start="178" data-end="198">
<p data-start="180" data-end="198">伪造生成带恶意域名的回调 URL</p>
</li>
<li data-start="199" data-end="220">
<p data-start="201" data-end="220">绕过某些基于 Host 判断的逻辑</p>
</li>
<li data-start="221" data-end="235">
<p data-start="223" data-end="235">触发开放重定向等漏洞</p>
</li>
</ul>
<p data-start="237" data-end="287">IIS 默认不会严格验证 Host，所以 ASP.NET Core 应用必须自己限制可信 Host。</p>
<hr data-start="289" data-end="292" />
<h1 data-start="294" data-end="351"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f680.png" alt="🚀" class="wp-smiley" style="height: 1em; max-height: 1em;" /> <strong data-start="299" data-end="351">ASP.NET Core 官方推荐做法：使用 Host Filtering Middleware</strong></h1>
<p data-start="353" data-end="433">ASP.NET Core 自带 <code data-start="369" data-end="405">Microsoft.AspNetCore.HostFiltering</code> 中间件，可以 <strong data-start="413" data-end="432">限制允许访问的 Host 列表</strong>。</p>
<h2 data-start="435" data-end="469">1）在 appsettings.json 添加允许的 Host</h2>
<div class="contain-inline-size rounded-2xl relative bg-token-sidebar-surface-primary">
<div class="sticky top-9">
<div class="absolute end-0 bottom-0 flex h-9 items-center pe-2">
<div class="bg-token-bg-elevated-secondary text-token-text-secondary flex items-center gap-4 rounded-sm px-2 font-sans text-xs"></div>
</div>
</div>
<div class="overflow-y-auto p-4" dir="ltr"><code class="whitespace-pre! language-json"><span class="hljs-punctuation">{</span><br />
<span class="hljs-attr">"AllowedHosts"</span><span class="hljs-punctuation">:</span> <span class="hljs-string">"www.yourdomain.com;yourdomain.com;localhost"</span><br />
<span class="hljs-punctuation">}</span><br />
</code></div>
</div>
<p data-start="552" data-end="583"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/26a0.png" alt="⚠" class="wp-smiley" style="height: 1em; max-height: 1em;" /> <strong data-start="555" data-end="575">必须列出所有可能访问的 Host</strong><br data-start="575" data-end="578" />例如：</p>
<ul data-start="584" data-end="672">
<li data-start="584" data-end="594">
<p data-start="586" data-end="594">不带 www</p>
</li>
<li data-start="595" data-end="604">
<p data-start="597" data-end="604">带 www</p>
</li>
<li data-start="605" data-end="620">
<p data-start="607" data-end="620">内网 IP（如有需要）</p>
</li>
<li data-start="621" data-end="672">
<p data-start="623" data-end="672">HTTPS 端口如使用 5001 这种自定义端口要标明：<code data-start="651" data-end="672">yourdomain.com:5001</code></p>
</li>
</ul>
<hr data-start="674" data-end="677" />
<h2 data-start="679" data-end="727">2）在 Program.cs / Startup.cs 启用 Host Filtering</h2>
<h3 data-start="729" data-end="752">.NET 6+（Program.cs）</h3>
<div class="contain-inline-size rounded-2xl relative bg-token-sidebar-surface-primary">
<div class="sticky top-9">
<div class="absolute end-0 bottom-0 flex h-9 items-center pe-2">
<div class="bg-token-bg-elevated-secondary text-token-text-secondary flex items-center gap-4 rounded-sm px-2 font-sans text-xs"></div>
</div>
</div>
<div class="overflow-y-auto p-4" dir="ltr">
<p><code class="whitespace-pre! language-csharp"><span class="hljs-keyword">var</span> builder = WebApplication.CreateBuilder(args);</code></p>
<p>builder.Services.AddControllers();</p>
<p><span class="hljs-comment">// 启用 Host Filtering</span><br />
builder.Services.AddHostFiltering(options =&gt;<br />
{<br />
<span class="hljs-comment">// 自动从 AllowedHosts 加载</span><br />
});</p>
<p><span class="hljs-keyword">var</span> app = builder.Build();</p>
<p>app.UseHostFiltering();</p>
<p>app.UseRouting();<br />
app.UseAuthorization();<br />
app.MapControllers();<br />
app.Run();</p>
</div>
</div>
<h3 data-start="1084" data-end="1102">若使用 Startup.cs</h3>
<div class="contain-inline-size rounded-2xl relative bg-token-sidebar-surface-primary">
<div class="sticky top-9">
<div class="absolute end-0 bottom-0 flex h-9 items-center pe-2">
<div class="bg-token-bg-elevated-secondary text-token-text-secondary flex items-center gap-4 rounded-sm px-2 font-sans text-xs"></div>
</div>
</div>
<div class="overflow-y-auto p-4" dir="ltr"><code class="whitespace-pre! language-csharp"><code class="whitespace-pre! language-csharp"><span class="hljs-function"><span class="hljs-keyword">public</span></span> <span class="hljs-keyword">void</span> <span class="hljs-title">ConfigureServices</span>(<span class="hljs-params">IServiceCollection services</span>)<br />
{<br />
services.AddControllers();<br />
services.AddHostFiltering();<br />
}</code></code><span class="hljs-function"><span class="hljs-keyword">public</span></span> <span class="hljs-keyword">void</span> <span class="hljs-title">Configure</span>(<span class="hljs-params">IApplicationBuilder app, IWebHostEnvironment env</span>)<br />
{<br />
app.UseHostFiltering();<br />
app.UseRouting();<br />
app.UseAuthorization();<br />
app.UseEndpoints(endpoints =&gt;<br />
{<br />
endpoints.MapControllers();<br />
});<br />
}</p>
</div>
</div>
<hr data-start="1485" data-end="1488" />
<h1 data-start="1490" data-end="1502"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/270b.png" alt="✋" class="wp-smiley" style="height: 1em; max-height: 1em;" /> 中间件会做什么？</h1>
<p data-start="1503" data-end="1535">当请求头中 <code data-start="1509" data-end="1516">Host:</code> 不在 AllowedHosts 内：</p>
<ul data-start="1536" data-end="1613">
<li data-start="1536" data-end="1573">
<p data-start="1538" data-end="1573">ASP.NET Core 返回 <strong data-start="1554" data-end="1573">400 Bad Request</strong></p>
</li>
<li data-start="1574" data-end="1613">
<p data-start="1576" data-end="1613">阻止进一步处理请求<br data-start="1585" data-end="1588" />→ 有效修补 Host Header Attack</p>
</li>
</ul>
<hr data-start="1615" data-end="1618" />
<h1 data-start="1620" data-end="1637"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f512.png" alt="🔒" class="wp-smiley" style="height: 1em; max-height: 1em;" /> IIS 额外加固（可选）</h1>
<h2 data-start="1639" data-end="1667">1）限制操作系统级别的 Host 绑定（强烈推荐）</h2>
<p data-start="1668" data-end="1680">在 IIS 网站绑定中：</p>
<ul data-start="1681" data-end="1743">
<li data-start="1681" data-end="1721">
<p data-start="1683" data-end="1721">只填写正确的 Host Name（如 <a class="decorated-link cursor-pointer" target="_new" rel="noopener" data-start="1702" data-end="1721">www.yourdomain.com）</a></p>
</li>
<li data-start="1722" data-end="1743">
<p data-start="1724" data-end="1743">不要使用 <code data-start="1729" data-end="1734">*:*</code> 或空的 Host</p>
</li>
</ul>
<p data-start="1745" data-end="1748">例如：</p>
<div class="_tableContainer_1rjym_1">
<div class="group _tableWrapper_1rjym_13 flex w-fit flex-col-reverse" tabindex="-1">
<table class="w-fit min-w-(--thread-content-width)" data-start="1750" data-end="1875">
<thead data-start="1750" data-end="1777">
<tr data-start="1750" data-end="1777">
<th data-start="1750" data-end="1757" data-col-size="sm">Type</th>
<th data-start="1757" data-end="1769" data-col-size="sm">Host Name</th>
<th data-start="1769" data-end="1777" data-col-size="sm">Port</th>
</tr>
</thead>
<tbody data-start="1806" data-end="1875">
<tr data-start="1806" data-end="1842">
<td data-start="1806" data-end="1814" data-col-size="sm">https</td>
<td data-col-size="sm" data-start="1814" data-end="1835"><a class="decorated-link cursor-pointer" target="_new" rel="noopener" data-start="1816" data-end="1834">www.yourdomain.com</a></td>
<td data-col-size="sm" data-start="1835" data-end="1842">443</td>
</tr>
<tr data-start="1843" data-end="1875">
<td data-start="1843" data-end="1851" data-col-size="sm">https</td>
<td data-col-size="sm" data-start="1851" data-end="1868">yourdomain.com</td>
<td data-col-size="sm" data-start="1868" data-end="1875">443</td>
</tr>
</tbody>
</table>
</div>
</div>
<p data-start="1877" data-end="1897">这样 IIS 只接受你允许的 Host。</p>
<hr data-start="1899" data-end="1902" />
<h1 data-start="1904" data-end="1945"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f6e1.png" alt="🛡" class="wp-smiley" style="height: 1em; max-height: 1em;" /> 额外防护：阻止 X-Forwarded-Host 注入（若使用反向代理）</h1>
<p data-start="1947" data-end="2023">如果你在前面使用 <strong data-start="1956" data-end="1990">Nginx / Apache / Load Balancer</strong><br data-start="1990" data-end="1993" />请开启 Host Forwarding Strict 模式：</p>
<div class="contain-inline-size rounded-2xl relative bg-token-sidebar-surface-primary">
<div class="sticky top-9">
<div class="absolute end-0 bottom-0 flex h-9 items-center pe-2">
<div class="bg-token-bg-elevated-secondary text-token-text-secondary flex items-center gap-4 rounded-sm px-2 font-sans text-xs"></div>
</div>
</div>
<div class="overflow-y-auto p-4" dir="ltr"><code class="whitespace-pre! language-csharp">app.UseForwardedHeaders(<span class="hljs-keyword">new</span> ForwardedHeadersOptions<br />
{<br />
ForwardedHeaders = ForwardedHeaders.XForwardedHost,<br />
AllowedHosts = { <span class="hljs-string">"yourdomain.com"</span>, <span class="hljs-string">"www.yourdomain.com"</span> }<br />
});<br />
</code></div>
</div>
<hr data-start="2216" data-end="2219" />
<h1 data-start="2221" data-end="2233"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2714.png" alt="✔" class="wp-smiley" style="height: 1em; max-height: 1em;" /> 完整修补步骤总结</h1>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>在麒麟KylinOS、统信UOS等Linux系统安装.Net SDK</title>
		<link>https://e673.com/install-dotnet-sdk-on-kylinos-uos-linux/</link>
		
		<dc:creator><![CDATA[ahe]]></dc:creator>
		<pubDate>Tue, 25 Nov 2025 12:32:22 +0000</pubDate>
				<category><![CDATA[信创环境]]></category>
		<category><![CDATA[.Net]]></category>
		<category><![CDATA[国产系统]]></category>
		<guid isPermaLink="false">https://e673.com/?p=3061</guid>

					<description><![CDATA[本文演示如何使用安装脚本或通过提&#46;&#46;&#46;]]></description>
										<content:encoded><![CDATA[<p>本文演示如何使用安装脚本或通过提取二进制文件，在 Linux 上安装 .NET SDK 或 .NET 运行时。 有关支持内置包管理器的发行版列表，请参阅<a href="https://learn.microsoft.com/zh-cn/dotnet/core/install/linux" data-linktype="relative-path">在 Linux 上安装 .NET</a>。</p>
<p>如果要开发 .NET 应用，请安装 SDK（包括运行时）。 或者，如果只需运行应用程序，请安装运行时。 如果要安装该运行时，建议安装 ASP.NET Core 运行时，因为它同时包括 .NET 和 ASP.NET Core 运行时。</p>
<p>使用 <code>dotnet --list-sdks</code> 和 <code>dotnet --list-runtimes</code> 命令查看安装的版本。 有关详细信息，请参阅<a href="https://learn.microsoft.com/zh-cn/dotnet/core/install/how-to-detect-installed-versions" data-linktype="relative-path">如何检查是否已安装 .NET</a>。</p>
<div class="heading-wrapper" data-heading-level="h2">
<h2 id="net-releases" class="heading-anchor">.NET 版本</h2>
</div>
<p>有两种类型的受支持版本：长期支持（LTS）和标准期限支持（STS）。 所有版本的质量都是一样的。 唯一的区别是支持的时间长短。 LTS 版本获得三年的免费支持和修补程序。 STS 版本可以获得两年的免费支持和修补程序。 有关详细信息，请参阅 <a href="https://dotnet.microsoft.com/platform/support/policy/dotnet-core" data-linktype="external">.NET 支持策略</a>。</p>
<p>下表列出了每个版本的 .NET（和 .NET Core）的支持状态：</p>
<div class="buttons buttons-right margin-bottom-none margin-top-sm"></div>
<div class="inner-focus">
<table class="table table-sm margin-top-none" aria-label=".NET 版本">
<thead>
<tr>
<th><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2714.png" alt="✔" class="wp-smiley" style="height: 1em; max-height: 1em;" /> 受支持</th>
<th><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/274c.png" alt="❌" class="wp-smiley" style="height: 1em; max-height: 1em;" /> 支持不足</th>
</tr>
</thead>
<tbody>
<tr>
<td>10 （LTS）</td>
<td>7</td>
</tr>
<tr>
<td>9 （STS）</td>
<td>6</td>
</tr>
<tr>
<td>8 （LTS）</td>
<td>5</td>
</tr>
<tr>
<td></td>
<td>3.1</td>
</tr>
<tr>
<td></td>
<td>3.0</td>
</tr>
<tr>
<td></td>
<td>2.2</td>
</tr>
<tr>
<td></td>
<td>2.1</td>
</tr>
<tr>
<td></td>
<td>2.0</td>
</tr>
<tr>
<td></td>
<td>1.1</td>
</tr>
<tr>
<td></td>
<td>1.0</td>
</tr>
</tbody>
</table>
</div>
<div class="heading-wrapper" data-heading-level="h2">
<h2 id="dependencies" class="heading-anchor">依赖项</h2>
</div>
<p>安装 .NET 时，可能不会安装某些特定的依赖项，特别是在 <a href="https://learn.microsoft.com/zh-cn/dotnet/core/install/linux-scripted-manual#manual-install" data-linktype="self-bookmark">手动安装</a>时。 以下列表详细介绍了Microsoft支持的 Linux 分发版，并具有可能需要安装的依赖项。 更多信息，请查看发行版页面：</p>
<ul>
<li><a href="https://learn.microsoft.com/zh-cn/dotnet/core/install/linux-alpine#dependencies" data-linktype="relative-path">高山</a></li>
<li><a href="https://learn.microsoft.com/zh-cn/dotnet/core/install/linux-debian#dependencies" data-linktype="relative-path">Debian</a></li>
<li><a href="https://learn.microsoft.com/zh-cn/dotnet/core/install/linux-fedora#dependencies" data-linktype="relative-path">Fedora</a></li>
<li><a href="https://learn.microsoft.com/zh-cn/dotnet/core/install/linux-rhel#dependencies" data-linktype="relative-path">RHEL 和 CentOS Stream</a></li>
<li><a href="https://learn.microsoft.com/zh-cn/dotnet/core/install/linux-sles#dependencies" data-linktype="relative-path">SLES</a></li>
<li><a href="https://learn.microsoft.com/zh-cn/dotnet/core/install/linux-ubuntu-decision#dependencies" data-linktype="relative-path">Ubuntu</a></li>
</ul>
<p>有关依赖项的一般信息，请参阅<a href="https://github.com/dotnet/core/blob/main/Documentation/self-contained-linux-apps.md" data-linktype="external">独立式 Linux 应用</a>。</p>
<div class="heading-wrapper" data-heading-level="h3">
<h3 id="rpm-dependencies" class="heading-anchor">RPM 依赖项</h3>
</div>
<p>如果以前未列出分发版且基于 RPM，则可能需要以下依赖项：</p>
<ul>
<li>glibc</li>
<li>libgcc</li>
<li>CA证书</li>
<li>openssl-libs</li>
<li>libstdc++</li>
<li>libicu</li>
<li>tzdata</li>
<li>krb5-libs</li>
</ul>
<div class="heading-wrapper" data-heading-level="h3">
<h3 id="deb-dependencies" class="heading-anchor">DEB 依赖项</h3>
</div>
<p>如果以前未列出分发版且基于 debian，则可能需要以下依赖项：</p>
<ul>
<li>libc6</li>
<li>libgcc1</li>
<li>libgssapi-krb5-2</li>
<li>libicu70</li>
<li>libssl3</li>
<li>libstdc++6</li>
<li>zlib1g</li>
</ul>
<div class="heading-wrapper" data-heading-level="h2">
<h2 id="scripted-install" class="heading-anchor">脚本安装</h2>
</div>
<p><a href="https://learn.microsoft.com/zh-cn/dotnet/core/tools/dotnet-install-script" data-linktype="relative-path">dotnet-install 脚本</a>用于 <strong>SDK</strong> 和<strong>运行时</strong>的自动化和非管理员安装。 可通过 <a href="https://dot.net/v1/dotnet-install.sh" data-linktype="external">https://dot.net/v1/dotnet-install.sh</a> 下载脚本。如果以这种方式安装 .NET，必须安装 Linux 发行版所需的依赖项。 使用<a href="https://learn.microsoft.com/zh-cn/dotnet/core/install/linux" data-linktype="relative-path">在 Linux 上安装 .NET</a>一文中的链接获得特定 Linux 分发版。</p>
<div class="alert is-primary">
<p class="alert-title"> 重要</p>
<p>需要 Bash 才能运行该脚本。</p>
</div>
<p>可通过 <code>wget</code> 下载脚本：</p>
<div id="code-try-0" class="code-block-header margin-top-sm" data-code-block-header="" data-bi-name="code-header"><span class="code-block-header-language">Bash</span><button class="button button-sm action inner-focus display-none-print" type="button" data-bi-name="copy" data-code-header-copy-button=""></button></div>
<p></p><pre class="crayon-plain-tag">wget https://dot.net/v1/dotnet-install.sh -O dotnet-install.sh</pre><p>或者，使用 <code>curl</code>：</p>
<div id="code-try-1" class="code-block-header margin-top-sm" data-code-block-header="" data-bi-name="code-header"><span class="code-block-header-language">Bash</span><button class="button button-sm action inner-focus display-none-print" type="button" data-bi-name="copy" data-code-header-copy-button=""></button></div>
<p></p><pre class="crayon-plain-tag">curl -L https://dot.net/v1/dotnet-install.sh -o dotnet-install.sh</pre><p>运行此脚本之前，请确保授予此脚本作为可执行文件运行的权限：</p>
<div id="code-try-2" class="code-block-header margin-top-sm" data-code-block-header="" data-bi-name="code-header"><span class="code-block-header-language">Bash</span><button class="button button-sm action inner-focus display-none-print" type="button" data-bi-name="copy" data-code-header-copy-button=""></button></div>
<p></p><pre class="crayon-plain-tag">chmod +x ./dotnet-install.sh</pre><p>该脚本默认安装最新的 <a href="https://dotnet.microsoft.com/platform/support/policy/dotnet-core" data-linktype="external">长期支持 （LTS）</a> SDK 版本，即 .NET 10。 若要安装最新版本（可能不是 (LTS) 版本），请使用 <code>--version latest</code> 参数。</p>
<div id="code-try-3" class="code-block-header margin-top-sm" data-code-block-header="" data-bi-name="code-header"><span class="code-block-header-language">Bash</span><button class="button button-sm action inner-focus display-none-print" type="button" data-bi-name="copy" data-code-header-copy-button=""></button></div>
<p></p><pre class="crayon-plain-tag">./dotnet-install.sh --version latest</pre><p>若要安装 .NET 运行时而非 SDK，请使用 <code>--runtime</code> 参数。</p>
<div id="code-try-4" class="code-block-header margin-top-sm" data-code-block-header="" data-bi-name="code-header"><span class="code-block-header-language">Bash</span><button class="button button-sm action inner-focus display-none-print" type="button" data-bi-name="copy" data-code-header-copy-button=""></button></div>
<p></p><pre class="crayon-plain-tag">./dotnet-install.sh --version latest --runtime aspnetcore</pre><p>可以通过 <code>--channel</code> 参数更改特定主要版本来指示特定版本。 以下命令安装 .NET 9.0 SDK。</p>
<div id="code-try-5" class="code-block-header margin-top-sm" data-code-block-header="" data-bi-name="code-header"><span class="code-block-header-language">Bash</span><button class="button button-sm action inner-focus display-none-print" type="button" data-bi-name="copy" data-code-header-copy-button=""></button></div>
<p></p><pre class="crayon-plain-tag">./dotnet-install.sh --channel 9.0</pre><p>有关详细信息，请参阅 <a href="https://learn.microsoft.com/zh-cn/dotnet/core/tools/dotnet-install-script" data-linktype="relative-path">dotnet-install 脚本参考</a>。</p>
<p>若要在命令行上启用 .NET，请参阅<a href="https://learn.microsoft.com/zh-cn/dotnet/core/install/linux-scripted-manual#set-environment-variables-system-wide" data-linktype="self-bookmark">设置系统范围的环境变量</a>。</p>
<p>若要了解如何使用 .NET CLI，请参阅 <a href="https://learn.microsoft.com/zh-cn/dotnet/core/tools/" data-linktype="relative-path">.NET CLI 概述</a>。</p>
<div class="heading-wrapper" data-heading-level="h2">
<h2 id="manual-install" class="heading-anchor">手动安装</h2>
</div>
<p>除了使用包管理器，还可以下载并手动安装 SDK 和运行时。 手动安装通常作为持续集成测试的一部分执行，或在不支持的 Linux 发行版上执行。 对于开发人员或用户，使用包管理器会更好。</p>
<p>从以下站点之一下载 SDK 或运行时的<strong>二进制</strong>版本。 .NET SDK 包括相应的运行时：</p>
<ul>
<li><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2714.png" alt="✔" class="wp-smiley" style="height: 1em; max-height: 1em;" /> <a href="https://dotnet.microsoft.com/download/dotnet/10.0" data-linktype="external">.NET 10 下载</a></li>
<li><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2714.png" alt="✔" class="wp-smiley" style="height: 1em; max-height: 1em;" /> <a href="https://dotnet.microsoft.com/download/dotnet/9.0" data-linktype="external">.NET 9 下载</a></li>
<li><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2714.png" alt="✔" class="wp-smiley" style="height: 1em; max-height: 1em;" /> <a href="https://dotnet.microsoft.com/download/dotnet/8.0" data-linktype="external">.NET 8 下载</a></li>
<li><a href="https://dotnet.microsoft.com/download/dotnet" data-linktype="external">所有 .NET Core 下载项</a></li>
</ul>
<p>提取已下载的文件并使用 <code>export</code> 命令将 <code>DOTNET_ROOT</code> 设置为提取文件夹的位置，然后确保 .NET 位于 PATH 中。 导出 <code>DOTNET_ROOT</code> 会使 .NET CLI 命令在终端中可用。 有关 .NET 环境变量的详细信息，请参阅 <a href="https://learn.microsoft.com/zh-cn/dotnet/core/tools/dotnet-environment-variables#net-sdk-and-cli-environment-variables" data-linktype="relative-path">.NET SDK 和 CLI 环境变量</a>。</p>
<p>可以将不同版本的 .NET 提取到同一文件夹，这些版本并存。</p>
<div class="heading-wrapper" data-heading-level="h3">
<h3 id="example" class="heading-anchor">示例</h3>
</div>
<p>以下命令使用 Bash 将环境变量 <code>DOTNET_ROOT</code> 设置为当前工作目录，后跟 <code>.dotnet</code>。 如果该目录不存在，则会创建它。 <code>DOTNET_FILE</code> 环境变量是要安装的 .NET 二进制版本的文件名。 此文件会提取到 <code>DOTNET_ROOT</code> 目录中。 <code>DOTNET_ROOT</code> 目录及其 <code>tools</code> 子目录都添加到 <code>PATH</code> 环境变量中。</p>
<div class="alert is-primary">
<p class="alert-title"> 重要</p>
<p>如果运行这些命令，请记住将 <code>DOTNET_FILE</code> 值更改为下载的 .NET 二进制文件的名称。</p>
</div>
<div id="code-try-6" class="code-block-header margin-top-sm" data-code-block-header="" data-bi-name="code-header"><span class="code-block-header-language">Bash</span><button class="button button-sm action inner-focus display-none-print" type="button" data-bi-name="copy" data-code-header-copy-button=""></button></div>
<p></p><pre class="crayon-plain-tag">DOTNET_FILE=dotnet-sdk-9.0.306-linux-x64.tar.gz
&lt;span class=&quot;hljs-built_in&quot;&gt;export&lt;/span&gt; DOTNET_ROOT=$(&lt;span class=&quot;hljs-built_in&quot;&gt;pwd&lt;/span&gt;)/.dotnet

&lt;span class=&quot;hljs-built_in&quot;&gt;mkdir&lt;/span&gt; -p &lt;span class=&quot;hljs-string&quot;&gt;&quot;&lt;span class=&quot;hljs-variable&quot;&gt;$DOTNET_ROOT&lt;/span&gt;&quot;&lt;/span&gt; &amp;amp;&amp;amp; tar zxf &lt;span class=&quot;hljs-string&quot;&gt;&quot;&lt;span class=&quot;hljs-variable&quot;&gt;$DOTNET_FILE&lt;/span&gt;&quot;&lt;/span&gt; -C &lt;span class=&quot;hljs-string&quot;&gt;&quot;&lt;span class=&quot;hljs-variable&quot;&gt;$DOTNET_ROOT&lt;/span&gt;&quot;&lt;/span&gt;

&lt;span class=&quot;hljs-built_in&quot;&gt;export&lt;/span&gt; PATH=&lt;span class=&quot;hljs-variable&quot;&gt;$PATH&lt;/span&gt;:&lt;span class=&quot;hljs-variable&quot;&gt;$DOTNET_ROOT&lt;/span&gt;:&lt;span class=&quot;hljs-variable&quot;&gt;$DOTNET_ROOT&lt;/span&gt;/tools</pre><p>可以在同一文件夹中安装多个版本的 .NET。</p>
<p>还可以将 .NET 安装到由 <code>HOME</code> 变量或 <code>~</code> 路径标识的主目录：</p>
<div id="code-try-7" class="code-block-header margin-top-sm" data-code-block-header="" data-bi-name="code-header"><span class="code-block-header-language">Bash</span><button class="button button-sm action inner-focus display-none-print" type="button" data-bi-name="copy" data-code-header-copy-button=""></button></div>
<p></p><pre class="crayon-plain-tag">&lt;span class=&quot;hljs-built_in&quot;&gt;export&lt;/span&gt; DOTNET_ROOT=&lt;span class=&quot;hljs-variable&quot;&gt;$HOME&lt;/span&gt;/.dotnet</pre><p>若要了解如何使用 .NET CLI，请参阅 <a href="https://learn.microsoft.com/zh-cn/dotnet/core/tools/" data-linktype="relative-path">.NET CLI 概述</a>。</p>
<div class="heading-wrapper" data-heading-level="h2">
<h2 id="verify-downloaded-binaries" class="heading-anchor">验证下载的二进制文件</h2>
</div>
<p>下载安装程序或二进制版本后，请对其进行验证，以确保文件未被更改或损坏。 可以验证计算机上的校验和，然后将其与下载网站上报告的内容进行比较。</p>
<p>从官方下载页下载文件时，文件的校验和会显示在文本框中。 选择“<strong>复制</strong>”按钮将校验和值复制到剪贴板。</p>
<p><span class="mx-imgBorder"><img loading="lazy" decoding="async" class="alignnone size-full wp-image-3062" src="https://e673.com/wp-content/uploads/2025/11/checksum.png" width="900" height="381" alt="具有校验和的 .NET 下载页" srcset="https://e673.com/wp-content/uploads/2025/11/checksum.png 900w, https://e673.com/wp-content/uploads/2025/11/checksum-500x212.png 500w, https://e673.com/wp-content/uploads/2025/11/checksum-768x325.png 768w, https://e673.com/wp-content/uploads/2025/11/checksum-670x284.png 670w" sizes="(max-width: 900px) 100vw, 900px" /></span></p>
<p>使用 <code>sha512sum</code> 命令打印已下载的文件的校验和。 例如，以下命令显示 <em>dotnet-sdk-9.0.306-linux-x64.tar.gz</em> 文件的校验和：</p>
<div id="code-try-8" class="code-block-header margin-top-sm" data-code-block-header="" data-bi-name="code-header"><span class="code-block-header-language">Bash</span><button class="button button-sm action inner-focus display-none-print" type="button" data-bi-name="copy" data-code-header-copy-button=""></button></div>
<p></p><pre class="crayon-plain-tag">$ sha512sum dotnet-sdk-9.0.306-linux-x64.tar.gz
bbb6bdc3c8048e7cc189759b406257839e7d4bd6b8b1ba4bcdaeea8f92340e6855231043dd73f902130ca5357af72b810bb51a4da4d1315a2927ff85f831f1d5  dotnet-sdk-9.0.306-linux-x64.tar.gz</pre><p>将校验和与下载站点提供的值进行比较。</p>
<div class="heading-wrapper" data-heading-level="h3">
<h3 id="use-a-checksum-file-to-validate" class="heading-anchor">使用校验和文件进行验证</h3>
</div>
<p>.NET 发行说明包含校验和文件的链接，可用于验证下载的文件。 以下步骤介绍了如何下载校验和文件并验证 .NET 安装二进制文件：</p>
<ol>
<li>GitHub <a href="https://github.com/dotnet/core/tree/main/release-notes/9.0#releases" data-linktype="external">https://github.com/dotnet/core/tree/main/release-notes/9.0#releases</a> 上 .NET 9 的发行说明页包含名为 <strong>Releases</strong> 的部分。 该部分的表格链接到每个 .NET 9 版本的下载和校验和文件。 下图显示了 .NET 8 发布表作为参考：
<p><span class="mx-imgBorder"><img loading="lazy" decoding="async" class="alignnone size-full wp-image-3063" src="https://e673.com/wp-content/uploads/2025/11/release-notes-root.png" width="258" height="278" alt=".NET 的 github 发行说明版本表" /></span></li>
<li>选择下载的 .NET 版本的链接。
<p>上一部分使用了 .NET SDK 9.0.306，该版本位于 .NET 9.0.10 版本中。</li>
<li>在发布页面中，可以看到 .NET 运行时和 .NET SDK 版本，以及校验和文件的链接。 下图显示了 .NET 8 发布表作为参考：
<p><span class="mx-imgBorder"><img loading="lazy" decoding="async" class="alignnone size-full wp-image-3064" src="https://e673.com/wp-content/uploads/2025/11/release-notes-version.png" width="1055" height="487" alt="具有 .NET 校验和的下载表" srcset="https://e673.com/wp-content/uploads/2025/11/release-notes-version.png 1055w, https://e673.com/wp-content/uploads/2025/11/release-notes-version-500x231.png 500w, https://e673.com/wp-content/uploads/2025/11/release-notes-version-1024x473.png 1024w, https://e673.com/wp-content/uploads/2025/11/release-notes-version-768x355.png 768w, https://e673.com/wp-content/uploads/2025/11/release-notes-version-670x309.png 670w" sizes="(max-width: 1055px) 100vw, 1055px" /></span></li>
<li>右键单击 <strong>校验和</strong> 链接并将其复制到剪贴板。</li>
<li>打开终端。</li>
<li>使用 <code>curl -O {link}</code> 下载校验和文件。
<p>用复制的链接替换以下命令中的链接。</p>
<div id="code-try-9" class="code-block-header margin-top-sm" data-code-block-header="" data-bi-name="code-header"><span class="code-block-header-language">Bash</span><button class="button button-sm action inner-focus display-none-print" type="button" data-bi-name="copy" data-code-header-copy-button=""></button></div>
<p></p><pre class="crayon-plain-tag">curl -O https://builds.dotnet.microsoft.com/dotnet/checksums/9.0.10-sha.txt</pre><p>
</li>
<li>将校验和文件和 .NET 版本文件下载到同一目录后，请使用 <code>sha512sum -c {file} --ignore-missing</code> 命令来验证下载的文件。
<p>如果验证通过，会看到打印了 <strong>OK</strong> 状态的文件：</p>
<div id="code-try-10" class="code-block-header margin-top-sm" data-code-block-header="" data-bi-name="code-header"><span class="code-block-header-language">Bash</span><button class="button button-sm action inner-focus display-none-print" type="button" data-bi-name="copy" data-code-header-copy-button=""></button></div>
<p></p><pre class="crayon-plain-tag">$ sha512sum -c 9.0.10-sha.txt --ignore-missing
dotnet-sdk-9.0.306-linux-x64.tar.gz: OK</pre><p>如果看到文件标记为<strong>失败</strong>，则下载的文件无效，不应使用。</p>
<div id="code-try-11" class="code-block-header margin-top-sm" data-code-block-header="" data-bi-name="code-header"><span class="code-block-header-language">Bash</span><button class="button button-sm action inner-focus display-none-print" type="button" data-bi-name="copy" data-code-header-copy-button=""></button></div>
<p></p><pre class="crayon-plain-tag">$ sha512sum -c 9.0.10-sha.txt --ignore-missing
dotnet-sdk-9.0.306-linux-x64.tar.gz: FAILED
sha512sum: WARNING: 1 computed checksum did NOT match
sha512sum: 9.0.10-sha.txt: no file was verified</pre><p>
</li>
</ol>
<div class="heading-wrapper" data-heading-level="h2">
<h2 id="set-environment-variables-system-wide" class="heading-anchor">设置系统范围的环境变量</h2>
</div>
<p>如果使用了以前的安装脚本，则设置的变量仅适用于当前的终端会话。 将其添加到 shell 配置文件。 Linux 提供了许多不同的 shell，每个都有不同的配置文件。 例如：</p>
<ul>
<li><strong>Bash Shell</strong>: <em>~/.bash_profile</em> 或 <em>~/.bashrc</em></li>
<li><strong>Korn Shell</strong>：~/.kshrc 或 .profile</li>
<li><strong>Z Shell</strong>：~/.zshrc 或 .zprofile</li>
</ul>
<p>在 shell 配置文件中设置以下两个环境变量：</p>
<ul>
<li><code>DOTNET_ROOT</code>
<p>此变量设置为 .NET 安装到的文件夹，如 <code>$HOME/.dotnet</code>：</p>
<div id="code-try-12" class="code-block-header margin-top-sm" data-code-block-header="" data-bi-name="code-header"><span class="code-block-header-language">Bash</span><button class="button button-sm action inner-focus display-none-print" type="button" data-bi-name="copy" data-code-header-copy-button=""></button></div>
<p></p><pre class="crayon-plain-tag">&lt;span class=&quot;hljs-built_in&quot;&gt;export&lt;/span&gt; DOTNET_ROOT=&lt;span class=&quot;hljs-variable&quot;&gt;$HOME&lt;/span&gt;/.dotnet</pre><p>
</li>
<li><code>PATH</code>
<p>此变量应同时包含 <code>DOTNET_ROOT</code> 文件夹和 <code>DOTNET_ROOT/tools</code> 文件夹：</p>
<div id="code-try-13" class="code-block-header margin-top-sm" data-code-block-header="" data-bi-name="code-header"><span class="code-block-header-language">Bash</span><button class="button button-sm action inner-focus display-none-print" type="button" data-bi-name="copy" data-code-header-copy-button=""></button></div>
<p><pre class="crayon-plain-tag">&lt;span class=&quot;hljs-built_in&quot;&gt;export&lt;/span&gt; PATH=&lt;span class=&quot;hljs-variable&quot;&gt;$PATH&lt;/span&gt;:&lt;span class=&quot;hljs-variable&quot;&gt;$DOTNET_ROOT&lt;/span&gt;:&lt;span class=&quot;hljs-variable&quot;&gt;$DOTNET_ROOT&lt;/span&gt;/tools</pre>
</li>
</ul>
<div class="heading-wrapper" data-heading-level="h2">
<h2 id="next-steps" class="heading-anchor">后续步骤</h2>
</div>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>电脉冲刺激器中脉冲量参数的计算</title>
		<link>https://e673.com/calculate-charge-per-pulse-in-pulse-stimulator/</link>
		
		<dc:creator><![CDATA[ahe]]></dc:creator>
		<pubDate>Mon, 24 Nov 2025 02:52:31 +0000</pubDate>
				<category><![CDATA[应用笔记]]></category>
		<category><![CDATA[电路]]></category>
		<guid isPermaLink="false">https://e673.com/?p=3058</guid>

					<description><![CDATA[脉冲量（Charge per P&#46;&#46;&#46;]]></description>
										<content:encoded><![CDATA[<p data-start="0" data-end="75"><strong data-start="0" data-end="32">脉冲量（Charge per Pulse, 单位 µC）</strong> 是电脉冲刺激器最重要的安全参数之一，它表示 <strong data-start="55" data-end="74">单个脉冲向人体组织传递的电荷量</strong>。</p>
<p data-start="77" data-end="88">它的计算公式非常固定：</p>
<hr data-start="90" data-end="93" />
<h1 data-start="95" data-end="114"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2705.png" alt="✅" class="wp-smiley" style="height: 1em; max-height: 1em;" /> <strong data-start="99" data-end="114">脉冲量（µC）计算公式</strong></h1>
<p data-start="116" data-end="152"><strong data-start="116" data-end="152">电荷 Q（库仑） = 电流 I（安培） × 脉冲宽度 PW（秒）</strong></p>
<p data-start="154" data-end="171">为了得到微库仑（µC），通常使用：</p>
<p><span class="katex-display"><span class="katex"><span class="katex-mathml">Q (µC)=I(mA)×PW(µs)÷1000\textbf{Q (µC)} = I(\textbf{mA}) \times PW(\textbf{µs}) \div 1000</span><span class="katex-html" aria-hidden="true"><span class="base"><span class="mord text"><span class="mord textbf">Q (µC)</span></span><span class="mrel">=</span></span><span class="base"><span class="mord mathnormal">I</span><span class="mopen">(</span><span class="mord text"><span class="mord textbf">mA</span></span><span class="mclose">)</span><span class="mbin">×</span></span><span class="base"><span class="mord mathnormal">P</span><span class="mord mathnormal">W</span><span class="mopen">(</span><span class="mord text"><span class="mord textbf">µs</span></span><span class="mclose">)</span><span class="mbin">÷</span></span><span class="base"><span class="mord">1000</span></span></span></span></span></p>
<p data-start="246" data-end="249">因为：</p>
<ul data-start="251" data-end="310">
<li data-start="251" data-end="270">
<p data-start="253" data-end="270">1 mA = 1×10⁻³ A</p>
</li>
<li data-start="271" data-end="290">
<p data-start="273" data-end="290">1 µs = 1×10⁻⁶ s</p>
</li>
<li data-start="291" data-end="310">
<p data-start="293" data-end="310">1 µC = 1×10⁻⁶ C</p>
</li>
</ul>
<p data-start="312" data-end="326">组合起来就是除以 1000。</p>
<hr data-start="328" data-end="331" />
<h1 data-start="333" data-end="346"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f50d.png" alt="🔍" class="wp-smiley" style="height: 1em; max-height: 1em;" /> <strong data-start="338" data-end="346">举例说明</strong></h1>
<h3 data-start="348" data-end="360"><strong data-start="352" data-end="360">例 1：</strong></h3>
<ul data-start="361" data-end="399">
<li data-start="361" data-end="379">
<p data-start="363" data-end="379">电流 = <strong data-start="368" data-end="377">10 mA</strong></p>
</li>
<li data-start="380" data-end="399">
<p data-start="382" data-end="399">脉冲宽度 = <strong data-start="389" data-end="399">200 µs</strong></p>
</li>
</ul>
<p><span class="katex-display"><span class="katex"><span class="katex-mathml">Q=10×200÷1000=2 µCQ = 10 \times 200 \div 1000 = \textbf{2 µC}</span><span class="katex-html" aria-hidden="true"><span class="base"><span class="mord mathnormal">Q</span><span class="mrel">=</span></span><span class="base"><span class="mord">10</span><span class="mbin">×</span></span><span class="base"><span class="mord">200</span><span class="mbin">÷</span></span><span class="base"><span class="mord">1000</span><span class="mrel">=</span></span><span class="base"><span class="mord text"><span class="mord textbf">2 µC</span></span></span></span></span></span></p>
<hr data-start="452" data-end="455" />
<h3 data-start="457" data-end="475"><strong data-start="461" data-end="475">例 2（更强刺激）：</strong></h3>
<ul data-start="476" data-end="514">
<li data-start="476" data-end="494">
<p data-start="478" data-end="494">电流 = <strong data-start="483" data-end="492">20 mA</strong></p>
</li>
<li data-start="495" data-end="514">
<p data-start="497" data-end="514">脉冲宽度 = <strong data-start="504" data-end="514">300 µs</strong></p>
</li>
</ul>
<p><span class="katex-display"><span class="katex"><span class="katex-mathml">Q=20×300÷1000=6 µCQ = 20 \times 300 \div 1000 = \textbf{6 µC}</span><span class="katex-html" aria-hidden="true"><span class="base"><span class="mord mathnormal">Q</span><span class="mrel">=</span></span><span class="base"><span class="mord">20</span><span class="mbin">×</span></span><span class="base"><span class="mord">300</span><span class="mbin">÷</span></span><span class="base"><span class="mord">1000</span><span class="mrel">=</span></span><span class="base"><span class="mord text"><span class="mord textbf">6 µC</span></span></span></span></span></span></p>
<hr data-start="567" data-end="570" />
<h1 data-start="572" data-end="586"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/26a0.png" alt="⚠" class="wp-smiley" style="height: 1em; max-height: 1em;" /> 注意：若是双相脉冲</h1>
<p data-start="588" data-end="635">许多刺激器（如 TENS、EMS、FES）使用 <strong data-start="612" data-end="632">对称双相脉冲（biphasic）</strong>，则：</p>
<ul data-start="637" data-end="703">
<li data-start="637" data-end="670">
<p data-start="639" data-end="670">正相 + 负相 电荷互相抵消，净电荷 <strong data-start="658" data-end="668">≈ 0 µC</strong></p>
</li>
<li data-start="671" data-end="703">
<p data-start="673" data-end="703">但安全分析一般仍看 <strong data-start="683" data-end="703">单相电荷量（per phase）</strong></p>
</li>
</ul>
<p data-start="705" data-end="721">公式一样，只是对每一相各算一次。</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Avalonia.Media.Color中的色彩常量</title>
		<link>https://e673.com/avalonia-media-color-consts/</link>
		
		<dc:creator><![CDATA[ahe]]></dc:creator>
		<pubDate>Fri, 21 Nov 2025 03:32:27 +0000</pubDate>
				<category><![CDATA[参考手册]]></category>
		<category><![CDATA[应用笔记]]></category>
		<category><![CDATA[.Net]]></category>
		<category><![CDATA[Avalonia]]></category>
		<guid isPermaLink="false">https://e673.com/?p=3055</guid>

					<description><![CDATA[Colors in Avalon&#46;&#46;&#46;]]></description>
										<content:encoded><![CDATA[<p>Colors in Avalonia.Media.Color</p>
<p><img loading="lazy" decoding="async" class="alignnone size-large wp-image-3056" src="https://e673.com/wp-content/uploads/2025/11/avalonia_color_map-683x1024.png" alt="" width="683" height="1024" srcset="https://e673.com/wp-content/uploads/2025/11/avalonia_color_map-683x1024.png 683w, https://e673.com/wp-content/uploads/2025/11/avalonia_color_map-333x500.png 333w, https://e673.com/wp-content/uploads/2025/11/avalonia_color_map-768x1152.png 768w, https://e673.com/wp-content/uploads/2025/11/avalonia_color_map-670x1005.png 670w, https://e673.com/wp-content/uploads/2025/11/avalonia_color_map.png 1024w" sizes="(max-width: 683px) 100vw, 683px" /></p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>SqlSugar的插入或更新/AddOrUpdate/InsertOrUpdate</title>
		<link>https://e673.com/sqlsugar-addorupdate-insertorupdate/</link>
		
		<dc:creator><![CDATA[ahe]]></dc:creator>
		<pubDate>Mon, 17 Nov 2025 00:26:24 +0000</pubDate>
				<category><![CDATA[应用笔记]]></category>
		<category><![CDATA[.Net]]></category>
		<category><![CDATA[数据库]]></category>
		<guid isPermaLink="false">https://e673.com/?p=3051</guid>

					<description><![CDATA[简单用例 1、简化写法 新功能 &#46;&#46;&#46;]]></description>
										<content:encoded><![CDATA[<h2 id="blogTitle0">简单用例</h2>
<h3 id="blogTitle1">1、简化写法</h3>
<p>新功能 5.0.6.2+</p>
<p>优点：代码简洁</p>
<p>缺点：没办法使用insertable updateable 扩展方法</p>
<table class="syntaxhighlighter  c#" border="0" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td class="code">
<div class="container">
<div class="line number1 index0 alt2"><code class="c# comments">//功能1:存在数据库更新 不存在插入 (默认是主键)</code></div>
<div class="line number2 index1 alt1"><code class="c# plain">Db.Storageable(list2).ExecuteCommand()</code><code class="c# comments">//（老版本是Saveable）</code></div>
<div class="line number3 index2 alt2"></div>
<div class="line number4 index3 alt1"><code class="c# comments">//分页 5.1.4.103-preview04+</code></div>
<div class="line number5 index4 alt2"><code class="c# plain">Db.Storageable(list2).PageSize(1000).ExecuteCommand();</code></div>
<div class="line number6 index5 alt1"><code class="c# plain">Db.Storageable(list2).PageSize(1000,exrows=&gt; {   }).ExecuteCommand();</code></div>
<div class="line number7 index6 alt2"></div>
<div class="line number8 index7 alt1"></div>
<div class="line number9 index8 alt2"><code class="c# comments">//实体如果没主键可以通过WhereColumn(it=&gt;it.Id)指定虚拟主键 </code></div>
<div class="line number10 index9 alt1"></div>
<div class="line number11 index10 alt2"></div>
<div class="line number12 index11 alt1"><code class="c# comments">//功能2:主键等于默认值插入否则更新（如果可以满足需求这种性能要好的多） 5.1.4.62</code></div>
<div class="line number13 index12 alt2"><code class="c# plain">Db.Storageable(list).DefaultAddElseUpdate().ExecuteCommand()</code></div>
<div class="line number14 index13 alt1"><code class="c# comments">//原理: id=0插入 id不等于0更新</code></div>
<div class="line number15 index14 alt2"></div>
<div class="line number16 index15 alt1"><code class="c# comments">//或功能3:大数据插入或者更新 （部分库不支持自增）</code></div>
<div class="line number17 index16 alt2"><code class="c# plain">db.Fastest&lt;Order&gt;().BulkMerge(List);</code></div>
<div class="line number18 index17 alt1"><code class="c# comments">//db.Storageable&lt;Order&gt;(data).ExecuteSqlBulkCopy()</code></div>
<div class="line number19 index18 alt2"></div>
<div class="line number20 index19 alt1"></div>
<div class="line number21 index20 alt2"><code class="c# comments">//功能4:分表 5.1.4.132+</code></div>
<div class="line number22 index21 alt1"><code class="c# plain">db.Storageable(data).SplitTable().ExecuteCommand();  </code></div>
<div class="line number23 index22 alt2"><code class="c# plain">db.Storageable&lt;Order&gt;(data).SplitTable().ExecuteSqlBulkCopy()</code></div>
</div>
</td>
</tr>
</tbody>
</table>
<h3 id="blogTitle2">2、功能写法</h3>
<p>这种写法后期扩展性强 ，调试也方便，insertable updateable支持扩展方法</p>
<table class="syntaxhighlighter  c#" border="0" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td class="code">
<div class="container">
<div class="line number1 index0 alt2"><code class="c# spaces"> </code><code class="c# comments">//功能写法可以将插入和更新拆开，然后调用插入和更新独有特性</code></div>
<div class="line number2 index1 alt1"><code class="c# spaces"> </code><code class="c# keyword">var</code> <code class="c# plain">x= db.Storageable(item).ToStorage();</code></div>
<div class="line number3 index2 alt2"><code class="c# spaces">  </code><code class="c# plain">x.AsInsertable.ExecuteCommand();</code><code class="c# comments">//不存在插入</code></div>
<div class="line number4 index3 alt1"><code class="c# spaces">  </code><code class="c# plain">x.AsUpdateable.ExecuteCommand();</code><code class="c# comments">//存在更新</code></div>
<div class="line number5 index4 alt2"><code class="c# spaces"> </code></div>
<div class="line number6 index5 alt1"><code class="c# spaces"> </code><code class="c# comments">//现实案例: 如果是插入：F_Status=草稿箱，如果是更新：不更新这个字段</code></div>
<div class="line number7 index6 alt2"><code class="c# spaces"> </code><code class="c# plain">item.F_Status=</code><code class="c# string">"草稿箱"</code><code class="c# plain">;</code></div>
<div class="line number8 index7 alt1"><code class="c# spaces"> </code><code class="c# keyword">var</code> <code class="c# plain">x= db.Storageable(item).ToStorage();</code></div>
<div class="line number9 index8 alt2"><code class="c# spaces"> </code><code class="c# plain">x.AsInsertable.ExecuteCommand();</code><code class="c# comments">//不存在插入</code></div>
<div class="line number10 index9 alt1"><code class="c# spaces"> </code><code class="c# plain">x.AsUpdateable.IgnoreColumns(z=&gt;z.F_Status).ExecuteCommand();</code><code class="c# comments">//存在更新</code></div>
<div class="line number11 index10 alt2"><code class="c# spaces">    </code></div>
<div class="line number12 index11 alt1"><code class="c# spaces"> </code><code class="c# comments">//你可以写成只插入不更新</code></div>
<div class="line number13 index12 alt2"><code class="c# spaces"> </code><code class="c# keyword">var</code> <code class="c# plain">x= db.Storageable(item).ToStorage();</code></div>
<div class="line number14 index13 alt1"><code class="c# spaces"> </code><code class="c# plain">x.AsInsertable.ExecuteCommand(); </code></div>
<div class="line number15 index14 alt2"><code class="c# spaces">  </code></div>
<div class="line number16 index15 alt1"><code class="c# spaces"> </code><code class="c# comments">//你可以写成只更新不插入</code></div>
<div class="line number17 index16 alt2"><code class="c# spaces">  </code><code class="c# keyword">var</code> <code class="c# plain">x= db.Storageable(item).ToStorage();</code></div>
<div class="line number18 index17 alt1"><code class="c# spaces"> </code><code class="c# plain">x.AsUpdateable.ExecuteCommand(); </code></div>
<div class="line number19 index18 alt2"></div>
<div class="line number20 index19 alt1"><code class="c# spaces"> </code></div>
<div class="line number21 index20 alt2"><code class="c# spaces"> </code><code class="c# comments">//你也可以拿到更新哪几条和插入哪几条</code></div>
<div class="line number22 index21 alt1"><code class="c# spaces">  </code><code class="c# keyword">var</code> <code class="c# plain">x= db.Storageable(item).ToStorage();</code></div>
<div class="line number23 index22 alt2"><code class="c# spaces"> </code><code class="c# keyword">var</code> <code class="c# plain">insertList=x.InsertList.Select(z=&gt;z.Item).ToList(); </code></div>
<div class="line number24 index23 alt1"><code class="c# spaces"> </code><code class="c# keyword">var</code> <code class="c# plain">updateList=x.UpdateList.Select(z=&gt;z.Item).ToList();</code></div>
<div class="line number25 index24 alt2"><code class="c# spaces"> </code></div>
<div class="line number26 index25 alt1"><code class="c# spaces">    </code></div>
<div class="line number27 index26 alt2"><code class="c# spaces"> </code><code class="c# comments">//原理 </code></div>
<div class="line number28 index27 alt1"><code class="c# spaces"> </code><code class="c# plain">x.AsInsertable.ExecuteCommand() 等于 </code></div>
<div class="line number29 index28 alt2"><code class="c# spaces"> </code><code class="c# plain">Db.Insertable(x.InsertList.Select(it=&gt;it.Item).ToList()).ExecuteCommand()</code></div>
<div class="line number30 index29 alt1"></div>
<div class="line number31 index30 alt2"><code class="c# spaces"> </code><code class="c# plain">x.AsUpdateable.ExecuteCommand()  等于  </code></div>
<div class="line number32 index31 alt1"><code class="c# spaces"> </code><code class="c# plain">Db.Updateable(x.UpdateList.Select(it=&gt;it.Item).ToList()).ExecuteCommand()</code></div>
</div>
</td>
</tr>
</tbody>
</table>
<h3 id="blogTitle3">3、添加事务锁</h3>
<table class="syntaxhighlighter  c#" border="0" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td class="code">
<div class="container">
<div class="line number1 index0 alt2"><code class="c# comments">//需要事务才能用这个锁</code></div>
<div class="line number2 index1 alt1"><code class="c# plain">Db.Storageable(list2).TranLock(DbLockType.Wait).ExecuteCommand()</code><code class="c# comments">//建议单条保存使用并且用主键这样会走行锁，不锁整表</code></div>
<div class="line number3 index2 alt2"><code class="c# comments">//DbLockType.Wait 多个并发等待执行</code></div>
<div class="line number4 index3 alt1"><code class="c# comments">//DbLockType.Error 并发只保留一个其他扔错</code></div>
</div>
</td>
</tr>
</tbody>
</table>
<h2 id="blogTitle4">调试数据</h2>
<p>在执行插入或者更新前打上断点，我们可以看到是走更新还是走插入，具体哪些是更新，哪些是插入</p>
<p><img loading="lazy" decoding="async" class="alignnone size-full wp-image-3052" src="https://e673.com/wp-content/uploads/2025/11/6378174222510941513821492.png" width="1177" height="570" alt="image.png" title="image.png" srcset="https://e673.com/wp-content/uploads/2025/11/6378174222510941513821492.png 1177w, https://e673.com/wp-content/uploads/2025/11/6378174222510941513821492-500x242.png 500w, https://e673.com/wp-content/uploads/2025/11/6378174222510941513821492-1024x496.png 1024w, https://e673.com/wp-content/uploads/2025/11/6378174222510941513821492-768x372.png 768w, https://e673.com/wp-content/uploads/2025/11/6378174222510941513821492-670x324.png 670w" sizes="(max-width: 1177px) 100vw, 1177px" /></p>
<table class="syntaxhighlighter  c#" border="0" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td class="code">
<div class="container">
<div class="line number1 index0 alt2"><code class="c# plain">样插入和更新就不会存毫秒</code></div>
</div>
</td>
</tr>
</tbody>
</table>
<h2 id="blogTitle5">无主键用法</h2>
<p>不用主键作为条件有2种情况</p>
<p>实体有主键并且是Sqlite请升级到5.1.4.94以上版本</p>
<table class="syntaxhighlighter  c#" border="0" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td class="code">
<div class="container">
<div class="line number1 index0 alt2"><code class="c# plain">Db.Storageable(list2) </code></div>
<div class="line number2 index1 alt1"><code class="c# spaces">      </code><code class="c# plain">.WhereColumns(it=&gt;it.Id)</code><code class="c# comments">//指定一个条件，当然支持多个 new {it.id,it.name}</code></div>
<div class="line number3 index2 alt2"><code class="c# spaces">      </code><code class="c# plain">.ExecuteCommand();</code><code class="c# comments">//将数据进行分组</code></div>
<div class="line number4 index3 alt1"><code class="c# spaces">      </code></div>
<div class="line number5 index4 alt2"><code class="c# comments">//注意：实体存在主键并且条件不是主键要升级较高版本</code></div>
</div>
</td>
</tr>
</tbody>
</table>
<h2 id="blogTitle6">时间类型问题</h2>
<p>新功能：5.0.9.3-preview05 时间格式化 防止时止时间精度引起的失效，针对多元化时间格式进行处理</p>
<table class="syntaxhighlighter  c#" border="0" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td class="code">
<div class="container">
<div class="line number1 index0 alt2"><code class="c# spaces"> </code><code class="c# keyword">var</code> <code class="c# plain">x=Db.Storageable(list2) </code></div>
<div class="line number2 index1 alt1"><code class="c# spaces"> </code><code class="c# plain">.WhereColumns(it=&gt;it.CreateTime, date=&gt;date.ToString(</code><code class="c# string">"yyyy-MM-dd HH:mm:ss.fff"</code><code class="c# plain">))</code></div>
<div class="line number3 index2 alt2"><code class="c# spaces"> </code><code class="c# plain">.ToStorage();</code></div>
<div class="line number4 index3 alt1"><code class="c# spaces"> </code></div>
<div class="line number5 index4 alt2"><code class="c# spaces">   </code><code class="c# plain">x.AsInsertable.ExecuteCommand(); </code><code class="c# comments">//执行插入</code></div>
<div class="line number6 index5 alt1"><code class="c# spaces">   </code><code class="c# plain">x.AsUpdateable.ExecuteCommand(); </code><code class="c# comments">//执行更新　</code></div>
<div class="line number7 index6 alt2"><code class="c# spaces"> </code></div>
<div class="line number8 index7 alt1"><code class="c# spaces"> </code><code class="c# comments">//完美解决时间匹配不到问题</code></div>
</div>
</td>
</tr>
</tbody>
</table>
<p>其它方案：Oracle和Sqlite用户会有遇到</p>
<table class="syntaxhighlighter  c#" border="0" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td class="code">
<div class="container">
<div class="line number1 index0 alt2"><code class="c# spaces"> </code><code class="c# plain">db.CurrentConnectionConfig.MoreSettings = </code><code class="c# keyword">new</code> <code class="c# plain">ConnMoreSettings</code></div>
<div class="line number2 index1 alt1"><code class="c# spaces"> </code><code class="c# plain">{</code></div>
<div class="line number3 index2 alt2"><code class="c# spaces">       </code><code class="c# plain">DisableMillisecond=</code><code class="c# keyword">true</code><code class="c# comments">//插入和更新禁用毫秒</code></div>
<div class="line number4 index3 alt1"><code class="c# spaces"> </code><code class="c# plain">};</code></div>
</div>
</td>
</tr>
</tbody>
</table>
<h2 id="blogTitle7">Object、接口、抽象类保存</h2>
<p>object.GetType必须还是类，只是用于弱类型接收，并不是真的Object</p>
<table class="syntaxhighlighter  c#" border="0" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td class="code">
<div class="container">
<div class="line number1 index0 alt2"><code class="c# comments">//单条</code></div>
<div class="line number2 index1 alt1"><code class="c# keyword">object</code> <code class="c# plain">o=</code><code class="c# keyword">new</code> <code class="c# plain">Order{id=1,name=</code><code class="c# string">"a"</code><code class="c# plain">};</code><code class="c# comments">//虽然是object类型必须是真实的类 ，一般于用反射出来的对象</code></div>
<div class="line number3 index2 alt2"><code class="c# plain">db.StorageableByObject(o).ExecuteCommand();</code><code class="c# comments">//API比较简单没有其他功能</code></div>
<div class="line number4 index3 alt1"></div>
<div class="line number5 index4 alt2"><code class="c# comments">//多条</code></div>
<div class="line number6 index5 alt1"><code class="c# keyword">object</code> <code class="c# plain">o=</code><code class="c# keyword">new</code> <code class="c# plain">List&lt;Order&gt;(){...};</code><code class="c# comments">//虽然是object类型必须是真实的类 ，一般于用反射出来的对象</code></div>
<div class="line number7 index6 alt2"><code class="c# plain">db.StorageableByObject(o).ExecuteCommand();</code><code class="c# comments">//API比较简单没有其他功能</code></div>
</div>
</td>
</tr>
</tbody>
</table>
<h2 id="blogTitle8">DataTable类型:保存5.0.4.8</h2>
<table class="syntaxhighlighter  c#" border="0" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td class="code">
<div class="container">
<div class="line number1 index0 alt2"><code class="c# keyword">var</code> <code class="c# plain">dt=</code><code class="c# keyword">new</code> <code class="c# plain">DataTable();</code></div>
<div class="line number2 index1 alt1"><code class="c# plain">dt.TableName = </code><code class="c# string">"order"</code><code class="c# plain">; </code><code class="c# comments">//设置表名</code></div>
<div class="line number3 index2 alt2"><code class="c# spaces">            </code></div>
<div class="line number4 index3 alt1"><code class="c# keyword">var</code> <code class="c# plain">addRow = dt.NewRow();</code></div>
<div class="line number5 index4 alt2"><code class="c# plain">addRow[</code><code class="c# string">"id"</code><code class="c# plain">] = 0;</code></div>
<div class="line number6 index5 alt1"><code class="c# plain">addRow[</code><code class="c# string">"price"</code><code class="c# plain">] = 1;</code></div>
<div class="line number7 index6 alt2"><code class="c# plain">addRow[</code><code class="c# string">"Name"</code><code class="c# plain">] = </code><code class="c# string">"a"</code><code class="c# plain">;</code></div>
<div class="line number8 index7 alt1"><code class="c# plain">dt.Rows.Add(addRow);</code><code class="c# comments">//添加数据</code></div>
<div class="line number9 index8 alt2"><code class="c# spaces">            </code></div>
<div class="line number10 index9 alt1"><code class="c# keyword">var</code> <code class="c# plain">x= db.Storageable(dt).WhereColumns(</code><code class="c# string">"id"</code><code class="c# plain">).ToStorage();</code><code class="c# comments">//id作为主键</code></div>
<div class="line number11 index10 alt2"><code class="c# plain">x.AsInsertable.IgnoreColumns(</code><code class="c# string">"id"</code><code class="c# plain">).ExecuteCommand();</code><code class="c# comments">//如果是自增要添加IgnoreColumns</code></div>
<div class="line number12 index11 alt1"><code class="c# plain">x.AsUpdateable.ExecuteCommand();</code></div>
<div class="line number13 index12 alt2"></div>
<div class="line number14 index13 alt1"></div>
<div class="line number15 index14 alt2"><code class="c# comments">//DataTable也可以分页</code></div>
<div class="line number16 index15 alt1"><code class="c# plain">db.Utilities.PageEach(dataTable.Rows.Cast&lt;DataRow&gt;().ToList(),100, it =&gt;</code></div>
<div class="line number17 index16 alt2"><code class="c# plain">{</code></div>
<div class="line number18 index17 alt1"><code class="c# spaces">    </code><code class="c# keyword">var</code> <code class="c# plain">newdt = it.CopyToDataTable();</code></div>
<div class="line number19 index18 alt2"><code class="c# spaces">    </code><code class="c# plain">newdt.TableName=dt.TableName; </code></div>
<div class="line number20 index19 alt1"><code class="c# spaces">    </code><code class="c# plain">db.Storageable(newdt ).....</code><code class="c# comments">//使用分页的dt</code></div>
<div class="line number21 index20 alt2"><code class="c# spaces">    </code><code class="c# plain">....</code></div>
<div class="line number22 index21 alt1"><code class="c# spaces">    </code><code class="c# plain">....</code></div>
<div class="line number23 index22 alt2"><code class="c# plain">}</code></div>
</div>
</td>
</tr>
</tbody>
</table>
<p>调试：我们在执行插入更前打上断点，可以看到插入有哪些数据，更新有哪些数据</p>
<p><img loading="lazy" decoding="async" class="alignnone size-full wp-image-3053" src="https://e673.com/wp-content/uploads/2025/11/6378174202914064269617231.png" width="1212" height="495" alt="image.png" title="image.png" srcset="https://e673.com/wp-content/uploads/2025/11/6378174202914064269617231.png 1212w, https://e673.com/wp-content/uploads/2025/11/6378174202914064269617231-500x204.png 500w, https://e673.com/wp-content/uploads/2025/11/6378174202914064269617231-1024x418.png 1024w, https://e673.com/wp-content/uploads/2025/11/6378174202914064269617231-768x314.png 768w, https://e673.com/wp-content/uploads/2025/11/6378174202914064269617231-670x274.png 670w" sizes="(max-width: 1212px) 100vw, 1212px" /></p>
<h2 id="blogTitle9">字典类型:保存</h2>
<p>用法区别和DataTable一样，唯一区别是需要设置一下表名</p>
<table class="syntaxhighlighter  c#" border="0" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td class="code">
<div class="container">
<div class="line number1 index0 alt2"><code class="c# plain">List&lt;Dictionary&lt;</code><code class="c# keyword">string</code><code class="c# plain">,</code><code class="c# keyword">object</code><code class="c# plain">&gt;&gt; dictionaryList=xxxx;</code></div>
<div class="line number2 index1 alt1"><code class="c# keyword">var</code> <code class="c# plain">x= db.Storageable(dictionaryList,</code><code class="c# string">"表名"</code><code class="c# plain">).WhereColumns(</code><code class="c# string">"id"</code><code class="c# plain">).ToStorage();</code><code class="c# comments">//id作为主键</code></div>
<div class="line number3 index2 alt2"><code class="c# plain">x.AsInsertable.IgnoreColumns(</code><code class="c# string">"id"</code><code class="c# plain">).ExecuteCommand();</code><code class="c# comments">//如果是自增要添加IgnoreColumns</code></div>
<div class="line number4 index3 alt1"><code class="c# plain">x.AsUpdateable.ExecuteCommand();</code></div>
</div>
</td>
</tr>
</tbody>
</table>
<h2 id="blogTitle10">大数据：性能优化  merge into</h2>
<p>高级保存一般适用于2万以下数据处理，超过2万就会明显变慢，所以我们需要分页处理，性能有质的提升</p>
<table class="syntaxhighlighter  c#" border="0" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td class="code">
<div class="container">
<div class="line number1 index0 alt2"><code class="c# comments">/********************新版本写法 5.1.4.109 ********************/</code></div>
<div class="line number2 index1 alt1"></div>
<div class="line number3 index2 alt2"><code class="c# comments">//大数据插入或者更新 </code></div>
<div class="line number4 index3 alt1"><code class="c# comments">//原理 merge into</code></div>
<div class="line number5 index4 alt2"><code class="c# comments">//Oracle和SqlServer使用了Merge Into+BulkCopy </code></div>
<div class="line number6 index5 alt1"><code class="c# comments">//其他库底层是 db.Storageable(list).ExecuteSqlBulkCopy()  </code></div>
<div class="line number7 index6 alt2"><code class="c# plain">db.Fastest&lt;Order&gt;().BulkMerge(List);</code></div>
<div class="line number8 index7 alt1"><code class="c# plain">db.Fastest&lt;Order&gt;().PageSize(100000).BulkMerge(List);</code></div>
<div class="line number9 index8 alt2"></div>
<div class="line number10 index9 alt1"><code class="c# comments">//普通插入或者更新</code></div>
<div class="line number11 index10 alt2"><code class="c# plain">Db.Storageable(list2).PageSize(1000).ExecuteCommand();</code></div>
<div class="line number12 index11 alt1"><code class="c# plain">Db.Storageable(list2).PageSize(1000,exrows=&gt; {   }).ExecuteCommand();</code></div>
<div class="line number13 index12 alt2"></div>
<div class="line number14 index13 alt1"><code class="c# comments">//如果这么写出现CPU过高那么，就需要检查条件字段</code></div>
<div class="line number15 index14 alt2"><code class="c# comments">//varchar设置50以下千万不能用大字段，如果是非重复数据有索引最佳</code></div>
<div class="line number16 index15 alt1"><code class="c# comments">//数据库可以把varchar换成navarchar测试一下2者性能差距，选取最优的类型</code></div>
<div class="line number17 index16 alt2"></div>
<div class="line number18 index17 alt1"></div>
<div class="line number19 index18 alt2"><code class="c# comments">/********************分页函数********************/</code></div>
<div class="line number20 index19 alt1"></div>
<div class="line number21 index20 alt2"><code class="c# comments">//异步用 PageEachAsync</code></div>
<div class="line number22 index21 alt1"><code class="c# plain">db.Utilities.PageEach(list, 2000 ,pageList=&gt; {</code></div>
<div class="line number23 index22 alt2"><code class="c# spaces">      </code></div>
<div class="line number24 index23 alt1"><code class="c# spaces">     </code><code class="c# keyword">var</code> <code class="c# plain">x= db.Storageable(pageList).ToStorage();</code></div>
<div class="line number25 index24 alt2"><code class="c# spaces">      </code><code class="c# plain">x.AsUpdateable.ExecuteCommand();</code></div>
<div class="line number26 index25 alt1"><code class="c# spaces">     </code></div>
<div class="line number27 index26 alt2"><code class="c# plain">});</code></div>
<div class="line number28 index27 alt1"><code class="c# comments">//异步用 PageEachAsync</code></div>
</div>
</td>
</tr>
</tbody>
</table>
<h2 id="blogTitle11">导航支持高级保存</h2>
<p>具体用法看导航更新</p>
<table class="syntaxhighlighter  c#" border="0" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td class="code">
<div class="container">
<div class="line number1 index0 alt2"><code class="c# plain">db.UpdateNav(list,</code><code class="c# keyword">new</code> <code class="c# plain">UpdateNavRootOptions(){IsInsertRoot=</code><code class="c# keyword">true</code><code class="c# plain">})</code><code class="c# comments">//IsInsertRoot=true表示不存在插入主表</code></div>
<div class="line number2 index1 alt1"><code class="c# plain">.Include(x =&gt; x.Roles).ExecuteCommand();</code></div>
</div>
</td>
</tr>
</tbody>
</table>
<h2 id="blogTitle12">分表（新）</h2>
<p>请升级:5.1.4.100</p>
<table class="syntaxhighlighter  c#" border="0" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td class="code">
<div class="container">
<div class="line number1 index0 alt2"><code class="c# comments">//分表字段必须要有正确的值才能找对应的表</code></div>
<div class="line number2 index1 alt1"><code class="c# plain">db.Storageable(</code><code class="c# keyword">new</code> <code class="c# plain">OrderSpliteTest() { Name=</code><code class="c# string">"A"</code> <code class="c# plain">,Time=DateTime.Now })</code></div>
<div class="line number3 index2 alt2"><code class="c# spaces">                </code><code class="c# plain">.SplitTable().ExecuteCommand();</code><code class="c# comments">//内部1000条分页一次</code></div>
<div class="line number4 index3 alt1"><code class="c# spaces">                </code></div>
<div class="line number5 index4 alt2"><code class="c# comments">//BulkCopy                </code></div>
<div class="line number6 index5 alt1"><code class="c# plain">db.Storageable(</code><code class="c# keyword">new</code> <code class="c# plain">Order() { Name = </code><code class="c# string">"A"</code><code class="c# plain">, Time = DateTime.Now })</code></div>
<div class="line number7 index6 alt2"><code class="c# spaces">                </code><code class="c# plain">.SplitTable().ExecuteSqlBulkCopy();</code><code class="c# comments">//内部1000条分页一次</code></div>
</div>
</td>
</tr>
</tbody>
</table>
<h2 id="blogTitle13">表格保存 增+删+改</h2>
<p><a href="https://www.donet5.com/Home/Doc?typeId=2568" target="_blank" rel="noopener">https://www.donet5.com/Home/Doc?typeId=2568</a></p>
<h2 id="blogTitle14">指定更新表的范围</h2>
<p>注意：了解规则后在用这个功能，这个功能一般是特殊规则下使用</p>
<table class="syntaxhighlighter  c#" border="0" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td class="code">
<div class="container">
<div class="line number1 index0 alt2"><code class="c# plain">db.Storageable(list).TableDataRange(it=&gt;it.TypeId==1).ExecuteCommand();</code></div>
<div class="line number2 index1 alt1"><code class="c# comments">//也就是select * from 表 where typeId=1 里面是不是存在，如果存在更新，不存在插入</code></div>
</div>
</td>
</tr>
</tbody>
</table>
]]></content:encoded>
					
		
		
			</item>
	</channel>
</rss>
