www.久久久久|狼友网站av天堂|精品国产无码a片|一级av色欲av|91在线播放视频|亚洲无码主播在线|国产精品草久在线|明星AV网站在线|污污内射久久一区|婷婷综合视频网站

當(dāng)前位置:首頁 > 嵌入式 > 嵌入式大雜燴
[導(dǎo)讀]關(guān)注「嵌入式大雜燴」,星標(biāo)公眾號(hào),一起進(jìn)步!來源:裸機(jī)思維【說在前面的話】相信很多人都遇到過這樣的情況:在一個(gè)Cortex-M嵌入式應(yīng)用中要實(shí)現(xiàn)一個(gè)精確的毫秒級(jí)延時(shí)并不困難——如果你有RTOS,在任務(wù)中使用諸如os_sleep()之類的函數(shù)就可以輕松實(shí)現(xiàn);如果你是裸機(jī),也可以使用...

關(guān)注「嵌入式大雜燴」,星標(biāo)公眾號(hào),一起進(jìn)步!

來源:裸機(jī)思維


【說在前面的話】

相信很多人都遇到過這樣的情況:在一個(gè)Cortex-M嵌入式應(yīng)用中要實(shí)現(xiàn)一個(gè)精確的毫秒級(jí)延時(shí)并不困難——如果你有RTOS,在任務(wù)中使用諸如 os_sleep(<休眠時(shí)間>) 之類的函數(shù)就可以輕松實(shí)現(xiàn);如果你是裸機(jī),也可以使用每個(gè)Cortex-M芯片都默認(rèn)攜帶的SysTick來實(shí)現(xiàn)一個(gè),甚至Arm官方的CMSIS都提供了現(xiàn)成的API,即SysTick_Config(<中斷間隔的時(shí)鐘周期數(shù)>)
static volatile uint32_t s_wMSCounter = 0;
extern?uint32_t?SystemCoreClock;/*! \brief initialise platform before main() */__attribute__((constructor(101)))void platform_init(void){ SystemCoreClockUpdate(); /* Generate interrupt each 1 ms */ SysTick_Config(SystemCoreClock / 1000); }
__attribute__((weak))void systimer_1ms_handler(void){????/*?default?systimer?1ms?hander??????*?you?can?override?it?by?implement?a?non-weak version?????*/}
void SysTick_Handler (void) { if (s_wMSCounter) { s_wMSCounter--; }
systimer_1ms_handler();}
void delay_ms(uint32_t wMillisecond){ s_wMSCounter = wMillisecond; while( s_wMSCounter > 0 );}上述代碼非常典型,唯一需要強(qiáng)調(diào)的是SystemCoreClock是一個(gè)定義在啟動(dòng)文件system_<芯片型號(hào)>.c 里的全局變量,負(fù)責(zé)保存當(dāng)前處理器的工作頻率——上面的平臺(tái)初始化函數(shù) platform_init()?就是借助這一變量把 SysTick 初始化為以“1ms為間隔產(chǎn)生中斷”的。

如果要實(shí)現(xiàn)一個(gè)微秒級(jí)延時(shí)卻并不那么一帆風(fēng)順。首先,不同人關(guān)于實(shí)現(xiàn)方案就有不同的想法,比如:
  • 有的人習(xí)慣于直接用軟件方法堆積NOP()來實(shí)現(xiàn)——這種方法所產(chǎn)生的延時(shí)效果“可能”容易受到編譯器優(yōu)化等級(jí)的影響——據(jù)說這也是很多人懼怕開啟編譯器的原因之一,因?yàn)橐婚_優(yōu)化,很多對(duì)時(shí)間敏感的硬件時(shí)序就因?yàn)檠訒r(shí)函數(shù)的不穩(wěn)定而一起變得不可捉摸;

