當(dāng)前位置:首頁(yè) > 芯聞號(hào) > 充電吧
[導(dǎo)讀]使用CC2530的芯片,ZStack-CC2530-2.5.1a協(xié)議棧。對(duì)于任意接受到的數(shù)據(jù)包均有afIncomingMSGPacket_t::timestamp。根據(jù)對(duì)協(xié)議棧代碼的閱讀和網(wǎng)上一些資料

使用CC2530的芯片,ZStack-CC2530-2.5.1a協(xié)議棧。對(duì)于任意接受到的數(shù)據(jù)包均有afIncomingMSGPacket_t::timestamp。根據(jù)對(duì)協(xié)議棧代碼的閱讀和網(wǎng)上一些資料的查詢,只知道這個(gè)afIncomingMSGPacket_t::timestamp是數(shù)據(jù)包發(fā)送者發(fā)送時(shí)的MAC的時(shí)間。

timestamp unit is based on a basic time unit called Backoff Period(BP)
a Unit Backoff Period = the transmission time of 80bits(0.32ms)


對(duì)于osal_systemClock參數(shù),通過對(duì)協(xié)議棧代碼的閱讀和網(wǎng)上一些資料的查詢,這個(gè)參數(shù)將在osalTimeUpdate()中被更新,而osalTimeUpdate()函數(shù)在osal_run_system中被調(diào)用。而對(duì)于osal_run_system()函數(shù)的功能的介紹,我發(fā)現(xiàn)這是一個(gè)任務(wù)隊(duì)列的檢測(cè)和任務(wù)事件實(shí)現(xiàn)的入口函數(shù)。

1.OSAL 1.1 osal_start_system()函數(shù)

首先,通過協(xié)議棧會(huì)調(diào)用OSAL.c文件中osal_start_system()函數(shù)啟動(dòng)系統(tǒng):


/*********************************************************************
?*?@fn??????osal_start_system
?*
?*?@brief
?*
?*???This?function?is?the?main?loop?function?of?the?task?system?(if
?*???ZBIT?and?UBIT?are?not?defined).?This?Function?doesn't?return.
?*
?*?@param???void
?*
?*?@return??none
?*/
void?osal_start_system(?void?)
{
#if?!defined?(?ZBIT?)?&&?!defined?(?UBIT?)
??for(;;)??//?Forever?Loop
#endif
??{
????osal_run_system();
??}
}

該函數(shù)在一個(gè)一直循環(huán)中調(diào)用同位于OSAL.c文件中的osal_run_system()函數(shù): 1.2 osal_run_system()


/*********************************************************************
?*?@fn??????osal_run_system
?*
?*?@brief
?*
?*???This?function?will?make?one?pass?through?the?OSAL?taskEvents?table
?*???and?call?the?task_event_processor()?function?for?the?first?task?that
?*???is?found?with?at?least?one?event?pending.?If?there?are?no?pending
?*???events?(all?tasks),?this?function?puts?the?processor?into?Sleep.
?*
?*?@param???void
?*
?*?@return??none
?*/
void?osal_run_system(?void?)
{
??uint8?idx?=?0;

??osalTimeUpdate();?????????//更新時(shí)鐘
??Hal_ProcessPoll();????????//查看硬件是否有事件發(fā)生

??do?{
????if?(tasksEvents[idx])??//?Task?is?highest?priority?that?is?ready.
????{
??????break;
????}
??}?while?(++idx?<?tasksCnt);

??if?(idx?<?tasksCnt)
??{
????uint16?events;
????halIntState_t?intState;

????HAL_ENTER_CRITICAL_SECTION(intState);
????events?=?tasksEvents[idx];
????tasksEvents[idx]?=?0;??//?Clear?the?Events?for?this?task.
????HAL_EXIT_CRITICAL_SECTION(intState);

????activeTaskID?=?idx;
????events?=?(tasksArr[idx])(?idx,?events?);
????activeTaskID?=?TASK_NO_TASK;

????HAL_ENTER_CRITICAL_SECTION(intState);
????tasksEvents[idx]?|=?events;??//?Add?back?unprocessed?events?to?the?current?task.
????HAL_EXIT_CRITICAL_SECTION(intState);
??}
#if?defined(?POWER_SAVING?)
??else??//?Complete?pass?through?all?task?events?with?no?activity?
??{
????osal_pwrmgr_powerconserve();??//?Put?the?processor/system?into?sleep
??}
#endif

??/*?Yield?in?case?cooperative?scheduling?is?being?used.?*/
#if?defined?(configUSE_PREEMPTION)?&&?(configUSE_PREEMPTION?==?0)
??{
????osal_task_yield();
??}
#endif
}

