From cc432b761c884a0bd8e9d83db0a4e26109fc08b1 Mon Sep 17 00:00:00 2001 From: chen <15335560115@163.com> Date: 星期五, 08 十一月 2024 15:35:38 +0800 Subject: [PATCH] 安邦手环GPS删除部分无用数据和修改4G波特率9600出厂测试固件 --- keil/include/components/wsf/sources/port/baremetal/wsf_timer.c | 414 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 414 insertions(+), 0 deletions(-) diff --git a/keil/include/components/wsf/sources/port/baremetal/wsf_timer.c b/keil/include/components/wsf/sources/port/baremetal/wsf_timer.c new file mode 100644 index 0000000..903d97f --- /dev/null +++ b/keil/include/components/wsf/sources/port/baremetal/wsf_timer.c @@ -0,0 +1,414 @@ +/*************************************************************************************************/ +/*! + * \file wsf_timer.c + * + * \brief Timer service. + * + * Copyright (c) 2009-2019 Arm Ltd. All Rights Reserved. + * + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/*************************************************************************************************/ + +#include "wsf_types.h" +#include "wsf_queue.h" +#include "wsf_timer.h" + +#include "wsf_assert.h" +#include "wsf_cs.h" +#include "wsf_trace.h" +#include "pal_sys.h" + +/************************************************************************************************** + Macros +**************************************************************************************************/ + +#if (WSF_MS_PER_TICK == 10) + +/*! \brief WSF timer ticks per second. */ +#define WSF_TIMER_TICKS_PER_SEC (1000 / WSF_MS_PER_TICK) + +/* convert seconds to timer ticks */ +#define WSF_TIMER_SEC_TO_TICKS(sec) (WSF_TIMER_TICKS_PER_SEC * (sec)) + +/* convert milliseconds to timer ticks */ +#define WSF_TIMER_MS_TO_TICKS(ms) ((ms) / WSF_MS_PER_TICK) + +#else +#error "WSF_TIMER_MS_TO_TICKS and WSF_TIMER_SEC_TO_TICKS not defined for WSF_MS_PER_TICK" +#endif + +/*! \brief Minimum RTC ticks required to go into sleep. */ +#define WSF_TIMER_MIN_MS_FOR_POWERDOWN (2) +#define WSF_TIMER_MAX_MS_FOR_POWERDOWN (10000) + +/************************************************************************************************** + Global Variables +**************************************************************************************************/ + +static wsfQueue_t wsfTimerTimerQueue; /*!< Timer queue */ + +/*! \brief Last SysTick value read. */ +static uint32_t wsfTimerSysTickcLastTick = 0; + +/*************************************************************************************************/ +/*! + * \brief Remove a timer from queue. Note this function does not lock task scheduling. + * + * \param pTimer Pointer to timer. + */ +/*************************************************************************************************/ +static void wsfTimerRemove(wsfTimer_t *pTimer) +{ + wsfTimer_t *pElem; + wsfTimer_t *pPrev = NULL; + + pElem = (wsfTimer_t *)wsfTimerTimerQueue.pHead; + + /* find timer in queue */ + while (pElem != NULL) + { + if (pElem == pTimer) + { + break; + } + pPrev = pElem; + pElem = pElem->pNext; + } + + /* if timer found remove from queue */ + if (pElem != NULL) + { + WsfQueueRemove(&wsfTimerTimerQueue, pTimer, pPrev); + + pTimer->isStarted = FALSE; + } +} + +/*************************************************************************************************/ +/*! + * \brief Insert a timer into the queue sorted by the timer expiration. + * + * \param pTimer Pointer to timer. + * \param ticks Timer ticks until expiration. + * \param mode Timer work mode. + */ +/*************************************************************************************************/ +static void wsfTimerInsert(wsfTimer_t *pTimer, wsfTimerTicks_t ticks, uint8_t mode) +{ + wsfTimer_t *pElem; + wsfTimer_t *pPrev = NULL; + + /* task schedule lock */ + uint32_t lock = WsfTaskLock(); + + /* if timer is already running stop it first */ + if (pTimer->isStarted) + { + wsfTimerRemove(pTimer); + } + + pTimer->isStarted = TRUE; + pTimer->ticks = ticks; + pTimer->count = ticks; + pTimer->mode = mode; + + pElem = (wsfTimer_t *)wsfTimerTimerQueue.pHead; + + /* find insertion point in queue */ + while (pElem != NULL) + { + if (pTimer->ticks < pElem->ticks) + { + break; + } + pPrev = pElem; + pElem = pElem->pNext; + } + + /* insert timer into queue */ + WsfQueueInsert(&wsfTimerTimerQueue, pTimer, pPrev); + + /* task schedule unlock */ + WsfTaskUnlock(lock); +} + +/*************************************************************************************************/ +/*! + * \brief Return the number of ticks until the next timer expiration. Note that this + * function can return zero even if a timer is running, indicating a timer + * has expired but has not yet been serviced. + * + * \param pTimerRunning Returns TRUE if a timer is running, FALSE if no timers running. + * + * \return The number of ticks until the next timer expiration. + */ +/*************************************************************************************************/ +static wsfTimerTicks_t WsfTimerNextExpiration(bool_t *pTimerRunning) +{ + wsfTimerTicks_t ticks; + + /* task schedule lock */ + uint32_t lock = WsfTaskLock(); + + if (wsfTimerTimerQueue.pHead == NULL) + { + *pTimerRunning = FALSE; + ticks = 0; + } + else + { + *pTimerRunning = TRUE; + ticks = ((wsfTimer_t *)wsfTimerTimerQueue.pHead)->ticks; + } + + /* task schedule unlock */ + WsfTaskUnlock(lock); + + return ticks; +} + +/*************************************************************************************************/ +/*! + * \brief Initialize the timer service. This function should only be called once + * upon system initialization. + */ +/*************************************************************************************************/ +void WsfTimerInit(void) +{ + WSF_QUEUE_INIT(&wsfTimerTimerQueue); +} + +/*************************************************************************************************/ +/*! + * \brief Start a timer in units of seconds. + * + * \param pTimer Pointer to timer. + * \param sec Seconds until expiration. + * \param mode Timer work mode. + */ +/*************************************************************************************************/ +void WsfTimerStartSec(wsfTimer_t *pTimer, wsfTimerTicks_t sec, uint8_t mode) +{ + WSF_TRACE_INFO2("WsfTimerStartSec pTimer:0x%x ticks:%u", (uint32_t)pTimer, WSF_TIMER_SEC_TO_TICKS(sec)); + + /* insert timer into queue */ + wsfTimerInsert(pTimer, WSF_TIMER_SEC_TO_TICKS(sec), mode); +} + +/*************************************************************************************************/ +/*! + * \brief Start a timer in units of milliseconds. + * + * \param pTimer Pointer to timer. + * \param ms Milliseconds until expiration. + * \param mode Timer work mode. + */ +/*************************************************************************************************/ +void WsfTimerStartMs(wsfTimer_t *pTimer, wsfTimerTicks_t ms, uint8_t mode) +{ + WSF_TRACE_INFO2("WsfTimerStartMs pTimer:0x%x ticks:%u", (uint32_t)pTimer, WSF_TIMER_MS_TO_TICKS(ms)); + + /* insert timer into queue */ + wsfTimerInsert(pTimer, WSF_TIMER_MS_TO_TICKS(ms), mode); +} + +/*************************************************************************************************/ +/*! + * \brief Stop a timer. + * + * \param pTimer Pointer to timer. + */ +/*************************************************************************************************/ +void WsfTimerStop(wsfTimer_t *pTimer) +{ + WSF_TRACE_INFO1("WsfTimerStop pTimer:0x%x", pTimer); + + /* task schedule lock */ + uint32_t lock = WsfTaskLock(); + + wsfTimerRemove(pTimer); + + /* task schedule unlock */ + WsfTaskUnlock(lock); +} + +/*************************************************************************************************/ +/*! + * \brief Update the timer service with the number of elapsed ticks. + * + * \param ticks Number of ticks since last update. + */ +/*************************************************************************************************/ +void WsfTimerUpdate(wsfTimerTicks_t ticks) +{ + wsfTimer_t *pElem; + + /* task schedule lock */ + uint32_t lock = WsfTaskLock(); + + pElem = (wsfTimer_t *)wsfTimerTimerQueue.pHead; + + /* iterate over timer queue */ + while (pElem != NULL) + { + /* decrement ticks while preventing underflow */ + if (pElem->ticks > ticks) + { + pElem->ticks -= ticks; + } + else + { + pElem->ticks = 0; + + /* timer expired; set task for this timer as ready */ + WsfTaskSetReady(pElem->handlerId, WSF_TIMER_EVENT); + } + + pElem = pElem->pNext; + } + + /* task schedule unlock */ + WsfTaskUnlock(lock); +} + +/*************************************************************************************************/ +/*! + * \brief Service expired timers for the given task. + * + * \param taskId Task ID. + * + * \return Pointer to timer or NULL. + */ +/*************************************************************************************************/ +wsfTimer_t *WsfTimerServiceExpired(wsfTaskId_t taskId) +{ + wsfTimer_t *pElem; + wsfTimer_t *pPrev = NULL; + + /* Unused parameters */ + (void)taskId; + + /* task schedule lock */ + uint32_t lock = WsfTaskLock(); + + /* find expired timers in queue */ + pElem = (wsfTimer_t *)wsfTimerTimerQueue.pHead; + if ((pElem != NULL) && (pElem->ticks == 0)) + { + if (pElem->mode == WSF_TIMER_PERIODIC) + { + wsfTimerInsert(pElem, pElem->count, WSF_TIMER_PERIODIC); + } + else + { + /* remove timer from queue */ + WsfQueueRemove(&wsfTimerTimerQueue, pElem, pPrev); + + pElem->isStarted = FALSE; + } + + /* task schedule unlock */ + WsfTaskUnlock(lock); + + WSF_TRACE_INFO1("Timer expired pTimer:0x%x", pElem); + + /* return timer */ + return pElem; + } + + /* task schedule unlock */ + WsfTaskUnlock(lock); + + return NULL; +} + +/*************************************************************************************************/ +/*! + * \brief Function for checking if there is an active timer and if there is enough time to + * go to sleep and going to sleep. + */ +/*************************************************************************************************/ +uint8_t WsfTimerSleepCheck(uint32_t *sleep_ms) +{ + wsfTimerTicks_t nextExpiration; + + /* If PAL system is busy, no need to sleep. */ + if (PalSysIsBusy()) + { + // active + return 0; + } + + bool_t running; + nextExpiration = WsfTimerNextExpiration(&running); + + if (running) + { + uint32_t awake = WSF_MS_PER_TICK * nextExpiration; + uint32_t elapsed = PalSysTickElapse(); + + /* if we have time to sleep before timer expiration */ + if ((awake - elapsed) > WSF_TIMER_MIN_MS_FOR_POWERDOWN) + { + *sleep_ms = awake - elapsed; + // Power down + return 2; + } + else + { + /* Not enough time to go to powerdown. Let the system sleep. */ + // Sleep + return 1; + } + } + else + { + *sleep_ms = WSF_TIMER_MAX_MS_FOR_POWERDOWN; + // Power down + return 2; + } +} + +//***************************************************************************** +// +// Calculate the elapsed time, and update the WSF software timers. +// +//***************************************************************************** +void WsfTimerUpdateTicks(void) +{ + uint32_t ui32CurrentTick, ui32ElapsedTicks; + + // + // Read the continuous systick. + // + ui32CurrentTick = PalSysTickGet(); + + // + // Figure out how long it has been since the last time we've read the + // continuous systick. + // + if (ui32CurrentTick > wsfTimerSysTickcLastTick) + { + ui32ElapsedTicks = ui32CurrentTick - wsfTimerSysTickcLastTick; + } + else + { + ui32ElapsedTicks = 0xffffffff - wsfTimerSysTickcLastTick + ui32CurrentTick; + } + + WsfTimerUpdate(ui32ElapsedTicks); + wsfTimerSysTickcLastTick = ui32CurrentTick; +} -- Gitblit v1.9.3