extern?uint32_t?SystemCoreClock;
#ifndef DELAY_US_CALIBRATION/*!?\brief?不要問我為啥是?8, 我也不知道,但在當(dāng)前這個(gè)工程下,8貌似最準(zhǔn)?*!????????你如果不服,就自己測一個(gè),然后定義這個(gè)宏……?*!????????如果你頭鐵改了工程的優(yōu)化等級(jí),請也無比親自測一下……具體怎么?*! ???????測,我也不知道。如果你也怕麻煩,就不要改優(yōu)化等級(jí)。 */# define DELAY_US_CALIBRATION 8#endif
void?delay_us(uint32_t?wUS){????//!?calcluate?how?many?cycles?required?for?1us????uint32_t?wCyclesPerUS?=?SystemCoreClock?/?1000000ul;????????/*!?subtract some cycles from wCyclesPerUS based on the ?????*!?experience?or?actual?measurement?in?current?optimisation?????*/????wCyclesPerUS?-=?DELAY_US_CALIBRATION;
????for?(int?i?=?0;?i?????????for?(j?=?0;?j?< wCyclesPerUS; j ) {???????? __NOP();????????}????}}
  • 有的人提倡使用定時(shí)器來實(shí)現(xiàn)精確延時(shí),這一方案顯然不太懼怕編譯器優(yōu)化的“血腥巨斧”。想法是沒錯(cuò)的,但如果要保證這樣寫出來的延時(shí)庫有一定的可移植性,就需要保證 delay_us() 函數(shù)實(shí)現(xiàn)所依賴的硬件定時(shí)器是“通用的”和“普遍存在”的——符合這一要求的第一選擇是SysTick——然而既然SysTick已經(jīng)被 delay_ms() 占用了,又如何能抽的開身呢?


既然 SysTick 被占用了,那有沒有別的符合要求的硬件呢?如果不算Cortex-M0/M0 的話,從某種程度上說還真有——DWT。這是一個(gè)系統(tǒng)外設(shè),專門用來為Cortex-M3及其以上芯片提供調(diào)試和追蹤的硬件輔助功能。在【裸機(jī)思維】往期轉(zhuǎn)載的文章中,就有使用DWT實(shí)現(xiàn)延時(shí)的內(nèi)容。這個(gè)方法好是好,但缺點(diǎn)也是非常突出的:
  • DWT 根本就不是設(shè)計(jì)給用戶用的,它是Cortex-M處理器預(yù)留給上位機(jī)調(diào)試軟件(例如MDK)進(jìn)行調(diào)試和追蹤的。換句話說,上位機(jī)調(diào)試軟件覺得這是自己的私人財(cái)產(chǎn),從來沒想過用戶會(huì)去使用它——這就導(dǎo)致調(diào)試過程中,IDE會(huì)按照自己的意思隨意修改它的配置——啥時(shí)候會(huì)改呢?這要看IDE的心情。如果你的程序依賴了DWT進(jìn)行延時(shí),那么調(diào)試的時(shí)候,IDE的一個(gè)無心之舉可能就會(huì)毀了你的時(shí)序——這一知識(shí)點(diǎn)非常容易忽略掉,從而導(dǎo)致很多人遇到調(diào)試的時(shí)候,系統(tǒng)隨機(jī)性的功能不正常的坑,從而浪費(fèi)大把的時(shí)間,往往還想不到是DWT導(dǎo)致的——說這一方法是天坑可能一點(diǎn)也不為過。

  • DWT 不是所有 Cortex-M 芯片都有……(Cortex-M0/M0 就沒有)


既然 SysTick 被占用、DWT?又是天坑,是不是意味著我們就只能使用芯片的普通定時(shí)器了?——這每個(gè)廠家都不一樣……每個(gè)應(yīng)用對(duì)定時(shí)器的使用情況也都不同,那我還怎么做通用的延時(shí)庫???

