| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359 |
- /*
- * Copyright (c) 2006-2025, 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
- * 2025-08-18 wdfk_prog fix osDelay bug
- */
- #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 (CMSIS_RT_SCHED_CTX(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 ((CMSIS_RT_SCHED_CTX(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);
- return osOK;
- }
- else if (-RT_ETIMEOUT == result)
- {
- return osErrorTimeout;
- }
- else
- {
- return osError;
- }
- }
- /// 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(&(thread_cb->thread));
- 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)
- {
- if (rt_interrupt_get_nest() != 0)
- {
- return osErrorISR;
- }
- else
- {
- if(rt_thread_delay(ticks) != RT_EOK)
- {
- return osError;
- }
- else
- {
- 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;
- }
- if(timeout == osWaitForever)
- {
- timeout = RT_WAITING_FOREVER;
- }
- 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();
- if(timeout == osWaitForever)
- {
- timeout = RT_WAITING_FOREVER;
- }
- 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;
- }
- if(timeout == osWaitForever)
- {
- timeout = RT_WAITING_FOREVER;
- }
- 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;
- }
- if(timeout == osWaitForever)
- {
- timeout = RT_WAITING_FOREVER;
- }
- 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;
- }
- if(timeout == osWaitForever)
- {
- timeout = RT_WAITING_FOREVER;
- }
- result = rt_mq_send_wait(&(mq_cb->mq), (void *)msg_ptr, mq_cb->init_msg_size, timeout);
- if (RT_EOK == result)
- return osOK;
- else if (-RT_EFULL == result)
- return osErrorResource;
- else if (-RT_ETIMEOUT == result)
- {
- return osErrorTimeout;
- }
- 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;
- }
- if(timeout == osWaitForever)
- {
- timeout = RT_WAITING_FOREVER;
- }
- result = rt_mq_recv(&(mq_cb->mq), msg_ptr, mq_cb->init_msg_size, timeout);
- if (result > 0)
- {
- return osOK;
- }
- else if (-RT_ETIMEOUT == result)
- {
- if (0U == timeout)
- return osErrorResource;
- return osErrorTimeout;
- }
- 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;
- }
- if(timeout == osWaitForever)
- {
- timeout = RT_WAITING_FOREVER;
- }
- 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
|