通過代碼我們可以看出,osal_run_system是一個(gè)事件的喚起函數(shù),通過該函數(shù)中調(diào)用的osalTimeUpdate()更新系統(tǒng)時(shí)鐘,調(diào)用Hal_ProcessPoll()處理任務(wù)事件,然后循環(huán)的查看是否需要添加任務(wù)事件。對(duì)于Hal_ProcessPoll()函數(shù)我們暫時(shí)不管。現(xiàn)在我們看一下位置為OSAL_Clock.c文件中的osalTimeUpdate()函數(shù):


1.3 osalTimeUpdate()


/*********************************************************************
?*?@fn??????osalTimeUpdate
?*
?*?@brief???Uses?the?free?running?rollover?count?of?the?MAC?backoff?timer;
?*??????????this?timer?runs?freely?with?a?constant?320?usec?interval.??The
?*??????????count?of?320-usec?ticks?is?converted?to?msecs?and?used?to?update
?*??????????the?OSAL?clock?and?Timers?by?invoking?osalClockUpdate()?and
?*??????????osalTimerUpdate().??This?function?is?intended?to?be?invoked
?*??????????from?the?background,?not?interrupt?level.
?*
?*?@param???None.
?*
?*?@return??None.
?*/
void?osalTimeUpdate(?void?)
{
??halIntState_t?intState;
??uint32?tmp;
??uint32?ticks320us;
??uint16?elapsedMSec?=?0;

??HAL_ENTER_CRITICAL_SECTION(intState);
??//?Get?the?free-running?count?of?320us?timer?ticks
??tmp?=?macMcuPrecisionCount();
??HAL_EXIT_CRITICAL_SECTION(intState);
??
??if?(?tmp?!=?previousMacTimerTick?)
??{
????//?Calculate?the?elapsed?ticks?of?the?free-running?timer.
????ticks320us?=?(tmp?-?previousMacTimerTick)?&?0xffffffffu;

????//?Store?the?MAC?Timer?tick?count?for?the?next?time?through?this?function.
????previousMacTimerTick?=?tmp;
????
????//?update?converted?number?with?remaining?ticks?from?loop?and?the
????//?accumulated?remainder?from?loop
????tmp?=?(ticks320us?*?8)?+?remUsTicks;

????//?Convert?the?320?us?ticks?into?milliseconds?and?a?remainder
????CONVERT_320US_TO_MS_ELAPSED_REMAINDER(?tmp,?elapsedMSec,?remUsTicks?);

????//?Update?OSAL?Clock?and?Timers
????if?(?elapsedMSec?)
????{
??????osalClockUpdate(?elapsedMSec?);
??????osalTimerUpdate(?elapsedMSec?);
????}
??}
}