別急,今天我們就來介紹一種在完全不影響 SysTick 已有功能的前提下,繼續(xù)把它榨干——提供更多功能的方法。為了避免誤解,我把這種方法的目標(biāo)需求列舉如下:
  • 提供一個(gè)精確的 delay_us() 函數(shù);

  • 提供一個(gè)精確測量任意代碼塊所實(shí)際占用系統(tǒng)周期數(shù)的方法;

  • 實(shí)現(xiàn)一個(gè)記錄從進(jìn)入 main() 函數(shù)以來總共經(jīng)歷了多少個(gè)時(shí)鐘周期(且在合理的時(shí)間范圍內(nèi)不會(huì)溢出)的計(jì)數(shù)器(時(shí)間戳);

  • 用戶已有的 SysTick 功能不能受到干擾

    • 比如用戶使用 SysTick 作為RTOS的基準(zhǔn)時(shí)鐘(非Tickless模式);

    • 比如用戶使用 SysTick 作為普通的毫秒級(jí)延時(shí)(就像前面例子代碼所展示的那樣);

  • 用戶不需要修改自己任何已有的 SysTick 代碼。



【部署 perf_counter 庫】

要實(shí)現(xiàn)上述功能,可以直接借助一個(gè)叫做 perf_counter 的庫,這是我基于這幾年在代碼性能分析中總結(jié)出來的,我已經(jīng)把它放在 github 上進(jìn)行開源,其地址為:https://github.com/GorgonMeducer/perf_counter
這個(gè)庫目前支持 Arm Compiler 5(armcc) 和 Arm Compiler 6(armclang)。它不僅提供了源代碼,還提供了編譯好的 library (.lib)可供全系列Cortex-M處理器使用。
第一步,下載最新的release:


解壓縮后可以看到如下的內(nèi)容:

如果只是普通的使用,直接拷貝 lib 目錄到你的工程即可。


第二步,將庫加入到已有的 MDK 工程中:



別忘記在工程的頭文件搜尋路勁中包含 perf_counter.h 所在文件夾,例如(具體位置根據(jù)你工程的情況而定,不要死腦經(jīng)):



第三步:編譯并調(diào)整一些工程選項(xiàng)

如果你編譯后很順利,則請?zhí)^下面的內(nèi)容,快進(jìn)到 0 error 0 warning的圖片之后。



好,下面讓我們來談?wù)勀憧赡苡龅降膯栴},以及對(duì)應(yīng)的解決方案:


問題一:提示找不到 $Super$$SysTick_Handler

.\Out\example.axf: Error: L6218E: Undefined symbol $Super$$SysTick_Handler (referred from systick_wrapper_ual.o).Not enough information to list image symbols.Not enough information to list load addresses in the image map.Finished: 2 information, 0 warning and 1 error messages.".\Out\example.axf" - 1 Error(s), 0 Warning(s).

perf_counter 庫是一個(gè)“附加型”庫——它假設(shè)你自己已經(jīng)實(shí)現(xiàn)了一個(gè)SysTick的中斷處理程序,并開啟了中斷模式——如果你沒有,直接加一個(gè)空的就好了:

void SysTick_Handler (void) {}好,問題解決。什么?你的工程也根本沒有用SysTick?好辦,請?jiān)?span>進(jìn)入main后調(diào)用函數(shù)init_cycle_counter()?并傳遞false,例如:

int main(void){ ... init_cycle_counter(false); ...}這樣做的目的是告訴 perf_counter:“請自己玩的開心”。


問題二:wchar和enum的尺寸不兼容:

需要強(qiáng)調(diào)的是,perf_counter.lib 庫在編譯的時(shí)候,開啟了 Short enums/wchar(分別對(duì)應(yīng)命令行的?-fshort-enums -fshort-wchar)。這么做其實(shí)沒什么特別的原因,但如果你的工程使用了不同的配置,例如:


下圖的工程配置中,沒有勾選 "Short enums/wchar"


你一定會(huì)看到這樣的編譯錯(cuò)誤:

.\Out\example.axf: Error: L6242E: Cannot link object perf_counter.o as its attributes are incompatible with the image attributes. ... wchart-16 clashes with wchart-32. ... packed-enum clashes with enum_is_int.

