[{"data":1,"prerenderedAt":5276},["ShallowReactive",2],{"/blog/freertos-scheduling-strategy-research":3},{"id":4,"title":5,"body":6,"date":5252,"description":5253,"draft":5254,"extension":5255,"meta":5256,"navigation":1876,"path":5265,"seo":5266,"stem":5267,"tags":5268,"toc":1876,"__hash__":5275},"blog/blog/freertos-scheduling-strategy-research.md","FreeRTOS 实时操作系统调度策略研究",{"type":7,"value":8,"toc":5221},"minimark",[9,13,16,19,23,27,35,38,107,111,118,121,194,201,251,254,257,261,268,279,329,842,1071,1429,1432,1679,1683,1692,1821,1824,1827,1833,1836,1942,1948,1955,1959,1963,1970,2195,2198,2218,2221,2224,2318,2323,2326,2398,2405,2409,2412,2466,2612,2615,2712,2723,2795,2798,2805,3008,3013,3108,3113,3120,3125,3215,3220,3224,3227,3232,3239,3244,3251,3254,3258,3503,3510,3513,3516,3639,3642,3645,3652,3661,3667,3782,3787,3993,3996,3999,4013,4180,4183,4233,4244,4248,4255,4318,4321,4324,4327,4330,4679,4734,4868,4932,4936,5019,5022,5029,5099,5106,5109,5118,5127,5141,5155,5164,5174,5184,5198,5208,5217],[10,11,12],"p",{},"实时操作系统（Real-Time Operating System, RTOS）是嵌入式领域的核心系统软件，其调度策略的设计直接决定任务响应的确定性与时间可预测性。",[10,14,15],{},"FreeRTOS 是全球市场占有率长期领先的开源实时操作系统——它用约 9000 行 C 代码，在仅约 6 KB ROM / 1 KB RAM 的最小配置下实现了微秒级的任务切换与有界中断延迟。这种“以最简洁的机制换取最强的确定性”的工程哲学，正是它值得被仔细拆解的地方。",[10,17,18],{},"本文将以 FreeRTOS 为研究对象，完整梳理其任务模型、调度算法、上下文切换机制、实时性保障手段及性能特征，并给出可调度性验证方法与典型行业的应用数据。",[20,21,22],"h2",{"id":22},"引言",[24,25,26],"h3",{"id":26},"实时操作系统的定义与分类",[10,28,29,30,34],{},"实时操作系统是能在规定时间约束内完成特定任务处理的操作系统。区别于通用操作系统追求的高吞吐量与平均性能，RTOS 的核心指标是",[31,32,33],"strong",{},"时间确定性（Temporal Determinism）","——系统对外部事件的响应时间必须有可验证的上界。",[10,36,37],{},"根据截止时间违反的后果，实时任务可分为三类：",[39,40,41,61],"table",{},[42,43,44],"thead",{},[45,46,47,52,55,58],"tr",{},[48,49,51],"th",{"align":50},"left","类型",[48,53,54],{"align":50},"定义",[48,56,57],{"align":50},"截止时间违反后果",[48,59,60],{"align":50},"典型场景",[62,63,64,79,93],"tbody",{},[45,65,66,70,73,76],{},[67,68,69],"td",{"align":50},"硬实时（Hard RT）",[67,71,72],{"align":50},"必须在截止时间前完成",[67,74,75],{"align":50},"系统失效，可能造成灾难",[67,77,78],{"align":50},"飞控、ABS 制动、心脏起搏器",[45,80,81,84,87,90],{},[67,82,83],{"align":50},"固实时（Firm RT）",[67,85,86],{"align":50},"截止时间后结果无效",[67,88,89],{"align":50},"结果丢弃，但系统不失效",[67,91,92],{"align":50},"金融报价流、直播帧渲染",[45,94,95,98,101,104],{},[67,96,97],{"align":50},"软实时（Soft RT）",[67,99,100],{"align":50},"截止时间尽量满足",[67,102,103],{"align":50},"性能降级，偶尔违反可容忍",[67,105,106],{"align":50},"视频点播缓冲、GPS 导航刷新",[24,108,110],{"id":109},"freertos-的地位与背景","FreeRTOS 的地位与背景",[10,112,113,114,117],{},"FreeRTOS 由英国工程师 Richard Barry 于 2003 年创建，2017 年由 Amazon Web Services（AWS）接管并持续维护至今（商业强化版本曾称 Amazon FreeRTOS，现已统一更名为 FreeRTOS）。根据 2022 年 EE Times 嵌入式市场调查报告，FreeRTOS 在 RTOS 市场占有率达到 ",[31,115,116],{},"34%","，连续多年位居第一，远超 Micrium µC/OS（9%）、VxWorks（8%）、ThreadX（7%）等商业 RTOS。",[10,119,120],{},"截至 FreeRTOS v10.5，其代码规模如下：",[39,122,123,133],{},[42,124,125],{},[45,126,127,130],{},[48,128,129],{"align":50},"模块",[48,131,132],{"align":50},"代码行数",[62,134,135,148,159,170,182],{},[45,136,137,145],{},[67,138,139,140,144],{"align":50},"内核核心（",[141,142,143],"code",{},"tasks.c","）",[67,146,147],{"align":50},"~4500 行",[45,149,150,156],{},[67,151,152,153,144],{"align":50},"队列/信号量（",[141,154,155],{},"queue.c",[67,157,158],{"align":50},"~2800 行",[45,160,161,167],{},[67,162,163,164,144],{"align":50},"定时器（",[141,165,166],{},"timers.c",[67,168,169],{"align":50},"~1000 行",[45,171,172,179],{},[67,173,174,175,178],{"align":50},"移植层（",[141,176,177],{},"port.c","，以 Cortex-M4 为例）",[67,180,181],{"align":50},"~300 行",[45,183,184,189],{},[67,185,186],{"align":50},[31,187,188],{},"合计",[67,190,191],{"align":50},[31,192,193],{},"~9000 行",[10,195,196,197,200],{},"编译后的二进制大小（以 ARM Cortex-M4，GCC ",[141,198,199],{},"-O2"," 优化为例）：",[39,202,203,216],{},[42,204,205],{},[45,206,207,210,213],{},[48,208,209],{"align":50},"配置",[48,211,212],{"align":50},"Flash（ROM）占用",[48,214,215],{"align":50},"RAM 占用",[62,217,218,229,240],{},[45,219,220,223,226],{},[67,221,222],{"align":50},"最小配置（仅任务 + 调度）",[67,224,225],{"align":50},"~6 KB",[67,227,228],{"align":50},"~1 KB",[45,230,231,234,237],{},[67,232,233],{"align":50},"标准配置（含队列、信号量、定时器）",[67,235,236],{"align":50},"~10 KB",[67,238,239],{"align":50},"~2–4 KB",[45,241,242,245,248],{},[67,243,244],{"align":50},"完整配置（含 FPU、统计、追踪）",[67,246,247],{"align":50},"~16 KB",[67,249,250],{"align":50},"~6–8 KB",[10,252,253],{},"这一极低的资源占用使 FreeRTOS 能够运行在 Flash 仅 32 KB、RAM 仅 8 KB 的低端 MCU 上，覆盖了从 8 位 AVR 到 64 位 RISC-V 的广泛平台。",[20,255,256],{"id":256},"实时调度理论基础",[24,258,260],{"id":259},"速率单调调度rms","速率单调调度（RMS）",[10,262,263,264,267],{},"Liu 和 Layland 于 1973 年发表的论文《Scheduling Algorithms for Multiprogramming in a Hard-Real-Time Environment》，提出了两个奠基性的实时调度算法，其中之一便是",[31,265,266],{},"速率单调调度（Rate Monotonic Scheduling, RMS）","。",[10,269,270,271,274,275,278],{},"RMS 是一种静态优先级分配算法：任务的调度优先级与其执行周期成反比，即",[31,272,273],{},"周期越短，优先级越高","。它是在抢占式调度下固定优先级策略中的",[31,276,277],{},"最优算法","——若任何固定优先级分配方案能使任务集合满足截止时间，RMS 也必然能满足。",[10,280,281,282,328],{},"对于 ",[283,284,287,309],"span",{"className":285},[286],"katex",[283,288,291],{"className":289},[290],"katex-mathml",[292,293,295],"math",{"xmlns":294},"http://www.w3.org/1998/Math/MathML",[296,297,298,305],"semantics",{},[299,300,301],"mrow",{},[302,303,304],"mi",{},"n",[306,307,304],"annotation",{"encoding":308},"application/x-tex",[283,310,314],{"className":311,"ariaHidden":313},[312],"katex-html","true",[283,315,318,323],{"className":316},[317],"base",[283,319],{"className":320,"style":322},[321],"strut","height:0.4306em;",[283,324,304],{"className":325},[326,327],"mord","mathnormal"," 个独立的周期性任务，RMS 的 CPU 利用率可调度上界为：",[283,330,333],{"className":331},[332],"katex-display",[283,334,336,432],{"className":335},[286],[283,337,339],{"className":338},[290],[292,340,342],{"xmlns":294,"display":341},"block",[296,343,344,429],{},[299,345,346,356,360,379,396,399,401,405,421,424,426],{},[347,348,349,352],"msub",{},[302,350,351],{},"U",[353,354,355],"mtext",{},"RMS",[357,358,359],"mo",{},"=",[361,362,363,366,377],"munderover",{},[357,364,365],{},"∑",[299,367,368,371,373],{},[302,369,370],{},"i",[357,372,359],{},[374,375,376],"mn",{},"1",[302,378,304],{},[380,381,382,389],"mfrac",{},[347,383,384,387],{},[302,385,386],{},"C",[302,388,370],{},[347,390,391,394],{},[302,392,393],{},"T",[302,395,370],{},[357,397,398],{},"≤",[302,400,304],{},[357,402,404],{"stretchy":403},"false","(",[406,407,408,411],"msup",{},[374,409,410],{},"2",[299,412,413,415,419],{},[374,414,376],{},[302,416,418],{"mathvariant":417},"normal","/",[302,420,304],{},[357,422,423],{},"−",[374,425,376],{},[357,427,428],{"stretchy":403},")",[306,430,431],{"encoding":308},"U_{\\text{RMS}} = \\sum_{i=1}^{n} \\frac{C_i}{T_i} \\leq n(2^{1/n} - 1)",[283,433,435,518,767,829],{"className":434,"ariaHidden":313},[312],[283,436,438,442,506,511,515],{"className":437},[317],[283,439],{"className":440,"style":441},[321],"height:0.8333em;vertical-align:-0.15em;",[283,443,445,449],{"className":444},[326],[283,446,351],{"className":447,"style":448},[326,327],"margin-right:0.109em;",[283,450,453],{"className":451},[452],"msupsub",[283,454,458,497],{"className":455},[456,457],"vlist-t","vlist-t2",[283,459,462,492],{"className":460},[461],"vlist-r",[283,463,467],{"className":464,"style":466},[465],"vlist","height:0.3283em;",[283,468,470,475],{"style":469},"top:-2.55em;margin-left:-0.109em;margin-right:0.05em;",[283,471],{"className":472,"style":474},[473],"pstrut","height:2.7em;",[283,476,482],{"className":477},[478,479,480,481],"sizing","reset-size6","size3","mtight",[283,483,485],{"className":484},[326,481],[283,486,489],{"className":487},[326,488,481],"text",[283,490,355],{"className":491},[326,481],[283,493,496],{"className":494},[495],"vlist-s","​",[283,498,500],{"className":499},[461],[283,501,504],{"className":502,"style":503},[465],"height:0.15em;",[283,505],{},[283,507],{"className":508,"style":510},[509],"mspace","margin-right:0.2778em;",[283,512,359],{"className":513},[514],"mrel",[283,516],{"className":517,"style":510},[509],[283,519,521,525,602,606,758,761,764],{"className":520},[317],[283,522],{"className":523,"style":524},[321],"height:2.9291em;vertical-align:-1.2777em;",[283,526,530],{"className":527},[528,529],"mop","op-limits",[283,531,533,593],{"className":532},[456,457],[283,534,536,590],{"className":535},[461],[283,537,540,562,575],{"className":538,"style":539},[465],"height:1.6514em;",[283,541,543,547],{"style":542},"top:-1.8723em;margin-left:0em;",[283,544],{"className":545,"style":546},[473],"height:3.05em;",[283,548,550],{"className":549},[478,479,480,481],[283,551,553,556,559],{"className":552},[326,481],[283,554,370],{"className":555},[326,327,481],[283,557,359],{"className":558},[514,481],[283,560,376],{"className":561},[326,481],[283,563,565,568],{"style":564},"top:-3.05em;",[283,566],{"className":567,"style":546},[473],[283,569,570],{},[283,571,365],{"className":572},[528,573,574],"op-symbol","large-op",[283,576,578,581],{"style":577},"top:-4.3em;margin-left:0em;",[283,579],{"className":580,"style":546},[473],[283,582,584],{"className":583},[478,479,480,481],[283,585,587],{"className":586},[326,481],[283,588,304],{"className":589},[326,327,481],[283,591,496],{"className":592},[495],[283,594,596],{"className":595},[461],[283,597,600],{"className":598,"style":599},[465],"height:1.2777em;",[283,601],{},[283,603],{"className":604,"style":605},[509],"margin-right:0.1667em;",[283,607,609,614,754],{"className":608},[326],[283,610],{"className":611},[612,613],"mopen","nulldelimiter",[283,615,617],{"className":616},[380],[283,618,620,745],{"className":619},[456,457],[283,621,623,742],{"className":622},[461],[283,624,627,680,691],{"className":625,"style":626},[465],"height:1.3603em;",[283,628,630,634],{"style":629},"top:-2.314em;",[283,631],{"className":632,"style":633},[473],"height:3em;",[283,635,637],{"className":636},[326],[283,638,640,644],{"className":639},[326],[283,641,393],{"className":642,"style":643},[326,327],"margin-right:0.1389em;",[283,645,647],{"className":646},[452],[283,648,650,672],{"className":649},[456,457],[283,651,653,669],{"className":652},[461],[283,654,657],{"className":655,"style":656},[465],"height:0.3117em;",[283,658,660,663],{"style":659},"top:-2.55em;margin-left:-0.1389em;margin-right:0.05em;",[283,661],{"className":662,"style":474},[473],[283,664,666],{"className":665},[478,479,480,481],[283,667,370],{"className":668},[326,327,481],[283,670,496],{"className":671},[495],[283,673,675],{"className":674},[461],[283,676,678],{"className":677,"style":503},[465],[283,679],{},[283,681,683,686],{"style":682},"top:-3.23em;",[283,684],{"className":685,"style":633},[473],[283,687],{"className":688,"style":690},[689],"frac-line","border-bottom-width:0.04em;",[283,692,694,697],{"style":693},"top:-3.677em;",[283,695],{"className":696,"style":633},[473],[283,698,700],{"className":699},[326],[283,701,703,707],{"className":702},[326],[283,704,386],{"className":705,"style":706},[326,327],"margin-right:0.0715em;",[283,708,710],{"className":709},[452],[283,711,713,734],{"className":712},[456,457],[283,714,716,731],{"className":715},[461],[283,717,719],{"className":718,"style":656},[465],[283,720,722,725],{"style":721},"top:-2.55em;margin-left:-0.0715em;margin-right:0.05em;",[283,723],{"className":724,"style":474},[473],[283,726,728],{"className":727},[478,479,480,481],[283,729,370],{"className":730},[326,327,481],[283,732,496],{"className":733},[495],[283,735,737],{"className":736},[461],[283,738,740],{"className":739,"style":503},[465],[283,741],{},[283,743,496],{"className":744},[495],[283,746,748],{"className":747},[461],[283,749,752],{"className":750,"style":751},[465],"height:0.836em;",[283,753],{},[283,755],{"className":756},[757,613],"mclose",[283,759],{"className":760,"style":510},[509],[283,762,398],{"className":763},[514],[283,765],{"className":766,"style":510},[509],[283,768,770,774,777,780,818,822,826],{"className":769},[317],[283,771],{"className":772,"style":773},[321],"height:1.188em;vertical-align:-0.25em;",[283,775,304],{"className":776},[326,327],[283,778,404],{"className":779},[612],[283,781,783,786],{"className":782},[326],[283,784,410],{"className":785},[326],[283,787,789],{"className":788},[452],[283,790,792],{"className":791},[456],[283,793,795],{"className":794},[461],[283,796,799],{"className":797,"style":798},[465],"height:0.938em;",[283,800,802,805],{"style":801},"top:-3.113em;margin-right:0.05em;",[283,803],{"className":804,"style":474},[473],[283,806,808],{"className":807},[478,479,480,481],[283,809,811,815],{"className":810},[326,481],[283,812,814],{"className":813},[326,481],"1/",[283,816,304],{"className":817},[326,327,481],[283,819],{"className":820,"style":821},[509],"margin-right:0.2222em;",[283,823,423],{"className":824},[825],"mbin",[283,827],{"className":828,"style":821},[509],[283,830,832,836,839],{"className":831},[317],[283,833],{"className":834,"style":835},[321],"height:1em;vertical-align:-0.25em;",[283,837,376],{"className":838},[326],[283,840,428],{"className":841},[757],[10,843,844,845,915,916,945,946,1016,1017,1070],{},"其中 ",[283,846,848,866],{"className":847},[286],[283,849,851],{"className":850},[290],[292,852,853],{"xmlns":294},[296,854,855,863],{},[299,856,857],{},[347,858,859,861],{},[302,860,386],{},[302,862,370],{},[306,864,865],{"encoding":308},"C_i",[283,867,869],{"className":868,"ariaHidden":313},[312],[283,870,872,875],{"className":871},[317],[283,873],{"className":874,"style":441},[321],[283,876,878,881],{"className":877},[326],[283,879,386],{"className":880,"style":706},[326,327],[283,882,884],{"className":883},[452],[283,885,887,907],{"className":886},[456,457],[283,888,890,904],{"className":889},[461],[283,891,893],{"className":892,"style":656},[465],[283,894,895,898],{"style":721},[283,896],{"className":897,"style":474},[473],[283,899,901],{"className":900},[478,479,480,481],[283,902,370],{"className":903},[326,327,481],[283,905,496],{"className":906},[495],[283,908,910],{"className":909},[461],[283,911,913],{"className":912,"style":503},[465],[283,914],{}," 为任务 ",[283,917,919,932],{"className":918},[286],[283,920,922],{"className":921},[290],[292,923,924],{"xmlns":294},[296,925,926,930],{},[299,927,928],{},[302,929,370],{},[306,931,370],{"encoding":308},[283,933,935],{"className":934,"ariaHidden":313},[312],[283,936,938,942],{"className":937},[317],[283,939],{"className":940,"style":941},[321],"height:0.6595em;",[283,943,370],{"className":944},[326,327]," 的最坏情况执行时间（Worst-Case Execution Time, WCET），",[283,947,949,967],{"className":948},[286],[283,950,952],{"className":951},[290],[292,953,954],{"xmlns":294},[296,955,956,964],{},[299,957,958],{},[347,959,960,962],{},[302,961,393],{},[302,963,370],{},[306,965,966],{"encoding":308},"T_i",[283,968,970],{"className":969,"ariaHidden":313},[312],[283,971,973,976],{"className":972},[317],[283,974],{"className":975,"style":441},[321],[283,977,979,982],{"className":978},[326],[283,980,393],{"className":981,"style":643},[326,327],[283,983,985],{"className":984},[452],[283,986,988,1008],{"className":987},[456,457],[283,989,991,1005],{"className":990},[461],[283,992,994],{"className":993,"style":656},[465],[283,995,996,999],{"style":659},[283,997],{"className":998,"style":474},[473],[283,1000,1002],{"className":1001},[478,479,480,481],[283,1003,370],{"className":1004},[326,327,481],[283,1006,496],{"className":1007},[495],[283,1009,1011],{"className":1010},[461],[283,1012,1014],{"className":1013,"style":503},[465],[283,1015],{}," 为任务周期。当 ",[283,1018,1020,1040],{"className":1019},[286],[283,1021,1023],{"className":1022},[290],[292,1024,1025],{"xmlns":294},[296,1026,1027,1037],{},[299,1028,1029,1031,1034],{},[302,1030,304],{},[357,1032,1033],{},"→",[302,1035,1036],{"mathvariant":417},"∞",[306,1038,1039],{"encoding":308},"n \\to \\infty",[283,1041,1043,1061],{"className":1042,"ariaHidden":313},[312],[283,1044,1046,1049,1052,1055,1058],{"className":1045},[317],[283,1047],{"className":1048,"style":322},[321],[283,1050,304],{"className":1051},[326,327],[283,1053],{"className":1054,"style":510},[509],[283,1056,1033],{"className":1057},[514],[283,1059],{"className":1060,"style":510},[509],[283,1062,1064,1067],{"className":1063},[317],[283,1065],{"className":1066,"style":322},[321],[283,1068,1036],{"className":1069},[326]," 时：",[283,1072,1074],{"className":1073},[332],[283,1075,1077,1162],{"className":1076},[286],[283,1078,1080],{"className":1079},[290],[292,1081,1082],{"xmlns":294,"display":341},[296,1083,1084,1159],{},[299,1085,1086,1099,1101,1119,1121,1123,1135,1137,1139,1141,1143,1146,1148,1150,1153,1156],{},[1087,1088,1089,1091,1093,1096],"msubsup",{},[302,1090,351],{},[353,1092,355],{},[302,1094,1095],{},"max",[357,1097,1098],{},"⁡",[357,1100,359],{},[1102,1103,1104,1111],"munder",{},[299,1105,1106,1109],{},[302,1107,1108],{},"lim",[357,1110,1098],{},[299,1112,1113,1115,1117],{},[302,1114,304],{},[357,1116,1033],{},[302,1118,1036],{"mathvariant":417},[302,1120,304],{},[357,1122,404],{"stretchy":403},[406,1124,1125,1127],{},[374,1126,410],{},[299,1128,1129,1131,1133],{},[374,1130,376],{},[302,1132,418],{"mathvariant":417},[302,1134,304],{},[357,1136,423],{},[374,1138,376],{},[357,1140,428],{"stretchy":403},[357,1142,359],{},[302,1144,1145],{},"ln",[357,1147,1098],{},[374,1149,410],{},[357,1151,1152],{},"≈",[374,1154,1155],{},"69.3",[302,1157,1158],{"mathvariant":417},"%",[306,1160,1161],{"encoding":308},"U_{\\text{RMS}}^{\\max} = \\lim_{n \\to \\infty} n(2^{1/n} - 1) = \\ln 2 \\approx 69.3\\%",[283,1163,1165,1256,1373,1394,1418],{"className":1164,"ariaHidden":313},[312],[283,1166,1168,1172,1247,1250,1253],{"className":1167},[317],[283,1169],{"className":1170,"style":1171},[321],"height:0.9614em;vertical-align:-0.247em;",[283,1173,1175,1178],{"className":1174},[326],[283,1176,351],{"className":1177,"style":448},[326,327],[283,1179,1181],{"className":1180},[452],[283,1182,1184,1238],{"className":1183},[456,457],[283,1185,1187,1235],{"className":1186},[461],[283,1188,1191,1209],{"className":1189,"style":1190},[465],"height:0.7144em;",[283,1192,1194,1197],{"style":1193},"top:-2.453em;margin-left:-0.109em;margin-right:0.05em;",[283,1195],{"className":1196,"style":474},[473],[283,1198,1200],{"className":1199},[478,479,480,481],[283,1201,1203],{"className":1202},[326,481],[283,1204,1206],{"className":1205},[326,488,481],[283,1207,355],{"className":1208},[326,481],[283,1210,1211,1214],{"style":801},[283,1212],{"className":1213,"style":474},[473],[283,1215,1217],{"className":1216},[478,479,480,481],[283,1218,1220],{"className":1219},[326,481],[283,1221,1223,1227,1231],{"className":1222},[528,481],[283,1224,1226],{"className":1225},[481],"m",[283,1228,1230],{"className":1229},[481],"a",[283,1232,1234],{"className":1233},[481],"x",[283,1236,496],{"className":1237},[495],[283,1239,1241],{"className":1240},[461],[283,1242,1245],{"className":1243,"style":1244},[465],"height:0.247em;",[283,1246],{},[283,1248],{"className":1249,"style":510},[509],[283,1251,359],{"className":1252},[514],[283,1254],{"className":1255,"style":510},[509],[283,1257,1259,1263,1320,1323,1326,1329,1364,1367,1370],{"className":1258},[317],[283,1260],{"className":1261,"style":1262},[321],"height:1.638em;vertical-align:-0.7em;",[283,1264,1266],{"className":1265},[528,529],[283,1267,1269,1311],{"className":1268},[456,457],[283,1270,1272,1308],{"className":1271},[461],[283,1273,1276,1297],{"className":1274,"style":1275},[465],"height:0.6944em;",[283,1277,1279,1282],{"style":1278},"top:-2.4em;margin-left:0em;",[283,1280],{"className":1281,"style":633},[473],[283,1283,1285],{"className":1284},[478,479,480,481],[283,1286,1288,1291,1294],{"className":1287},[326,481],[283,1289,304],{"className":1290},[326,327,481],[283,1292,1033],{"className":1293},[514,481],[283,1295,1036],{"className":1296},[326,481],[283,1298,1300,1303],{"style":1299},"top:-3em;",[283,1301],{"className":1302,"style":633},[473],[283,1304,1305],{},[283,1306,1108],{"className":1307},[528],[283,1309,496],{"className":1310},[495],[283,1312,1314],{"className":1313},[461],[283,1315,1318],{"className":1316,"style":1317},[465],"height:0.7em;",[283,1319],{},[283,1321],{"className":1322,"style":605},[509],[283,1324,304],{"className":1325},[326,327],[283,1327,404],{"className":1328},[612],[283,1330,1332,1335],{"className":1331},[326],[283,1333,410],{"className":1334},[326],[283,1336,1338],{"className":1337},[452],[283,1339,1341],{"className":1340},[456],[283,1342,1344],{"className":1343},[461],[283,1345,1347],{"className":1346,"style":798},[465],[283,1348,1349,1352],{"style":801},[283,1350],{"className":1351,"style":474},[473],[283,1353,1355],{"className":1354},[478,479,480,481],[283,1356,1358,1361],{"className":1357},[326,481],[283,1359,814],{"className":1360},[326,481],[283,1362,304],{"className":1363},[326,327,481],[283,1365],{"className":1366,"style":821},[509],[283,1368,423],{"className":1369},[825],[283,1371],{"className":1372,"style":821},[509],[283,1374,1376,1379,1382,1385,1388,1391],{"className":1375},[317],[283,1377],{"className":1378,"style":835},[321],[283,1380,376],{"className":1381},[326],[283,1383,428],{"className":1384},[757],[283,1386],{"className":1387,"style":510},[509],[283,1389,359],{"className":1390},[514],[283,1392],{"className":1393,"style":510},[509],[283,1395,1397,1400,1403,1406,1409,1412,1415],{"className":1396},[317],[283,1398],{"className":1399,"style":1275},[321],[283,1401,1145],{"className":1402},[528],[283,1404],{"className":1405,"style":605},[509],[283,1407,410],{"className":1408},[326],[283,1410],{"className":1411,"style":510},[509],[283,1413,1152],{"className":1414},[514],[283,1416],{"className":1417,"style":510},[509],[283,1419,1421,1425],{"className":1420},[317],[283,1422],{"className":1423,"style":1424},[321],"height:0.8056em;vertical-align:-0.0556em;",[283,1426,1428],{"className":1427},[326],"69.3%",[10,1430,1431],{},"各任务数对应的 RMS 利用率上界（工程上通常会再留出余量）：",[39,1433,1434,1586],{},[42,1435,1436],{},[45,1437,1438,1470,1583],{},[48,1439,1441,1442],{"align":1440},"center","任务数 ",[283,1443,1445,1458],{"className":1444},[286],[283,1446,1448],{"className":1447},[290],[292,1449,1450],{"xmlns":294},[296,1451,1452,1456],{},[299,1453,1454],{},[302,1455,304],{},[306,1457,304],{"encoding":308},[283,1459,1461],{"className":1460,"ariaHidden":313},[312],[283,1462,1464,1467],{"className":1463},[317],[283,1465],{"className":1466,"style":322},[321],[283,1468,304],{"className":1469},[326,327],[48,1471,1472],{"align":1440},[283,1473,1475,1509],{"className":1474},[286],[283,1476,1478],{"className":1477},[290],[292,1479,1480],{"xmlns":294},[296,1481,1482,1506],{},[299,1483,1484,1486,1488,1500,1502,1504],{},[302,1485,304],{},[357,1487,404],{"stretchy":403},[406,1489,1490,1492],{},[374,1491,410],{},[299,1493,1494,1496,1498],{},[374,1495,376],{},[302,1497,418],{"mathvariant":417},[302,1499,304],{},[357,1501,423],{},[374,1503,376],{},[357,1505,428],{"stretchy":403},[306,1507,1508],{"encoding":308},"n(2^{1/n}-1)",[283,1510,1512,1571],{"className":1511,"ariaHidden":313},[312],[283,1513,1515,1519,1522,1525,1562,1565,1568],{"className":1514},[317],[283,1516],{"className":1517,"style":1518},[321],"height:1.138em;vertical-align:-0.25em;",[283,1520,304],{"className":1521},[326,327],[283,1523,404],{"className":1524},[612],[283,1526,1528,1531],{"className":1527},[326],[283,1529,410],{"className":1530},[326],[283,1532,1534],{"className":1533},[452],[283,1535,1537],{"className":1536},[456],[283,1538,1540],{"className":1539},[461],[283,1541,1544],{"className":1542,"style":1543},[465],"height:0.888em;",[283,1545,1547,1550],{"style":1546},"top:-3.063em;margin-right:0.05em;",[283,1548],{"className":1549,"style":474},[473],[283,1551,1553],{"className":1552},[478,479,480,481],[283,1554,1556,1559],{"className":1555},[326,481],[283,1557,814],{"className":1558},[326,481],[283,1560,304],{"className":1561},[326,327,481],[283,1563],{"className":1564,"style":821},[509],[283,1566,423],{"className":1567},[825],[283,1569],{"className":1570,"style":821},[509],[283,1572,1574,1577,1580],{"className":1573},[317],[283,1575],{"className":1576,"style":835},[321],[283,1578,376],{"className":1579},[326],[283,1581,428],{"className":1582},[757],[48,1584,1585],{"align":1440},"工程推荐上界（留余量）",[62,1587,1588,1598,1608,1619,1630,1641],{},[45,1589,1590,1592,1595],{},[67,1591,376],{"align":1440},[67,1593,1594],{"align":1440},"100.0%",[67,1596,1597],{"align":1440},"80%",[45,1599,1600,1602,1605],{},[67,1601,410],{"align":1440},[67,1603,1604],{"align":1440},"82.8%",[67,1606,1607],{"align":1440},"70%",[45,1609,1610,1613,1616],{},[67,1611,1612],{"align":1440},"3",[67,1614,1615],{"align":1440},"78.0%",[67,1617,1618],{"align":1440},"65%",[45,1620,1621,1624,1627],{},[67,1622,1623],{"align":1440},"5",[67,1625,1626],{"align":1440},"74.3%",[67,1628,1629],{"align":1440},"60%",[45,1631,1632,1635,1638],{},[67,1633,1634],{"align":1440},"10",[67,1636,1637],{"align":1440},"71.8%",[67,1639,1640],{"align":1440},"57%",[45,1642,1643,1674,1676],{},[67,1644,1645],{"align":1440},[283,1646,1648,1662],{"className":1647},[286],[283,1649,1651],{"className":1650},[290],[292,1652,1653],{"xmlns":294},[296,1654,1655,1659],{},[299,1656,1657],{},[302,1658,1036],{"mathvariant":417},[306,1660,1661],{"encoding":308},"\\infty",[283,1663,1665],{"className":1664,"ariaHidden":313},[312],[283,1666,1668,1671],{"className":1667},[317],[283,1669],{"className":1670,"style":322},[321],[283,1672,1036],{"className":1673},[326],[67,1675,1428],{"align":1440},[67,1677,1678],{"align":1440},"55%",[24,1680,1682],{"id":1681},"最早截止时间优先edf","最早截止时间优先（EDF）",[10,1684,1685,1688,1689,1691],{},[31,1686,1687],{},"最早截止时间优先（Earliest Deadline First, EDF）"," 是动态优先级算法：在每次调度决策时，选择距截止时间最近的就绪任务执行。EDF 是单处理器抢占式调度下的",[31,1690,277],{},"，其理论 CPU 利用率上界可达：",[283,1693,1695],{"className":1694},[332],[283,1696,1698,1728],{"className":1697},[286],[283,1699,1701],{"className":1700},[290],[292,1702,1703],{"xmlns":294,"display":341},[296,1704,1705,1725],{},[299,1706,1707,1714,1716,1718,1720,1723],{},[347,1708,1709,1711],{},[302,1710,351],{},[353,1712,1713],{},"EDF",[357,1715,398],{},[374,1717,376],{},[357,1719,359],{},[374,1721,1722],{},"100",[302,1724,1158],{"mathvariant":417},[306,1726,1727],{"encoding":308},"U_{\\text{EDF}} \\leq 1 = 100\\%",[283,1729,1731,1792,1811],{"className":1730,"ariaHidden":313},[312],[283,1732,1734,1737,1783,1786,1789],{"className":1733},[317],[283,1735],{"className":1736,"style":441},[321],[283,1738,1740,1743],{"className":1739},[326],[283,1741,351],{"className":1742,"style":448},[326,327],[283,1744,1746],{"className":1745},[452],[283,1747,1749,1775],{"className":1748},[456,457],[283,1750,1752,1772],{"className":1751},[461],[283,1753,1755],{"className":1754,"style":466},[465],[283,1756,1757,1760],{"style":469},[283,1758],{"className":1759,"style":474},[473],[283,1761,1763],{"className":1762},[478,479,480,481],[283,1764,1766],{"className":1765},[326,481],[283,1767,1769],{"className":1768},[326,488,481],[283,1770,1713],{"className":1771},[326,481],[283,1773,496],{"className":1774},[495],[283,1776,1778],{"className":1777},[461],[283,1779,1781],{"className":1780,"style":503},[465],[283,1782],{},[283,1784],{"className":1785,"style":510},[509],[283,1787,398],{"className":1788},[514],[283,1790],{"className":1791,"style":510},[509],[283,1793,1795,1799,1802,1805,1808],{"className":1794},[317],[283,1796],{"className":1797,"style":1798},[321],"height:0.6444em;",[283,1800,376],{"className":1801},[326],[283,1803],{"className":1804,"style":510},[509],[283,1806,359],{"className":1807},[514],[283,1809],{"className":1810,"style":510},[509],[283,1812,1814,1817],{"className":1813},[317],[283,1815],{"className":1816,"style":1424},[321],[283,1818,1820],{"className":1819},[326],"100%",[10,1822,1823],{},"EDF 的调度利用率优于 RMS，但其动态优先级特性增加了运行时开销，且在过载情况下的行为难以预测（可能导致多个任务同时错过截止时间）。FreeRTOS 官方实现未采用 EDF，工程上通常选择 RMS 兼容的固定优先级方案，以换取更好的可预测性。",[24,1825,1826],{"id":1826},"优先级反转与优先级继承",[10,1828,1829,1832],{},[31,1830,1831],{},"优先级反转（Priority Inversion）"," 是实时系统中的经典问题，指高优先级任务被低优先级任务间接阻塞，导致调度语义被破坏。",[10,1834,1835],{},"典型场景（三任务模型）：低优先级任务 L 持有互斥量运行，高优先级任务 H 就绪后尝试获取该互斥量而阻塞；此时中优先级任务 M 就绪，由于 H 在等待、L 未运行，M 得以抢占 CPU 并长时间运行——H 被“间接”地压在了 M 之后。",[1837,1838,1843],"pre",{"className":1839,"code":1840,"language":1841,"meta":1842,"style":1842},"language-mermaid shiki shiki-themes houston","gantt\n    title 优先级反转时序图\n    dateFormat X\n    axisFormat %s\n\n    section Task_H（高）\n    等待Mutex :crit, wait, 3, 12\n    获取Mutex并执行 :done, run_h, 13, 16\n\n    section Task_M（中）\n    抢占L,长时间运行 :active, run_m, 5, 12\n\n    section Task_L（低）\n    获取Mutex并运行 :active, run_l1, 0, 3\n    被抢占 :wait_l, 3, 12\n    继续运行并释放Mutex :active, run_l2, 12, 13\n","mermaid","",[141,1844,1845,1853,1859,1865,1871,1878,1884,1890,1896,1901,1907,1913,1918,1924,1930,1936],{"__ignoreMap":1842},[283,1846,1849],{"class":1847,"line":1848},"line",1,[283,1850,1852],{"class":1851},"sLo_3","gantt\n",[283,1854,1856],{"class":1847,"line":1855},2,[283,1857,1858],{"class":1851},"    title 优先级反转时序图\n",[283,1860,1862],{"class":1847,"line":1861},3,[283,1863,1864],{"class":1851},"    dateFormat X\n",[283,1866,1868],{"class":1847,"line":1867},4,[283,1869,1870],{"class":1851},"    axisFormat %s\n",[283,1872,1874],{"class":1847,"line":1873},5,[283,1875,1877],{"emptyLinePlaceholder":1876},true,"\n",[283,1879,1881],{"class":1847,"line":1880},6,[283,1882,1883],{"class":1851},"    section Task_H（高）\n",[283,1885,1887],{"class":1847,"line":1886},7,[283,1888,1889],{"class":1851},"    等待Mutex :crit, wait, 3, 12\n",[283,1891,1893],{"class":1847,"line":1892},8,[283,1894,1895],{"class":1851},"    获取Mutex并执行 :done, run_h, 13, 16\n",[283,1897,1899],{"class":1847,"line":1898},9,[283,1900,1877],{"emptyLinePlaceholder":1876},[283,1902,1904],{"class":1847,"line":1903},10,[283,1905,1906],{"class":1851},"    section Task_M（中）\n",[283,1908,1910],{"class":1847,"line":1909},11,[283,1911,1912],{"class":1851},"    抢占L,长时间运行 :active, run_m, 5, 12\n",[283,1914,1916],{"class":1847,"line":1915},12,[283,1917,1877],{"emptyLinePlaceholder":1876},[283,1919,1921],{"class":1847,"line":1920},13,[283,1922,1923],{"class":1851},"    section Task_L（低）\n",[283,1925,1927],{"class":1847,"line":1926},14,[283,1928,1929],{"class":1851},"    获取Mutex并运行 :active, run_l1, 0, 3\n",[283,1931,1933],{"class":1847,"line":1932},15,[283,1934,1935],{"class":1851},"    被抢占 :wait_l, 3, 12\n",[283,1937,1939],{"class":1847,"line":1938},16,[283,1940,1941],{"class":1851},"    继续运行并释放Mutex :active, run_l2, 12, 13\n",[10,1943,1944],{},[1945,1946,1947],"em",{},"图 1：优先级反转时序图（无优先级继承时）",[1949,1950,1952],"alert",{"type":1951},"danger",[10,1953,1954],{},"1997 年，NASA 火星探路者（Mars Pathfinder）任务中曾因优先级反转导致系统频繁复位，最终靠远程补丁在 vxWorks 的互斥量中启用优先级继承才得以解决——这是工程史上最著名的优先级反转事故之一。",[20,1956,1958],{"id":1957},"freertos-任务模型与数据结构","FreeRTOS 任务模型与数据结构",[24,1960,1962],{"id":1961},"任务控制块tcb","任务控制块（TCB）",[10,1964,1965,1966,1969],{},"FreeRTOS 中每个任务由一个",[31,1967,1968],{},"任务控制块（Task Control Block, TCB）"," 描述，其核心字段如下：",[1837,1971,1975],{"className":1972,"code":1973,"language":1974,"meta":1842,"style":1842},"language-c shiki shiki-themes houston","typedef struct tskTaskControlBlock {\n    volatile StackType_t *pxTopOfStack;       /* 栈顶指针（必须为第一个字段） */\n\n    ListItem_t xStateListItem;                /* 用于插入状态链表（就绪/阻塞/挂起） */\n    ListItem_t xEventListItem;                /* 用于插入事件等待链表 */\n\n    UBaseType_t uxPriority;                   /* 任务优先级（0=最低） */\n    StackType_t *pxStack;                     /* 栈底指针 */\n    char pcTaskName[configMAX_TASK_NAME_LEN]; /* 任务名（调试用） */\n\n#if ( configUSE_MUTEXES == 1 )\n    UBaseType_t uxBasePriority;               /* 优先级继承前的原始优先级 */\n    UBaseType_t uxMutexesHeld;                /* 持有互斥量数量 */\n#endif\n\n#if ( configUSE_TASK_NOTIFICATIONS == 1 )\n    volatile uint32_t ulNotifiedValue;        /* 任务通知值 */\n    volatile uint8_t ucNotifyState;           /* 通知状态 */\n#endif\n\n    /* 运行时统计（可选） */\n    uint32_t ulRunTimeCounter;                /* 累计运行时钟周期 */\n} TCB_t;\n","c",[141,1976,1977,1989,2007,2011,2019,2027,2031,2039,2052,2067,2071,2093,2101,2109,2114,2118,2133,2147,2161,2166,2171,2177,2189],{"__ignoreMap":1842},[283,1978,1979,1983,1986],{"class":1847,"line":1848},[283,1980,1982],{"class":1981},"sqF6k","typedef",[283,1984,1985],{"class":1981}," struct",[283,1987,1988],{"class":1851}," tskTaskControlBlock {\n",[283,1990,1991,1994,1997,2000,2003],{"class":1847,"line":1855},[283,1992,1993],{"class":1981},"    volatile",[283,1995,1996],{"class":1851}," StackType_t ",[283,1998,1999],{"class":1981},"*",[283,2001,2002],{"class":1851},"pxTopOfStack;",[283,2004,2006],{"class":2005},"sy89t","       /* 栈顶指针（必须为第一个字段） */\n",[283,2008,2009],{"class":1847,"line":1861},[283,2010,1877],{"emptyLinePlaceholder":1876},[283,2012,2013,2016],{"class":1847,"line":1867},[283,2014,2015],{"class":1851},"    ListItem_t xStateListItem;",[283,2017,2018],{"class":2005},"                /* 用于插入状态链表（就绪/阻塞/挂起） */\n",[283,2020,2021,2024],{"class":1847,"line":1873},[283,2022,2023],{"class":1851},"    ListItem_t xEventListItem;",[283,2025,2026],{"class":2005},"                /* 用于插入事件等待链表 */\n",[283,2028,2029],{"class":1847,"line":1880},[283,2030,1877],{"emptyLinePlaceholder":1876},[283,2032,2033,2036],{"class":1847,"line":1886},[283,2034,2035],{"class":1851},"    UBaseType_t uxPriority;",[283,2037,2038],{"class":2005},"                   /* 任务优先级（0=最低） */\n",[283,2040,2041,2044,2046,2049],{"class":1847,"line":1892},[283,2042,2043],{"class":1851},"    StackType_t ",[283,2045,1999],{"class":1981},[283,2047,2048],{"class":1851},"pxStack;",[283,2050,2051],{"class":2005},"                     /* 栈底指针 */\n",[283,2053,2054,2057,2061,2064],{"class":1847,"line":1898},[283,2055,2056],{"class":1981},"    char",[283,2058,2060],{"class":2059},"sb16X"," pcTaskName",[283,2062,2063],{"class":1851},"[configMAX_TASK_NAME_LEN];",[283,2065,2066],{"class":2005}," /* 任务名（调试用） */\n",[283,2068,2069],{"class":1847,"line":1903},[283,2070,1877],{"emptyLinePlaceholder":1876},[283,2072,2073,2076,2079,2083,2086,2090],{"class":1847,"line":1909},[283,2074,2075],{"class":1981},"#if",[283,2077,2078],{"class":1851}," ( ",[283,2080,2082],{"class":2081},"stHQG","configUSE_MUTEXES",[283,2084,2085],{"class":1981}," ==",[283,2087,2089],{"class":2088},"se2J0"," 1",[283,2091,2092],{"class":1851}," )\n",[283,2094,2095,2098],{"class":1847,"line":1915},[283,2096,2097],{"class":1851},"    UBaseType_t uxBasePriority;",[283,2099,2100],{"class":2005},"               /* 优先级继承前的原始优先级 */\n",[283,2102,2103,2106],{"class":1847,"line":1920},[283,2104,2105],{"class":1851},"    UBaseType_t uxMutexesHeld;",[283,2107,2108],{"class":2005},"                /* 持有互斥量数量 */\n",[283,2110,2111],{"class":1847,"line":1926},[283,2112,2113],{"class":1981},"#endif\n",[283,2115,2116],{"class":1847,"line":1932},[283,2117,1877],{"emptyLinePlaceholder":1876},[283,2119,2120,2122,2124,2127,2129,2131],{"class":1847,"line":1938},[283,2121,2075],{"class":1981},[283,2123,2078],{"class":1851},[283,2125,2126],{"class":2081},"configUSE_TASK_NOTIFICATIONS",[283,2128,2085],{"class":1981},[283,2130,2089],{"class":2088},[283,2132,2092],{"class":1851},[283,2134,2136,2138,2141,2144],{"class":1847,"line":2135},17,[283,2137,1993],{"class":1981},[283,2139,2140],{"class":1981}," uint32_t",[283,2142,2143],{"class":1851}," ulNotifiedValue;",[283,2145,2146],{"class":2005},"        /* 任务通知值 */\n",[283,2148,2150,2152,2155,2158],{"class":1847,"line":2149},18,[283,2151,1993],{"class":1981},[283,2153,2154],{"class":1981}," uint8_t",[283,2156,2157],{"class":1851}," ucNotifyState;",[283,2159,2160],{"class":2005},"           /* 通知状态 */\n",[283,2162,2164],{"class":1847,"line":2163},19,[283,2165,2113],{"class":1981},[283,2167,2169],{"class":1847,"line":2168},20,[283,2170,1877],{"emptyLinePlaceholder":1876},[283,2172,2174],{"class":1847,"line":2173},21,[283,2175,2176],{"class":2005},"    /* 运行时统计（可选） */\n",[283,2178,2180,2183,2186],{"class":1847,"line":2179},22,[283,2181,2182],{"class":1981},"    uint32_t",[283,2184,2185],{"class":1851}," ulRunTimeCounter;",[283,2187,2188],{"class":2005},"                /* 累计运行时钟周期 */\n",[283,2190,2192],{"class":1847,"line":2191},23,[283,2193,2194],{"class":1851},"} TCB_t;\n",[10,2196,2197],{},"其中两个细节值得注意：",[2199,2200,2201,2212],"ul",{},[2202,2203,2204,2207,2208,2211],"li",{},[141,2205,2206],{},"pxTopOfStack"," ",[31,2209,2210],{},"必须是结构体的第一个字段","——上下文切换的汇编代码会直接把 TCB 指针解引用为栈顶指针，不做偏移计算；",[2202,2213,2214,2217],{},[141,2215,2216],{},"uxBasePriority"," 仅在启用互斥量时存在——它记录优先级继承前的原始优先级，用于互斥量释放后恢复现场。",[24,2219,2220],{"id":2220},"任务状态机",[10,2222,2223],{},"FreeRTOS 任务在其生命周期内经历以下五种状态的转换：",[1837,2225,2227],{"className":1839,"code":2226,"language":1841,"meta":1842,"style":1842},"stateDiagram-v2\n    state \"任务生命周期\" as TaskLife {\n        Ready : 就绪态\n        Running : 运行态\n        Blocked : 阻塞态\n        Suspended : 挂起态\n\n        [*] --> Ready : vTaskCreate()\n        Ready --> Running : 调度器选中\n        Running --> Ready : 抢占/时间片到期\n        Running --> Blocked : 阻塞型API调用\n        Blocked --> Ready : 事件触发/超时到期\n        Running --> Suspended : vTaskSuspend()\n        Suspended --> Ready : vTaskResume()\n    }\n    TaskLife --> Deleted : vTaskDelete() (任何状态)\n    Deleted : 已删除\n    Deleted --> [*] : 待空闲任务回收栈\n",[141,2228,2229,2234,2239,2244,2249,2254,2259,2263,2268,2273,2278,2283,2288,2293,2298,2303,2308,2313],{"__ignoreMap":1842},[283,2230,2231],{"class":1847,"line":1848},[283,2232,2233],{"class":1851},"stateDiagram-v2\n",[283,2235,2236],{"class":1847,"line":1855},[283,2237,2238],{"class":1851},"    state \"任务生命周期\" as TaskLife {\n",[283,2240,2241],{"class":1847,"line":1861},[283,2242,2243],{"class":1851},"        Ready : 就绪态\n",[283,2245,2246],{"class":1847,"line":1867},[283,2247,2248],{"class":1851},"        Running : 运行态\n",[283,2250,2251],{"class":1847,"line":1873},[283,2252,2253],{"class":1851},"        Blocked : 阻塞态\n",[283,2255,2256],{"class":1847,"line":1880},[283,2257,2258],{"class":1851},"        Suspended : 挂起态\n",[283,2260,2261],{"class":1847,"line":1886},[283,2262,1877],{"emptyLinePlaceholder":1876},[283,2264,2265],{"class":1847,"line":1892},[283,2266,2267],{"class":1851},"        [*] --> Ready : vTaskCreate()\n",[283,2269,2270],{"class":1847,"line":1898},[283,2271,2272],{"class":1851},"        Ready --> Running : 调度器选中\n",[283,2274,2275],{"class":1847,"line":1903},[283,2276,2277],{"class":1851},"        Running --> Ready : 抢占/时间片到期\n",[283,2279,2280],{"class":1847,"line":1909},[283,2281,2282],{"class":1851},"        Running --> Blocked : 阻塞型API调用\n",[283,2284,2285],{"class":1847,"line":1915},[283,2286,2287],{"class":1851},"        Blocked --> Ready : 事件触发/超时到期\n",[283,2289,2290],{"class":1847,"line":1920},[283,2291,2292],{"class":1851},"        Running --> Suspended : vTaskSuspend()\n",[283,2294,2295],{"class":1847,"line":1926},[283,2296,2297],{"class":1851},"        Suspended --> Ready : vTaskResume()\n",[283,2299,2300],{"class":1847,"line":1932},[283,2301,2302],{"class":1851},"    }\n",[283,2304,2305],{"class":1847,"line":1938},[283,2306,2307],{"class":1851},"    TaskLife --> Deleted : vTaskDelete() (任何状态)\n",[283,2309,2310],{"class":1847,"line":2135},[283,2311,2312],{"class":1851},"    Deleted : 已删除\n",[283,2314,2315],{"class":1847,"line":2149},[283,2316,2317],{"class":1851},"    Deleted --> [*] : 待空闲任务回收栈\n",[10,2319,2320],{},[1945,2321,2322],{},"图 2：任务生命周期状态转换图",[10,2324,2325],{},"各状态转换的触发条件如下：",[39,2327,2328,2338],{},[42,2329,2330],{},[45,2331,2332,2335],{},[48,2333,2334],{"align":50},"转换",[48,2336,2337],{"align":50},"触发方式",[62,2339,2340,2348,2366,2374,2384],{},[45,2341,2342,2345],{},[67,2343,2344],{"align":50},"Ready → Running",[67,2346,2347],{"align":50},"调度器在 Tick 中断或抢占点选中",[45,2349,2350,2353],{},[67,2351,2352],{"align":50},"Running → Blocked",[67,2354,2355,2358,2359,2358,2362,2365],{"align":50},[141,2356,2357],{},"vTaskDelay()","、",[141,2360,2361],{},"xQueueReceive()",[141,2363,2364],{},"xSemaphoreTake()"," 等阻塞调用",[45,2367,2368,2371],{},[67,2369,2370],{"align":50},"Blocked → Ready",[67,2372,2373],{"align":50},"阻塞超时到期，或等待的事件（队列非空、信号量可用）发生",[45,2375,2376,2379],{},[67,2377,2378],{"align":50},"Running → Suspended",[67,2380,2381],{"align":50},[141,2382,2383],{},"vTaskSuspend(xTask)",[45,2385,2386,2389],{},[67,2387,2388],{"align":50},"Suspended → Ready",[67,2390,2391,2394,2395],{"align":50},[141,2392,2393],{},"vTaskResume(xTask)"," 或中断中 ",[141,2396,2397],{},"vTaskResumeFromISR()",[10,2399,2400,2401,2404],{},"挂起态与阻塞态的区别容易被混淆：",[31,2402,2403],{},"阻塞态有超时约束，等待的是事件；挂起态没有超时，等待的是显式的恢复调用","。因此挂起态的任务即使其等待的事件发生也不会被唤醒。",[20,2406,2408],{"id":2407},"freertos-核心调度机制","FreeRTOS 核心调度机制",[24,2410,2411],{"id":2411},"就绪队列的数据结构设计",[10,2413,2414,2415,2418,2419,2465],{},"FreeRTOS 调度器的核心数据结构是",[31,2416,2417],{},"优先级就绪链表数组 + 优先级位图","，这是其 ",[283,2420,2422,2443],{"className":2421},[286],[283,2423,2425],{"className":2424},[290],[292,2426,2427],{"xmlns":294},[296,2428,2429,2440],{},[299,2430,2431,2434,2436,2438],{},[302,2432,2433],{},"O",[357,2435,404],{"stretchy":403},[374,2437,376],{},[357,2439,428],{"stretchy":403},[306,2441,2442],{"encoding":308},"O(1)",[283,2444,2446],{"className":2445,"ariaHidden":313},[312],[283,2447,2449,2452,2456,2459,2462],{"className":2448},[317],[283,2450],{"className":2451,"style":835},[321],[283,2453,2433],{"className":2454,"style":2455},[326,327],"margin-right:0.0278em;",[283,2457,404],{"className":2458},[612],[283,2460,376],{"className":2461},[326],[283,2463,428],{"className":2464},[757]," 调度复杂度的基础：",[1837,2467,2469],{"className":1972,"code":2468,"language":1974,"meta":1842,"style":1842},"/* 内核全局变量 */\nPRIVILEGED_DATA static List_t pxReadyTasksLists[configMAX_PRIORITIES];\n\n/* 当前最高就绪优先级（位图实现） */\n#if ( configUSE_PORT_OPTIMISED_TASK_SELECTION == 1 )\n    /* 方法一：硬件 CLZ（Count Leading Zeros）指令加速 */\n    #define portGET_HIGHEST_PRIORITY(uxTopPriority, uxReadyPriorities) \\\n        uxTopPriority = (31UL - (uint32_t)__clz((uxReadyPriorities)))\n#else\n    /* 方法二：通用软件位扫描 */\n    static volatile UBaseType_t uxTopReadyPriority;\n#endif\n",[141,2470,2471,2476,2493,2497,2502,2517,2522,2545,2587,2592,2597,2608],{"__ignoreMap":1842},[283,2472,2473],{"class":1847,"line":1848},[283,2474,2475],{"class":2005},"/* 内核全局变量 */\n",[283,2477,2478,2481,2484,2487,2490],{"class":1847,"line":1855},[283,2479,2480],{"class":1851},"PRIVILEGED_DATA ",[283,2482,2483],{"class":1981},"static",[283,2485,2486],{"class":1851}," List_t ",[283,2488,2489],{"class":2059},"pxReadyTasksLists",[283,2491,2492],{"class":1851},"[configMAX_PRIORITIES];\n",[283,2494,2495],{"class":1847,"line":1861},[283,2496,1877],{"emptyLinePlaceholder":1876},[283,2498,2499],{"class":1847,"line":1867},[283,2500,2501],{"class":2005},"/* 当前最高就绪优先级（位图实现） */\n",[283,2503,2504,2506,2508,2511,2513,2515],{"class":1847,"line":1873},[283,2505,2075],{"class":1981},[283,2507,2078],{"class":1851},[283,2509,2510],{"class":2081},"configUSE_PORT_OPTIMISED_TASK_SELECTION",[283,2512,2085],{"class":1981},[283,2514,2089],{"class":2088},[283,2516,2092],{"class":1851},[283,2518,2519],{"class":1847,"line":1880},[283,2520,2521],{"class":2005},"    /* 方法一：硬件 CLZ（Count Leading Zeros）指令加速 */\n",[283,2523,2524,2527,2530,2532,2536,2539,2542],{"class":1847,"line":1886},[283,2525,2526],{"class":1981},"    #define",[283,2528,2529],{"class":2081}," portGET_HIGHEST_PRIORITY",[283,2531,404],{"class":1851},[283,2533,2535],{"class":2534},"smONe","uxTopPriority",[283,2537,2538],{"class":1851},", ",[283,2540,2541],{"class":2534},"uxReadyPriorities",[283,2543,2544],{"class":1851},") \\\n",[283,2546,2547,2550,2552,2555,2558,2561,2564,2566,2569,2571,2574,2576,2578,2580,2582,2584],{"class":1847,"line":1892},[283,2548,2549],{"class":1851},"        uxTopPriority ",[283,2551,359],{"class":1981},[283,2553,2554],{"class":1851}," (",[283,2556,2557],{"class":2088},"31",[283,2559,2560],{"class":2059},"UL",[283,2562,2563],{"class":1981}," -",[283,2565,2554],{"class":1851},[283,2567,2568],{"class":1981},"uint32_t",[283,2570,428],{"class":1851},[283,2572,2573],{"class":2081},"__clz",[283,2575,404],{"class":2059},[283,2577,404],{"class":1851},[283,2579,2541],{"class":2059},[283,2581,428],{"class":1851},[283,2583,428],{"class":2059},[283,2585,2586],{"class":1851},")\n",[283,2588,2589],{"class":1847,"line":1898},[283,2590,2591],{"class":1981},"#else\n",[283,2593,2594],{"class":1847,"line":1903},[283,2595,2596],{"class":2005},"    /* 方法二：通用软件位扫描 */\n",[283,2598,2599,2602,2605],{"class":1847,"line":1909},[283,2600,2601],{"class":1981},"    static",[283,2603,2604],{"class":1981}," volatile",[283,2606,2607],{"class":1851}," UBaseType_t uxTopReadyPriority;\n",[283,2609,2610],{"class":1847,"line":1915},[283,2611,2113],{"class":1981},[10,2613,2614],{},"查找最高优先级就绪任务的过程：",[1837,2616,2618],{"className":1972,"code":2617,"language":1974,"meta":1842,"style":1842},"#define taskSELECT_HIGHEST_PRIORITY_TASK()                                    \\\n{                                                                             \\\n    UBaseType_t uxTopPriority;                                                \\\n    /* 步骤 1：通过位图（CLZ 指令）找到最高就绪优先级，O(1) */                \\\n    portGET_HIGHEST_PRIORITY(uxTopPriority, uxTopReadyPriority);              \\\n    /* 步骤 2：从该优先级的链表中取下一个任务（支持同级轮转），O(1) */        \\\n    pxCurrentTCB = listGET_OWNER_OF_NEXT_ENTRY(                               \\\n                        &(pxReadyTasksLists[uxTopPriority]));                 \\\n}\n",[141,2619,2620,2631,2636,2641,2649,2666,2674,2690,2707],{"__ignoreMap":1842},[283,2621,2622,2625,2628],{"class":1847,"line":1848},[283,2623,2624],{"class":1981},"#define",[283,2626,2627],{"class":2081}," taskSELECT_HIGHEST_PRIORITY_TASK",[283,2629,2630],{"class":1851},"()                                    \\\n",[283,2632,2633],{"class":1847,"line":1855},[283,2634,2635],{"class":1851},"{                                                                             \\\n",[283,2637,2638],{"class":1847,"line":1861},[283,2639,2640],{"class":1851},"    UBaseType_t uxTopPriority;                                                \\\n",[283,2642,2643,2646],{"class":1847,"line":1867},[283,2644,2645],{"class":2005},"    /* 步骤 1：通过位图（CLZ 指令）找到最高就绪优先级，O(1) */",[283,2647,2648],{"class":1851},"                \\\n",[283,2650,2651,2654,2657,2660,2663],{"class":1847,"line":1873},[283,2652,2653],{"class":2081},"    portGET_HIGHEST_PRIORITY",[283,2655,2656],{"class":2059},"(uxTopPriority",[283,2658,2659],{"class":1851},",",[283,2661,2662],{"class":2059}," uxTopReadyPriority)",[283,2664,2665],{"class":1851},";              \\\n",[283,2667,2668,2671],{"class":1847,"line":1880},[283,2669,2670],{"class":2005},"    /* 步骤 2：从该优先级的链表中取下一个任务（支持同级轮转），O(1) */",[283,2672,2673],{"class":1851},"        \\\n",[283,2675,2676,2679,2681,2684,2687],{"class":1847,"line":1886},[283,2677,2678],{"class":1851},"    pxCurrentTCB ",[283,2680,359],{"class":1981},[283,2682,2683],{"class":2081}," listGET_OWNER_OF_NEXT_ENTRY",[283,2685,2686],{"class":2059},"(                               ",[283,2688,2689],{"class":1851},"\\\n",[283,2691,2692,2695,2697,2700,2702,2704],{"class":1847,"line":1892},[283,2693,2694],{"class":1981},"                        &",[283,2696,404],{"class":1851},[283,2698,2699],{"class":2059},"pxReadyTasksLists[uxTopPriority]",[283,2701,428],{"class":1851},[283,2703,428],{"class":2059},[283,2705,2706],{"class":1851},";                 \\\n",[283,2708,2709],{"class":1847,"line":1898},[283,2710,2711],{"class":1851},"}\n",[10,2713,2714,2715,2718,2719,2722],{},"整个调度决策过程仅需 ",[31,2716,2717],{},"1 条 CLZ 硬件指令 + 几次指针操作","，在 168 MHz 的 Cortex-M4 上执行时间约为 ",[31,2720,2721],{},"6–12 ns","，对系统实时性的影响可忽略不计。",[10,2724,2725,2726,2790,2791,2794],{},"这里的设计思想与 Linux CFS 的红黑树（",[283,2727,2729,2758],{"className":2728},[286],[283,2730,2732],{"className":2731},[290],[292,2733,2734],{"xmlns":294},[296,2735,2736,2755],{},[299,2737,2738,2740,2742,2745,2748,2751,2753],{},[302,2739,2433],{},[357,2741,404],{"stretchy":403},[302,2743,2744],{},"l",[302,2746,2747],{},"o",[302,2749,2750],{},"g",[302,2752,304],{},[357,2754,428],{"stretchy":403},[306,2756,2757],{"encoding":308},"O(log n)",[283,2759,2761],{"className":2760,"ariaHidden":313},[312],[283,2762,2764,2767,2770,2773,2777,2780,2784,2787],{"className":2763},[317],[283,2765],{"className":2766,"style":835},[321],[283,2768,2433],{"className":2769,"style":2455},[326,327],[283,2771,404],{"className":2772},[612],[283,2774,2744],{"className":2775,"style":2776},[326,327],"margin-right:0.0197em;",[283,2778,2747],{"className":2779},[326,327],[283,2781,2750],{"className":2782,"style":2783},[326,327],"margin-right:0.0359em;",[283,2785,304],{"className":2786},[326,327],[283,2788,428],{"className":2789},[757],"）形成鲜明对比：FreeRTOS 用“",[31,2792,2793],{},"空间换时间","”——维护 32 条链表几乎不占额外计算，却把调度决策压缩到了常数时间。对于任务数量少（通常 3~20 个）但时序要求严苛的嵌入式场景，这是更合适的选择。",[24,2796,2797],{"id":2797},"三种调度模式详解",[10,2799,2800,2801,2804],{},"FreeRTOS 的调度行为通过 ",[141,2802,2803],{},"FreeRTOSConfig.h"," 中的宏配置，支持三种模式：",[2806,2807,2808,2901,2959],"tabs",{},[2809,2810,2811,2867,2870],"template",{"v-slot:P-固定优先级抢占式（默认）":1842},[1837,2812,2814],{"className":1972,"code":2813,"language":1974,"meta":1842,"style":1842},"/* FreeRTOSConfig.h —— 默认模式 */\n#define configUSE_PREEMPTION       1\n#define configUSE_TIME_SLICING     0\n#define configMAX_PRIORITIES       32   /* 32 个优先级，0 最低，31 最高 */\n#define configTICK_RATE_HZ         1000 /* 1ms 系统心跳 */\n",[141,2815,2816,2821,2831,2841,2854],{"__ignoreMap":1842},[283,2817,2818],{"class":1847,"line":1848},[283,2819,2820],{"class":2005},"/* FreeRTOSConfig.h —— 默认模式 */\n",[283,2822,2823,2825,2828],{"class":1847,"line":1855},[283,2824,2624],{"class":1981},[283,2826,2827],{"class":2081}," configUSE_PREEMPTION",[283,2829,2830],{"class":2088},"       1\n",[283,2832,2833,2835,2838],{"class":1847,"line":1861},[283,2834,2624],{"class":1981},[283,2836,2837],{"class":2081}," configUSE_TIME_SLICING",[283,2839,2840],{"class":2088},"     0\n",[283,2842,2843,2845,2848,2851],{"class":1847,"line":1867},[283,2844,2624],{"class":1981},[283,2846,2847],{"class":2081}," configMAX_PRIORITIES",[283,2849,2850],{"class":2088},"       32",[283,2852,2853],{"class":2005},"   /* 32 个优先级，0 最低，31 最高 */\n",[283,2855,2856,2858,2861,2864],{"class":1847,"line":1873},[283,2857,2624],{"class":1981},[283,2859,2860],{"class":2081}," configTICK_RATE_HZ",[283,2862,2863],{"class":2088},"         1000",[283,2865,2866],{"class":2005}," /* 1ms 系统心跳 */\n",[10,2868,2869],{},"调度规则：",[2871,2872,2873,2884,2891,2898],"ol",{},[2202,2874,2875,2876,2879,2880,2883],{},"每个任务拥有 0 ~ ",[141,2877,2878],{},"configMAX_PRIORITIES - 1"," 之间的",[31,2881,2882],{},"静态优先级","，数值越大优先级越高；",[2202,2885,2886,2887,2890],{},"调度器始终运行",[31,2888,2889],{},"就绪队列中优先级最高","的任务；",[2202,2892,2893,2894,2897],{},"当更高优先级任务进入就绪态时（无论是从阻塞态恢复，还是由 ISR 释放同步原语），当前任务",[31,2895,2896],{},"立即被抢占","，发生上下文切换；",[2202,2899,2900],{},"相同优先级的任务不切换，按 FIFO 顺序持续执行直到主动放弃 CPU。",[2809,2902,2903,2942,2949],{"v-slot:T-时间片轮转":1842},[1837,2904,2906],{"className":1972,"code":2905,"language":1974,"meta":1842,"style":1842},"/* FreeRTOSConfig.h —— 同级时间片轮转 */\n#define configUSE_PREEMPTION       1\n#define configUSE_TIME_SLICING     1   /* 开启同级时间片轮转 */\n#define configTICK_RATE_HZ         1000\n",[141,2907,2908,2913,2921,2933],{"__ignoreMap":1842},[283,2909,2910],{"class":1847,"line":1848},[283,2911,2912],{"class":2005},"/* FreeRTOSConfig.h —— 同级时间片轮转 */\n",[283,2914,2915,2917,2919],{"class":1847,"line":1855},[283,2916,2624],{"class":1981},[283,2918,2827],{"class":2081},[283,2920,2830],{"class":2088},[283,2922,2923,2925,2927,2930],{"class":1847,"line":1861},[283,2924,2624],{"class":1981},[283,2926,2837],{"class":2081},[283,2928,2929],{"class":2088},"     1",[283,2931,2932],{"class":2005},"   /* 开启同级时间片轮转 */\n",[283,2934,2935,2937,2939],{"class":1847,"line":1867},[283,2936,2624],{"class":1981},[283,2938,2860],{"class":2081},[283,2940,2941],{"class":2088},"         1000\n",[10,2943,2944,2945,2948],{},"在抢占式调度基础上，相同优先级的多个就绪任务将",[31,2946,2947],{},"按时间片轮转执行","。每次 Tick 中断（1ms）发生时，若就绪队列中存在与当前任务同等优先级的其他任务，则切换到同级链表中的下一个任务。",[1949,2950,2952],{"type":2951},"warning",[10,2953,2954,2955,2958],{},"时间片轮转仅发生在",[31,2956,2957],{},"同优先级任务之间","，不同优先级之间依然是纯抢占关系——时间片轮转不会让低优先级任务获得运行机会。",[2809,2960,2961,2983,2986,3005],{"v-slot:C-协作式":1842},[1837,2962,2964],{"className":1972,"code":2963,"language":1974,"meta":1842,"style":1842},"/* FreeRTOSConfig.h —— 协作式调度 */\n#define configUSE_PREEMPTION  0  /* 关闭抢占 */\n",[141,2965,2966,2971],{"__ignoreMap":1842},[283,2967,2968],{"class":1847,"line":1848},[283,2969,2970],{"class":2005},"/* FreeRTOSConfig.h —— 协作式调度 */\n",[283,2972,2973,2975,2977,2980],{"class":1847,"line":1855},[283,2974,2624],{"class":1981},[283,2976,2827],{"class":2081},[283,2978,2979],{"class":2088},"  0",[283,2981,2982],{"class":2005},"  /* 关闭抢占 */\n",[10,2984,2985],{},"关闭抢占后，CPU 只能被以下方式释放：",[2199,2987,2988,2995,2998],{},[2202,2989,2990,2991,2994],{},"任务主动调用 ",[141,2992,2993],{},"taskYIELD()","；",[2202,2996,2997],{},"任务进入阻塞态（调用阻塞型 API）；",[2202,2999,3000,3001,3004],{},"任务调用 ",[141,3002,3003],{},"vTaskDelete()"," 删除自身。",[10,3006,3007],{},"协作式调度适合对任务切换时机有严格控制要求的场景（如需要操作大量共享数据而不希望中途被抢占），但牺牲了实时响应性。",[10,3009,3010],{},[31,3011,3012],{},"调度时序示意（三优先级任务，H=3 > M=2 > L=1）：",[1837,3014,3016],{"className":1839,"code":3015,"language":1841,"meta":1842,"style":1842},"gantt\n    title 固定优先级抢占式调度时序图 (H=3, M=2, L=1)\n    dateFormat X\n    axisFormat t%s\n\n    section Task_H\n    运行 :active, h1, 2, 4\n    运行 :active, h2, 8, 9\n\n    section Task_M\n    运行 :active, m1, 4, 7\n\n    section Task_L\n    运行 :active, l1, 0, 2\n    被H抢占 :crit, w1, 2, 4\n    被M抢占 :crit, w2, 4, 7\n    运行 :active, l2, 7, 8\n    被H抢占 :crit, w3, 8, 9\n    运行 :active, l3, 9, 12\n",[141,3017,3018,3022,3027,3031,3036,3040,3045,3050,3055,3059,3064,3069,3073,3078,3083,3088,3093,3098,3103],{"__ignoreMap":1842},[283,3019,3020],{"class":1847,"line":1848},[283,3021,1852],{"class":1851},[283,3023,3024],{"class":1847,"line":1855},[283,3025,3026],{"class":1851},"    title 固定优先级抢占式调度时序图 (H=3, M=2, L=1)\n",[283,3028,3029],{"class":1847,"line":1861},[283,3030,1864],{"class":1851},[283,3032,3033],{"class":1847,"line":1867},[283,3034,3035],{"class":1851},"    axisFormat t%s\n",[283,3037,3038],{"class":1847,"line":1873},[283,3039,1877],{"emptyLinePlaceholder":1876},[283,3041,3042],{"class":1847,"line":1880},[283,3043,3044],{"class":1851},"    section Task_H\n",[283,3046,3047],{"class":1847,"line":1886},[283,3048,3049],{"class":1851},"    运行 :active, h1, 2, 4\n",[283,3051,3052],{"class":1847,"line":1892},[283,3053,3054],{"class":1851},"    运行 :active, h2, 8, 9\n",[283,3056,3057],{"class":1847,"line":1898},[283,3058,1877],{"emptyLinePlaceholder":1876},[283,3060,3061],{"class":1847,"line":1903},[283,3062,3063],{"class":1851},"    section Task_M\n",[283,3065,3066],{"class":1847,"line":1909},[283,3067,3068],{"class":1851},"    运行 :active, m1, 4, 7\n",[283,3070,3071],{"class":1847,"line":1915},[283,3072,1877],{"emptyLinePlaceholder":1876},[283,3074,3075],{"class":1847,"line":1920},[283,3076,3077],{"class":1851},"    section Task_L\n",[283,3079,3080],{"class":1847,"line":1926},[283,3081,3082],{"class":1851},"    运行 :active, l1, 0, 2\n",[283,3084,3085],{"class":1847,"line":1932},[283,3086,3087],{"class":1851},"    被H抢占 :crit, w1, 2, 4\n",[283,3089,3090],{"class":1847,"line":1938},[283,3091,3092],{"class":1851},"    被M抢占 :crit, w2, 4, 7\n",[283,3094,3095],{"class":1847,"line":2135},[283,3096,3097],{"class":1851},"    运行 :active, l2, 7, 8\n",[283,3099,3100],{"class":1847,"line":2149},[283,3101,3102],{"class":1851},"    被H抢占 :crit, w3, 8, 9\n",[283,3104,3105],{"class":1847,"line":2163},[283,3106,3107],{"class":1851},"    运行 :active, l3, 9, 12\n",[10,3109,3110],{},[1945,3111,3112],{},"图 3：固定优先级抢占式调度时序图",[10,3114,3115,3116,3119],{},"注意 L 在 4~7 段被“间接”推迟了 3 个时间单位：H 与 M 的抢占是直接可解释的，但 M 之所以能运行，是因为 H 已进入阻塞（或尚未就绪）。这也是为什么",[31,3117,3118],{},"中断延迟与最长阻塞时间","才是硬实时系统关注的关键指标。",[10,3121,3122],{},[31,3123,3124],{},"同优先级时间片轮转的时序（时间片 = 1 Tick = 1ms）：",[1837,3126,3128],{"className":1839,"code":3127,"language":1841,"meta":1842,"style":1842},"gantt\n    title 同优先级时间片轮转调度时序图 (时间片 = 1 Tick = 1ms)\n    dateFormat X\n    axisFormat %s ms\n\n    section Task_A\n    运行 :active, a1, 0, 1\n    运行 :active, a2, 3, 4\n    运行 :active, a3, 6, 7\n\n    section Task_B\n    运行 :active, b1, 1, 2\n    运行 :active, b2, 4, 5\n    运行 :active, b3, 7, 8\n\n    section Task_C\n    运行 :active, c1, 2, 3\n    运行 :active, c2, 5, 6\n",[141,3129,3130,3134,3139,3143,3148,3152,3157,3162,3167,3172,3176,3181,3186,3191,3196,3200,3205,3210],{"__ignoreMap":1842},[283,3131,3132],{"class":1847,"line":1848},[283,3133,1852],{"class":1851},[283,3135,3136],{"class":1847,"line":1855},[283,3137,3138],{"class":1851},"    title 同优先级时间片轮转调度时序图 (时间片 = 1 Tick = 1ms)\n",[283,3140,3141],{"class":1847,"line":1861},[283,3142,1864],{"class":1851},[283,3144,3145],{"class":1847,"line":1867},[283,3146,3147],{"class":1851},"    axisFormat %s ms\n",[283,3149,3150],{"class":1847,"line":1873},[283,3151,1877],{"emptyLinePlaceholder":1876},[283,3153,3154],{"class":1847,"line":1880},[283,3155,3156],{"class":1851},"    section Task_A\n",[283,3158,3159],{"class":1847,"line":1886},[283,3160,3161],{"class":1851},"    运行 :active, a1, 0, 1\n",[283,3163,3164],{"class":1847,"line":1892},[283,3165,3166],{"class":1851},"    运行 :active, a2, 3, 4\n",[283,3168,3169],{"class":1847,"line":1898},[283,3170,3171],{"class":1851},"    运行 :active, a3, 6, 7\n",[283,3173,3174],{"class":1847,"line":1903},[283,3175,1877],{"emptyLinePlaceholder":1876},[283,3177,3178],{"class":1847,"line":1909},[283,3179,3180],{"class":1851},"    section Task_B\n",[283,3182,3183],{"class":1847,"line":1915},[283,3184,3185],{"class":1851},"    运行 :active, b1, 1, 2\n",[283,3187,3188],{"class":1847,"line":1920},[283,3189,3190],{"class":1851},"    运行 :active, b2, 4, 5\n",[283,3192,3193],{"class":1847,"line":1926},[283,3194,3195],{"class":1851},"    运行 :active, b3, 7, 8\n",[283,3197,3198],{"class":1847,"line":1932},[283,3199,1877],{"emptyLinePlaceholder":1876},[283,3201,3202],{"class":1847,"line":1938},[283,3203,3204],{"class":1851},"    section Task_C\n",[283,3206,3207],{"class":1847,"line":2135},[283,3208,3209],{"class":1851},"    运行 :active, c1, 2, 3\n",[283,3211,3212],{"class":1847,"line":2149},[283,3213,3214],{"class":1851},"    运行 :active, c2, 5, 6\n",[10,3216,3217],{},[1945,3218,3219],{},"图 4：同优先级时间片轮转调度时序图",[24,3221,3223],{"id":3222},"上下文切换机制以-arm-cortex-m4-为例","上下文切换机制（以 ARM Cortex-M4 为例）",[10,3225,3226],{},"上下文切换是实时调度的关键执行路径，其开销直接决定系统的最大任务切换频率和中断响应延迟。",[3228,3229,3231],"h4",{"id":3230},"触发机制pendsv-异常","触发机制：PendSV 异常",[10,3233,3234,3235,3238],{},"FreeRTOS 在 ARM Cortex-M 架构上利用 ",[31,3236,3237],{},"PendSV（Pendable Service Call）异常","执行上下文切换。PendSV 被配置为系统中最低优先级的异常，确保上下文切换仅在所有其他 ISR 执行完毕后才进行，避免中断嵌套期间切换任务导致的不一致。",[10,3240,3241],{},[31,3242,3243],{},"切换触发路径：",[1837,3245,3249],{"className":3246,"code":3248,"language":488,"meta":1842},[3247],"language-text","路径一：Tick 中断\nSysTick_Handler() → xTaskIncrementTick() → 检查是否需要切换\n→ 若需要，设置 SCB->ICSR |= SCB_ICSR_PENDSVSET → PendSV 挂起\n\n路径二：高优先级任务就绪（ISR 中释放信号量等）\nxSemaphoreGiveFromISR() → xTaskResumeFromISR() → 更新就绪队列\n→ portYIELD_FROM_ISR() → 设置 PendSV → PendSV 挂起\n",[141,3250,3248],{"__ignoreMap":1842},[10,3252,3253],{},"这个“延迟切换”的设计非常巧妙：ISR 中只需设置一个挂起标志位，真正的上下文切换被推迟到所有中断处理完成后。这样既保证了切换过程不会被高优先级中断打断，也避免了在中断嵌套的复杂状态中操作任务栈。",[3228,3255,3257],{"id":3256},"上下文保存与恢复汇编核心代码","上下文保存与恢复（汇编核心代码）",[1837,3259,3263],{"className":3260,"code":3261,"language":3262,"meta":1842,"style":1842},"language-asm shiki shiki-themes houston","; FreeRTOS Cortex-M4 PendSV 处理函数（简化注释版）\nxPortPendSVHandler:\n    ; ── 保存当前任务上下文 ──\n    mrs  r0, psp               ; 读取进程栈指针（任务使用 PSP）\n    isb                        ; 指令同步屏障\n\n    ldr  r3, =pxCurrentTCB     ; 加载当前 TCB 指针地址\n    ldr  r2, [r3]\n\n    ; 保存 R4-R11（硬件自动保存 R0-R3, R12, LR, PC, xPSR）\n    stmdb r0!, {r4-r11, r14}   ; 将 R4-R11 和 LR 压栈，r0 更新为新栈顶\n    str   r0, [r2]             ; 将新栈顶保存到 TCB.pxTopOfStack\n\n    ; ── 调度器选择下一任务 ──\n    stmdb sp!, {r3, r14}       ; 保存 r3, lr 到 MSP（主栈）\n    mov  r0, #configMAX_SYSCALL_INTERRUPT_PRIORITY\n    msr  basepri, r0           ; 关闭低优先级中断（临界区）\n    bl   vTaskSwitchContext    ; 调用 C 函数：更新 pxCurrentTCB\n    mov  r0, #0\n    msr  basepri, r0           ; 重新开启中断\n    ldmia sp!, {r3, r14}       ; 恢复 r3, lr\n\n    ; ── 恢复新任务上下文 ──\n    ldr  r1, [r3]              ; 加载新任务 TCB\n    ldr  r0, [r1]              ; 读取新任务栈顶\n    ldmia r0!, {r4-r11, r14}   ; 从栈中恢复 R4-R11\n    msr  psp, r0               ; 更新 PSP 为新任务栈顶\n    isb\n    bx   r14                   ; 返回（硬件自动恢复 R0-R3, R12, PC, xPSR）\n","asm",[141,3264,3265,3270,3275,3280,3288,3296,3300,3308,3313,3317,3322,3341,3349,3353,3358,3377,3382,3390,3401,3409,3416,3432,3436,3441,3450,3459,3476,3485,3491],{"__ignoreMap":1842},[283,3266,3267],{"class":1847,"line":1848},[283,3268,3269],{"class":2005},"; FreeRTOS Cortex-M4 PendSV 处理函数（简化注释版）\n",[283,3271,3272],{"class":1847,"line":1855},[283,3273,3274],{"class":2081},"xPortPendSVHandler:\n",[283,3276,3277],{"class":1847,"line":1861},[283,3278,3279],{"class":2005},"    ; ── 保存当前任务上下文 ──\n",[283,3281,3282,3285],{"class":1847,"line":1867},[283,3283,3284],{"class":1851},"    mrs  r0, psp               ",[283,3286,3287],{"class":2005},"; 读取进程栈指针（任务使用 PSP）\n",[283,3289,3290,3293],{"class":1847,"line":1873},[283,3291,3292],{"class":1851},"    isb                        ",[283,3294,3295],{"class":2005},"; 指令同步屏障\n",[283,3297,3298],{"class":1847,"line":1880},[283,3299,1877],{"emptyLinePlaceholder":1876},[283,3301,3302,3305],{"class":1847,"line":1886},[283,3303,3304],{"class":1851},"    ldr  r3, =pxCurrentTCB     ",[283,3306,3307],{"class":2005},"; 加载当前 TCB 指针地址\n",[283,3309,3310],{"class":1847,"line":1892},[283,3311,3312],{"class":1851},"    ldr  r2, [r3]\n",[283,3314,3315],{"class":1847,"line":1898},[283,3316,1877],{"emptyLinePlaceholder":1876},[283,3318,3319],{"class":1847,"line":1903},[283,3320,3321],{"class":2005},"    ; 保存 R4-R11（硬件自动保存 R0-R3, R12, LR, PC, xPSR）\n",[283,3323,3324,3327,3330,3332,3335,3338],{"class":1847,"line":1909},[283,3325,3326],{"class":1851},"    stmdb r0!, {r4-",[283,3328,3329],{"class":2088},"r11",[283,3331,2538],{"class":1851},[283,3333,3334],{"class":2088},"r14",[283,3336,3337],{"class":1851},"}   ",[283,3339,3340],{"class":2005},"; 将 R4-R11 和 LR 压栈，r0 更新为新栈顶\n",[283,3342,3343,3346],{"class":1847,"line":1915},[283,3344,3345],{"class":1851},"    str   r0, [r2]             ",[283,3347,3348],{"class":2005},"; 将新栈顶保存到 TCB.pxTopOfStack\n",[283,3350,3351],{"class":1847,"line":1920},[283,3352,1877],{"emptyLinePlaceholder":1876},[283,3354,3355],{"class":1847,"line":1926},[283,3356,3357],{"class":2005},"    ; ── 调度器选择下一任务 ──\n",[283,3359,3360,3363,3366,3369,3371,3374],{"class":1847,"line":1932},[283,3361,3362],{"class":1851},"    stmdb ",[283,3364,3365],{"class":2088},"sp",[283,3367,3368],{"class":1851},"!, {r3, ",[283,3370,3334],{"class":2088},[283,3372,3373],{"class":1851},"}       ",[283,3375,3376],{"class":2005},"; 保存 r3, lr 到 MSP（主栈）\n",[283,3378,3379],{"class":1847,"line":1938},[283,3380,3381],{"class":1851},"    mov  r0, #configMAX_SYSCALL_INTERRUPT_PRIORITY\n",[283,3383,3384,3387],{"class":1847,"line":2135},[283,3385,3386],{"class":1851},"    msr  basepri, r0           ",[283,3388,3389],{"class":2005},"; 关闭低优先级中断（临界区）\n",[283,3391,3392,3395,3398],{"class":1847,"line":2149},[283,3393,3394],{"class":2088},"    bl",[283,3396,3397],{"class":1851},"   vTaskSwitchContext    ",[283,3399,3400],{"class":2005},"; 调用 C 函数：更新 pxCurrentTCB\n",[283,3402,3403,3406],{"class":1847,"line":2163},[283,3404,3405],{"class":1851},"    mov  r0, #",[283,3407,3408],{"class":2088},"0\n",[283,3410,3411,3413],{"class":1847,"line":2168},[283,3412,3386],{"class":1851},[283,3414,3415],{"class":2005},"; 重新开启中断\n",[283,3417,3418,3421,3423,3425,3427,3429],{"class":1847,"line":2173},[283,3419,3420],{"class":1851},"    ldmia ",[283,3422,3365],{"class":2088},[283,3424,3368],{"class":1851},[283,3426,3334],{"class":2088},[283,3428,3373],{"class":1851},[283,3430,3431],{"class":2005},"; 恢复 r3, lr\n",[283,3433,3434],{"class":1847,"line":2179},[283,3435,1877],{"emptyLinePlaceholder":1876},[283,3437,3438],{"class":1847,"line":2191},[283,3439,3440],{"class":2005},"    ; ── 恢复新任务上下文 ──\n",[283,3442,3444,3447],{"class":1847,"line":3443},24,[283,3445,3446],{"class":1851},"    ldr  r1, [r3]              ",[283,3448,3449],{"class":2005},"; 加载新任务 TCB\n",[283,3451,3453,3456],{"class":1847,"line":3452},25,[283,3454,3455],{"class":1851},"    ldr  r0, [r1]              ",[283,3457,3458],{"class":2005},"; 读取新任务栈顶\n",[283,3460,3462,3465,3467,3469,3471,3473],{"class":1847,"line":3461},26,[283,3463,3464],{"class":1851},"    ldmia r0!, {r4-",[283,3466,3329],{"class":2088},[283,3468,2538],{"class":1851},[283,3470,3334],{"class":2088},[283,3472,3337],{"class":1851},[283,3474,3475],{"class":2005},"; 从栈中恢复 R4-R11\n",[283,3477,3479,3482],{"class":1847,"line":3478},27,[283,3480,3481],{"class":1851},"    msr  psp, r0               ",[283,3483,3484],{"class":2005},"; 更新 PSP 为新任务栈顶\n",[283,3486,3488],{"class":1847,"line":3487},28,[283,3489,3490],{"class":1851},"    isb\n",[283,3492,3494,3497,3500],{"class":1847,"line":3493},29,[283,3495,3496],{"class":2088},"    bx",[283,3498,3499],{"class":2088},"   r14",[283,3501,3502],{"class":2005},"                   ; 返回（硬件自动恢复 R0-R3, R12, PC, xPSR）\n",[10,3504,3505,3506,3509],{},"Cortex-M 的硬件机制在这里减少了一半工作量：",[31,3507,3508],{},"R0-R3、R12、LR、PC、xPSR 由硬件在异常入口/出口自动保存与恢复","，软件只需处理 R4-R11 等调用者保存寄存器。FPU 启用时，额外的 S0-S15、FPSCR 等浮点上下文也由硬件按需保存。",[3228,3511,3512],{"id":3512},"上下文切换性能实测数据",[10,3514,3515],{},"以下数据来自 FreeRTOS 官方及社区 Benchmark，测试方法为 GPIO 翻转计时：",[39,3517,3518,3537],{},[42,3519,3520],{},[45,3521,3522,3525,3528,3531,3534],{},[48,3523,3524],{"align":50},"处理器平台",[48,3526,3527],{"align":1440},"主频",[48,3529,3530],{"align":1440},"不含 FPU 切换时间",[48,3532,3533],{"align":1440},"含 FPU 切换时间",[48,3535,3536],{"align":1440},"最大中断延迟",[62,3538,3539,3556,3573,3590,3606,3623],{},[45,3540,3541,3544,3547,3550,3553],{},[67,3542,3543],{"align":50},"ARM Cortex-M4（STM32F407）",[67,3545,3546],{"align":1440},"168 MHz",[67,3548,3549],{"align":1440},"~0.68 μs",[67,3551,3552],{"align":1440},"~1.52 μs",[67,3554,3555],{"align":1440},"2.5 μs",[45,3557,3558,3561,3564,3567,3570],{},[67,3559,3560],{"align":50},"ARM Cortex-M4（STM32F446）",[67,3562,3563],{"align":1440},"180 MHz",[67,3565,3566],{"align":1440},"~0.63 μs",[67,3568,3569],{"align":1440},"~1.40 μs",[67,3571,3572],{"align":1440},"2.3 μs",[45,3574,3575,3578,3581,3584,3587],{},[67,3576,3577],{"align":50},"ARM Cortex-M3（STM32F103）",[67,3579,3580],{"align":1440},"72 MHz",[67,3582,3583],{"align":1440},"~1.76 μs",[67,3585,3586],{"align":1440},"N/A",[67,3588,3589],{"align":1440},"5.8 μs",[45,3591,3592,3595,3598,3601,3603],{},[67,3593,3594],{"align":50},"ARM Cortex-M0+（RP2040）",[67,3596,3597],{"align":1440},"133 MHz",[67,3599,3600],{"align":1440},"~1.20 μs",[67,3602,3586],{"align":1440},[67,3604,3605],{"align":1440},"4.5 μs",[45,3607,3608,3611,3614,3617,3620],{},[67,3609,3610],{"align":50},"ARM Cortex-A7（i.MX6UL）",[67,3612,3613],{"align":1440},"528 MHz",[67,3615,3616],{"align":1440},"~1.50 μs",[67,3618,3619],{"align":1440},"~3.20 μs",[67,3621,3622],{"align":1440},"8.0 μs",[45,3624,3625,3628,3631,3634,3636],{},[67,3626,3627],{"align":50},"RISC-V（ESP32-C3）",[67,3629,3630],{"align":1440},"160 MHz",[67,3632,3633],{"align":1440},"~1.05 μs",[67,3635,3586],{"align":1440},[67,3637,3638],{"align":1440},"4.0 μs",[20,3640,3641],{"id":3641},"实时性保障机制",[24,3643,3644],{"id":3644},"优先级继承互斥量",[10,3646,3647,3648,3651],{},"FreeRTOS 通过",[31,3649,3650],{},"互斥量（Mutex）"," 实现优先级继承协议（Priority Inheritance Protocol, PIP），以缓解优先级反转问题。",[1949,3653,3654],{"type":2951},[10,3655,3656,3657,3660],{},"需要注意：FreeRTOS 互斥量实现的是",[31,3658,3659],{},"优先级继承","，而非优先级上限协议（PCP），因此不能完全消除死锁，但能显著缩短高优先级任务的最坏阻塞时间。",[10,3662,3663,3666],{},[31,3664,3665],{},"优先级继承的工作原理","（Task_H 优先级 5，Task_L 优先级 1）：",[1837,3668,3670],{"className":1972,"code":3669,"language":1974,"meta":1842,"style":1842},"/* Task_L 代码 */\nvoid Task_L(void *p) {\n    xSemaphoreTake(xMutex, portMAX_DELAY);\n    /* ←── Task_H 在此处等待时，Task_L 优先级被临时提升至 5 */\n    /* 临界区操作 */\n    xSemaphoreGive(xMutex);\n    /* ←── Task_L 优先级恢复至 1 */\n}\n\n/* Task_H 代码 */\nvoid Task_H(void *p) {\n    xSemaphoreTake(xMutex, portMAX_DELAY); /* 触发优先级继承 */\n    /* 临界区操作 */\n    xSemaphoreGive(xMutex);\n}\n",[141,3671,3672,3677,3697,3705,3710,3715,3723,3728,3732,3736,3741,3758,3768,3772,3778],{"__ignoreMap":1842},[283,3673,3674],{"class":1847,"line":1848},[283,3675,3676],{"class":2005},"/* Task_L 代码 */\n",[283,3678,3679,3682,3685,3687,3689,3692,3694],{"class":1847,"line":1855},[283,3680,3681],{"class":1981},"void",[283,3683,3684],{"class":2081}," Task_L",[283,3686,404],{"class":1851},[283,3688,3681],{"class":1981},[283,3690,3691],{"class":1981}," *",[283,3693,10],{"class":2534},[283,3695,3696],{"class":1851},") {\n",[283,3698,3699,3702],{"class":1847,"line":1861},[283,3700,3701],{"class":2081},"    xSemaphoreTake",[283,3703,3704],{"class":1851},"(xMutex, portMAX_DELAY);\n",[283,3706,3707],{"class":1847,"line":1867},[283,3708,3709],{"class":2005},"    /* ←── Task_H 在此处等待时，Task_L 优先级被临时提升至 5 */\n",[283,3711,3712],{"class":1847,"line":1873},[283,3713,3714],{"class":2005},"    /* 临界区操作 */\n",[283,3716,3717,3720],{"class":1847,"line":1880},[283,3718,3719],{"class":2081},"    xSemaphoreGive",[283,3721,3722],{"class":1851},"(xMutex);\n",[283,3724,3725],{"class":1847,"line":1886},[283,3726,3727],{"class":2005},"    /* ←── Task_L 优先级恢复至 1 */\n",[283,3729,3730],{"class":1847,"line":1892},[283,3731,2711],{"class":1851},[283,3733,3734],{"class":1847,"line":1898},[283,3735,1877],{"emptyLinePlaceholder":1876},[283,3737,3738],{"class":1847,"line":1903},[283,3739,3740],{"class":2005},"/* Task_H 代码 */\n",[283,3742,3743,3745,3748,3750,3752,3754,3756],{"class":1847,"line":1909},[283,3744,3681],{"class":1981},[283,3746,3747],{"class":2081}," Task_H",[283,3749,404],{"class":1851},[283,3751,3681],{"class":1981},[283,3753,3691],{"class":1981},[283,3755,10],{"class":2534},[283,3757,3696],{"class":1851},[283,3759,3760,3762,3765],{"class":1847,"line":1915},[283,3761,3701],{"class":2081},[283,3763,3764],{"class":1851},"(xMutex, portMAX_DELAY);",[283,3766,3767],{"class":2005}," /* 触发优先级继承 */\n",[283,3769,3770],{"class":1847,"line":1920},[283,3771,3714],{"class":2005},[283,3773,3774,3776],{"class":1847,"line":1926},[283,3775,3719],{"class":2081},[283,3777,3722],{"class":1851},[283,3779,3780],{"class":1847,"line":1932},[283,3781,2711],{"class":1851},[10,3783,3784],{},[31,3785,3786],{},"内核侧的优先级提升代码路径（简化）：",[1837,3788,3790],{"className":1972,"code":3789,"language":1974,"meta":1842,"style":1842},"/* queue.c: prvCopyDataToQueue / xQueueSemaphoreTake */\nif( pxTCB->uxPriority \u003C pxCurrentTCB->uxPriority ) {\n    /* 持有互斥量的任务优先级低于等待者，执行继承 */\n    if( listIS_CONTAINED_WITHIN(\n        &( pxReadyTasksLists[ pxTCB->uxPriority ] ),\n        &( pxTCB->xStateListItem ) ) != pdFALSE ) {\n        /* 从旧优先级链表中移除 */\n        listREMOVE_ITEM(&(pxTCB->xStateListItem));\n        /* 提升优先级 */\n        pxTCB->uxPriority = pxCurrentTCB->uxPriority;\n        /* 插入新优先级链表 */\n        prvAddTaskToReadyList(pxTCB);\n    } else {\n        /* 任务处于阻塞态，仅更新优先级字段 */\n        pxTCB->uxPriority = pxCurrentTCB->uxPriority;\n    }\n}\n",[141,3791,3792,3797,3822,3827,3841,3864,3886,3891,3912,3917,3938,3943,3951,3962,3967,3985,3989],{"__ignoreMap":1842},[283,3793,3794],{"class":1847,"line":1848},[283,3795,3796],{"class":2005},"/* queue.c: prvCopyDataToQueue / xQueueSemaphoreTake */\n",[283,3798,3799,3802,3805,3808,3811,3814,3817,3819],{"class":1847,"line":1855},[283,3800,3801],{"class":1981},"if",[283,3803,3804],{"class":1851},"( pxTCB",[283,3806,3807],{"class":1981},"->",[283,3809,3810],{"class":1851},"uxPriority ",[283,3812,3813],{"class":1981},"\u003C",[283,3815,3816],{"class":1851}," pxCurrentTCB",[283,3818,3807],{"class":1981},[283,3820,3821],{"class":1851},"uxPriority ) {\n",[283,3823,3824],{"class":1847,"line":1861},[283,3825,3826],{"class":2005},"    /* 持有互斥量的任务优先级低于等待者，执行继承 */\n",[283,3828,3829,3832,3835,3838],{"class":1847,"line":1867},[283,3830,3831],{"class":1981},"    if",[283,3833,3834],{"class":1851},"( ",[283,3836,3837],{"class":2081},"listIS_CONTAINED_WITHIN",[283,3839,3840],{"class":1851},"(\n",[283,3842,3843,3846,3848,3850,3853,3856,3858,3861],{"class":1847,"line":1873},[283,3844,3845],{"class":1981},"        &",[283,3847,3834],{"class":1851},[283,3849,2489],{"class":2059},[283,3851,3852],{"class":1851},"[ ",[283,3854,3855],{"class":2059},"pxTCB",[283,3857,3807],{"class":1851},[283,3859,3860],{"class":2059},"uxPriority",[283,3862,3863],{"class":1851}," ] ),\n",[283,3865,3866,3868,3870,3872,3874,3877,3880,3883],{"class":1847,"line":1880},[283,3867,3845],{"class":1981},[283,3869,3834],{"class":1851},[283,3871,3855],{"class":2059},[283,3873,3807],{"class":1851},[283,3875,3876],{"class":2059},"xStateListItem",[283,3878,3879],{"class":1851}," ) ) ",[283,3881,3882],{"class":1981},"!=",[283,3884,3885],{"class":1851}," pdFALSE ) {\n",[283,3887,3888],{"class":1847,"line":1886},[283,3889,3890],{"class":2005},"        /* 从旧优先级链表中移除 */\n",[283,3892,3893,3896,3898,3901,3903,3905,3907,3909],{"class":1847,"line":1892},[283,3894,3895],{"class":2081},"        listREMOVE_ITEM",[283,3897,404],{"class":1851},[283,3899,3900],{"class":1981},"&",[283,3902,404],{"class":1851},[283,3904,3855],{"class":2059},[283,3906,3807],{"class":1851},[283,3908,3876],{"class":2059},[283,3910,3911],{"class":1851},"));\n",[283,3913,3914],{"class":1847,"line":1898},[283,3915,3916],{"class":2005},"        /* 提升优先级 */\n",[283,3918,3919,3922,3924,3926,3929,3931,3933,3935],{"class":1847,"line":1903},[283,3920,3921],{"class":2059},"        pxTCB",[283,3923,3807],{"class":1851},[283,3925,3860],{"class":2059},[283,3927,3928],{"class":1981}," =",[283,3930,3816],{"class":2059},[283,3932,3807],{"class":1851},[283,3934,3860],{"class":2059},[283,3936,3937],{"class":1851},";\n",[283,3939,3940],{"class":1847,"line":1909},[283,3941,3942],{"class":2005},"        /* 插入新优先级链表 */\n",[283,3944,3945,3948],{"class":1847,"line":1915},[283,3946,3947],{"class":2081},"        prvAddTaskToReadyList",[283,3949,3950],{"class":1851},"(pxTCB);\n",[283,3952,3953,3956,3959],{"class":1847,"line":1920},[283,3954,3955],{"class":1851},"    } ",[283,3957,3958],{"class":1981},"else",[283,3960,3961],{"class":1851}," {\n",[283,3963,3964],{"class":1847,"line":1926},[283,3965,3966],{"class":2005},"        /* 任务处于阻塞态，仅更新优先级字段 */\n",[283,3968,3969,3971,3973,3975,3977,3979,3981,3983],{"class":1847,"line":1932},[283,3970,3921],{"class":2059},[283,3972,3807],{"class":1851},[283,3974,3860],{"class":2059},[283,3976,3928],{"class":1981},[283,3978,3816],{"class":2059},[283,3980,3807],{"class":1851},[283,3982,3860],{"class":2059},[283,3984,3937],{"class":1851},[283,3986,3987],{"class":1847,"line":1938},[283,3988,2302],{"class":1851},[283,3990,3991],{"class":1847,"line":2135},[283,3992,2711],{"class":1851},[10,3994,3995],{},"Task_L 被提升到优先级 5 后，中优先级的 Task_M 便无法再抢占它——反转窗口被压缩到“互斥量被持有期间”的最短可能。这正是解决火星探路者事故时所采用的方案。",[24,3997,3998],{"id":3998},"绝对时间延时与周期性任务",[10,4000,4001,4002,4005,4006,4009,4010,4012],{},"FreeRTOS 提供 ",[141,4003,4004],{},"vTaskDelayUntil()"," 实现",[31,4007,4008],{},"绝对时间定期唤醒","，相比相对延时（",[141,4011,2357],{},"）可消除累积时钟漂移：",[1837,4014,4016],{"className":1972,"code":4015,"language":1974,"meta":1842,"style":1842},"/* 相对延时：每次执行时间不确定，误差累积 */\nvoid vTask_Relative(void *p) {\n    for(;;) {\n        vTaskDelay(pdMS_TO_TICKS(10));            /* 每次等待 10ms，但执行时间会累积 */\n        do_work();\n    }\n}\n\n/* 绝对延时：严格 10ms 周期，无累积误差 */\nvoid vTask_Absolute(void *p) {\n    TickType_t xLastWakeTime = xTaskGetTickCount();\n    const TickType_t xPeriod  = pdMS_TO_TICKS(10); /* 10ms 周期 */\n    for(;;) {\n        vTaskDelayUntil(&xLastWakeTime, xPeriod); /* 绝对唤醒时间 */\n        do_work();\n    }\n}\n",[141,4017,4018,4023,4040,4048,4068,4076,4080,4084,4088,4093,4110,4122,4145,4151,4166,4172,4176],{"__ignoreMap":1842},[283,4019,4020],{"class":1847,"line":1848},[283,4021,4022],{"class":2005},"/* 相对延时：每次执行时间不确定，误差累积 */\n",[283,4024,4025,4027,4030,4032,4034,4036,4038],{"class":1847,"line":1855},[283,4026,3681],{"class":1981},[283,4028,4029],{"class":2081}," vTask_Relative",[283,4031,404],{"class":1851},[283,4033,3681],{"class":1981},[283,4035,3691],{"class":1981},[283,4037,10],{"class":2534},[283,4039,3696],{"class":1851},[283,4041,4042,4045],{"class":1847,"line":1861},[283,4043,4044],{"class":1981},"    for",[283,4046,4047],{"class":1851},"(;;) {\n",[283,4049,4050,4053,4055,4058,4060,4062,4065],{"class":1847,"line":1867},[283,4051,4052],{"class":2081},"        vTaskDelay",[283,4054,404],{"class":1851},[283,4056,4057],{"class":2081},"pdMS_TO_TICKS",[283,4059,404],{"class":1851},[283,4061,1634],{"class":2088},[283,4063,4064],{"class":1851},"));",[283,4066,4067],{"class":2005},"            /* 每次等待 10ms，但执行时间会累积 */\n",[283,4069,4070,4073],{"class":1847,"line":1873},[283,4071,4072],{"class":2081},"        do_work",[283,4074,4075],{"class":1851},"();\n",[283,4077,4078],{"class":1847,"line":1880},[283,4079,2302],{"class":1851},[283,4081,4082],{"class":1847,"line":1886},[283,4083,2711],{"class":1851},[283,4085,4086],{"class":1847,"line":1892},[283,4087,1877],{"emptyLinePlaceholder":1876},[283,4089,4090],{"class":1847,"line":1898},[283,4091,4092],{"class":2005},"/* 绝对延时：严格 10ms 周期，无累积误差 */\n",[283,4094,4095,4097,4100,4102,4104,4106,4108],{"class":1847,"line":1903},[283,4096,3681],{"class":1981},[283,4098,4099],{"class":2081}," vTask_Absolute",[283,4101,404],{"class":1851},[283,4103,3681],{"class":1981},[283,4105,3691],{"class":1981},[283,4107,10],{"class":2534},[283,4109,3696],{"class":1851},[283,4111,4112,4115,4117,4120],{"class":1847,"line":1909},[283,4113,4114],{"class":1851},"    TickType_t xLastWakeTime ",[283,4116,359],{"class":1981},[283,4118,4119],{"class":2081}," xTaskGetTickCount",[283,4121,4075],{"class":1851},[283,4123,4124,4127,4130,4132,4135,4137,4139,4142],{"class":1847,"line":1915},[283,4125,4126],{"class":1981},"    const",[283,4128,4129],{"class":1851}," TickType_t xPeriod  ",[283,4131,359],{"class":1981},[283,4133,4134],{"class":2081}," pdMS_TO_TICKS",[283,4136,404],{"class":1851},[283,4138,1634],{"class":2088},[283,4140,4141],{"class":1851},");",[283,4143,4144],{"class":2005}," /* 10ms 周期 */\n",[283,4146,4147,4149],{"class":1847,"line":1920},[283,4148,4044],{"class":1981},[283,4150,4047],{"class":1851},[283,4152,4153,4156,4158,4160,4163],{"class":1847,"line":1926},[283,4154,4155],{"class":2081},"        vTaskDelayUntil",[283,4157,404],{"class":1851},[283,4159,3900],{"class":1981},[283,4161,4162],{"class":1851},"xLastWakeTime, xPeriod);",[283,4164,4165],{"class":2005}," /* 绝对唤醒时间 */\n",[283,4167,4168,4170],{"class":1847,"line":1932},[283,4169,4072],{"class":2081},[283,4171,4075],{"class":1851},[283,4173,4174],{"class":1847,"line":1938},[283,4175,2302],{"class":1851},[283,4177,4178],{"class":1847,"line":2135},[283,4179,2711],{"class":1851},[10,4181,4182],{},"两者的差异在长周期运行时非常显著（执行时间 = 2ms，周期 = 10ms，运行 1000 次后）：",[39,4184,4185,4201],{},[42,4186,4187],{},[45,4188,4189,4192,4195,4198],{},[48,4190,4191],{"align":50},"方式",[48,4193,4194],{"align":1440},"理论总时间",[48,4196,4197],{"align":1440},"实际总时间",[48,4199,4200],{"align":1440},"累积误差",[62,4202,4203,4219],{},[45,4204,4205,4210,4213,4216],{},[67,4206,4207],{"align":50},[141,4208,4209],{},"vTaskDelay(10ms)",[67,4211,4212],{"align":1440},"10,000 ms",[67,4214,4215],{"align":1440},"12,000 ms",[67,4217,4218],{"align":1440},"+2000 ms",[45,4220,4221,4226,4228,4230],{},[67,4222,4223],{"align":50},[141,4224,4225],{},"vTaskDelayUntil(10ms)",[67,4227,4212],{"align":1440},[67,4229,4212],{"align":1440},[67,4231,4232],{"align":1440},"~0 ms",[1949,4234,4236],{"type":4235},"info",[10,4237,4238,4239,267,4241,4243],{},"对于周期性控制任务（如电机控制环、传感器采样），应始终使用 ",[141,4240,4004],{},[141,4242,2357],{}," 的实际周期是“延时 + 执行时间”，在需要长期稳定周期性的场景下会产生可观的漂移。",[24,4245,4247],{"id":4246},"tickless-低功耗调度模式","Tickless 低功耗调度模式",[10,4249,4250,4251,4254],{},"当所有任务均处于阻塞态时，FreeRTOS 可通过 ",[31,4252,4253],{},"Tickless Idle 模式","抑制系统心跳中断，让处理器进入深度睡眠：",[1837,4256,4258],{"className":1972,"code":4257,"language":1974,"meta":1842,"style":1842},"/* 配置启用 Tickless */\n#define configUSE_TICKLESS_IDLE  1\n\n/* 移植层实现（以 STM32 为例）：处理器进入 STOP 模式 */\nvoid vPortSuppressTicksAndSleep(TickType_t xExpectedIdleTime) {\n    /* 1. 重新编程低功耗定时器（LPTIM）替代 SysTick */\n    /* 2. 进入处理器低功耗模式（如 __WFI 指令） */\n    /* 3. 唤醒后补偿被抑制的 Tick 计数 */\n}\n",[141,4259,4260,4265,4275,4279,4284,4299,4304,4309,4314],{"__ignoreMap":1842},[283,4261,4262],{"class":1847,"line":1848},[283,4263,4264],{"class":2005},"/* 配置启用 Tickless */\n",[283,4266,4267,4269,4272],{"class":1847,"line":1855},[283,4268,2624],{"class":1981},[283,4270,4271],{"class":2081}," configUSE_TICKLESS_IDLE",[283,4273,4274],{"class":2088},"  1\n",[283,4276,4277],{"class":1847,"line":1861},[283,4278,1877],{"emptyLinePlaceholder":1876},[283,4280,4281],{"class":1847,"line":1867},[283,4282,4283],{"class":2005},"/* 移植层实现（以 STM32 为例）：处理器进入 STOP 模式 */\n",[283,4285,4286,4288,4291,4294,4297],{"class":1847,"line":1873},[283,4287,3681],{"class":1981},[283,4289,4290],{"class":2081}," vPortSuppressTicksAndSleep",[283,4292,4293],{"class":1851},"(TickType_t",[283,4295,4296],{"class":2534}," xExpectedIdleTime",[283,4298,3696],{"class":1851},[283,4300,4301],{"class":1847,"line":1880},[283,4302,4303],{"class":2005},"    /* 1. 重新编程低功耗定时器（LPTIM）替代 SysTick */\n",[283,4305,4306],{"class":1847,"line":1886},[283,4307,4308],{"class":2005},"    /* 2. 进入处理器低功耗模式（如 __WFI 指令） */\n",[283,4310,4311],{"class":1847,"line":1892},[283,4312,4313],{"class":2005},"    /* 3. 唤醒后补偿被抑制的 Tick 计数 */\n",[283,4315,4316],{"class":1847,"line":1898},[283,4317,2711],{"class":1851},[10,4319,4320],{},"其基本思路是：调度器发现“空闲时长”（从当前位置到下一个任务唤醒时间）超过阈值时，关闭周期性的 SysTick 中断，改用低功耗定时器在空闲结束时唤醒处理器，并在唤醒后补偿被跳过的 Tick 计数，保证系统的“时间感”不失真。此机制可将 MCU 的空闲功耗从 mA 级降至 μA 级，对电池供电设备意义重大。",[20,4322,4323],{"id":4323},"可调度性分析与工程应用",[24,4325,4326],{"id":4326},"可调度性验证方法",[10,4328,4329],{},"在使用 FreeRTOS 部署硬实时系统时，需验证任务集合的可调度性。以三任务系统为例：",[39,4331,4332,4610],{},[42,4333,4334],{},[45,4335,4336,4339,4411,4483,4607],{},[48,4337,4338],{"align":50},"任务",[48,4340,4341,4342],{"align":1440},"周期 ",[283,4343,4345,4362],{"className":4344},[286],[283,4346,4348],{"className":4347},[290],[292,4349,4350],{"xmlns":294},[296,4351,4352,4360],{},[299,4353,4354],{},[347,4355,4356,4358],{},[302,4357,393],{},[302,4359,370],{},[306,4361,966],{"encoding":308},[283,4363,4365],{"className":4364,"ariaHidden":313},[312],[283,4366,4368,4371],{"className":4367},[317],[283,4369],{"className":4370,"style":441},[321],[283,4372,4374,4377],{"className":4373},[326],[283,4375,393],{"className":4376,"style":643},[326,327],[283,4378,4380],{"className":4379},[452],[283,4381,4383,4403],{"className":4382},[456,457],[283,4384,4386,4400],{"className":4385},[461],[283,4387,4389],{"className":4388,"style":656},[465],[283,4390,4391,4394],{"style":659},[283,4392],{"className":4393,"style":474},[473],[283,4395,4397],{"className":4396},[478,479,480,481],[283,4398,370],{"className":4399},[326,327,481],[283,4401,496],{"className":4402},[495],[283,4404,4406],{"className":4405},[461],[283,4407,4409],{"className":4408,"style":503},[465],[283,4410],{},[48,4412,4413,4414],{"align":1440},"WCET ",[283,4415,4417,4434],{"className":4416},[286],[283,4418,4420],{"className":4419},[290],[292,4421,4422],{"xmlns":294},[296,4423,4424,4432],{},[299,4425,4426],{},[347,4427,4428,4430],{},[302,4429,386],{},[302,4431,370],{},[306,4433,865],{"encoding":308},[283,4435,4437],{"className":4436,"ariaHidden":313},[312],[283,4438,4440,4443],{"className":4439},[317],[283,4441],{"className":4442,"style":441},[321],[283,4444,4446,4449],{"className":4445},[326],[283,4447,386],{"className":4448,"style":706},[326,327],[283,4450,4452],{"className":4451},[452],[283,4453,4455,4475],{"className":4454},[456,457],[283,4456,4458,4472],{"className":4457},[461],[283,4459,4461],{"className":4460,"style":656},[465],[283,4462,4463,4466],{"style":721},[283,4464],{"className":4465,"style":474},[473],[283,4467,4469],{"className":4468},[478,479,480,481],[283,4470,370],{"className":4471},[326,327,481],[283,4473,496],{"className":4474},[495],[283,4476,4478],{"className":4477},[461],[283,4479,4481],{"className":4480,"style":503},[465],[283,4482],{},[48,4484,4485,4486],{"align":1440},"利用率 ",[283,4487,4489,4515],{"className":4488},[286],[283,4490,4492],{"className":4491},[290],[292,4493,4494],{"xmlns":294},[296,4495,4496,4512],{},[299,4497,4498,4504,4506],{},[347,4499,4500,4502],{},[302,4501,386],{},[302,4503,370],{},[302,4505,418],{"mathvariant":417},[347,4507,4508,4510],{},[302,4509,393],{},[302,4511,370],{},[306,4513,4514],{"encoding":308},"C_i/T_i",[283,4516,4518],{"className":4517,"ariaHidden":313},[312],[283,4519,4521,4524,4564,4567],{"className":4520},[317],[283,4522],{"className":4523,"style":835},[321],[283,4525,4527,4530],{"className":4526},[326],[283,4528,386],{"className":4529,"style":706},[326,327],[283,4531,4533],{"className":4532},[452],[283,4534,4536,4556],{"className":4535},[456,457],[283,4537,4539,4553],{"className":4538},[461],[283,4540,4542],{"className":4541,"style":656},[465],[283,4543,4544,4547],{"style":721},[283,4545],{"className":4546,"style":474},[473],[283,4548,4550],{"className":4549},[478,479,480,481],[283,4551,370],{"className":4552},[326,327,481],[283,4554,496],{"className":4555},[495],[283,4557,4559],{"className":4558},[461],[283,4560,4562],{"className":4561,"style":503},[465],[283,4563],{},[283,4565,418],{"className":4566},[326],[283,4568,4570,4573],{"className":4569},[326],[283,4571,393],{"className":4572,"style":643},[326,327],[283,4574,4576],{"className":4575},[452],[283,4577,4579,4599],{"className":4578},[456,457],[283,4580,4582,4596],{"className":4581},[461],[283,4583,4585],{"className":4584,"style":656},[465],[283,4586,4587,4590],{"style":659},[283,4588],{"className":4589,"style":474},[473],[283,4591,4593],{"className":4592},[478,479,480,481],[283,4594,370],{"className":4595},[326,327,481],[283,4597,496],{"className":4598},[495],[283,4600,4602],{"className":4601},[461],[283,4603,4605],{"className":4604,"style":503},[465],[283,4606],{},[48,4608,4609],{"align":1440},"FreeRTOS 优先级",[62,4611,4612,4629,4645,4661],{},[45,4613,4614,4617,4620,4623,4626],{},[67,4615,4616],{"align":50},"电机控制环",[67,4618,4619],{"align":1440},"1 ms",[67,4621,4622],{"align":1440},"0.15 ms",[67,4624,4625],{"align":1440},"15.0%",[67,4627,4628],{"align":1440},"3（最高）",[45,4630,4631,4634,4637,4640,4643],{},[67,4632,4633],{"align":50},"传感器采样",[67,4635,4636],{"align":1440},"5 ms",[67,4638,4639],{"align":1440},"0.60 ms",[67,4641,4642],{"align":1440},"12.0%",[67,4644,410],{"align":1440},[45,4646,4647,4650,4653,4656,4659],{},[67,4648,4649],{"align":50},"状态上报",[67,4651,4652],{"align":1440},"50 ms",[67,4654,4655],{"align":1440},"5.00 ms",[67,4657,4658],{"align":1440},"10.0%",[67,4660,376],{"align":1440},[45,4662,4663,4667,4670,4672,4677],{},[67,4664,4665],{"align":50},[31,4666,188],{},[67,4668,4669],{"align":1440},"—",[67,4671,4669],{"align":1440},[67,4673,4674],{"align":1440},[31,4675,4676],{},"37.0%",[67,4678,4669],{"align":1440},[10,4680,4681,4682,4733],{},"RMS 可调度上界（",[283,4683,4685,4703],{"className":4684},[286],[283,4686,4688],{"className":4687},[290],[292,4689,4690],{"xmlns":294},[296,4691,4692,4700],{},[299,4693,4694,4696,4698],{},[302,4695,304],{},[357,4697,359],{},[374,4699,1612],{},[306,4701,4702],{"encoding":308},"n = 3",[283,4704,4706,4724],{"className":4705,"ariaHidden":313},[312],[283,4707,4709,4712,4715,4718,4721],{"className":4708},[317],[283,4710],{"className":4711,"style":322},[321],[283,4713,304],{"className":4714},[326,327],[283,4716],{"className":4717,"style":510},[509],[283,4719,359],{"className":4720},[514],[283,4722],{"className":4723,"style":510},[509],[283,4725,4727,4730],{"className":4726},[317],[283,4728],{"className":4729,"style":1798},[321],[283,4731,1612],{"className":4732},[326],"）：",[283,4735,4737],{"className":4736},[332],[283,4738,4740,4781],{"className":4739},[286],[283,4741,4743],{"className":4742},[290],[292,4744,4745],{"xmlns":294,"display":341},[296,4746,4747,4778],{},[299,4748,4749,4751,4753,4765,4767,4769,4771,4773,4776],{},[374,4750,1612],{},[357,4752,404],{"stretchy":403},[406,4754,4755,4757],{},[374,4756,410],{},[299,4758,4759,4761,4763],{},[374,4760,376],{},[302,4762,418],{"mathvariant":417},[374,4764,1612],{},[357,4766,423],{},[374,4768,376],{},[357,4770,428],{"stretchy":403},[357,4772,359],{},[374,4774,4775],{},"78.0",[302,4777,1158],{"mathvariant":417},[306,4779,4780],{"encoding":308},"3(2^{1/3} - 1) = 78.0\\%",[283,4782,4784,4838,4859],{"className":4783,"ariaHidden":313},[312],[283,4785,4787,4790,4793,4796,4829,4832,4835],{"className":4786},[317],[283,4788],{"className":4789,"style":773},[321],[283,4791,1612],{"className":4792},[326],[283,4794,404],{"className":4795},[612],[283,4797,4799,4802],{"className":4798},[326],[283,4800,410],{"className":4801},[326],[283,4803,4805],{"className":4804},[452],[283,4806,4808],{"className":4807},[456],[283,4809,4811],{"className":4810},[461],[283,4812,4814],{"className":4813,"style":798},[465],[283,4815,4816,4819],{"style":801},[283,4817],{"className":4818,"style":474},[473],[283,4820,4822],{"className":4821},[478,479,480,481],[283,4823,4825],{"className":4824},[326,481],[283,4826,4828],{"className":4827},[326,481],"1/3",[283,4830],{"className":4831,"style":821},[509],[283,4833,423],{"className":4834},[825],[283,4836],{"className":4837,"style":821},[509],[283,4839,4841,4844,4847,4850,4853,4856],{"className":4840},[317],[283,4842],{"className":4843,"style":835},[321],[283,4845,376],{"className":4846},[326],[283,4848,428],{"className":4849},[757],[283,4851],{"className":4852,"style":510},[509],[283,4854,359],{"className":4855},[514],[283,4857],{"className":4858,"style":510},[509],[283,4860,4862,4865],{"className":4861},[317],[283,4863],{"className":4864,"style":1424},[321],[283,4866,1615],{"className":4867},[326],[10,4869,4870,4871,4927,4928,4931],{},"由于 ",[283,4872,4874,4897],{"className":4873},[286],[283,4875,4877],{"className":4876},[290],[292,4878,4879],{"xmlns":294},[296,4880,4881,4894],{},[299,4882,4883,4886,4888,4890,4892],{},[374,4884,4885],{},"37.0",[302,4887,1158],{"mathvariant":417},[357,4889,3813],{},[374,4891,4775],{},[302,4893,1158],{"mathvariant":417},[306,4895,4896],{"encoding":308},"37.0\\% \u003C 78.0\\%",[283,4898,4900,4918],{"className":4899,"ariaHidden":313},[312],[283,4901,4903,4906,4909,4912,4915],{"className":4902},[317],[283,4904],{"className":4905,"style":1424},[321],[283,4907,4676],{"className":4908},[326],[283,4910],{"className":4911,"style":510},[509],[283,4913,3813],{"className":4914},[514],[283,4916],{"className":4917,"style":510},[509],[283,4919,4921,4924],{"className":4920},[317],[283,4922],{"className":4923,"style":1424},[321],[283,4925,1615],{"className":4926},[326],"，该任务集合",[31,4929,4930],{},"可调度","，且留有充裕余量。工程实践中，这个“先算利用率、再留余量”的流程应成为硬实时项目设计阶段的标准动作——架构层面的可调度性验证，远比上线后靠测试兜底可靠。",[24,4933,4935],{"id":4934},"freertos-在典型行业的应用","FreeRTOS 在典型行业的应用",[39,4937,4938,4951],{},[42,4939,4940],{},[45,4941,4942,4945,4948],{},[48,4943,4944],{"align":50},"行业领域",[48,4946,4947],{"align":50},"典型产品",[48,4949,4950],{"align":50},"使用的实时约束",[62,4952,4953,4964,4975,4986,4997,5008],{},[45,4954,4955,4958,4961],{},[67,4956,4957],{"align":50},"工业自动化",[67,4959,4960],{"align":50},"西门子 PLC 控制单元",[67,4962,4963],{"align":50},"运动控制环 ≤ 1ms 周期",[45,4965,4966,4969,4972],{},[67,4967,4968],{"align":50},"汽车电子",[67,4970,4971],{"align":50},"大陆 ECU（发动机控制）",[67,4973,4974],{"align":50},"燃油喷射控制 ≤ 100μs",[45,4976,4977,4980,4983],{},[67,4978,4979],{"align":50},"医疗器械",[67,4981,4982],{"align":50},"飞利浦便携超声",[67,4984,4985],{"align":50},"超声信号采集 ≤ 500μs",[45,4987,4988,4991,4994],{},[67,4989,4990],{"align":50},"航空电子",[67,4992,4993],{"align":50},"无人机飞控（ArduPilot）",[67,4995,4996],{"align":50},"姿态控制环 ≤ 4ms",[45,4998,4999,5002,5005],{},[67,5000,5001],{"align":50},"消费电子",[67,5003,5004],{"align":50},"苹果 AirPods（H1 芯片）",[67,5006,5007],{"align":50},"音频处理 ≤ 1ms",[45,5009,5010,5013,5016],{},[67,5011,5012],{"align":50},"物联网",[67,5014,5015],{"align":50},"AWS IoT Greengrass v2",[67,5017,5018],{"align":50},"传感器事件响应 ≤ 10ms",[20,5020,5021],{"id":5021},"总结",[10,5023,5024,5025,5028],{},"FreeRTOS 通过精心设计的",[31,5026,5027],{},"固定优先级抢占式调度","框架，在极简内核体积内实现了工业级的实时性保障。其核心设计决策体现了清晰的工程权衡哲学：",[2871,5030,5031,5081,5087,5093],{},[2202,5032,5033,5080],{},[31,5034,5035,5036,5079],{},"选择 ",[283,5037,5039,5058],{"className":5038},[286],[283,5040,5042],{"className":5041},[290],[292,5043,5044],{"xmlns":294},[296,5045,5046,5056],{},[299,5047,5048,5050,5052,5054],{},[302,5049,2433],{},[357,5051,404],{"stretchy":403},[374,5053,376],{},[357,5055,428],{"stretchy":403},[306,5057,2442],{"encoding":308},[283,5059,5061],{"className":5060,"ariaHidden":313},[312],[283,5062,5064,5067,5070,5073,5076],{"className":5063},[317],[283,5065],{"className":5066,"style":835},[321],[283,5068,2433],{"className":5069,"style":2455},[326,327],[283,5071,404],{"className":5072},[612],[283,5074,376],{"className":5075},[326],[283,5077,428],{"className":5078},[757]," 固定优先级而非 EDF","：牺牲约 30% 的理论利用率上界，换取完全可预测的调度行为和简单的可调度性分析方法；",[2202,5082,5083,5086],{},[31,5084,5085],{},"选择优先级继承而非优先级上限协议","：实现更简单，虽不能完全避免死锁，但足以应对大多数实际工程场景；",[2202,5088,5089,5092],{},[31,5090,5091],{},"选择 PendSV 延迟上下文切换","：避免在 ISR 内直接切换任务上下文，消除中断嵌套场景下的安全隐患；",[2202,5094,5095,5098],{},[31,5096,5097],{},"选择 Tickless 可选功耗优化","：在不影响实时性的前提下，为电池供电设备提供显著的能耗降低手段。",[10,5100,5101,5102,5105],{},"FreeRTOS 的成功印证了“",[31,5103,5104],{},"以最简洁的机制换取最强的确定性","”这一实时系统设计原则，其在嵌入式 RTOS 市场长达十余年的统治地位，是工程实践对该设计哲学的最好验证。",[20,5107,5108],{"id":5108},"参考文献",[10,5110,5111,5113,5114,5117],{},[283,5112,376],{}," Buttazzo, G. C. (2011). ",[1945,5115,5116],{},"Hard Real-Time Computing Systems: Predictable Scheduling Algorithms and Applications"," (3rd ed.). Springer. pp. 1–30.",[10,5119,5120,5122,5123,5126],{},[283,5121,410],{}," EE Times / Aspencore. (2022). ",[1945,5124,5125],{},"Embedded Markets Study: Developer Survey Report 2022",". Aspencore Media.",[10,5128,5129,5131,5132,5135,5136],{},[283,5130,1612],{}," Barry, R. (2016). ",[1945,5133,5134],{},"Mastering the FreeRTOS Real Time Kernel: A Hands On Tutorial Guide",". Real Time Engineers Ltd. ",[1230,5137,5138],{"href":5138,"rel":5139},"https://freertos.org/Documentation/RTOS_book.html",[5140],"nofollow",[10,5142,5143,5146,5147,5150,5151],{},[283,5144,5145],{},"4"," Liu, C. L., & Layland, J. W. (1973). Scheduling algorithms for multiprogramming in a hard-real-time environment. ",[1945,5148,5149],{},"Journal of the ACM (JACM)",", 20(1), 46–61. ",[1230,5152,5153],{"href":5153,"rel":5154},"https://doi.org/10.1145/321738.321743",[5140],[10,5156,5157,5159,5160,5163],{},[283,5158,1623],{}," Reeves, G. E. (1997). What really happened on Mars? Risks to the public in computers and related systems. ",[1945,5161,5162],{},"ACM SIGSOFT Software Engineering Notes",", 22(6), 22–26.",[10,5165,5166,5169,5170,5173],{},[283,5167,5168],{},"6"," Yiu, J. (2013). ",[1945,5171,5172],{},"The Definitive Guide to ARM Cortex-M3 and Cortex-M4 Processors"," (3rd ed.). Newnes/Elsevier. Chapter 10: OS Support and Privileged Access.",[10,5175,5176,5179,5180,5183],{},[283,5177,5178],{},"7"," Labrosse, J. J. (2002). ",[1945,5181,5182],{},"MicroC/OS-II: The Real-Time Kernel"," (2nd ed.). CMP Books.（FreeRTOS 性能对比参考基准）",[10,5185,5186,5189,5190,5193,5194],{},[283,5187,5188],{},"8"," Amazon Web Services. (2023). ",[1945,5191,5192],{},"FreeRTOS Reference Manual v10.5.0",". ",[1230,5195,5196],{"href":5196,"rel":5197},"https://freertos.org/Documentation/FreeRTOS_Reference_Manual_V10.0.0.pdf",[5140],[10,5199,5200,5203,5204,5207],{},[283,5201,5202],{},"9"," Sha, L., Rajkumar, R., & Lehoczky, J. P. (1990). Priority inheritance protocols: An approach to real-time synchronization. ",[1945,5205,5206],{},"IEEE Transactions on Computers",", 39(9), 1175–1185.",[10,5209,5210,5212,5213,5216],{},[283,5211,1634],{}," Burns, A., & Wellings, A. (2009). ",[1945,5214,5215],{},"Real-Time Systems and Programming Languages"," (4th ed.). Addison-Wesley. Chapter 13.",[5218,5219,5220],"style",{},"html pre.shiki code .sLo_3, html code.shiki .sLo_3{--shiki-default:#EEF0F9}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html pre.shiki code .sqF6k, html code.shiki .sqF6k{--shiki-default:#54B9FF}html pre.shiki code .sy89t, html code.shiki .sy89t{--shiki-default:#EEF0F98F;--shiki-default-font-style:italic}html pre.shiki code .sb16X, html code.shiki .sb16X{--shiki-default:#4BF3C8}html pre.shiki code .stHQG, html code.shiki .stHQG{--shiki-default:#00DAEF}html pre.shiki code .se2J0, html code.shiki .se2J0{--shiki-default:#FFD493}html pre.shiki code .smONe, html code.shiki .smONe{--shiki-default:#4BF3C8;--shiki-default-font-style:italic}",{"title":1842,"searchDepth":1855,"depth":1855,"links":5222},[5223,5227,5232,5236,5241,5246,5250,5251],{"id":22,"depth":1855,"text":22,"children":5224},[5225,5226],{"id":26,"depth":1861,"text":26},{"id":109,"depth":1861,"text":110},{"id":256,"depth":1855,"text":256,"children":5228},[5229,5230,5231],{"id":259,"depth":1861,"text":260},{"id":1681,"depth":1861,"text":1682},{"id":1826,"depth":1861,"text":1826},{"id":1957,"depth":1855,"text":1958,"children":5233},[5234,5235],{"id":1961,"depth":1861,"text":1962},{"id":2220,"depth":1861,"text":2220},{"id":2407,"depth":1855,"text":2408,"children":5237},[5238,5239,5240],{"id":2411,"depth":1861,"text":2411},{"id":2797,"depth":1861,"text":2797},{"id":3222,"depth":1861,"text":3223},{"id":3641,"depth":1855,"text":3641,"children":5242},[5243,5244,5245],{"id":3644,"depth":1861,"text":3644},{"id":3998,"depth":1861,"text":3998},{"id":4246,"depth":1861,"text":4247},{"id":4323,"depth":1855,"text":4323,"children":5247},[5248,5249],{"id":4326,"depth":1861,"text":4326},{"id":4934,"depth":1861,"text":4935},{"id":5021,"depth":1855,"text":5021},{"id":5108,"depth":1855,"text":5108},"2026-06-05","以全球市场占有率第一的开源实时操作系统 FreeRTOS 为研究对象，系统拆解其固定优先级抢占式调度、O(1) 就绪队列、PendSV 上下文切换与优先级继承机制，附可调度性验证方法与行业应用数据。",false,"md",{"excerpt":5257},{"type":7,"value":5258},[5259,5261,5263],[10,5260,12],{},[10,5262,15],{},[10,5264,18],{},"/blog/freertos-scheduling-strategy-research",{"title":5,"description":5253},"blog/freertos-scheduling-strategy-research",[5269,5270,5271,5272,5273,5274],"rtos","freertos","embedded","real-time","scheduling","cortex-m","IgmYXDPw-iDZnR_kJewQkuIrwvuV2SVd5zrB3rCt90U",1789936009814]