該函數(shù)通過調(diào)用macMcuPrecisionCount()函數(shù)去返回自定時(shí)器2啟動(dòng)到現(xiàn)在為止的單位是320us的時(shí)間戳tmp,然后對(duì)于使用ticks320us去存儲(chǔ)新增加的時(shí)間數(shù),然后將previousMacTimerTick設(shè)置為當(dāng)前讀取的tmp,再將tmp設(shè)置為距離上次記錄時(shí)間時(shí)新增的時(shí)間和上次轉(zhuǎn)換成單位為ms時(shí)剩下的單位為us的剩余量之和,然后將tmp轉(zhuǎn)換成單位為ms的elapseMSec和小于1000us的單位為40us的remUsTicks,當(dāng)elapseMSec不為0是通過調(diào)用OSAL_Clock.c文件中的osalClockUpdate( elapseMSec )函數(shù)去修改系統(tǒng)時(shí)鐘,調(diào)用OSAL_Timers.c文件中的osalTimerUpdate( elapseMSec )函數(shù)去修改定時(shí)器系統(tǒng)時(shí)鐘。

1.4 系統(tǒng)時(shí)鐘?osalClockUpdate( uint16 elapsedMSec )



/*********************************************************************
?*?@fn??????osalClockUpdate
?*
?*?@brief???Updates?the?OSAL?Clock?time?with?elapsed?milliseconds.
?*
?*?@param???elapsedMSec?-?elapsed?milliseconds
?*
?*?@return??none
?*/
static?void?osalClockUpdate(?uint16?elapsedMSec?)
{
??//?Add?elapsed?milliseconds?to?the?saved?millisecond?portion?of?time
??timeMSec?+=?elapsedMSec;

??//?Roll?up?milliseconds?to?the?number?of?seconds
??if?(?timeMSec?>=?1000?)
??{
????OSAL_timeSeconds?+=?timeMSec?/?1000;
????timeMSec?=?timeMSec?%?1000;
??}
}

其中OSAL_timerSeconds參數(shù)可以通過osal_setClock()函數(shù)設(shè)置,也可以通過osal_getClock()函數(shù)讀取:



/*********************************************************************
?*?@fn??????osal_setClock
?*
?*?@brief???Set?the?new?time.??This?will?only?set?the?seconds?portion
?*??????????of?time?and?doesn't?change?the?factional?second?counter.
?*
?*?@param???newTime?-?number?of?seconds?since?0?hrs,?0?minutes,
?*????????????????????0?seconds,?on?the?1st?of?January?2000?UTC
?*
?*?@return??none
?*/
void?osal_setClock(?UTCTime?newTime?)
{
??OSAL_timeSeconds?=?newTime;
}

/*********************************************************************
?*?@fn??????osal_getClock
?*
?*?@brief???Gets?the?current?time.??This?will?only?return?the?seconds
?*??????????portion?of?time?and?doesn't?include?the?factional?second
?*??????????counter.
?*
?*?@param???none
?*
?*?@return??number?of?seconds?since?0?hrs,?0?minutes,?0?seconds,
?*??????????on?the?1st?of?January?2000?UTC
?*/
UTCTime?osal_getClock(?void?)
{
??return?(?OSAL_timeSeconds?);
}

而OSAL_Timers.c文件中的osalTimerUpdate(?elapseMSec?)函數(shù)如下所示: 1.5 定時(shí)器?osalClockUpdate( uint16 elapsedMSec )