既然知道了原因,解決方法就很簡單,要么在工程配置中勾選上這一選項(xiàng);要么使用源代碼編譯(不使用lib):



也就是圖中所示的:perf_counter.c systick_wrapper_ual.s。


? ? perf_counter.c 依賴了 CMSIS,所以確保你的工程中加入了對(duì)CMSIS的支持——推薦的是使用MDK自帶的 CMSIS,在RTE配置界面中勾選:



如果你使用的是工程自帶的CMSIS(很多STM32工程就是這樣),請確保你的CMSIS?是較新的版本(判斷標(biāo)準(zhǔn)就是是否帶有 cmsis_compiler.h)。


此外,這里的 systick_wrapper_ual.s 是一個(gè)匯編源程序,使用的是Arm的老語法(Unified Assembly Language),如果你的工程使用的是 Arm Compiler 5(armcc),這里就沒什么需要特別注意的了;如果你的工程使用的是 Arm Compiler 6(armclang),則你需要檢查工程配置,以確保MDK能正確的選擇對(duì)應(yīng)的Assembler


注意這里的 Assembler Option,根據(jù)你MDK版本的不同,它可能有以下幾個(gè)有效選項(xiàng):
  • armclang(Auto Select)——我吐血推薦選這個(gè)

  • armclang(GNU Syntax)——?這個(gè)意思就是使用 GNU的匯編語法,顯然不能選它;

  • armclang(Arm Syntax)——這是最新MDK(從5.32開始)才有的選項(xiàng),選了也行;

  • armasm(Arm Syntax)——這就是 Arm Compiler 5里一直使用的老匯編器,選他當(dāng)然兼容性最好。


做好了以上兩個(gè)準(zhǔn)備工作,編譯應(yīng)該就很順利了。是不是覺得有點(diǎn)頭大?頭大就用?.lib 啊……完全不用經(jīng)歷這些痛苦。




至此,我們完成了 perf_counter 庫在工程中的部署。那么它帶給我們哪些功能呢?


【SysTick第一吃:微秒級(jí)精確延時(shí)】


#include?"perf_counter.h"
...delay_us(30);????//!...

再也不用擔(dān)心編譯器優(yōu)化導(dǎo)致延時(shí)不準(zhǔn)啦?。?!

再也不擔(dān)心庫不通用啦?。?!

再也不用擔(dān)心芯片不支持DWT啦?。。。。?!

再也不用擔(dān)心調(diào)試/追蹤會(huì)干擾DWT啦?。。?!





【SysTick第二吃:精確測量代碼的時(shí)鐘周期】

perf_counter.h 提供了兩個(gè)函數(shù),用于精確測量任意代碼片段所消耗的CPU時(shí)鐘周期數(shù)(不是us數(shù)哦):
extern void start_cycle_counter(void);extern int32_t stop_cycle_counter(void);它們的使用非常簡單直接,例如:
start_cycle_counter();//!?測量?打印??"Hello?World\r\n" 究竟用了多少個(gè)時(shí)鐘周期printf("Hello World! \r\n");int32_t?iCycleUsed?=?stop_cycle_counter(void);printf("Cycle?Used:?%d",?iCycleUsed);當(dāng)然,如果你的工程環(huán)境允許你用printf的話,還可以用 perf_counter.h 自帶的宏將上述代碼簡化一下:

//!?the?demo?of?__cycleof__()__cycleof__() {????printf("Hello?World\r\n");}其運(yùn)行結(jié)果為:

(以上結(jié)果為FVP仿真結(jié)果,CPU周期數(shù)值不可以做參考)


我們甚至還可以添加一點(diǎn)注釋性的字符串,幫助我們區(qū)分測試的范圍:

//!?the?demo?of?__cycleof__()__cycleof__("Print?string")?{????printf("Hello?World\r\n");}

我們看到,傳遞給__cycleof__的提示字符串"Print string"被添加到了"total cycle count:..." 的前面,一目了然。


