| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294 |
- /*
- * Copyright (c) 2006-2021, RT-Thread Development Team
- *
- * SPDX-License-Identifier: Apache-2.0
- *
- * Change Logs:
- * Date Author Notes
- * 2018-04-12 misonyo the first version
- * 2019-04-04 misonyo fix some bugs
- */
- #include <cmsis_os2.h>
- #include "cmsis_rtthread.h"
- #include <board.h>
- #include <os_tick.h>
- #include <rthw.h>
- #define KERNEL_Id "RT-Thread" ///< Kernel identification string
- #define DEFAULT_STACK_SIZE 512
- #define DEFAULT_TICK 5
- #define WAITING_THREAD_FLAGS 0x08
- #define MALLOC_CB 0x10
- #define MALLOC_STACK 0x04
- #define MALLOC_MEM 0x02
- static osKernelState_t kernel_state = osKernelInactive;
- static void thread_cleanup(rt_thread_t thread)
- {
- thread_cb_t *thread_cb;
- thread_cb = (thread_cb_t *)(thread->user_data);
- /* clear cleanup function */
- thread->cleanup = RT_NULL;
- if (thread_cb->flags & osThreadJoinable)
- {
- rt_sem_release(thread_cb->joinable_sem);
- }
- else
- {
- if (thread_cb->flags & MALLOC_STACK)
- rt_free(thread_cb->thread.stack_addr);
- if (thread_cb->flags & MALLOC_CB)
- rt_free(thread_cb);
- }
- }
- // ==== Kernel Management Functions ====
- // ==== Helper functions ====
- /// Block Kernel (disable: thread switching, time tick, post ISR processing).
- #ifdef SysTick
- static volatile uint8_t blocked; ///< Blocked
- static uint8_t pendSV; ///< Pending SV
- /// Get Pending SV (Service Call) Flag
- /// \return Pending SV Flag
- __STATIC_INLINE uint8_t GetPendSV (void)
- {
- return ((uint8_t)((SCB->ICSR & (SCB_ICSR_PENDSVSET_Msk)) >> 24));
- }
- /// Clear Pending SV (Service Call) Flag
- __STATIC_INLINE void ClrPendSV (void)
- {
- SCB->ICSR = SCB_ICSR_PENDSVCLR_Msk;
- }
- /// Set Pending SV (Service Call) Flag
- __STATIC_INLINE void SetPendSV (void)
- {
- SCB->ICSR = SCB_ICSR_PENDSVSET_Msk;
- }
- /// Block Kernel (disable: thread switching, time tick, post ISR processing).
- static void KernelBlock (void)
- {
- OS_Tick_Disable();
- blocked = 1U;
- __DSB();
- if (GetPendSV() != 0U)
- {
- ClrPendSV();
- pendSV = 1U;
- }
- }
- /// Unblock Kernel
- static void KernelUnblock (void)
- {
- blocked = 0U;
- __DSB();
- if (pendSV != 0U)
- {
- pendSV = 0U;
- SetPendSV();
- }
- OS_Tick_Enable();
- }
- #endif
- /// Initialize the RTOS Kernel.
- /// \return status code that indicates the execution status of the function.
- osStatus_t osKernelInitialize(void)
- {
- kernel_state = osKernelReady;
- return osOK;
- }
- /// Get RTOS Kernel Information.
- /// \param[out] version pointer to buffer for retrieving version information.
- /// \param[out] id_buf pointer to buffer for retrieving kernel identification string.
- /// \param[in] id_size size of buffer for kernel identification string.
- /// \return status code that indicates the execution status of the function.
- osStatus_t osKernelGetInfo(osVersion_t *version, char *id_buf, uint32_t id_size)
- {
- if ((RT_NULL == version) || (RT_NULL == id_buf) || id_size < sizeof(KERNEL_Id))
- return osErrorParameter;
- version->api = KERNEL_VERSION;
- version->kernel = KERNEL_VERSION;
- id_size = sizeof(KERNEL_Id);
- rt_strncpy(id_buf, KERNEL_Id, id_size);
- return osOK;
- }
- /// Get the current RTOS Kernel state.
- /// \return current RTOS Kernel state.
- osKernelState_t osKernelGetState(void)
- {
- return kernel_state;
- }
- /// Start the RTOS Kernel scheduler.
- /// \return status code that indicates the execution status of the function.
- osStatus_t osKernelStart(void)
- {
- osStatus_t state;
- if (osKernelReady == kernel_state)
- {
- kernel_state = osKernelRunning;
- state = osOK;
- }
- else
- {
- state = osError;
- }
- return state;
- }
- /// Lock the RTOS Kernel scheduler.
- /// \return previous lock state (1 - locked, 0 - not locked, error code if negative).
- int32_t osKernelLock(void)
- {
- rt_uint16_t level;
- level = rt_critical_level();
- rt_enter_critical();
- kernel_state = osKernelLocked;
- if (level)
- {
- return 1;
- }
- else
- {
- return 0;
- }
- }
- /// Unlock the RTOS Kernel scheduler.
- /// \return previous lock state (1 - locked, 0 - not locked, error code if negative).
- int32_t osKernelUnlock(void)
- {
- rt_uint16_t level;
- level = rt_critical_level();
- if (0U == level)
- {
- return 0;
- }
- else
- {
- rt_exit_critical();
- if (1u == level)
- kernel_state = osKernelRunning;
- return 1;
- }
- }
- /// Restore the RTOS Kernel scheduler lock state.
- /// \param[in] lock lock state obtained by \ref osKernelLock or \ref osKernelUnlock.
- /// \return new lock state (1 - locked, 0 - not locked, error code if negative).
- int32_t osKernelRestoreLock(int32_t lock)
- {
- if (1u == lock)
- {
- osKernelLock();
- return 1;
- }
- else
- {
- osKernelUnlock();
- return 0;
- }
- }
- /// Get the RTOS kernel tick count.
- /// \return RTOS kernel current tick count.
- uint32_t osKernelGetTickCount(void)
- {
- return (uint32_t)rt_tick_get();
- }
- /// Get the RTOS kernel tick frequency.
- /// \return frequency of the kernel tick.
- uint32_t osKernelGetTickFreq(void)
- {
- return RT_TICK_PER_SECOND;
- }
- /// The function returns the current RTOS kernel system timer as a 32-bit value.
- /// \return RTOS kernel current system timer count as 32-bit value
- #ifdef SysTick
- uint32_t osKernelGetSysTimerCount(void)
- {
- uint32_t irqmask ;
- rt_tick_t ticks;
- uint32_t val;
- irqmask = rt_hw_interrupt_disable();
- ticks = rt_tick_get();
- val = OS_Tick_GetCount();
- if (OS_Tick_GetOverflow() != 0U)
- {
- val = OS_Tick_GetCount();
- ticks++;
- }
- val += ticks * OS_Tick_GetInterval();
- rt_hw_interrupt_enable(irqmask);
- return (val);
- }
- #endif /*SysTick*/
- /// Get the RTOS kernel system timer frequency.
- /// \return frequency of the system timer.
- uint32_t osKernelGetSysTimerFreq(void)
- {
- return RT_TICK_PER_SECOND;
- }
- /// Suspend the RTOS Kernel scheduler.
- /// \return time in ticks, for how long the system can sleep or power-down.
- #ifdef SysTick
- uint32_t osKernelSuspend (void)
- {
- rt_thread_t thread;
- rt_timer_t timer;
- struct rt_object_information *info_thread;
- struct rt_object_information *info_timer;
- struct rt_list_node *node;
- rt_uint8_t timer_index = 0;
- rt_tick_t min_tick = 0;
- rt_tick_t cur_tick = 0;
- rt_tick_t temp_tick = 0;
- if (kernel_state != osKernelRunning)
- {
- return 0U;
- }
- info_thread = rt_object_get_information(RT_Object_Class_Thread);
- info_timer = rt_object_get_information(RT_Object_Class_Timer);
- KernelBlock();
- min_tick = osWaitForever;
- cur_tick = rt_tick_get();
- /*check thread delay list*/
- if (info_thread != NULL)
- {
- for (node = info_thread->object_list.next; node != &(info_thread->object_list); node = node->next)
- {
- thread = thread_rt_list_entry(node, rt_thread);
- if (thread->thread_timer.parent.flag & RT_TIMER_FLAG_ACTIVATED)
- {
- temp_tick = thread->thread_timer.timeout_tick - cur_tick;
- if (temp_tick < min_tick)
- {
- min_tick = temp_tick;
- }
- }
- }
- }
- /*check active timer list*/
- if (info_timer != NULL)
- {
- for (node = info_timer->object_list.next; node != &(info_timer->object_list); node = node->next)
- {
- timer = rt_list_entry(node, struct rt_timer, row[timer_index++]);
- if (timer->parent.flag & RT_TIMER_FLAG_ACTIVATED)
- {
- temp_tick = timer->timeout_tick - cur_tick;
- if (temp_tick < min_tick)
- {
- min_tick = temp_tick;
- }
- }
- }
- }
- if (osWaitForever == min_tick)
- min_tick = 0U;
- kernel_state = osKernelSuspended;
- return (min_tick);
- }
- #endif /* SysTick */
- /// Resume the RTOS Kernel scheduler.
- /// \param[in] sleep_ticks time in ticks for how long the system was in sleep or power-down mode.
- #ifdef SysTick
- void osKernelResume (uint32_t sleep_ticks)
- {
- rt_tick_t delay_tick = 0;
- if (kernel_state != osKernelSuspended)
- {
- return;
- }
- delay_tick = (rt_tick_t)sleep_ticks;
- rt_enter_critical();
- while(delay_tick > 0)
- {
- rt_tick_increase(); /*Process Thread Delay list and Process Active Timer list*/
- delay_tick --;
- }
- rt_exit_critical();
- kernel_state = osKernelRunning;
- KernelUnblock();
- return;
- }
- #endif
- // ==== Thread Management Functions ====
- /// Create a thread and add it to Active Threads.
- /// \param[in] func thread function.
- /// \param[in] argument pointer that is passed to the thread function as start argument.
- /// \param[in] attr thread attributes; NULL: default values.
- /// \return thread ID for reference by other functions or NULL in case of error.
- osThreadId_t osThreadNew(osThreadFunc_t func, void *argument, const osThreadAttr_t *attr)
- {
- void *stack;
- rt_uint8_t rtt_prio;
- rt_uint32_t stack_size;
- thread_cb_t *thread_cb;
- char name[RT_NAME_MAX];
- static rt_uint16_t thread_number = 1U;
- /* Check parameters */
- if (RT_NULL == func)
- {
- return RT_NULL;
- }
- if ((RT_NULL == attr) || (RT_NULL == attr->cb_mem))
- {
- thread_cb = rt_malloc(sizeof(thread_cb_t));
- if (RT_NULL == thread_cb)
- return RT_NULL;
- rt_memset(thread_cb, 0, sizeof(thread_cb_t));
- thread_cb->flags |= MALLOC_CB;
- }
- else
- {
- if (attr->cb_size >= sizeof(thread_cb_t))
- {
- thread_cb = attr->cb_mem;
- thread_cb->flags = 0;
- }
- else
- return RT_NULL;
- }
- if ((RT_NULL == attr) || (RT_NULL == attr->name))
- rt_snprintf(name, sizeof(name), "th%02d", thread_number ++);
- else
- rt_snprintf(name, sizeof(name), "%s", attr->name);
- if ((RT_NULL == attr) || (osPriorityNone == attr->priority))
- {
- thread_cb->prio = osPriorityNormal;
- }
- else
- {
- if ((attr->priority < osPriorityIdle) || (attr->priority > osPriorityISR))
- return RT_NULL;
- thread_cb->prio = attr->priority;
- }
- if ((RT_NULL == attr) || (0U == attr->stack_size))
- stack_size = DEFAULT_STACK_SIZE;
- else
- stack_size = attr->stack_size;
- if ((RT_NULL == attr) || (RT_NULL == attr->stack_mem))
- {
- stack = rt_malloc(stack_size);
- if (RT_NULL == stack)
- {
- if (thread_cb->flags & MALLOC_CB)
- rt_free(thread_cb);
- return RT_NULL;
- }
- thread_cb->flags |= MALLOC_STACK;
- }
- else
- {
- stack = (void *)(attr->stack_mem);
- }
- if ((RT_NULL != attr) && (0 != attr->attr_bits))
- thread_cb->flags |= attr->attr_bits;
- rtt_prio = (osPriorityISR - thread_cb->prio) * RT_THREAD_PRIORITY_MAX / osPriorityISR;
- rt_thread_init(&(thread_cb->thread), name, func, argument, stack, stack_size, rtt_prio, DEFAULT_TICK);
- if (thread_cb->flags & osThreadJoinable)
- {
- thread_cb->joinable_sem = rt_sem_create(name, 0, RT_IPC_FLAG_FIFO);
- if (RT_NULL == thread_cb->joinable_sem)
- {
- if (thread_cb->flags & MALLOC_CB)
- rt_free(thread_cb);
- if (thread_cb->flags & MALLOC_STACK)
- rt_free(stack);
- return RT_NULL;
- }
- }
- else
- thread_cb->joinable_sem = RT_NULL;
- thread_cb->thread.cleanup = thread_cleanup;
- thread_cb->thread.user_data = (rt_uint32_t)thread_cb;
- rt_thread_startup(&(thread_cb->thread));
- return thread_cb;
- }
- /// Get name of a thread.
- /// \param[in] thread_id thread ID obtained by \ref osThreadNew or \ref osThreadGetId.
- /// \return name as NULL terminated string.
- const char *osThreadGetName(osThreadId_t thread_id)
- {
- thread_cb_t *thread_cb = (thread_cb_t *)thread_id;
- /* Check parameters */
- if ((RT_NULL == thread_cb) || (rt_object_get_type((rt_object_t)(&thread_cb->thread)) != RT_Object_Class_Thread))
- {
- return RT_NULL;
- }
- return THREAD_NAME(thread_cb);
- }
- /// Return the thread ID of the current running thread.
- /// \return thread ID for reference by other functions or NULL in case of error.
- osThreadId_t osThreadGetId(void)
- {
- rt_thread_t thread;
- thread = rt_thread_self();
- return (osThreadId_t)(thread->user_data);
- }
- /// Get current thread state of a thread.
- /// \param[in] thread_id thread ID obtained by \ref osThreadNew or \ref osThreadGetId.
- /// \return current thread state of the specified thread.
- osThreadState_t osThreadGetState(osThreadId_t thread_id)
- {
- osThreadState_t state;
- thread_cb_t *thread_cb = (thread_cb_t *)thread_id;
- /* Check parameters */
- if ((RT_NULL == thread_cb) || (rt_object_get_type((rt_object_t)(&thread_cb->thread)) != RT_Object_Class_Thread))
- {
- return osThreadError;
- }
- switch (thread_cb->thread.stat)
- {
- case RT_THREAD_INIT:
- state = osThreadInactive;
- break;
- case RT_THREAD_READY:
- state = osThreadReady;
- break;
- case RT_THREAD_SUSPEND:
- state = osThreadBlocked;
- break;
- case RT_THREAD_RUNNING:
- state = osThreadRunning;
- break;
- case RT_THREAD_CLOSE:
- state = osThreadTerminated;
- break;
- default:
- state = osThreadError;
- break;
- }
- return state;
- }
- /// Get stack size of a thread.
- /// \param[in] thread_id thread ID obtained by \ref osThreadNew or \ref osThreadGetId.
- /// \return stack size in bytes.
- uint32_t osThreadGetStackSize(osThreadId_t thread_id)
- {
- thread_cb_t *thread_cb = (thread_cb_t *)thread_id;
- /* Check parameters */
- if ((RT_NULL == thread_cb) || (rt_object_get_type((rt_object_t)(&thread_cb->thread)) != RT_Object_Class_Thread))
- {
- return 0U;
- }
- return ((uint32_t)thread_cb->thread.stack_size);
- }
- /// Get available stack space of a thread based on stack watermark recording during execution.
- /// \param[in] thread_id thread ID obtained by \ref osThreadNew or \ref osThreadGetId.
- /// \return remaining stack space in bytes.
- uint32_t osThreadGetStackSpace(osThreadId_t thread_id)
- {
- rt_uint8_t *ptr;
- thread_cb_t *thread_cb = (thread_cb_t *)thread_id;
- /* Check parameters */
- if ((RT_NULL == thread_cb) || (rt_object_get_type((rt_object_t)(&thread_cb->thread)) != RT_Object_Class_Thread))
- {
- return 0U;
- }
- ptr = (rt_uint8_t *)thread_cb->thread.stack_addr;
- while (*ptr == '#')ptr ++;
- return (ptr - (rt_uint8_t *)thread_cb->thread.stack_addr);
- }
- /// Change priority of a thread.
- /// \param[in] thread_id thread ID obtained by \ref osThreadNew or \ref osThreadGetId.
- /// \param[in] priority new priority value for the thread function.
- /// \return status code that indicates the execution status of the function.
- osStatus_t osThreadSetPriority(osThreadId_t thread_id, osPriority_t priority)
- {
- rt_uint8_t rt_priority;
- thread_cb_t *thread_cb = (thread_cb_t *)thread_id;
- // Check parameters
- if ((RT_NULL == thread_cb) || (priority < osPriorityIdle) || (priority > osPriorityISR))
- {
- return osErrorParameter;
- }
- thread_cb->prio = priority;
- rt_priority = (osPriorityISR - thread_cb->prio) * RT_THREAD_PRIORITY_MAX / osPriorityISR;
- rt_thread_control(&(thread_cb->thread), RT_THREAD_CTRL_CHANGE_PRIORITY, &rt_priority);
- return osOK;
- }
- /// Get current priority of a thread.
- /// \param[in] thread_id thread ID obtained by \ref osThreadNew or \ref osThreadGetId.
- /// \return current priority value of the specified thread.
- osPriority_t osThreadGetPriority(osThreadId_t thread_id)
- {
- thread_cb_t *thread_cb = (thread_cb_t *)thread_id;
- /* Check parameters */
- if ((RT_NULL == thread_cb) || (rt_object_get_type((rt_object_t)(&thread_cb->thread)) != RT_Object_Class_Thread))
- {
- return osPriorityError;
- }
- return (osPriority_t)thread_cb->prio;
- }
- /// Pass control to next thread that is in state \b READY.
- /// \return status code that indicates the execution status of the function.
- osStatus_t osThreadYield(void)
- {
- rt_thread_yield();
- return osOK;
- }
- /// Suspend execution of a thread.
- /// \param[in] thread_id thread ID obtained by \ref osThreadNew or \ref osThreadGetId.
- /// \return status code that indicates the execution status of the function.
- osStatus_t osThreadSuspend(osThreadId_t thread_id)
- {
- rt_err_t result;
- thread_cb_t *thread_cb = (thread_cb_t *)thread_id;
- /* Check parameters */
- if (RT_NULL == thread_cb)
- {
- return osErrorParameter;
- }
- result = rt_thread_suspend(&(thread_cb->thread));
- if (RT_EOK == result)
- return osOK;
- else
- return osError;
- }
- /// Resume execution of a thread.
- /// \param[in] thread_id thread ID obtained by \ref osThreadNew or \ref osThreadGetId.
- /// \return status code that indicates the execution status of the function.
- osStatus_t osThreadResume(osThreadId_t thread_id)
- {
- rt_err_t result;
- thread_cb_t *thread_cb = (thread_cb_t *)thread_id;
- /* Check parameters */
- if (RT_NULL == thread_cb)
- {
- return osErrorParameter;
- }
- result = rt_thread_resume(&(thread_cb->thread));
- if (RT_EOK == result)
- return osOK;
- else
- return osError;
- }
- /// Detach a thread (thread storage can be reclaimed when thread terminates).
- /// \param[in] thread_id thread ID obtained by \ref osThreadNew or \ref osThreadGetId.
- /// \return status code that indicates the execution status of the function.
- osStatus_t osThreadDetach(osThreadId_t thread_id)
- {
- thread_cb_t *thread_cb = (thread_cb_t *)thread_id;
- /* Check parameters */
- if ((RT_NULL == thread_cb) || (rt_object_get_type((rt_object_t)(&thread_cb->thread)) != RT_Object_Class_Thread))
- {
- return osErrorParameter;
- }
- /* Check object attributes */
- /*
- if ((thread_cb->flags & osThreadJoinable) == 0)
- {
- return osErrorResource;
- }
- */
- if ((thread_cb->thread.stat & RT_THREAD_STAT_MASK) == RT_THREAD_CLOSE)
- {
- rt_thread_detach(&(thread_cb->thread));
- if (thread_cb->flags & osThreadJoinable)
- rt_sem_delete(thread_cb->joinable_sem);
- if (thread_cb->flags & MALLOC_STACK)
- rt_free(thread_cb->thread.stack_addr);
- if (thread_cb->flags & MALLOC_CB)
- rt_free(thread_cb);
- }
- else
- {
- rt_enter_critical();
- /* change to detach state */
- thread_cb->flags &= ~osThreadJoinable;
- /* delete joinable semaphore */
- if (RT_NULL != thread_cb->joinable_sem)
- {
- rt_sem_delete(thread_cb->joinable_sem);
- thread_cb->joinable_sem = RT_NULL;
- }
- /* detach thread object */
- rt_thread_detach(&thread_cb->thread);
- rt_exit_critical();
- }
- return osOK;
- }
- /// Wait for specified thread to terminate.
- /// \param[in] thread_id thread ID obtained by \ref osThreadNew or \ref osThreadGetId.
- /// \return status code that indicates the execution status of the function.
- osStatus_t osThreadJoin(osThreadId_t thread_id)
- {
- rt_err_t result;
- thread_cb_t *thread_cb = (thread_cb_t *)thread_id;
- /* Check parameters */
- if (RT_NULL == thread_cb)
- {
- return osErrorParameter;
- }
- if (((&thread_cb->thread) == rt_thread_self()) ||
- (0 == (thread_cb->flags & osThreadJoinable)))
- {
- /* join self or join a detached thread*/
- return osErrorResource;
- }
- result = rt_sem_take(thread_cb->joinable_sem, RT_WAITING_FOREVER);
- if (RT_EOK == result)
- {
- /* release resource */
- if (thread_cb->flags & osThreadJoinable)
- rt_sem_delete(thread_cb->joinable_sem);
- if (thread_cb->flags & MALLOC_STACK)
- rt_free(thread_cb->thread.stack_addr);
- if (thread_cb->flags & MALLOC_CB)
- rt_free(thread_cb);
- }
- else
- return osError;
- return osOK;
- }
- /// Terminate execution of current running thread.
- __NO_RETURN void osThreadExit(void)
- {
- rt_thread_t self = rt_thread_self();
- rt_thread_control(self, RT_THREAD_CTRL_CLOSE, RT_NULL);
- RT_ASSERT(0);
- while(1);
- }
- /// Terminate execution of a thread.
- /// \param[in] thread_id thread ID obtained by \ref osThreadNew or \ref osThreadGetId.
- /// \return status code that indicates the execution status of the function.
- osStatus_t osThreadTerminate(osThreadId_t thread_id)
- {
- thread_cb_t *thread_cb;
- thread_cb = (thread_cb_t *)(rt_thread_self()->user_data);
- /* Check parameters */
- if (RT_NULL == thread_cb)
- {
- return osErrorParameter;
- }
- rt_thread_detach(&(thread_cb->thread));
- rt_schedule();
- return osOK;
- }
- /// Get number of active threads.
- /// \return number of active threads.
- uint32_t osThreadGetCount(void)
- {
- rt_uint32_t thread_count = 0U;
- struct rt_object_information *info;
- info = rt_object_get_information(RT_Object_Class_Thread);
- rt_enter_critical();
- thread_count = rt_list_len(&(info->object_list));
- rt_exit_critical();
- return thread_count;
- }
- /// Enumerate active threads.
- /// \param[out] thread_array pointer to array for retrieving thread IDs.
- /// \param[in] array_items maximum number of items in array for retrieving thread IDs.
- /// \return number of enumerated threads.
- uint32_t osThreadEnumerate(osThreadId_t *thread_array, uint32_t array_items)
- {
- rt_uint32_t thread_count = 0U;
- rt_thread_t thread;
- struct rt_object_information *info;
- struct rt_list_node *node;
- /* Check parameters */
- if ((RT_NULL == thread_array) || (0U == array_items))
- {
- return 0U;
- }
- info = rt_object_get_information(RT_Object_Class_Thread);
- rt_enter_critical();
- for (node = info->object_list.next; node != &(info->object_list); node = node->next)
- {
- thread = thread_rt_list_entry(node, rt_thread);
- thread_array[thread_count] = (osThreadId_t)thread;
- thread_count++;
- if (thread_count >= array_items)
- break;
- }
- rt_exit_critical();
- return thread_count;
- }
- // ==== Thread Flags Functions ====
- /// Set the specified Thread Flags of a thread.
- /// \param[in] thread_id thread ID obtained by \ref osThreadNew or \ref osThreadGetId.
- /// \param[in] flags specifies the flags of the thread that shall be set.
- /// \return thread flags after setting or error code if highest bit set.
- uint32_t osThreadFlagsSet(osThreadId_t thread_id, uint32_t flags)
- {
- register rt_base_t status;
- register rt_ubase_t level;
- rt_bool_t need_schedule = RT_FALSE;
- thread_cb_t *thread_cb;
- rt_uint32_t return_value;
- thread_cb = (thread_cb_t *)(thread_id);
- /* Check parameters */
- if ((RT_NULL == thread_cb) || (rt_object_get_type((rt_object_t)(&thread_cb->thread)) != RT_Object_Class_Thread))
- {
- return osFlagsErrorParameter;
- }
- level = rt_hw_interrupt_disable();
- thread_cb->flag_set |= flags;
- return_value = thread_cb->flag_set;
- /* Check if Thread is waiting for Thread Flags */
- if (thread_cb->thread.event_info & WAITING_THREAD_FLAGS)
- {
- status = -RT_ERROR;
- if (thread_cb->thread.event_info & osFlagsWaitAll)
- {
- if ((thread_cb->thread.event_set & thread_cb->flag_set) == thread_cb->thread.event_set)
- {
- /* received an AND event */
- status = RT_EOK;
- }
- }
- else
- {
- if (thread_cb->thread.event_set & thread_cb->flag_set)
- {
- /* save recieved event set */
- thread_cb->thread.event_set &= thread_cb->flag_set;
- /* received an OR event */
- status = RT_EOK;
- }
- }
- /* condition is satisfied, resume thread */
- if (RT_EOK == status)
- {
- thread_cb->thread.event_info &= ~WAITING_THREAD_FLAGS;
- /* clear event */
- if (!(thread_cb->thread.event_info & osFlagsNoClear))
- thread_cb->flag_set &= ~thread_cb->thread.event_set;
- /* resume thread, and thread list breaks out */
- rt_thread_resume(rt_thread_self());
- need_schedule = RT_TRUE;
- }
- }
- rt_hw_interrupt_enable(level);
- if (need_schedule == RT_TRUE)
- rt_schedule();
- return return_value;
- }
- /// Clear the specified Thread Flags of current running thread.
- /// \param[in] flags specifies the flags of the thread that shall be cleared.
- /// \return thread flags before clearing or error code if highest bit set.
- uint32_t osThreadFlagsClear(uint32_t flags)
- {
- rt_thread_t thread = rt_thread_self();
- thread_cb_t *thread_cb;
- rt_uint32_t flag;
- /* Check parameters */
- if (RT_NULL == thread)
- {
- return osFlagsErrorParameter;
- }
- thread_cb = (thread_cb_t *)(thread->user_data);
- rt_enter_critical();
- flag = thread_cb->flag_set;
- thread_cb->flag_set &= ~flags;
- rt_exit_critical();
- return flag;
- }
- /// Get the current Thread Flags of current running thread.
- /// \return current thread flags.
- uint32_t osThreadFlagsGet(void)
- {
- rt_thread_t thread = rt_thread_self();
- thread_cb_t *thread_cb;
- /* Check parameters */
- if (RT_NULL == thread)
- {
- return osFlagsErrorParameter;
- }
- thread_cb = (thread_cb_t *)(thread->user_data);
- return thread_cb->flag_set;
- }
- /// Wait for one or more Thread Flags of the current running thread to become signaled.
- /// \param[in] flags specifies the flags to wait for.
- /// \param[in] options specifies flags options (osFlagsXxxx).
- /// \param[in] timeout \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out.
- /// \return thread flags before clearing or error code if highest bit set.
- uint32_t osThreadFlagsWait(uint32_t flags, uint32_t options, uint32_t timeout)
- {
- rt_uint32_t return_value;
- register rt_ubase_t level;
- register rt_base_t status = -RT_ERROR;
- rt_thread_t thread = rt_thread_self();
- thread_cb_t *thread_cb;
- /* Check parameters */
- if (RT_NULL == thread)
- {
- return osFlagsErrorParameter;
- }
- thread->error = RT_EOK;
- thread_cb = (thread_cb_t *)(thread->user_data);
- level = rt_hw_interrupt_disable();
- if (options & osFlagsWaitAll)
- {
- if ((thread_cb->flag_set & flags) == flags)
- status = RT_EOK;
- }
- else
- {
- if (thread_cb->flag_set & flags)
- status = RT_EOK;
- }
- if (RT_EOK == status)
- {
- return_value = thread_cb->flag_set & flags;
- if (!(options & osFlagsNoClear))
- thread_cb->flag_set &= ~flags;
- }
- else if (0U == timeout)
- {
- rt_hw_interrupt_enable(level);
- return osFlagsErrorResource;
- }
- else
- {
- thread->event_set = flags;
- thread->event_info = options | WAITING_THREAD_FLAGS;
- rt_thread_suspend(thread);
- /* if there is a waiting timeout, active thread timer */
- if ((timeout > 0U) && (timeout != osWaitForever))
- {
- /* reset the timeout of thread timer and start it */
- rt_timer_control(&(thread->thread_timer),
- RT_TIMER_CTRL_SET_TIME,
- &timeout);
- rt_timer_start(&(thread->thread_timer));
- }
- rt_hw_interrupt_enable(level);
- rt_schedule();
- if (thread->error != RT_EOK)
- {
- return thread->error;
- }
- level = rt_hw_interrupt_disable();
- return_value = thread->event_set;
- }
- rt_hw_interrupt_enable(level);
- return return_value;
- }
- // ==== Generic Wait Functions ====
- /// Wait for Timeout (Time Delay).
- /// \param[in] ticks \ref CMSIS_RTOS_TimeOutValue "time ticks" value
- /// \return status code that indicates the execution status of the function.
- osStatus_t osDelay(uint32_t ticks)
- {
- rt_thread_delay(ticks);
- return osOK;
- }
- /// Wait until specified time.
- /// \param[in] ticks absolute time in ticks
- /// \return status code that indicates the execution status of the function.
- osStatus_t osDelayUntil(uint32_t ticks)
- {
- uint64_t cur_ticks;
- cur_ticks = rt_tick_get();
- if (ticks == cur_ticks)
- {
- }
- else if (ticks > cur_ticks)
- {
- rt_thread_delay(ticks - cur_ticks);
- }
- else
- {
- rt_thread_delay(((rt_uint32_t) - 1) - cur_ticks + ticks);
- }
- return osOK;
- }
- // ==== Timer Management Functions ====
- /// Create and Initialize a timer.
- /// \param[in] func start address of a timer call back function.
- /// \param[in] type osTimerOnce for one-shot or osTimerPeriodic for periodic behavior.
- /// \param[in] argument argument to the timer call back function.
- /// \param[in] attr timer attributes; NULL: default values.
- /// \return timer ID for reference by other functions or NULL in case of error.
- osTimerId_t osTimerNew(osTimerFunc_t func, osTimerType_t type, void *argument, const osTimerAttr_t *attr)
- {
- timer_cb_t *timer_cb;
- char name[RT_NAME_MAX];
- static rt_uint16_t timer_number = 0U;
- rt_uint8_t flag = RT_TIMER_FLAG_SOFT_TIMER;
- /* Check parameters */
- if ((RT_NULL == func) || ((type != osTimerOnce) && (type != osTimerPeriodic)))
- {
- return RT_NULL;
- }
- /* RT-Thread object's name can't be NULL */
- if ((RT_NULL == attr) || (RT_NULL == attr->name))
- rt_snprintf(name, sizeof(name), "timer%02d", timer_number++);
- else
- rt_snprintf(name, sizeof(name), "%s", attr->name);
- if ((RT_NULL == attr) || (RT_NULL == attr->cb_mem))
- {
- timer_cb = rt_malloc(sizeof(timer_cb_t));
- if (RT_NULL == timer_cb)
- return RT_NULL;
- rt_memset(timer_cb, 0, sizeof(timer_cb_t));
- timer_cb->flags |= MALLOC_CB;
- }
- else
- {
- if (attr->cb_size >= sizeof(timer_cb_t))
- {
- timer_cb = attr->cb_mem;
- timer_cb->flags = 0;
- }
- else
- return RT_NULL;
- }
- if (osTimerPeriodic == type)
- {
- flag |= RT_TIMER_FLAG_PERIODIC;
- }
- rt_timer_init(&(timer_cb->timer), name, func, argument, 0, flag);
- return timer_cb;
- }
- /// Get name of a timer.
- /// \param[in] timer_id timer ID obtained by \ref osTimerNew.
- /// \return name as NULL terminated string.
- const char *osTimerGetName(osTimerId_t timer_id)
- {
- timer_cb_t *timer_cb;
- timer_cb = (timer_cb_t *)timer_id;
- /* Check parameters */
- if ((RT_NULL == timer_cb) || (rt_object_get_type(&timer_cb->timer.parent) != RT_Object_Class_Timer))
- {
- return RT_NULL;
- }
- return timer_cb->timer.parent.name;
- }
- /// Start or restart a timer.
- /// \param[in] timer_id timer ID obtained by \ref osTimerNew.
- /// \param[in] ticks \ref CMSIS_RTOS_TimeOutValue "time ticks" value of the timer.
- /// \return status code that indicates the execution status of the function.
- osStatus_t osTimerStart(osTimerId_t timer_id, uint32_t ticks)
- {
- rt_err_t result;
- timer_cb_t *timer_cb;
- timer_cb = (timer_cb_t *)timer_id;
- /* Check parameters */
- if ((RT_NULL == timer_cb) || (ticks == 0))
- {
- return osErrorParameter;
- }
- rt_timer_control(&(timer_cb->timer), RT_TIMER_CTRL_SET_TIME, &ticks);
- result = rt_timer_start(&(timer_cb->timer));
- if (RT_EOK == result)
- return osOK;
- else
- return osError;
- }
- /// Stop a timer.
- /// \param[in] timer_id timer ID obtained by \ref osTimerNew.
- /// \return status code that indicates the execution status of the function.
- osStatus_t osTimerStop(osTimerId_t timer_id)
- {
- rt_err_t result;
- timer_cb_t *timer_cb;
- timer_cb = (timer_cb_t *)timer_id;
- /* Check parameters */
- if (RT_NULL == timer_cb)
- {
- return osErrorParameter;
- }
- result = rt_timer_stop(&(timer_cb->timer));
- if (RT_EOK == result)
- return osOK;
- else
- return osError;
- }
- /// Check if a timer is running.
- /// \param[in] timer_id timer ID obtained by \ref osTimerNew.
- /// \return 0 not running, 1 running.
- uint32_t osTimerIsRunning(osTimerId_t timer_id)
- {
- timer_cb_t *timer_cb;
- timer_cb = (timer_cb_t *)timer_id;
- /* Check parameters */
- if ((RT_NULL == timer_cb) || (rt_object_get_type(&timer_cb->timer.parent) != RT_Object_Class_Timer))
- {
- return 0U;
- }
- if ((timer_cb->timer.parent.flag & RT_TIMER_FLAG_ACTIVATED) == 1u)
- {
- return 1;
- }
- else
- return 0U;
- }
- /// Delete a timer.
- /// \param[in] timer_id timer ID obtained by \ref osTimerNew.
- /// \return status code that indicates the execution status of the function.
- osStatus_t osTimerDelete(osTimerId_t timer_id)
- {
- timer_cb_t *timer_cb;
- timer_cb = (timer_cb_t *)timer_id;
- /* Check parameters */
- if (RT_NULL == timer_cb)
- {
- return osErrorParameter;
- }
- rt_timer_detach(&(timer_cb->timer));
- if (timer_cb->flags & MALLOC_CB)
- rt_free(timer_cb);
- return osOK;
- }
- #ifdef RT_USING_EVENT
- // ==== Event Flags Management Functions ====
- /// Create and Initialize an Event Flags object.
- /// \param[in] attr event flags attributes; NULL: default values.
- /// \return event flags ID for reference by other functions or NULL in case of error.
- osEventFlagsId_t osEventFlagsNew(const osEventFlagsAttr_t *attr)
- {
- char name[RT_NAME_MAX];
- event_cb_t *event_cb;
- static rt_uint16_t event_number = 0U;
- if ((RT_NULL == attr) || (RT_NULL == attr->name))
- {
- rt_snprintf(name, sizeof(name), "event%02d", event_number++);
- }
- else
- rt_snprintf(name, sizeof(name), "%s", attr->name);
- if ((RT_NULL == attr) || (RT_NULL == attr->cb_mem))
- {
- event_cb = rt_malloc(sizeof(event_cb_t));
- if (RT_NULL == event_cb)
- return RT_NULL;
- rt_memset(event_cb, 0, sizeof(event_cb_t));
- event_cb->flags |= MALLOC_CB;
- }
- else
- {
- if (attr->cb_size >= sizeof(event_cb_t))
- {
- event_cb = attr->cb_mem;
- event_cb->flags = 0;
- }
- else
- return RT_NULL;
- }
- rt_event_init(&(event_cb->event), name, RT_IPC_FLAG_FIFO);
- return event_cb;
- }
- /// Get name of an Event Flags object.
- /// \param[in] ef_id event flags ID obtained by \ref osEventFlagsNew.
- /// \return name as NULL terminated string.
- const char *osEventFlagsGetName(osEventFlagsId_t ef_id)
- {
- event_cb_t *event_cb = (event_cb_t *)ef_id;
- /* Check parameters */
- if ((RT_NULL == event_cb) || (rt_object_get_type(&event_cb->event.parent.parent) != RT_Object_Class_Event))
- {
- return RT_NULL;
- }
- return event_cb->event.parent.parent.name;
- }
- /// Set the specified Event Flags.
- /// \param[in] ef_id event flags ID obtained by \ref osEventFlagsNew.
- /// \param[in] flags specifies the flags that shall be set.
- /// \return event flags after setting or error code if highest bit set.
- uint32_t osEventFlagsSet(osEventFlagsId_t ef_id, uint32_t flags)
- {
- rt_err_t result;
- rt_uint32_t set_flags;
- event_cb_t *event_cb = (event_cb_t *)ef_id;
- /* Check parameters */
- if ((RT_NULL == event_cb) || (rt_object_get_type(&event_cb->event.parent.parent) != RT_Object_Class_Event))
- {
- return ((uint32_t)osFlagsErrorParameter);
- }
- set_flags = event_cb->event.set |= flags;
- result = rt_event_send(&(event_cb->event), flags);
- if (RT_EOK == result)
- return set_flags;
- else
- return osFlagsError;
- }
- /// Clear the specified Event Flags.
- /// \param[in] ef_id event flags ID obtained by \ref osEventFlagsNew.
- /// \param[in] flags specifies the flags that shall be cleared.
- /// \return event flags before clearing or error code if highest bit set.
- uint32_t osEventFlagsClear(osEventFlagsId_t ef_id, uint32_t flags)
- {
- rt_uint32_t set_flags;
- register rt_ubase_t level;
- event_cb_t *event_cb = (event_cb_t *)ef_id;
- /* Check parameters */
- if ((RT_NULL == event_cb) || (rt_object_get_type(&event_cb->event.parent.parent) != RT_Object_Class_Event))
- {
- return ((uint32_t)osFlagsErrorParameter);
- }
- set_flags = event_cb->event.set;
- level = rt_hw_interrupt_disable();
- event_cb->event.set &= ~flags;
- rt_hw_interrupt_enable(level);
- return set_flags;
- }
- /// Get the current Event Flags.
- /// \param[in] ef_id event flags ID obtained by \ref osEventFlagsNew.
- /// \return current event flags.
- uint32_t osEventFlagsGet(osEventFlagsId_t ef_id)
- {
- event_cb_t *event_cb = (event_cb_t *)ef_id;
- /* Check parameters */
- if ((RT_NULL == event_cb) || (rt_object_get_type(&event_cb->event.parent.parent) != RT_Object_Class_Event))
- {
- return 0U;
- }
- return event_cb->event.set;
- }
- /// Wait for one or more Event Flags to become signaled.
- /// \param[in] ef_id event flags ID obtained by \ref osEventFlagsNew.
- /// \param[in] flags specifies the flags to wait for.
- /// \param[in] options specifies flags options (osFlagsXxxx).
- /// \param[in] timeout \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out.
- /// \return event flags before clearing or error code if highest bit set.
- uint32_t osEventFlagsWait(osEventFlagsId_t ef_id, uint32_t flags, uint32_t options, uint32_t timeout)
- {
- rt_err_t result;
- rt_uint32_t rt_recv;
- rt_uint8_t rt_options = 0U;
- event_cb_t *event_cb = (event_cb_t *)ef_id;
- /* Check parameters */
- if (RT_NULL == event_cb)
- {
- return ((uint32_t)osFlagsErrorParameter);
- }
- if (options & osFlagsWaitAll)
- {
- rt_options |= RT_EVENT_FLAG_AND;
- }
- else
- {
- rt_options |= RT_EVENT_FLAG_OR;
- }
- if (!(options & osFlagsNoClear))
- {
- rt_options |= RT_EVENT_FLAG_CLEAR;
- }
- result = rt_event_recv(&(event_cb->event), flags, (rt_uint8_t)rt_options, timeout, &rt_recv);
- if (RT_EOK == result)
- return rt_recv;
- else if (-RT_ETIMEOUT == result)
- {
- if (0U == timeout)
- return osFlagsErrorResource;
- else
- return osFlagsErrorTimeout;
- }
- else
- return osFlagsErrorUnknown;
- }
- /// Delete an Event Flags object.
- /// \param[in] ef_id event flags ID obtained by \ref osEventFlagsNew.
- /// \return status code that indicates the execution status of the function.
- osStatus_t osEventFlagsDelete(osEventFlagsId_t ef_id)
- {
- event_cb_t *event_cb = (event_cb_t *)ef_id;
- /* Check parameters */
- if (RT_NULL == event_cb)
- {
- return osErrorParameter;
- }
- rt_event_detach(&(event_cb->event));
- if (event_cb->flags & MALLOC_CB)
- rt_free(event_cb);
- return osOK;
- }
- #endif
- #ifdef RT_USING_MUTEX
- // ==== Mutex Management Functions ====
- /// Create and Initialize a Mutex object.
- /// \param[in] attr mutex attributes; NULL: default values.
- /// \return mutex ID for reference by other functions or NULL in case of error.
- osMutexId_t osMutexNew(const osMutexAttr_t *attr)
- {
- char name[RT_NAME_MAX];
- mutex_cb_t *mutex_cb;
- static rt_uint16_t mutex_number = 0U;
- if ((RT_NULL == attr) || (RT_NULL == attr->name))
- {
- rt_snprintf(name, sizeof(name), "mutex%02d", mutex_number++);
- }
- else
- rt_snprintf(name, sizeof(name), "%s", attr->name);
- if ((RT_NULL == attr) || (RT_NULL == attr->cb_mem))
- {
- mutex_cb = rt_malloc(sizeof(mutex_cb_t));
- if (RT_NULL == mutex_cb)
- return RT_NULL;
- rt_memset(mutex_cb, 0, sizeof(mutex_cb_t));
- mutex_cb->flags |= MALLOC_CB;
- }
- else
- {
- if (attr->cb_size >= sizeof(mutex_cb_t))
- {
- mutex_cb = attr->cb_mem;
- mutex_cb->flags = 0;
- }
- else
- return RT_NULL;
- }
- if ((RT_NULL == attr) || (0 == attr->attr_bits))
- {
- mutex_cb->flags |= osMutexRecursive;
- }
- else
- mutex_cb->flags |= attr->attr_bits;
- rt_mutex_init(&(mutex_cb->mutex), name, RT_IPC_FLAG_FIFO);
- return mutex_cb;
- }
- /// Get name of a Mutex object.
- /// \param[in] mutex_id mutex ID obtained by \ref osMutexNew.
- /// \return name as NULL terminated string.
- const char *osMutexGetName(osMutexId_t mutex_id)
- {
- mutex_cb_t *mutex_cb = (mutex_cb_t *)mutex_id;
- /* Check parameters */
- if ((RT_NULL == mutex_cb) || (rt_object_get_type(&mutex_cb->mutex.parent.parent) != RT_Object_Class_Mutex))
- {
- return RT_NULL;
- }
- return mutex_cb->mutex.parent.parent.name;
- }
- /// Acquire a Mutex or timeout if it is locked.
- /// \param[in] mutex_id mutex ID obtained by \ref osMutexNew.
- /// \param[in] timeout \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out.
- /// \return status code that indicates the execution status of the function.
- osStatus_t osMutexAcquire(osMutexId_t mutex_id, uint32_t timeout)
- {
- rt_err_t result;
- mutex_cb_t *mutex_cb = (mutex_cb_t *)mutex_id;
- /* Check parameters */
- if (RT_NULL == mutex_cb)
- {
- return osErrorParameter;
- }
- rt_enter_critical();
- if ((mutex_cb->mutex.owner == rt_thread_self()) && !(mutex_cb->flags & osMutexRecursive))
- {
- rt_exit_critical();
- return osError;
- }
- rt_exit_critical();
- result = rt_mutex_take(&(mutex_cb->mutex), timeout);
- if (RT_EOK == result)
- return osOK;
- else if (-RT_ETIMEOUT == result)
- {
- if (0U == timeout)
- return osErrorResource;
- else
- return osErrorTimeout;
- }
- else
- return osError;
- }
- /// Release a Mutex that was acquired by \ref osMutexAcquire.
- /// \param[in] mutex_id mutex ID obtained by \ref osMutexNew.
- /// \return status code that indicates the execution status of the function.
- osStatus_t osMutexRelease(osMutexId_t mutex_id)
- {
- rt_err_t result;
- mutex_cb_t *mutex_cb = (mutex_cb_t *)mutex_id;
- /* Check parameters */
- if (RT_NULL == mutex_cb)
- {
- return osErrorParameter;
- }
- result = rt_mutex_release(&(mutex_cb->mutex));
- if (RT_EOK == result)
- return osOK;
- else
- return osErrorResource;
- }
- /// Get Thread which owns a Mutex object.
- /// \param[in] mutex_id mutex ID obtained by \ref osMutexNew.
- /// \return thread ID of owner thread or NULL when mutex was not acquired.
- osThreadId_t osMutexGetOwner(osMutexId_t mutex_id)
- {
- mutex_cb_t *mutex_cb = (mutex_cb_t *)mutex_id;
- /* Check parameters */
- if ((RT_NULL == mutex_cb) || (rt_object_get_type(&mutex_cb->mutex.parent.parent) != RT_Object_Class_Mutex))
- {
- return RT_NULL;
- }
- return mutex_cb->mutex.owner;
- }
- /// Delete a Mutex object.
- /// \param[in] mutex_id mutex ID obtained by \ref osMutexNew.
- /// \return status code that indicates the execution status of the function.
- osStatus_t osMutexDelete(osMutexId_t mutex_id)
- {
- mutex_cb_t *mutex_cb = (mutex_cb_t *)mutex_id;
- /* Check parameters */
- if (RT_NULL == mutex_cb)
- {
- return osErrorParameter;
- }
- rt_mutex_detach(&(mutex_cb->mutex));
- if (mutex_cb->flags & MALLOC_CB)
- rt_free(mutex_cb);
- return osOK;
- }
- #endif
- #ifdef RT_USING_SEMAPHORE
- osSemaphoreId_t osSemaphoreNew(uint32_t max_count, uint32_t initial_count, const osSemaphoreAttr_t *attr)
- {
- char name[RT_NAME_MAX];
- sem_cb_t *sem_cb;
- static rt_uint16_t semaphore_number = 0U;
- /* Check parameters */
- if ((0U == max_count) || (initial_count > max_count))
- {
- return RT_NULL;
- }
- if ((RT_NULL == attr) || (RT_NULL == attr->name))
- {
- rt_snprintf(name, sizeof(name), "sem%02d", semaphore_number++);
- }
- else
- rt_snprintf(name, sizeof(name), "%s", attr->name);
- if ((RT_NULL == attr) || (RT_NULL == attr->cb_mem))
- {
- sem_cb = rt_malloc(sizeof(sem_cb_t));
- if (RT_NULL == sem_cb)
- return RT_NULL;
- rt_memset(sem_cb, 0, sizeof(sem_cb_t));
- sem_cb->flags |= MALLOC_CB;
- }
- else
- {
- if (attr->cb_size >= sizeof(sem_cb_t))
- {
- sem_cb = attr->cb_mem;
- sem_cb->flags = 0;
- }
- else
- return RT_NULL;
- }
- rt_sem_init(&(sem_cb->sem), name, initial_count, RT_IPC_FLAG_FIFO);
- return sem_cb;
- }
- /// Get name of a Semaphore object.
- /// \param[in] semaphore_id semaphore ID obtained by \ref osSemaphoreNew.
- /// \return name as NULL terminated string.
- const char *osSemaphoreGetName(osSemaphoreId_t semaphore_id)
- {
- sem_cb_t *sem_cb = (sem_cb_t *)semaphore_id;
- /* Check parameters */
- if ((RT_NULL == sem_cb) || (rt_object_get_type(&sem_cb->sem.parent.parent) != RT_Object_Class_Semaphore))
- {
- return RT_NULL;
- }
- return sem_cb->sem.parent.parent.name;
- }
- /// Acquire a Semaphore token or timeout if no tokens are available.
- /// \param[in] semaphore_id semaphore ID obtained by \ref osSemaphoreNew.
- /// \param[in] timeout \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out.
- /// \return status code that indicates the execution status of the function.
- osStatus_t osSemaphoreAcquire(osSemaphoreId_t semaphore_id, uint32_t timeout)
- {
- rt_err_t result;
- sem_cb_t *sem_cb = (sem_cb_t *)semaphore_id;
- /* Check parameters */
- if (RT_NULL == sem_cb)
- {
- return osErrorParameter;
- }
- result = rt_sem_take(&(sem_cb->sem), timeout);
- if (RT_EOK == result)
- return osOK;
- else if (-RT_ETIMEOUT == result)
- {
- if (0U == timeout)
- return osErrorResource;
- else
- return osErrorTimeout;
- }
- else
- return osError;
- }
- /// Release a Semaphore token that was acquired by \ref osSemaphoreAcquire.
- /// \param[in] semaphore_id semaphore ID obtained by \ref osSemaphoreNew.
- /// \return status code that indicates the execution status of the function.
- osStatus_t osSemaphoreRelease(osSemaphoreId_t semaphore_id)
- {
- rt_err_t result;
- sem_cb_t *sem_cb = (sem_cb_t *)semaphore_id;
- /* Check parameters */
- if (RT_NULL == sem_cb)
- {
- return osErrorParameter;
- }
- result = rt_sem_release(&(sem_cb->sem));
- if (RT_EOK == result)
- return osOK;
- else
- return osError;
- }
- /// Get current Semaphore token count.
- /// \param[in] semaphore_id semaphore ID obtained by \ref osSemaphoreNew.
- /// \return number of tokens available.
- uint32_t osSemaphoreGetCount(osSemaphoreId_t semaphore_id)
- {
- sem_cb_t *sem_cb = (sem_cb_t *)semaphore_id;
- /* Check parameters */
- if ((RT_NULL == sem_cb) || (rt_object_get_type(&sem_cb->sem.parent.parent) != RT_Object_Class_Semaphore))
- {
- return 0U;
- }
- return sem_cb->sem.value;
- }
- /// Delete a Semaphore object.
- /// \param[in] semaphore_id semaphore ID obtained by \ref osSemaphoreNew.
- /// \return status code that indicates the execution status of the function.
- osStatus_t osSemaphoreDelete(osSemaphoreId_t semaphore_id)
- {
- sem_cb_t *sem_cb = (sem_cb_t *)semaphore_id;
- /* Check parameters */
- if (RT_NULL == sem_cb)
- {
- return osErrorParameter;
- }
- rt_sem_detach(&(sem_cb->sem));
- if (sem_cb->flags & MALLOC_CB)
- rt_free(sem_cb);
- return osOK;
- }
- #endif
- #ifdef RT_USING_MEMPOOL
- // ==== Memory Pool Management Functions ====
- /// Create and Initialize a Memory Pool object.
- /// \param[in] block_count maximum number of memory blocks in memory pool.
- /// \param[in] block_size memory block size in bytes.
- /// \param[in] attr memory pool attributes; NULL: default values.
- /// \return memory pool ID for reference by other functions or NULL in case of error.
- osMemoryPoolId_t osMemoryPoolNew(uint32_t block_count, uint32_t block_size, const osMemoryPoolAttr_t *attr)
- {
- char name[RT_NAME_MAX];
- void *mp_addr;
- rt_uint32_t mp_size;
- mempool_cb_t *mempool_cb;
- static rt_uint16_t memory_pool_number = 0U;
- /* Check parameters */
- if ((0U == block_count) || (0U == block_size))
- {
- return RT_NULL;
- }
- if ((RT_NULL == attr) || (RT_NULL == attr->name))
- {
- rt_snprintf(name, sizeof(name), "mp%02d", memory_pool_number++);
- }
- else
- rt_snprintf(name, sizeof(name), "%s", attr->name);
- if ((RT_NULL == attr) || (RT_NULL == attr->cb_mem))
- {
- mempool_cb = rt_malloc(sizeof(mempool_cb_t));
- if (RT_NULL == mempool_cb)
- return RT_NULL;
- rt_memset(mempool_cb, 0, sizeof(mempool_cb_t));
- mempool_cb->flags |= MALLOC_CB;
- }
- else
- {
- if (attr->cb_size >= sizeof(mempool_cb_t))
- {
- mempool_cb = attr->cb_mem;
- mempool_cb->flags = 0;
- }
- else
- return RT_NULL;
- }
- if ((RT_NULL == attr) || (RT_NULL == attr->mp_mem))
- {
- block_size = RT_ALIGN(block_size, RT_ALIGN_SIZE);
- mp_size = (block_size + sizeof(rt_uint8_t *)) * block_count;
- mp_addr = rt_malloc((block_size + sizeof(rt_uint8_t *)) * block_count);
- if (RT_NULL == mp_addr)
- {
- if (mempool_cb->flags & MALLOC_CB)
- rt_free(mempool_cb);
- return RT_NULL;
- }
- mempool_cb->flags |= MALLOC_MEM;
- }
- else
- {
- mp_addr = (void *)(attr->mp_mem);
- mp_size = attr->mp_size;
- }
- rt_mp_init(&(mempool_cb->mp), name, mp_addr, mp_size, block_size);
- return mempool_cb;
- }
- /// Get name of a Memory Pool object.
- /// \param[in] mp_id memory pool ID obtained by \ref osMemoryPoolNew.
- /// \return name as NULL terminated string.
- const char *osMemoryPoolGetName(osMemoryPoolId_t mp_id)
- {
- mempool_cb_t *mempool_cb = (mempool_cb_t *)mp_id;
- /* Check parameters */
- if ((RT_NULL == mempool_cb) || (rt_object_get_type(&mempool_cb->mp.parent) != RT_Object_Class_MemPool))
- {
- return RT_NULL;
- }
- return mempool_cb->mp.parent.name;
- }
- /// Allocate a memory block from a Memory Pool.
- /// \param[in] mp_id memory pool ID obtained by \ref osMemoryPoolNew.
- /// \param[in] timeout \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out.
- /// \return address of the allocated memory block or NULL in case of no memory is available.
- void *osMemoryPoolAlloc(osMemoryPoolId_t mp_id, uint32_t timeout)
- {
- mempool_cb_t *mempool_cb = (mempool_cb_t *)mp_id;
- /* Check parameters */
- if (RT_NULL == mempool_cb)
- {
- return RT_NULL;
- }
- return rt_mp_alloc(&(mempool_cb->mp), timeout);
- }
- /// Return an allocated memory block back to a Memory Pool.
- /// \param[in] mp_id memory pool ID obtained by \ref osMemoryPoolNew.
- /// \param[in] block address of the allocated memory block to be returned to the memory pool.
- /// \return status code that indicates the execution status of the function.
- osStatus_t osMemoryPoolFree(osMemoryPoolId_t mp_id, void *block)
- {
- mempool_cb_t *mempool_cb = (mempool_cb_t *)mp_id;
- /* Check parameters */
- if (RT_NULL == mempool_cb)
- {
- return osErrorParameter;
- }
- rt_mp_free(block);
- return osOK;
- }
- /// Get maximum number of memory blocks in a Memory Pool.
- /// \param[in] mp_id memory pool ID obtained by \ref osMemoryPoolNew.
- /// \return maximum number of memory blocks.
- uint32_t osMemoryPoolGetCapacity(osMemoryPoolId_t mp_id)
- {
- mempool_cb_t *mempool_cb = (mempool_cb_t *)mp_id;
- /* Check parameters */
- if ((RT_NULL == mempool_cb) || (rt_object_get_type(&mempool_cb->mp.parent) != RT_Object_Class_MemPool))
- {
- return 0U;
- }
- return mempool_cb->mp.block_total_count;
- }
- /// Get memory block size in a Memory Pool.
- /// \param[in] mp_id memory pool ID obtained by \ref osMemoryPoolNew.
- /// \return memory block size in bytes.
- uint32_t osMemoryPoolGetBlockSize(osMemoryPoolId_t mp_id)
- {
- mempool_cb_t *mempool_cb = (mempool_cb_t *)mp_id;
- /* Check parameters */
- if ((RT_NULL == mempool_cb) || (rt_object_get_type(&mempool_cb->mp.parent) != RT_Object_Class_MemPool))
- {
- return 0U;
- }
- return mempool_cb->mp.block_size;
- }
- /// Get number of memory blocks used in a Memory Pool.
- /// \param[in] mp_id memory pool ID obtained by \ref osMemoryPoolNew.
- /// \return number of memory blocks used.
- uint32_t osMemoryPoolGetCount(osMemoryPoolId_t mp_id)
- {
- rt_size_t used_blocks;
- mempool_cb_t *mempool_cb = (mempool_cb_t *)mp_id;
- /* Check parameters */
- if ((RT_NULL == mempool_cb) || (rt_object_get_type(&mempool_cb->mp.parent) != RT_Object_Class_MemPool))
- {
- return 0U;
- }
- used_blocks = mempool_cb->mp.block_total_count - mempool_cb->mp.block_free_count;
- return (uint32_t)used_blocks;
- }
- /// Get number of memory blocks available in a Memory Pool.
- /// \param[in] mp_id memory pool ID obtained by \ref osMemoryPoolNew.
- /// \return number of memory blocks available.
- uint32_t osMemoryPoolGetSpace(osMemoryPoolId_t mp_id)
- {
- mempool_cb_t *mempool_cb = (mempool_cb_t *)mp_id;
- /* Check parameters */
- if ((RT_NULL == mempool_cb) || (rt_object_get_type(&mempool_cb->mp.parent) != RT_Object_Class_MemPool))
- {
- return 0U;
- }
- return mempool_cb->mp.block_free_count;
- }
- /// Delete a Memory Pool object.
- /// \param[in] mp_id memory pool ID obtained by \ref osMemoryPoolNew.
- /// \return status code that indicates the execution status of the function.
- osStatus_t osMemoryPoolDelete(osMemoryPoolId_t mp_id)
- {
- mempool_cb_t *mempool_cb = (mempool_cb_t *)mp_id;
- /* Check parameters */
- if (RT_NULL == mempool_cb)
- {
- return osErrorParameter;
- }
- rt_mp_detach(&(mempool_cb->mp));
- if (mempool_cb->flags & MALLOC_CB)
- rt_free(mempool_cb);
- if (mempool_cb->flags & MALLOC_MEM)
- rt_free(mempool_cb->mp.start_address);
- return osOK;
- }
- #endif
- #ifdef RT_USING_MESSAGEQUEUE
- // ==== Message Queue Management Functions ====
- /// Create and Initialize a Message Queue object.
- /// \param[in] msg_count maximum number of messages in queue.
- /// \param[in] msg_size maximum message size in bytes.
- /// \param[in] attr message queue attributes; NULL: default values.
- /// \return message queue ID for reference by other functions or NULL in case of error.
- osMessageQueueId_t osMessageQueueNew(uint32_t msg_count, uint32_t msg_size, const osMessageQueueAttr_t *attr)
- {
- char name[RT_NAME_MAX];
- mq_cb_t *mq_cb;
- void *mq_addr;
- rt_uint32_t mq_size;
- static rt_uint16_t mq_number = 0U;
- /* Check parameters */
- if ((0U == msg_count) || (0U == msg_size))
- {
- return RT_NULL;
- }
- if ((RT_NULL == attr) || (RT_NULL == attr->name))
- {
- rt_snprintf(name, sizeof(name), "mq%02d", mq_number++);
- }
- else
- rt_snprintf(name, sizeof(name), "%s", attr->name);
- if ((RT_NULL == attr) || (RT_NULL == attr->cb_mem))
- {
- mq_cb = rt_malloc(sizeof(mq_cb_t));
- if (RT_NULL == mq_cb)
- return RT_NULL;
- rt_memset(mq_cb, 0, sizeof(mq_cb_t));
- mq_cb->flags |= MALLOC_CB;
- }
- else
- {
- if (attr->cb_size >= sizeof(mq_cb_t))
- {
- mq_cb = attr->cb_mem;
- mq_cb->flags = 0;
- }
- else
- return RT_NULL;
- }
- mq_cb->init_msg_size = msg_size;
- if ((RT_NULL == attr) || (RT_NULL == attr->mq_mem))
- {
- register rt_size_t msg_align_size;
- /* get correct message size */
- msg_align_size = RT_ALIGN(msg_size, RT_ALIGN_SIZE);
- mq_size = (msg_align_size + sizeof(struct rt_mq_message)) * msg_count;
- mq_addr = rt_malloc(mq_size);
- if (RT_NULL == mq_addr)
- {
- if (mq_cb->flags & MALLOC_CB)
- rt_free(mq_cb);
- return RT_NULL;
- }
- rt_memset(mq_addr, 0, sizeof(mq_size));
- mq_cb->flags |= MALLOC_MEM;
- }
- else
- {
- mq_addr = (void *)(attr->mq_mem);
- mq_size = attr->mq_size;
- }
- rt_mq_init(&(mq_cb->mq), name, mq_addr, msg_size, mq_size, RT_IPC_FLAG_FIFO);
- return mq_cb;
- }
- /// Get name of a Message Queue object.
- /// \param[in] mq_id message queue ID obtained by \ref osMessageQueueNew.
- /// \return name as NULL terminated string.
- const char *osMessageQueueGetName(osMessageQueueId_t mq_id)
- {
- mq_cb_t *mq_cb = (mq_cb_t *)mq_id;
- /* Check parameters */
- if ((RT_NULL == mq_cb) || (rt_object_get_type(&mq_cb->mq.parent.parent) != RT_Object_Class_MessageQueue))
- {
- return RT_NULL;
- }
- return mq_cb->mq.parent.parent.name;
- }
- /// Put a Message into a Queue or timeout if Queue is full.
- /// \param[in] mq_id message queue ID obtained by \ref osMessageQueueNew.
- /// \param[in] msg_ptr pointer to buffer with message to put into a queue.
- /// \param[in] msg_prio message priority.
- /// \param[in] timeout \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out.
- /// \return status code that indicates the execution status of the function.
- osStatus_t osMessageQueuePut(osMessageQueueId_t mq_id, const void *msg_ptr, uint8_t msg_prio, uint32_t timeout)
- {
- rt_err_t result;
- mq_cb_t *mq_cb = (mq_cb_t *)mq_id;
- /* Check parameters */
- if (RT_NULL == mq_cb || (RT_NULL == msg_ptr))
- {
- return osErrorParameter;
- }
- result = rt_mq_send(&(mq_cb->mq), (void *)msg_ptr, mq_cb->init_msg_size);
- if (RT_EOK == result)
- return osOK;
- else if (-RT_EFULL == result)
- return osErrorResource;
- else
- return osError;
- }
- /// Get a Message from a Queue or timeout if Queue is empty.
- /// \param[in] mq_id message queue ID obtained by \ref osMessageQueueNew.
- /// \param[out] msg_ptr pointer to buffer for message to get from a queue.
- /// \param[out] msg_prio pointer to buffer for message priority or NULL.
- /// \param[in] timeout \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out.
- /// \return status code that indicates the execution status of the function.
- #if defined(RT_VERSION_CHECK) && (RTTHREAD_VERSION >= RT_VERSION_CHECK(5, 0, 1))
- osStatus_t osMessageQueueGet(osMessageQueueId_t mq_id, void *msg_ptr, uint8_t *msg_prio, uint32_t timeout)
- {
- rt_ssize_t result = 0;
- mq_cb_t *mq_cb = (mq_cb_t *)mq_id;
- /* Check parameters */
- if (RT_NULL == mq_cb || (RT_NULL == msg_ptr))
- {
- return osErrorParameter;
- }
- result = rt_mq_recv(&(mq_cb->mq), msg_ptr, mq_cb->init_msg_size, timeout);
- if (result > 0)
- {
- return osOK;
- }
- else
- {
- return osError;
- }
- }
- #else /* legacy version macros (<5.0.1) */
- osStatus_t osMessageQueueGet(osMessageQueueId_t mq_id, void *msg_ptr, uint8_t *msg_prio, uint32_t timeout)
- {
- rt_err_t result;
- mq_cb_t *mq_cb = (mq_cb_t *)mq_id;
- /* Check parameters */
- if (RT_NULL == mq_cb || (RT_NULL == msg_ptr))
- {
- return osErrorParameter;
- }
- result = rt_mq_recv(&(mq_cb->mq), msg_ptr, mq_cb->init_msg_size, timeout);
- if (RT_EOK == result)
- return osOK;
- else if (-RT_ETIMEOUT == result)
- {
- if (0U == timeout)
- return osErrorResource;
- return osErrorTimeout;
- }
- else
- return osError;
- }
- #endif
- /// Get maximum number of messages in a Message Queue.
- /// \param[in] mq_id message queue ID obtained by \ref osMessageQueueNew.
- /// \return maximum number of messages.
- uint32_t osMessageQueueGetCapacity(osMessageQueueId_t mq_id)
- {
- mq_cb_t *mq_cb = (mq_cb_t *)mq_id;
- /* Check parameters */
- if ((RT_NULL == mq_cb) || (rt_object_get_type(&mq_cb->mq.parent.parent) != RT_Object_Class_MessageQueue))
- {
- return 0U;
- }
- return mq_cb->mq.max_msgs;
- }
- /// Get maximum message size in a Memory Pool.
- /// \param[in] mq_id message queue ID obtained by \ref osMessageQueueNew.
- /// \return maximum message size in bytes.
- uint32_t osMessageQueueGetMsgSize(osMessageQueueId_t mq_id)
- {
- mq_cb_t *mq_cb = (mq_cb_t *)mq_id;
- /* Check parameters */;
- if ((RT_NULL == mq_cb) || (rt_object_get_type(&mq_cb->mq.parent.parent) != RT_Object_Class_MessageQueue))
- {
- return 0U;
- }
- return mq_cb->mq.msg_size;
- }
- /// Get number of queued messages in a Message Queue.
- /// \param[in] mq_id message queue ID obtained by \ref osMessageQueueNew.
- /// \return number of queued messages.
- uint32_t osMessageQueueGetCount(osMessageQueueId_t mq_id)
- {
- mq_cb_t *mq_cb = (mq_cb_t *)mq_id;
- /* Check parameters */;
- if ((RT_NULL == mq_cb) || (rt_object_get_type(&mq_cb->mq.parent.parent) != RT_Object_Class_MessageQueue))
- {
- return 0U;
- }
- return mq_cb->mq.entry;
- }
- /// Get number of available slots for messages in a Message Queue.
- /// \param[in] mq_id message queue ID obtained by \ref osMessageQueueNew.
- /// \return number of available slots for messages.
- uint32_t osMessageQueueGetSpace(osMessageQueueId_t mq_id)
- {
- mq_cb_t *mq_cb = (mq_cb_t *)mq_id;
- /* Check parameters */;
- if ((RT_NULL == mq_cb) || (rt_object_get_type(&mq_cb->mq.parent.parent) != RT_Object_Class_MessageQueue))
- {
- return 0U;
- }
- return (mq_cb->mq.max_msgs - mq_cb->mq.entry);
- }
- /// Reset a Message Queue to initial empty state.
- /// \param[in] mq_id message queue ID obtained by \ref osMessageQueueNew.
- /// \return status code that indicates the execution status of the function.
- osStatus_t osMessageQueueReset(osMessageQueueId_t mq_id)
- {
- rt_err_t result;
- mq_cb_t *mq_cb = (mq_cb_t *)mq_id;
- /* Check parameters */;
- if (RT_NULL == mq_cb)
- {
- return osErrorParameter;
- }
- result = rt_mq_control(&(mq_cb->mq), RT_IPC_CMD_RESET, RT_NULL);
- if (RT_EOK == result)
- return osOK;
- else
- return osError;
- }
- /// Delete a Message Queue object.
- /// \param[in] mq_id message queue ID obtained by \ref osMessageQueueNew.
- /// \return status code that indicates the execution status of the function.
- osStatus_t osMessageQueueDelete(osMessageQueueId_t mq_id)
- {
- mq_cb_t *mq_cb = (mq_cb_t *)mq_id;
- /* Check parameters */;
- if (RT_NULL == mq_cb)
- {
- return osErrorParameter;
- }
- rt_mq_detach(&(mq_cb->mq));
- if (mq_cb->flags & MALLOC_CB)
- rt_free(mq_cb);
- if (mq_cb->flags & MALLOC_MEM)
- rt_free(mq_cb->mq.msg_pool);
- return osOK;
- }
- #endif
|