/*********************************************************************
?*?@fn??????osalTimerUpdate
?*
?*?@brief???Update?the?timer?structures?for?a?timer?tick.
?*
?*?@param???none
?*
?*?@return??none
?*********************************************************************/
void?osalTimerUpdate(?uint16?updateTime?)
{
??halIntState_t?intState;
??osalTimerRec_t?*srchTimer;
??osalTimerRec_t?*prevTimer;

??HAL_ENTER_CRITICAL_SECTION(?intState?);??//?Hold?off?interrupts.
??//?Update?the?system?time
??osal_systemClock?+=?updateTime;
??HAL_EXIT_CRITICAL_SECTION(?intState?);???//?Re-enable?interrupts.

??//?Look?for?open?timer?slot
??if?(?timerHead?!=?NULL?)
??{
????//?Add?it?to?the?end?of?the?timer?list
????srchTimer?=?timerHead;
????prevTimer?=?(void?*)NULL;

????//?Look?for?open?timer?slot
????while?(?srchTimer?)
????{
??????osalTimerRec_t?*freeTimer?=?NULL;
?????
??????HAL_ENTER_CRITICAL_SECTION(?intState?);??//?Hold?off?interrupts.
??????
??????if?(srchTimer->timeout?timeout?=?0;
??????}
??????else
??????{
????????srchTimer->timeout?=?srchTimer->timeout?-?updateTime;
??????}
??????
??????//?Check?for?reloading
??????if?(?(srchTimer->timeout?==?0)?&&?(srchTimer->reloadTimeout)?&&?(srchTimer->event_flag)?)
??????{
????????//?Notify?the?task?of?a?timeout
????????osal_set_event(?srchTimer->task_id,?srchTimer->event_flag?);
????????
????????//?Reload?the?timer?timeout?value
????????srchTimer->timeout?=?srchTimer->reloadTimeout;
??????}
??????
??????//?When?timeout?or?delete?(event_flag?==?0)
??????if?(?srchTimer->timeout?==?0?||?srchTimer->event_flag?==?0?)
??????{
????????//?Take?out?of?list
????????if?(?prevTimer?==?NULL?)
??????????timerHead?=?srchTimer->next;
????????else
??????????prevTimer->next?=?srchTimer->next;

????????//?Setup?to?free?memory
????????freeTimer?=?srchTimer;

????????//?Next
????????srchTimer?=?srchTimer->next;
??????}
??????else
??????{
????????//?Get?next
????????prevTimer?=?srchTimer;
????????srchTimer?=?srchTimer->next;
??????}
??????
??????HAL_EXIT_CRITICAL_SECTION(?intState?);???//?Re-enable?interrupts.
??????
??????if?(?freeTimer?)
??????{
????????if?(?freeTimer->timeout?==?0?)
????????{
??????????osal_set_event(?freeTimer->task_id,?freeTimer->event_flag?);
????????}
????????osal_mem_free(?freeTimer?);
??????}
????}
??}
}

通過這個(gè)函數(shù)去判斷是否有定時(shí)器事件產(chǎn)生并更新定時(shí)器事件剩余事件timeout參數(shù)。


2.MAC
2.1?macMcuPrecisionCount() 該函數(shù)位于~/MAC/Low Level/System/mac_mcu.c中

/**************************************************************************************************
?*?@fn??????????macMcuPrecisionCount
?*
?*?@brief???????This?function?is?used?by?higher?layer?to?read?a?free?running?counter?driven?by
?*??????????????MAC?timer.
?*
?*?@param???????none
?*
?*?@return??????overflowCount
?**************************************************************************************************
?*/
uint32?macMcuPrecisionCount(void)
{
??uint32?????????overflowCount?=?0;
??halIntState_t??s;

??HAL_ENTER_CRITICAL_SECTION(s);

??/*?This?T2?access?macro?allows?accessing?both?T2MOVFx?and?T2Mx?*/
??MAC_MCU_T2_ACCESS_OVF_COUNT_VALUE();

??/*?Latch?the?entire?T2MOVFx?first?by?reading?T2M0.
???*?T2M0?is?discarded.
???*/
??T2M0;
??((uint8?*)&overflowCount)[UINT32_NDX0]?=?T2MOVF0;
??((uint8?*)&overflowCount)[UINT32_NDX1]?=?T2MOVF1;
??((uint8?*)&overflowCount)[UINT32_NDX2]?=?T2MOVF2;

??/*?the?overflowCount?needs?to?account?for?the?accumulated?overflow?count?in?Beacon?mode.
???*/
??overflowCount?+=?accumulatedOverflowCount;
??
??/*
???*?Workaround?to?take?care?of?the?case?where?a?rollover?just?occured?and?the?call?to
???*?macBackoffTimerPeriodIsr()?hasn't?yet?occured?or?if?one?rollover?occured?during
???*?sleep?then?update?the?accumulatedoverflowCount?with?the?rollover
???*/
???if((prevoverflowCount?>?overflowCount)?&&?(prevAccumulatedOverflowCount?==?accumulatedOverflowCount))
??{
????accumulatedOverflowCount?+=?macGetBackOffTimerRollover();
????overflowCount?+=?macGetBackOffTimerRollover();
????/*don't?update?the?rollover?since?it?has?been?updated?already?*/
????updateRolloverflag?=?TRUE;
??}

??/*?store?the?current?value?of?overflowcount?and?accumulatedOverflowCount?*/
??prevoverflowCount?=?overflowCount;
??prevAccumulatedOverflowCount?=?accumulatedOverflowCount;
??HAL_EXIT_CRITICAL_SECTION(s);

??return(overflowCount);
}