實(shí)際上,start_cycle_counter()stop_cycle_counter() 的組合還可以用來測量中斷處理程序?qū)嶋H使用的系統(tǒng)周期數(shù)——讀過我【實(shí)時(shí)性迷思】系列文章的小伙伴,一定知道測量“事件處理函數(shù)所需時(shí)間”的意義:

volatile?int32_t?g_nMaxHandlingCycles = 0;
void?USART0_RX_Handler(void){????start_cycle_counter();????????//!?你的USART0 接收中斷處理程序?qū)嶋H內(nèi)容????...????????int32_t nCycles = stop_cycle_counter();????g_nMaxHandlingCycles?=?MAX(nCycles,?g_nMaxHandlingCycles);}

從此一舉告別“拍腦袋憑感覺”說中斷處理時(shí)間要多長的舊世界。


此外,start_cycle_counter()?和 stop_cycle_counter() 還支持類似體育老師所使用的秒表的功能,即,起跑后、可以分別記錄每一個(gè)學(xué)生所用的時(shí)間。具體表現(xiàn)為:

int32_t nCycles = 0;start_cycle_counter();???? //!...nCycles?=?stop_cycle_counter();??//!...nCycles?=?stop_cycle_counter();??//!...nCycles?=?stop_cycle_counter();??//!< 第三次獲取從開始以來的時(shí)間...具體什么情況下要用到這樣的方式就見仁見智了,這里就不再繼續(xù)展開。


最后,需要強(qiáng)調(diào)一下,雖然 start_cycle_counter()stop_cycle_counter()startstop 的字樣,但這只是邏輯上的,并不會(huì)真正的干擾 SysTick 的功能(也就是不會(huì)開啟或者關(guān)閉 SysTick)。這也是這個(gè)庫敢于聲稱自己不會(huì)影響用戶已有的 SysTick 功能的原因。

【SysTick第三吃:系統(tǒng)時(shí)間戳】

閱讀到這里,聰明的你一定已經(jīng)發(fā)現(xiàn)了:無論是 perf_counter(performance counter)庫名的明示,還是 start_cycle_counter()stop_cycle_counter() 的強(qiáng)大功能,都暗示其實(shí)這個(gè)庫應(yīng)該不是專門用來提供微秒延時(shí)函數(shù) delay_us() 的,實(shí)際上,只要你稍微看一眼源代碼就會(huì)發(fā)現(xiàn)上述猜想完全沒錯(cuò)—— delay_us() 其實(shí)才是附贈(zèng)的:
void delay_us(int32_t iUs){ iUs *= SystemCoreClock / 1000000ul; start_cycle_counter(); while(stop_cycle_counter() < iUs);}

看到真相的你,有沒有意識(shí)到,在 start_cycle_counter()stop_cycle_counter() 之間不能調(diào)用 delay_us() 呢?

既然 delay_us() 都是“cycle counter”送的,還有啥別的功能是附贈(zèng)的么?——還真有:系統(tǒng)時(shí)間戳。想象一下,既然 start_cycle_counter()stop_cycle_counter() 的組合可以獲得從開始以來的時(shí)間,那么如果我在進(jìn)入main()之前就執(zhí)行 start_cycle_counter() ,然后在需要的時(shí)候調(diào)用 stop_cycle_counter() 是不是就可以獲取“從main()開始已經(jīng)執(zhí)行了多少個(gè)周期”的系統(tǒng)時(shí)間戳呢?
Bingo!答對(duì)了,原理上就是這樣,只不過實(shí)際上,為了保留 start_cycle_counter() stop_cycle_counter() 給用戶使用,per_counter庫就自己獨(dú)立實(shí)現(xiàn)了對(duì)應(yīng)的邏輯——用戶可以通過調(diào)用函數(shù)?clock() 來獲取這一信息:
#ifdef __PERF_CNT_USE_LONG_CLOCK____attribute__((nothrow)) extern int64_t clock(void);#endif熟悉系統(tǒng)庫 朋友可能會(huì)立即產(chǎn)生疑問,真正的定義不應(yīng)該是這樣的么:
extern _ARMABI clock_t clock(void);clock_t 在 Cortex-M環(huán)境下定義如下:

typedef unsigned int clock_t; /* cpu time type */為什么perf_counter.h 要采用不一樣的定義呢?


說起來也簡單:clock() 函數(shù)返回的是系統(tǒng)周期數(shù),而不是什么以 us 或者 ms 為單位的時(shí)間——考慮到現(xiàn)在處理器頻率動(dòng)輒幾百兆赫茲,有的甚至達(dá)到了1GHz(比如 NXP的RT系列),如果用 int32_t?(哪怕用 uint32_t)也撐不了幾秒鐘。


假設(shè)系統(tǒng)頻率為1GHz,使用 uint32_t 來計(jì)數(shù),由于32bit整數(shù)取值范圍是0~4G,因此,最多4秒就撐不住了……


那究竟多長才夠呢?



當(dāng)我們使用 int64_t 的時(shí)候,哪怕系統(tǒng)頻率是 4GHz,2G 秒 ≈ 24855 天 ≈ 68年。雖然沒有一萬年那么久,不過多半一個(gè)嵌入式設(shè)備也沒法用這么久(千年蟲警告),但考慮到大部分Cortex-M嵌入式系統(tǒng)估計(jì)沒有4GHz這么夸張,輕松跑個(gè)1000多年不溢出應(yīng)該是沒有問題的。


既然我們鐵了心要用 int64_t 來取代 clock_t 原本的 int32_t,怎么解決這里的沖突呢?——顯然去修改系統(tǒng)頭文件 是不允許的!


翻開Arm的隱藏寶典:AAPCS,我們發(fā)現(xiàn)以下的規(guī)則:

32位系統(tǒng)下,

  • 如果函數(shù)的返回值其大小不超過32bit,則保存在寄存器 r0中;

  • 如果函數(shù)的返回值其大小為64bit,則其低 32bit 保存在 r0中、高32bit保存在 r1中。


顯然,當(dāng)我們實(shí)現(xiàn)clock()函數(shù)時(shí)返回 int64_t的值與 返回 int32_t其實(shí)是兼容的——因?yàn)榈?em>32bit的內(nèi)容實(shí)際上都是保存在 r0 里的,此時(shí)如果用戶調(diào)用clock() 的時(shí)候:

  • 使用的是里定義的函數(shù)原型,即? clock_t clock(void),則,當(dāng)函數(shù)返回時(shí),r1里保存的值會(huì)被無視,只有r0里的值被視作返回值;

  • 使用的是我們自己定義的函數(shù)原型,即 int64_t clock(void),則你可以獲得完整的 int64_t 時(shí)間戳。


既然原理清楚了,再看 perf_counter.h 里面的定義,我們會(huì)發(fā)現(xiàn)clock()的函數(shù)原型被一個(gè)宏?__PERF_CNT_USE_LONG_CLOCK__ 保護(hù)著:

#ifdef __PERF_CNT_USE_LONG_CLOCK____attribute__((nothrow)) extern int64_t clock(void);#endif這實(shí)際上是告訴我們,如果我們想獲得 int64_t 時(shí)間戳?xí)r,只要在工程中定義宏??__PERF_CNT_USE_LONG_CLOCK__?就可以了。



忙活了半天,有的小伙伴可能會(huì)疑惑了:饒了這么一大圈,clock() 究竟有啥用處呢?這玩法就多了,快一鍵三聯(lián)~ 下次我們好好來說說。



【后記】

perf_counter(https://github.com/GorgonMeducer/perf_counter)是我在工作中總結(jié)和整理出的一個(gè)庫,它的特點(diǎn)是在不干擾已有 SysTick 功能的前提下額外為我們提供系統(tǒng)周期測量的功能——并在這基礎(chǔ)上衍生出了 delay_us() 和 系統(tǒng)時(shí)間戳的功能——正可謂一鴨三吃,把SysTick榨干到了極致。perf_counter 庫的原理其實(shí)很簡單,但其中要處理的 corner case 確實(shí)很惱人,我也是歷經(jīng)一年多才真正想明白這里面的彎彎繞。后面如果閱讀量不錯(cuò)的話,我會(huì)考慮專門出一篇介紹 perf_counter 原理的文章。其中,關(guān)于如何“不影響現(xiàn)有SysTick中斷處理程序”的功能,已經(jīng)在之前的文章《【嵌入式秘術(shù)】手把手教你如何劫持RTOS》中進(jìn)行了詳細(xì)介紹,有興趣的小伙伴可以再回味回味。
在開源的過程中,為了簡化用戶的使用,我做了如下的優(yōu)化:
  • 在 Arm Compiler 5(armcc)和 Arm Compiler 6中,不需要用戶手工對(duì)庫進(jìn)行初始化——庫會(huì)在進(jìn)入main()之前“自己做”;

  • Lib中的perf_counter.lib適用于包含Cortex-M0在內(nèi)的全系列Cortex-M處理器,做到全覆蓋;

  • perf_counter.h 幾乎不依賴 之外的庫。使用.lib進(jìn)行部署,非常簡潔方便。


如果你要用 safe_atom_code(),則需要 __disable_irq() 和 __set_PRIMASK() 的定義,一般Cortex-M工程都有。這些定義是由 CMSIS提供的。一般來說,普通的 perf_counter 功能并不需要涉及任何這些內(nèi)容。


perf_counter庫的使用當(dāng)然也存在限制,重要的事情在最后說:
  • 如果你原本的 RTOS 使用了 SysTick并開啟了Tickless模式,perf_counter雖然不會(huì)干擾原有的 SysTick功能,但自己的計(jì)時(shí)功能卻會(huì)受到 Tickless模式的干擾;

  • perf_counter庫假設(shè)你原本的SysTick應(yīng)用會(huì)保持一個(gè)固定的定時(shí)周期——也就是 LOAD寄存器的內(nèi)容是固定的、不會(huì)隨著程序的執(zhí)行而經(jīng)常變化。其實(shí)RTOStickless模式會(huì)干擾perf_counter的計(jì)數(shù)可靠性也是這個(gè)原因。



一般來說,大部分RTOS和普通的周期性定時(shí)功能都不會(huì)經(jīng)常動(dòng)態(tài)的去改變SysTick的計(jì)數(shù)周期,所以不必太擔(dān)心。

原創(chuàng)不易,如果你喜歡我的思維、覺得我的文章對(duì)你有所啟發(fā),

請務(wù)必 “點(diǎn)贊、收藏、轉(zhuǎn)發(fā)” 三連,這對(duì)我很重要!謝謝!


歡迎訂閱 裸機(jī)思維


本站聲明: 本文章由作者或相關(guān)機(jī)構(gòu)授權(quán)發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點(diǎn),本站亦不保證或承諾內(nèi)容真實(shí)性等。需要轉(zhuǎn)載請聯(lián)系該專欄作者,如若文章內(nèi)容侵犯您的權(quán)益,請及時(shí)聯(lián)系本站刪除。
換一批
延伸閱讀

LED驅(qū)動(dòng)電源的輸入包括高壓工頻交流(即市電)、低壓直流、高壓直流、低壓高頻交流(如電子變壓器的輸出)等。

關(guān)鍵字: 驅(qū)動(dòng)電源

在工業(yè)自動(dòng)化蓬勃發(fā)展的當(dāng)下,工業(yè)電機(jī)作為核心動(dòng)力設(shè)備,其驅(qū)動(dòng)電源的性能直接關(guān)系到整個(gè)系統(tǒng)的穩(wěn)定性和可靠性。其中,反電動(dòng)勢抑制與過流保護(hù)是驅(qū)動(dòng)電源設(shè)計(jì)中至關(guān)重要的兩個(gè)環(huán)節(jié),集成化方案的設(shè)計(jì)成為提升電機(jī)驅(qū)動(dòng)性能的關(guān)鍵。

關(guān)鍵字: 工業(yè)電機(jī) 驅(qū)動(dòng)電源

LED 驅(qū)動(dòng)電源作為 LED 照明系統(tǒng)的 “心臟”,其穩(wěn)定性直接決定了整個(gè)照明設(shè)備的使用壽命。然而,在實(shí)際應(yīng)用中,LED 驅(qū)動(dòng)電源易損壞的問題卻十分常見,不僅增加了維護(hù)成本,還影響了用戶體驗(yàn)。要解決這一問題,需從設(shè)計(jì)、生...

關(guān)鍵字: 驅(qū)動(dòng)電源 照明系統(tǒng) 散熱

根據(jù)LED驅(qū)動(dòng)電源的公式,電感內(nèi)電流波動(dòng)大小和電感值成反比,輸出紋波和輸出電容值成反比。所以加大電感值和輸出電容值可以減小紋波。

關(guān)鍵字: LED 設(shè)計(jì) 驅(qū)動(dòng)電源

電動(dòng)汽車(EV)作為新能源汽車的重要代表,正逐漸成為全球汽車產(chǎn)業(yè)的重要發(fā)展方向。電動(dòng)汽車的核心技術(shù)之一是電機(jī)驅(qū)動(dòng)控制系統(tǒng),而絕緣柵雙極型晶體管(IGBT)作為電機(jī)驅(qū)動(dòng)系統(tǒng)中的關(guān)鍵元件,其性能直接影響到電動(dòng)汽車的動(dòng)力性能和...

關(guān)鍵字: 電動(dòng)汽車 新能源 驅(qū)動(dòng)電源

在現(xiàn)代城市建設(shè)中,街道及停車場照明作為基礎(chǔ)設(shè)施的重要組成部分,其質(zhì)量和效率直接關(guān)系到城市的公共安全、居民生活質(zhì)量和能源利用效率。隨著科技的進(jìn)步,高亮度白光發(fā)光二極管(LED)因其獨(dú)特的優(yōu)勢逐漸取代傳統(tǒng)光源,成為大功率區(qū)域...

關(guān)鍵字: 發(fā)光二極管 驅(qū)動(dòng)電源 LED

LED通用照明設(shè)計(jì)工程師會(huì)遇到許多挑戰(zhàn),如功率密度、功率因數(shù)校正(PFC)、空間受限和可靠性等。

關(guān)鍵字: LED 驅(qū)動(dòng)電源 功率因數(shù)校正

在LED照明技術(shù)日益普及的今天,LED驅(qū)動(dòng)電源的電磁干擾(EMI)問題成為了一個(gè)不可忽視的挑戰(zhàn)。電磁干擾不僅會(huì)影響LED燈具的正常工作,還可能對(duì)周圍電子設(shè)備造成不利影響,甚至引發(fā)系統(tǒng)故障。因此,采取有效的硬件措施來解決L...

關(guān)鍵字: LED照明技術(shù) 電磁干擾 驅(qū)動(dòng)電源

開關(guān)電源具有效率高的特性,而且開關(guān)電源的變壓器體積比串聯(lián)穩(wěn)壓型電源的要小得多,電源電路比較整潔,整機(jī)重量也有所下降,所以,現(xiàn)在的LED驅(qū)動(dòng)電源

關(guān)鍵字: LED 驅(qū)動(dòng)電源 開關(guān)電源

LED驅(qū)動(dòng)電源是把電源供應(yīng)轉(zhuǎn)換為特定的電壓電流以驅(qū)動(dòng)LED發(fā)光的電壓轉(zhuǎn)換器,通常情況下:LED驅(qū)動(dòng)電源的輸入包括高壓工頻交流(即市電)、低壓直流、高壓直流、低壓高頻交流(如電子變壓器的輸出)等。

關(guān)鍵字: LED 隧道燈 驅(qū)動(dòng)電源
關(guān)閉