?該函數(shù)將當(dāng)前定時(shí)器2的24位溢出寄存器的值讀入?yún)?shù)overflowCount(實(shí)際最大為24bit)中,然后將overflowCount參數(shù)與積累的24位溢出計(jì)數(shù)值accumulatedOverflowCount進(jìn)行加法計(jì)數(shù),此時(shí)overflowCount為從定時(shí)器2開始到現(xiàn)在的總的單位為320us的時(shí)間值。然后通過判斷是否存在溢出計(jì)數(shù)寄存器是否溢出一次,若溢出一次則更新accumulatedOverflowCount和overFlowCount,函數(shù)macGetBackOffTimerRollover()返回的是設(shè)置的溢出周期。然后返回當(dāng)前定時(shí)器2自啟動(dòng)至現(xiàn)在的單位為320us的總的時(shí)間值。
2.2?macMcuOverflowSetCount()函數(shù)

/**************************************************************************************************
?*?@fn??????????macMcuOverflowSetCount
?*
?*?@brief???????Sets?the?value?of?the?hardware?overflow?counter.
?*
?*?@param???????count?-?new?overflow?count?value
?*
?*?@return??????none
?**************************************************************************************************
?*/
MAC_INTERNAL_API?void?macMcuOverflowSetCount(uint32?count)
{
??halIntState_t??s;

??MAC_ASSERT(!?(count?>>?24)?);???/*?illegal?count?value?*/

??/*?save?the?current?overflow?count?*/
??accumulatedOverflowCount?+=?macMcuOverflowCount();
??
??/*?deduct?the?initial?count?*/
??accumulatedOverflowCount?-=?count;

??HAL_ENTER_CRITICAL_SECTION(s);
??MAC_MCU_T2_ACCESS_OVF_COUNT_VALUE();

??/*?for?efficiency,?the?32-bit?value?is?decoded?using?endian?abstracted?indexing?*/
??/*?T2OF2?must?be?written?last?*/
??T2MOVF0?=?((uint8?*)&count)[UINT32_NDX0];????//T2MOVF0?=?((uint8?*)&count)[0];
??T2MOVF1?=?((uint8?*)&count)[UINT32_NDX1];
??T2MOVF2?=?((uint8?*)&count)[UINT32_NDX2];
??HAL_EXIT_CRITICAL_SECTION(s);
}

該函數(shù)作用是在不修改總的時(shí)間值的前提下設(shè)置Timer2的溢出寄存器的值。

而osal_systemClock為當(dāng)前節(jié)點(diǎn)自身晶振讀取修改的以ms為單位的時(shí)間值。

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

9月2日消息,不造車的華為或?qū)⒋呱龈蟮莫?dú)角獸公司,隨著阿維塔和賽力斯的入局,華為引望愈發(fā)顯得引人矚目。

關(guān)鍵字: 阿維塔 塞力斯 華為

倫敦2024年8月29日 /美通社/ -- 英國(guó)汽車技術(shù)公司SODA.Auto推出其旗艦產(chǎn)品SODA V,這是全球首款涵蓋汽車工程師從創(chuàng)意到認(rèn)證的所有需求的工具,可用于創(chuàng)建軟件定義汽車。 SODA V工具的開發(fā)耗時(shí)1.5...

關(guān)鍵字: 汽車 人工智能 智能驅(qū)動(dòng) BSP

北京2024年8月28日 /美通社/ -- 越來越多用戶希望企業(yè)業(yè)務(wù)能7×24不間斷運(yùn)行,同時(shí)企業(yè)卻面臨越來越多業(yè)務(wù)中斷的風(fēng)險(xiǎn),如企業(yè)系統(tǒng)復(fù)雜性的增加,頻繁的功能更新和發(fā)布等。如何確保業(yè)務(wù)連續(xù)性,提升韌性,成...

關(guān)鍵字: 亞馬遜 解密 控制平面 BSP

8月30日消息,據(jù)媒體報(bào)道,騰訊和網(wǎng)易近期正在縮減他們對(duì)日本游戲市場(chǎng)的投資。

關(guān)鍵字: 騰訊 編碼器 CPU

8月28日消息,今天上午,2024中國(guó)國(guó)際大數(shù)據(jù)產(chǎn)業(yè)博覽會(huì)開幕式在貴陽(yáng)舉行,華為董事、質(zhì)量流程IT總裁陶景文發(fā)表了演講。

關(guān)鍵字: 華為 12nm EDA 半導(dǎo)體

8月28日消息,在2024中國(guó)國(guó)際大數(shù)據(jù)產(chǎn)業(yè)博覽會(huì)上,華為常務(wù)董事、華為云CEO張平安發(fā)表演講稱,數(shù)字世界的話語(yǔ)權(quán)最終是由生態(tài)的繁榮決定的。

關(guān)鍵字: 華為 12nm 手機(jī) 衛(wèi)星通信

要點(diǎn): 有效應(yīng)對(duì)環(huán)境變化,經(jīng)營(yíng)業(yè)績(jī)穩(wěn)中有升 落實(shí)提質(zhì)增效舉措,毛利潤(rùn)率延續(xù)升勢(shì) 戰(zhàn)略布局成效顯著,戰(zhàn)新業(yè)務(wù)引領(lǐng)增長(zhǎng) 以科技創(chuàng)新為引領(lǐng),提升企業(yè)核心競(jìng)爭(zhēng)力 堅(jiān)持高質(zhì)量發(fā)展策略,塑強(qiáng)核心競(jìng)爭(zhēng)優(yōu)勢(shì)...

關(guān)鍵字: 通信 BSP 電信運(yùn)營(yíng)商 數(shù)字經(jīng)濟(jì)

北京2024年8月27日 /美通社/ -- 8月21日,由中央廣播電視總臺(tái)與中國(guó)電影電視技術(shù)學(xué)會(huì)聯(lián)合牽頭組建的NVI技術(shù)創(chuàng)新聯(lián)盟在BIRTV2024超高清全產(chǎn)業(yè)鏈發(fā)展研討會(huì)上宣布正式成立。 活動(dòng)現(xiàn)場(chǎng) NVI技術(shù)創(chuàng)新聯(lián)...

關(guān)鍵字: VI 傳輸協(xié)議 音頻 BSP

北京2024年8月27日 /美通社/ -- 在8月23日舉辦的2024年長(zhǎng)三角生態(tài)綠色一體化發(fā)展示范區(qū)聯(lián)合招商會(huì)上,軟通動(dòng)力信息技術(shù)(集團(tuán))股份有限公司(以下簡(jiǎn)稱"軟通動(dòng)力")與長(zhǎng)三角投資(上海)有限...

關(guān)鍵字: BSP 信息技術(shù)
關(guān)閉
關(guān)閉