| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558 |
- /*
- * Copyright (c) 2006-2021, RT-Thread Development Team
- *
- * SPDX-License-Identifier: Apache-2.0
- *
- * Change Logs:
- * Date Author Notes
- * 2022-04-27 tyustli The first version
- */
- #include <rtthread.h>
- #include "cmsis_os.h"
- #define DEFAULT_TICK (5)
- #define DEFAULT_THREAD_STACK_SIZE (512)
- #define CMSIS_MEM_ALLOC(_size) rt_malloc(_size)
- #define CMSIS_MEM_FREE(_ptr) rt_free(_ptr)
- /* cmsis to rt-thread priority map */
- static const rt_uint8_t priorityArrayMap[7] =
- {
- RT_THREAD_PRIORITY_MAX - 1,
- RT_THREAD_PRIORITY_MAX - 1 - (RT_THREAD_PRIORITY_MAX / 6),
- RT_THREAD_PRIORITY_MAX - 1 - (RT_THREAD_PRIORITY_MAX / 3),
- RT_THREAD_PRIORITY_MAX / 2,
- RT_THREAD_PRIORITY_MAX / 3,
- RT_THREAD_PRIORITY_MAX / 6,
- 0,
- };
- /* Convert from CMSIS type osPriority to RT-Thread priority number */
- static rt_uint8_t makeRttPriority(osPriority priority)
- {
- rt_uint8_t rttPriority = RT_THREAD_PRIORITY_MAX;
- switch (priority)
- {
- case osPriorityIdle:
- rttPriority = priorityArrayMap[0];
- break;
- case osPriorityLow:
- rttPriority = priorityArrayMap[1];
- break;
- case osPriorityBelowNormal:
- rttPriority = priorityArrayMap[2];
- break;
- case osPriorityNormal:
- rttPriority = priorityArrayMap[3];
- break;
- case osPriorityAboveNormal:
- rttPriority = priorityArrayMap[4];
- break;
- case osPriorityHigh:
- rttPriority = priorityArrayMap[5];
- break;
- case osPriorityRealtime:
- rttPriority = priorityArrayMap[6];
- break;
- default:
- break;
- }
- return rttPriority;
- }
- /* Convert from RT-Thread priority number to CMSIS type osPriority */
- static osPriority makeCmsisPriority(rt_uint8_t rttPriority)
- {
- osPriority priority = osPriorityError;
- if (rttPriority == priorityArrayMap[0])
- priority = osPriorityIdle;
- else if (rttPriority == priorityArrayMap[1])
- priority = osPriorityLow;
- else if (rttPriority == priorityArrayMap[2])
- priority = osPriorityBelowNormal;
- else if (rttPriority == priorityArrayMap[3])
- priority = osPriorityNormal;
- else if (rttPriority == priorityArrayMap[4])
- priority = osPriorityAboveNormal;
- else if (rttPriority == priorityArrayMap[5])
- priority = osPriorityHigh;
- else if (rttPriority == priorityArrayMap[6])
- rttPriority = osPriorityRealtime;
- return priority;
- }
- /* Determine whether we are in thread mode or handler mode. */
- static int inHandlerMode(void)
- {
- return rt_interrupt_get_nest() != 0;
- }
- /*********************** Kernel Control Functions *****************************/
- /**
- * @brief Initialize the RTOS Kernel for creating objects.
- * @retval status code that indicates the execution status of the function.
- * @note MUST REMAIN UNCHANGED: \b osKernelInitialize shall be consistent in every CMSIS-RTOS.
- */
- osStatus osKernelInitialize(void)
- {
- return osOK;
- }
- /**
- * @brief Start the RTOS Kernel with executing the specified thread.
- * @param thread_def thread definition referenced with \ref osThread.
- * @param argument pointer that is passed to the thread function as start argument.
- * @retval status code that indicates the execution status of the function
- * @note MUST REMAIN UNCHANGED: \b osKernelStart shall be consistent in every CMSIS-RTOS.
- */
- osStatus osKernelStart(void)
- {
- /* Cannot be called from Interrupt Service Routines */
- if (inHandlerMode())
- return osErrorISR;
- return osOK;
- }
- /**
- * @brief Check if the RTOS kernel is already started
- * @param None
- * @retval (0) RTOS is not started
- * (1) RTOS is started
- * @note MUST REMAIN UNCHANGED: \b osKernelRunning shall be consistent in every CMSIS-RTOS.
- */
- int32_t osKernelRunning(void)
- {
- if (rt_thread_self())
- return 1;
- else
- return 0;
- }
- /**
- * @brief Get the value of the Kernel SysTick timer
- * @param None
- * @retval None
- * @note MUST REMAIN UNCHANGED: \b osKernelSysTick shall be consistent in every CMSIS-RTOS.
- */
- uint32_t osKernelSysTick(void)
- {
- /* Cannot be called from Interrupt Service Routines */
- if (inHandlerMode())
- return 0;
- return rt_tick_get();
- }
- /*********************** Thread Management *****************************/
- typedef struct os_thread_cb
- {
- rt_thread_t thread_id;
- rt_event_t event_id;
- } os_thread_cb_t;
- static void thread_cleanup(struct rt_thread *tid)
- {
- if (tid->user_data)
- {
- /* delete event */
- rt_event_delete(((struct os_thread_cb *)(tid->user_data))->event_id);
- /* free mem */
- CMSIS_MEM_FREE((void *)(tid->user_data));
- tid->user_data = RT_NULL;
- }
- }
- /**
- * @brief Create a thread and add it to Active Threads and set it to state READY.
- * @param thread_def thread definition referenced with \ref osThread.
- * @param argument pointer that is passed to the thread function as start argument.
- * @retval thread ID for reference by other functions or NULL in case of error.
- * @note MUST REMAIN UNCHANGED: \b osThreadCreate shall be consistent in every CMSIS-RTOS.
- */
- osThreadId osThreadCreate(const osThreadDef_t *thread_def, void *argument)
- {
- static rt_uint8_t thread_number = 0;
- char name[RT_NAME_MAX];
- rt_uint8_t rttPriority = 0;
- rt_uint32_t stack_size = 0;
- void (*entry)(void *parameter);
- os_thread_cb_t *thread_cb = RT_NULL;
- /* Cannot be called from Interrupt Service Routines */
- if (inHandlerMode())
- goto thread_create_failed;
- if (RT_NULL == thread_def || RT_NULL == thread_def->pthread)
- goto thread_create_failed;
- rt_snprintf(name, sizeof(name), "thread%02d", thread_number++); /* thread name */
- rttPriority = makeRttPriority(thread_def->tpriority); /* thread priority */
- entry = (void (*)(void *parameter))(thread_def->pthread); /* thread entry */
- stack_size = thread_def->stacksize; /* thread stack size */
- if (0 == thread_def->stacksize)
- stack_size = DEFAULT_THREAD_STACK_SIZE;
- thread_cb = (void *)CMSIS_MEM_ALLOC(sizeof(struct os_thread_cb));
- if (RT_NULL == thread_cb)
- goto thread_create_failed;
- thread_cb->thread_id = rt_thread_create(name,
- entry,
- argument,
- stack_size,
- rttPriority,
- DEFAULT_TICK);
- thread_cb->event_id = rt_event_create(name, RT_IPC_FLAG_PRIO);
- if (RT_NULL == thread_cb->thread_id || RT_NULL == thread_cb->event_id)
- goto thread_create_failed;
- thread_cb->thread_id->user_data = (rt_ubase_t)thread_cb;
- thread_cb->thread_id->cleanup = thread_cleanup; /* when thread done. event and mem must be free */
- /* start thread */
- rt_thread_startup(thread_cb->thread_id);
- return thread_cb;
- thread_create_failed:
- rt_kprintf("CMSIS RTOS1 %s failed\r\n", __func__);
- if (thread_cb)
- {
- if (thread_cb->thread_id)
- rt_thread_delete(thread_cb->thread_id);
- if (thread_cb->event_id)
- rt_event_delete(thread_cb->event_id);
- CMSIS_MEM_FREE(thread_cb);
- }
- return RT_NULL;
- }
- osStatus osThreadTerminate(osThreadId thread_id)
- {
- rt_err_t result;
- osStatus status;
- rt_thread_t thread;
- /* thread_id is incorrect */
- if (RT_NULL == thread_id)
- {
- status = osErrorParameter;
- goto thread_terminate_error;
- }
- thread = thread_id->thread_id;
- /* thread_id refers to a thread that is not an active thread. thread maybe done or has terminated*/
- if (rt_object_get_type((rt_object_t)thread) != RT_Object_Class_Thread)
- {
- status = osErrorResource;
- goto thread_terminate_error;
- }
- /* Cannot be called from Interrupt Service Routines */
- if (inHandlerMode())
- {
- status = osErrorISR;
- goto thread_terminate_error;
- }
- result = rt_thread_control(thread, RT_THREAD_CTRL_CLOSE, RT_NULL);
- if (result != RT_EOK)
- {
- status = osErrorOS;
- goto thread_terminate_error;
- }
- return osOK;
- thread_terminate_error:
- rt_kprintf("CMSIS RTOS1 %s failed error code is : 0x%x\r\n", __func__, status);
- return status;
- }
- /**
- * @brief Pass control to next thread that is in state \b READY.
- * @retval status code that indicates the execution status of the function.
- * @note MUST REMAIN UNCHANGED: \b osThreadYield shall be consistent in every CMSIS-RTOS.
- */
- osStatus osThreadYield(void)
- {
- /* Cannot be called from Interrupt Service Routines */
- if (inHandlerMode())
- return osErrorISR;
- rt_thread_yield();
- return osOK;
- }
- /**
- * @brief Return the thread ID of the current running thread.
- * @retval thread ID for reference by other functions or NULL in case of error.
- * @note MUST REMAIN UNCHANGED: \b osThreadGetId shall be consistent in every CMSIS-RTOS.
- */
- osThreadId osThreadGetId(void)
- {
- rt_thread_t thread;
- /* Cannot be called from Interrupt Service Routines */
- if (inHandlerMode())
- return RT_NULL;
- thread = rt_thread_self();
- return (osThreadId)(thread->user_data);
- }
- /**
- * @brief Change priority of an active thread.
- * @param thread_id thread ID obtained by \ref osThreadCreate or \ref osThreadGetId.
- * @param priority new priority value for the thread function.
- * @retval status code that indicates the execution status of the function.
- * @note MUST REMAIN UNCHANGED: \b osThreadSetPriority shall be consistent in every CMSIS-RTOS.
- */
- osStatus osThreadSetPriority(osThreadId thread_id, osPriority priority)
- {
- osStatus status;
- rt_err_t result;
- rt_uint8_t rttPriority = 0;
- rt_thread_t thread;
- /* thread_id is incorrect */
- if (RT_NULL == thread_id)
- {
- status = osErrorParameter;
- goto set_pri_error;
- }
- /* incorrect priority value */
- if (osPriorityError == priority)
- {
- status = osErrorValue;
- goto set_pri_error;
- }
- thread = thread_id->thread_id;
- /* thread_id refers to a thread that is not an active thread. thread maybe done or has terminated*/
- if (rt_object_get_type((rt_object_t)thread) != RT_Object_Class_Thread)
- {
- status = osErrorResource;
- goto set_pri_error;
- }
- /* Cannot be called from Interrupt Service Routines */
- if (inHandlerMode())
- {
- status = osErrorISR;
- goto set_pri_error;
- }
- rttPriority = makeRttPriority(priority);
- result = rt_thread_control(thread, RT_THREAD_CTRL_CHANGE_PRIORITY, &rttPriority);
- if (result != RT_EOK)
- {
- status = osErrorOS;
- goto set_pri_error;
- }
- return osOK;
- set_pri_error:
- rt_kprintf("CMSIS RTOS1 %s failed error code is : 0x%x\r\n", __func__, status);
- return status;
- }
- /**
- * @brief Get current priority of an active thread.
- * @param thread_id thread ID obtained by \ref osThreadCreate or \ref osThreadGetId.
- * @retval current priority value of the thread function.
- * @note MUST REMAIN UNCHANGED: \b osThreadGetPriority shall be consistent in every CMSIS-RTOS.
- */
- osPriority osThreadGetPriority(osThreadId thread_id)
- {
- rt_thread_t thread;
- if (RT_NULL == thread_id)
- goto get_pri_error;
- thread = thread_id->thread_id;
- /* thread_id refers to a thread that is not an active thread. thread maybe done or has terminated*/
- if (rt_object_get_type((rt_object_t)thread) != RT_Object_Class_Thread)
- goto get_pri_error;
- /* Cannot be called from Interrupt Service Routines */
- if (inHandlerMode())
- goto get_pri_error;
- return makeCmsisPriority(thread->current_priority);
- get_pri_error:
- rt_kprintf("CMSIS RTOS1 %s failed error code is : 0x%x\r\n", __func__);
- return osPriorityError;
- }
- /*********************** Generic Wait Functions *******************************/
- /**
- * @brief Wait for Timeout (Time Delay)
- * @param millisec time delay value
- * @retval status code that indicates the execution status of the function.
- */
- osStatus osDelay(uint32_t millisec)
- {
- /* Cannot be called from Interrupt Service Routines */
- if (inHandlerMode())
- return osErrorISR;
- rt_thread_mdelay(millisec);
- return osOK;
- }
- #if (defined(osFeature_Wait) && (osFeature_Wait != 0)) /* Generic Wait available */
- /**
- * @brief Wait for Signal, Message, Mail, or Timeout
- * @param millisec timeout value or 0 in case of no time-out
- * @retval event that contains signal, message, or mail information or error code.
- * @note MUST REMAIN UNCHANGED: \b osWait shall be consistent in every CMSIS-RTOS.
- */
- osEvent osWait(uint32_t millisec);
- #endif /* Generic Wait available */
- /*********************** Timer Management Functions ***************************/
- /**
- * @brief Create a timer.
- * @param timer_def timer object referenced with \ref osTimer.
- * @param type osTimerOnce for one-shot or osTimerPeriodic for periodic behavior.
- * @param argument argument to the timer call back function.
- * @retval timer ID for reference by other functions or NULL in case of error.
- * @note MUST REMAIN UNCHANGED: \b osTimerCreate shall be consistent in every CMSIS-RTOS.
- */
- osTimerId osTimerCreate(const osTimerDef_t *timer_def, os_timer_type type, void *argument)
- {
- rt_timer_t timer;
- static rt_uint16_t timer_number = 0U;
- rt_uint8_t flag = RT_TIMER_FLAG_SOFT_TIMER;
- char name[RT_NAME_MAX];
- void (*timeout_callback)(void *parameter);
- /* Cannot be called from Interrupt Service Routines */
- if (inHandlerMode())
- goto timer_create_error;
- if (RT_NULL == timer_def || RT_NULL == timer_def->ptimer)
- goto timer_create_error;
- if (osTimerPeriodic == type)
- flag |= RT_TIMER_FLAG_PERIODIC;
- else if (osTimerOnce == type)
- flag |= RT_TIMER_FLAG_ONE_SHOT;
- else
- goto timer_create_error;
- rt_snprintf(name, sizeof(name), "timer%02d", timer_number++); /* timer name */
- timeout_callback = (void (*)(void *parameter))(timer_def->ptimer); /* timeout callback */
- timer = rt_timer_create(name,
- timeout_callback,
- argument,
- 0,
- flag);
- if (RT_NULL == timer)
- goto timer_create_error;
- return (osTimerId)timer;
- timer_create_error:
- rt_kprintf("CMSIS RTOS1 %s failed\r\n", __func__);
- return RT_NULL;
- }
- /**
- * @brief Start or restart a timer.
- * @param timer_id timer ID obtained by \ref osTimerCreate.
- * @param millisec time delay value of the timer.
- * @retval status code that indicates the execution status of the function
- * @note MUST REMAIN UNCHANGED: \b osTimerStart shall be consistent in every CMSIS-RTOS.
- */
- osStatus osTimerStart(osTimerId timer_id, uint32_t millisec)
- {
- rt_err_t result;
- rt_tick_t ticks;
- osStatus status;
- /* timer_id is incorrect */
- if ((RT_NULL == timer_id))
- {
- status = osErrorParameter;
- goto timer_start_error;
- }
- /* Cannot be called from Interrupt Service Routines */
- if (inHandlerMode())
- {
- status = osErrorISR;
- goto timer_start_error;
- }
- ticks = rt_tick_from_millisecond(millisec);
- result = rt_timer_control((rt_timer_t)timer_id, RT_TIMER_CTRL_SET_TIME, &ticks);
- if (result != RT_EOK)
- {
- status = osErrorOS;
- goto timer_start_error;
- }
- result = rt_timer_start((rt_timer_t)timer_id);
- if (result != RT_EOK)
- {
- status = osErrorOS;
- goto timer_start_error;
- }
- return osOK;
- timer_start_error:
- rt_kprintf("CMSIS RTOS1 %s failed error code is : 0x%x\r\n", __func__, status);
- return status;
- }
- /**
- * @brief Stop a timer.
- * @param timer_id timer ID obtained by \ref osTimerCreate
- * @retval status code that indicates the execution status of the function.
- * @note MUST REMAIN UNCHANGED: \b osTimerStop shall be consistent in every CMSIS-RTOS.
- */
- osStatus osTimerStop(osTimerId timer_id)
- {
- rt_err_t result;
- rt_uint32_t timer_status;
- osStatus status;
- /* Cannot be called from Interrupt Service Routines */
- if (inHandlerMode())
- {
- status = osErrorISR;
- goto timer_stop_error;
- }
- /* timer_id is incorrect */
- if (RT_NULL == timer_id)
- {
- status = osErrorParameter;
- goto timer_stop_error;
- }
- /* the timer is not started */
- rt_timer_control((rt_timer_t)timer_id, RT_TIMER_CTRL_GET_STATE, &timer_status);
- if (RT_TIMER_FLAG_ACTIVATED != timer_status)
- {
- status = osErrorResource;
- goto timer_stop_error;
- }
- result = rt_timer_stop((rt_timer_t)timer_id);
- if (result != RT_EOK)
- {
- status = osErrorOS;
- goto timer_stop_error;
- }
- return osOK;
- timer_stop_error:
- rt_kprintf("CMSIS RTOS1 %s failed error code is : 0x%x\r\n", __func__, status);
- return status;
- }
- /**
- * @brief Delete a timer.
- * @param timer_id timer ID obtained by \ref osTimerCreate
- * @retval status code that indicates the execution status of the function.
- * @note MUST REMAIN UNCHANGED: \b osTimerDelete shall be consistent in every CMSIS-RTOS.
- */
- osStatus osTimerDelete(osTimerId timer_id)
- {
- rt_err_t result;
- osStatus status;
- /* timer_id is incorrect. */
- if (RT_NULL == timer_id)
- {
- status = osErrorParameter;
- goto timer_delete_error;
- }
- /* Cannot be called from Interrupt Service Routines. */
- if (inHandlerMode())
- {
- status = osErrorISR;
- goto timer_delete_error;
- }
- result = rt_timer_delete((rt_timer_t)timer_id);
- if (RT_EOK != result)
- {
- status = osErrorOS;
- goto timer_delete_error;
- }
- return osOK;
- timer_delete_error:
- rt_kprintf("CMSIS RTOS1 %s failed error code is : 0x%x\r\n", __func__, status);
- return status;
- }
- /*************************** Signal Management ********************************/
- /**
- * @brief Set the specified Signal Flags of an active thread.
- * @param thread_id thread ID obtained by \ref osThreadCreate or \ref osThreadGetId.
- * @param signals specifies the signal flags of the thread that should be set.
- * @retval previous signal flags of the specified thread or 0x80000000 in case of incorrect parameters.
- * @note MUST REMAIN UNCHANGED: \b osSignalSet shall be consistent in every CMSIS-RTOS.
- */
- int32_t osSignalSet(osThreadId thread_id, int32_t signal)
- {
- rt_event_t event;
- int32_t ret = 0x80000000;
- rt_err_t result;
- if (RT_NULL == thread_id)
- goto signal_set_error;
- event = thread_id->event_id;
- /* previous signal flags of the specified thread */
- rt_enter_critical();
- ret = event->set;
- rt_exit_critical();
- result = rt_event_send(event, signal);
- if (RT_EOK != result)
- {
- ret = 0x80000000;
- goto signal_set_error;
- }
- return ret;
- signal_set_error:
- rt_kprintf("CMSIS RTOS1 %s failed error code is : 0x%x\r\n", __func__, ret);
- return 0x80000000;
- }
- /**
- * @brief Clear the specified Signal Flags of an active thread.
- * @param thread_id thread ID obtained by \ref osThreadCreate or \ref osThreadGetId.
- * @param signals specifies the signal flags of the thread that shall be cleared.
- * @retval previous signal flags of the specified thread or 0x80000000 in case of incorrect parameters.
- * @note MUST REMAIN UNCHANGED: \b osSignalClear shall be consistent in every CMSIS-RTOS.
- */
- int32_t osSignalClear(osThreadId thread_id, int32_t signal)
- {
- rt_event_t event;
- int32_t ret = 0x80000000;
- if (RT_NULL == thread_id)
- goto signal_clear_error;
- /* Cannot be called from Interrupt Service Routines. */
- if (inHandlerMode())
- goto signal_clear_error;
- event = thread_id->event_id;
- /* previous signal flags of the specified thread */
- rt_enter_critical();
- ret = event->set;
- rt_exit_critical();
- rt_event_control(event, RT_IPC_CMD_RESET, RT_NULL);
- return ret;
- signal_clear_error:
- rt_kprintf("CMSIS RTOS1 %s failed error code is : 0x%x\r\n", __func__, ret);
- return 0x80000000;
- }
- /**
- * @brief Wait for one or more Signal Flags to become signaled for the current \b RUNNING thread.
- * @param signals wait until all specified signal flags set or 0 for any single signal flag.
- * @param millisec timeout value or 0 in case of no time-out.
- * @retval event flag information or error code.
- * @note MUST REMAIN UNCHANGED: \b osSignalWait shall be consistent in every CMSIS-RTOS.
- */
- osEvent osSignalWait(int32_t signals, uint32_t millisec)
- {
- osEvent event;
- rt_event_t recv_event;
- osThreadId thread_cb;
- rt_uint32_t recved;
- rt_uint32_t ticks = 0;
- rt_err_t result;
- /* Cannot be called from Interrupt Service Routines. */
- if (inHandlerMode())
- {
- event.status = osErrorISR;
- goto signal_wait_error;
- }
- /* get receive event */
- thread_cb = osThreadGetId();
- recv_event = thread_cb->event_id;
- /* get timeout */
- if (osWaitForever == millisec)
- ticks = RT_WAITING_FOREVER;
- else if (0U != millisec)
- ticks = rt_tick_from_millisecond(millisec);
- if (signals != 0)
- result = rt_event_recv(recv_event, signals, RT_EVENT_FLAG_AND | RT_EVENT_FLAG_CLEAR, ticks, &recved);
- else
- result = rt_event_recv(recv_event, signals, RT_EVENT_FLAG_OR | RT_EVENT_FLAG_CLEAR, ticks, &recved);
- if (-RT_ETIMEOUT == result)
- {
- event.status = osEventTimeout;
- goto signal_wait_error;
- }
- else if (RT_EOK != result)
- {
- event.status = osErrorOS;
- goto signal_wait_error;
- }
- event.status = osEventSignal;
- return event;
- signal_wait_error:
- rt_kprintf("CMSIS RTOS1 %s failed error code is : 0x%x\r\n", __func__, event.status);
- return event;
- }
- /**************************** Mutex Management ********************************/
- /**
- * @brief Create and Initialize a Mutex object
- * @param mutex_def mutex definition referenced with \ref osMutex.
- * @retval mutex ID for reference by other functions or NULL in case of error.
- * @note MUST REMAIN UNCHANGED: \b osMutexCreate shall be consistent in every CMSIS-RTOS.
- */
- osMutexId osMutexCreate(const osMutexDef_t *mutex_def)
- {
- #ifdef RT_USING_MUTEX
- static rt_uint16_t mutex_cnt = 0U;
- char name[RT_NAME_MAX];
- rt_mutex_t mutex;
- /* Cannot be called from Interrupt Service Routines. */
- if (inHandlerMode())
- goto mutex_create_failed;
- rt_snprintf(name, sizeof(name), "mutex%02d", mutex_cnt++); /* mutex name */
- mutex = rt_mutex_create(name, RT_IPC_FLAG_PRIO);
- if (RT_NULL == mutex)
- goto mutex_create_failed;
- return (osMutexId)mutex;
- mutex_create_failed:
- rt_kprintf("CMSIS RTOS1 %s failed\r\n", __func__);
- return RT_NULL;
- #else /* not define RT_USING_MUTEX */
- return RT_NULL;
- #endif /* RT_USING_MUTEX */
- }
- /**
- * @brief Wait until a Mutex becomes available
- * @param mutex_id mutex ID obtained by \ref osMutexCreate.
- * @param millisec timeout value or 0 in case of no time-out.
- * @retval status code that indicates the execution status of the function.
- * @note MUST REMAIN UNCHANGED: \b osMutexWait shall be consistent in every CMSIS-RTOS.
- */
- osStatus osMutexWait(osMutexId mutex_id, uint32_t millisec)
- {
- rt_err_t result;
- osStatus status;
- rt_uint32_t ticks = 0;
- /* the parameter mutex_id is incorrect */
- if (RT_NULL == mutex_id)
- {
- status = osErrorParameter;
- goto mutex_wait_error;
- }
- /* the mutex could not be obtained when no timeout was specified */
- if (0 == millisec)
- {
- status = osErrorResource;
- goto mutex_wait_error;
- }
- /* Cannot be called from Interrupt Service Routines. */
- if (inHandlerMode())
- {
- status = osErrorISR;
- goto mutex_wait_error;
- }
- rt_enter_critical();
- if (((rt_mutex_t)mutex_id)->owner == rt_thread_self())
- {
- rt_exit_critical();
- status = osErrorOS;
- goto mutex_wait_error;
- }
- rt_exit_critical();
- if (osWaitForever == millisec)
- ticks = RT_WAITING_FOREVER;
- else if (0U != millisec)
- ticks = rt_tick_from_millisecond(millisec);
- result = rt_mutex_take((rt_mutex_t)mutex_id, ticks);
- if (-RT_ETIMEOUT == result)
- {
- status = osErrorTimeoutResource;
- goto mutex_wait_error;
- }
- else if (RT_EOK != result)
- {
- status = osErrorOS;
- goto mutex_wait_error;
- }
- return osOK;
- mutex_wait_error:
- rt_kprintf("CMSIS RTOS1 %s failed\r\n", __func__);
- return status;
- }
- /**
- * @brief Release a Mutex that was obtained by \ref osMutexWait
- * @param mutex_id mutex ID obtained by \ref osMutexCreate.
- * @retval status code that indicates the execution status of the function.
- * @note MUST REMAIN UNCHANGED: \b osMutexRelease shall be consistent in every CMSIS-RTOS.
- */
- osStatus osMutexRelease(osMutexId mutex_id)
- {
- rt_err_t result;
- osStatus status;
- /* the parameter mutex_id is incorrect */
- if (RT_NULL == mutex_id)
- {
- status = osErrorParameter;
- goto mutex_release_error;
- }
- /* Cannot be called from Interrupt Service Routines. */
- if (inHandlerMode())
- {
- status = osErrorISR;
- goto mutex_release_error;
- }
- /* the mutex was not obtained before */
- if (rt_object_get_type(&((rt_mutex_t)mutex_id)->parent.parent) != RT_Object_Class_Mutex)
- {
- status = osErrorResource;
- goto mutex_release_error;
- }
- result = rt_mutex_release((rt_mutex_t)mutex_id);
- if (RT_EOK != result)
- {
- status = osErrorOS;
- goto mutex_release_error;
- }
- return osOK;
- mutex_release_error:
- rt_kprintf("CMSIS RTOS1 %s failed error code is : 0x%x\r\n", __func__, status);
- return status;
- }
- /**
- * @brief Delete a Mutex
- * @param mutex_id mutex ID obtained by \ref osMutexCreate.
- * @retval status code that indicates the execution status of the function.
- * @note MUST REMAIN UNCHANGED: \b osMutexDelete shall be consistent in every CMSIS-RTOS.
- */
- osStatus osMutexDelete(osMutexId mutex_id)
- {
- osStatus status;
- rt_err_t result;
- /* Check parameters */
- if (RT_NULL == mutex_id)
- {
- status = osErrorParameter;
- goto mutex_delete_error;
- }
- /* Cannot be called from Interrupt Service Routines */
- if (inHandlerMode())
- {
- status = osErrorISR;
- goto mutex_delete_error;
- }
- /* all tokens have already been released */
- if (rt_object_get_type(&((rt_mutex_t)mutex_id)->parent.parent) != RT_Object_Class_Mutex)
- {
- status = osErrorResource;
- goto mutex_delete_error;
- }
- result = rt_mutex_delete((rt_mutex_t)mutex_id);
- if (RT_EOK != result)
- {
- status = osErrorOS;
- goto mutex_delete_error;
- }
- return osOK;
- mutex_delete_error:
- rt_kprintf("CMSIS RTOS1 %s failed error code is :%d\r\n", __func__, status);
- return status;
- }
- /******************** Semaphore Management Functions **************************/
- #if (defined(osFeature_Semaphore) && (osFeature_Semaphore != 0))
- /**
- * @brief Create and Initialize a Semaphore object used for managing resources
- * @param semaphore_def semaphore definition referenced with \ref osSemaphore.
- * @param count number of available resources.
- * @retval semaphore ID for reference by other functions or NULL in case of error.
- * @note MUST REMAIN UNCHANGED: \b osSemaphoreCreate shall be consistent in every CMSIS-RTOS.
- */
- osSemaphoreId osSemaphoreCreate(const osSemaphoreDef_t *semaphore_def, int32_t count)
- {
- #ifdef RT_USING_SEMAPHORE
- static rt_uint16_t sem_cnt = 0U;
- char name[RT_NAME_MAX];
- rt_sem_t sem;
- /* Cannot be called from Interrupt Service Routines */
- if (inHandlerMode())
- goto sem_create_error;
- if (count < 0 || count > osFeature_Semaphore)
- goto sem_create_error;
- rt_snprintf(name, sizeof(name), "sem%02d", sem_cnt++);
- sem = rt_sem_create(name, count, RT_IPC_FLAG_PRIO);
- if (RT_NULL == sem)
- goto sem_create_error;
- return (osSemaphoreId)sem;
- sem_create_error:
- rt_kprintf("CMSIS RTOS1 %s failed error", __func__);
- return RT_NULL;
- #else /* not defined RT_USING_SEMAPHORE */
- return RT_NULL;
- #endif /* RT_USING_SEMAPHORE */
- }
- /* get semaphore cnt */
- static int32_t _osSemaphoreGetCount(osSemaphoreId semaphore_id)
- {
- rt_sem_t sem_cb = (rt_sem_t)semaphore_id;
- /* Check parameters */
- if ((RT_NULL == sem_cb) || (rt_object_get_type(&sem_cb->parent.parent) != RT_Object_Class_Semaphore))
- return 0U;
- return sem_cb->value;
- }
- /**
- * @brief Wait until a Semaphore token becomes available
- * @param semaphore_id semaphore object referenced with \ref osSemaphore.
- * @param millisec timeout value or 0 in case of no time-out.
- * @retval number of available tokens, or -1 in case of incorrect parameters.
- * @note MUST REMAIN UNCHANGED: \b osSemaphoreWait shall be consistent in every CMSIS-RTOS.
- */
- int32_t osSemaphoreWait(osSemaphoreId semaphore_id, uint32_t millisec)
- {
- rt_err_t result;
- rt_int32_t ticks = 0;
- if (RT_NULL == semaphore_id)
- goto sem_take_error;
- /* when millisec is set to osWaitForever the function will wait for an infinite time until the Semaphore token becomes available. */
- if (osWaitForever == millisec)
- ticks = RT_WAITING_FOREVER;
- else if (0U != millisec)
- ticks = rt_tick_from_millisecond(millisec);
- /* when millisec is 0, the function returns instantly */
- if (0 == millisec)
- result = rt_sem_trytake((rt_sem_t)semaphore_id);
- else
- result = rt_sem_take((rt_sem_t)semaphore_id, ticks);
- if (RT_EOK != result)
- goto sem_take_error;
- return _osSemaphoreGetCount(semaphore_id);
- sem_take_error:
- rt_kprintf("CMSIS RTOS1 %s failed \r\n", __func__);
- return 0; /* If 0 is returned, then no semaphore was available. */
- }
- /**
- * @brief Release a Semaphore token
- * @param semaphore_id semaphore object referenced with \ref osSemaphore.
- * @retval status code that indicates the execution status of the function.
- * @note MUST REMAIN UNCHANGED: \b osSemaphoreRelease shall be consistent in every CMSIS-RTOS.
- */
- osStatus osSemaphoreRelease(osSemaphoreId semaphore_id)
- {
- rt_err_t result;
- osStatus status;
- /* the parameter semaphore_id is incorrect. */
- if (RT_NULL == semaphore_id)
- {
- status = osErrorParameter;
- goto sem_release_error;
- }
- /* all tokens have already been released. */
- if (0 == _osSemaphoreGetCount(semaphore_id))
- {
- status = osErrorResource;
- goto sem_release_error;
- }
- result = rt_sem_release((rt_sem_t)semaphore_id);
- if (RT_EOK != result)
- {
- status = osErrorOS;
- goto sem_release_error;
- }
- return osOK;
- sem_release_error:
- rt_kprintf("CMSIS RTOS1 %s failed error code is : 0x%x\r\n", __func__, status);
- return status;
- }
- /**
- * @brief Delete a Semaphore
- * @param semaphore_id semaphore object referenced with \ref osSemaphore.
- * @retval status code that indicates the execution status of the function.
- * @note MUST REMAIN UNCHANGED: \b osSemaphoreDelete shall be consistent in every CMSIS-RTOS.
- */
- osStatus osSemaphoreDelete(osSemaphoreId semaphore_id)
- {
- rt_err_t result;
- osStatus status;
- /* the parameter semaphore_id is incorrect. */
- if (RT_NULL == semaphore_id)
- {
- status = osErrorParameter;
- goto sem_delete_error;
- }
- /* Cannot be called from Interrupt Service Routines */
- if (inHandlerMode())
- {
- status = osErrorISR;
- goto sem_delete_error;
- }
- /* the semaphore object could not be deleted. */
- if (rt_object_get_type((rt_object_t) & (((rt_sem_t)semaphore_id)->parent)) != RT_Object_Class_Semaphore)
- {
- status = osErrorResource;
- goto sem_delete_error;
- }
- result = rt_sem_delete((rt_sem_t)semaphore_id);
- if (RT_EOK != result)
- {
- status = osErrorOS;
- goto sem_delete_error;
- }
- return osOK;
- sem_delete_error:
- rt_kprintf("CMSIS RTOS1 %s failed error code is : 0x%x\r\n", __func__, status);
- return status;
- }
- #endif /* Use Semaphores */
- /******************* Memory Pool Management Functions ***********************/
- #if (defined(osFeature_Pool) && (osFeature_Pool != 0))
- /**
- * @brief Create and Initialize a memory pool
- * @param pool_def memory pool definition referenced with \ref osPool.
- * @retval memory pool ID for reference by other functions or NULL in case of error.
- * @note MUST REMAIN UNCHANGED: \b osPoolCreate shall be consistent in every CMSIS-RTOS.
- */
- osPoolId osPoolCreate(const osPoolDef_t *pool_def)
- {
- static rt_uint16_t mp_cnt = 0U;
- char name[RT_NAME_MAX];
- rt_mp_t mempool;
- rt_size_t block_size;
- /* Cannot be called from Interrupt Service Routines. */
- if (inHandlerMode())
- goto mp_create_error;
- if (RT_NULL == pool_def || 0 == pool_def->pool_sz || 0 == pool_def->item_sz)
- goto mp_create_error;
- rt_snprintf(name, sizeof(name), "mp%02d", mp_cnt++); /* name */
- block_size = RT_ALIGN(pool_def->item_sz, RT_ALIGN_SIZE); /* pool size */
- mempool = rt_mp_create(name, pool_def->pool_sz, block_size);
- if (RT_NULL == mempool)
- goto mp_create_error;
- return (osPoolId)mempool;
- mp_create_error:
- rt_kprintf("CMSIS RTOS1 %s failed\r\n", __func__);
- return RT_NULL;
- }
- /**
- * @brief Allocate a memory block from a memory pool
- * @param pool_id memory pool ID obtain referenced with \ref osPoolCreate.
- * @retval address of the allocated memory block or NULL in case of no memory available.
- * @note MUST REMAIN UNCHANGED: \b osPoolAlloc shall be consistent in every CMSIS-RTOS.
- */
- void *osPoolAlloc(osPoolId pool_id)
- {
- /* Check parameters */
- if (RT_NULL == pool_id)
- return RT_NULL;
- return rt_mp_alloc((rt_mp_t)pool_id, RT_WAITING_FOREVER);
- }
- /**
- * @brief Allocate a memory block from a memory pool and set memory block to zero
- * @param pool_id memory pool ID obtain referenced with \ref osPoolCreate.
- * @retval address of the allocated memory block or NULL in case of no memory available.
- * @note MUST REMAIN UNCHANGED: \b osPoolCAlloc shall be consistent in every CMSIS-RTOS.
- */
- void *osPoolCAlloc(osPoolId pool_id)
- {
- void *p = osPoolAlloc(pool_id);
- if (p != NULL)
- rt_memset(p, 0, ((rt_mp_t)pool_id)->block_size);
- return p;
- }
- /**
- * @brief Return an allocated memory block back to a specific memory pool
- * @param pool_id memory pool ID obtain referenced with \ref osPoolCreate.
- * @param block address of the allocated memory block that is returned to the memory pool.
- * @retval status code that indicates the execution status of the function.
- * @note MUST REMAIN UNCHANGED: \b osPoolFree shall be consistent in every CMSIS-RTOS.
- */
- osStatus osPoolFree(osPoolId pool_id, void *block)
- {
- osStatus status;
- /* Check parameters */
- if (NULL == pool_id)
- {
- status = osErrorParameter;
- goto pool_free_error;
- }
- if (NULL == block)
- {
- status = osErrorParameter;
- goto pool_free_error;
- }
- rt_mp_free(block);
- block = RT_NULL;
- return osOK;
- pool_free_error:
- rt_kprintf("CMSIS RTOS1 %s failed error code is : 0x%x\r\n", __func__, status);
- return status;
- }
- #endif /* Use Memory Pool Management */
- /******************* Message Queue Management Functions *********************/
- #if (defined(osFeature_MessageQ) && (osFeature_MessageQ != 0)) /* Use Message Queues */
- /**
- * @brief Create and Initialize a Message Queue
- * @param queue_def queue definition referenced with \ref osMessageQ.
- * @param thread_id thread ID (obtained by \ref osThreadCreate or \ref osThreadGetId) or NULL.
- * @retval message queue ID for reference by other functions or NULL in case of error.
- * @note MUST REMAIN UNCHANGED: \b osMessageCreate shall be consistent in every CMSIS-RTOS.
- */
- osMessageQId osMessageCreate(const osMessageQDef_t *queue_def, osThreadId thread_id)
- {
- #ifdef RT_USING_MAILBOX
- (void)thread_id;
- static rt_uint16_t mailbox_cnt = 0U;
- char name[RT_NAME_MAX];
- rt_mailbox_t mailbox;
- /* Cannot be called from Interrupt Service Routines. */
- if (inHandlerMode())
- goto message_create_error;
- /* param error */
- if (RT_NULL == queue_def || 0 == queue_def->queue_sz || sizeof(void *) != queue_def->item_sz)
- goto message_create_error;
- rt_snprintf(name, sizeof(name), "mailbox%02d", mailbox_cnt++);
- mailbox = rt_mb_create(name, queue_def->queue_sz, RT_IPC_FLAG_PRIO);
- if (mailbox == RT_NULL)
- goto message_create_error;
- return (osMessageQId)mailbox;
- message_create_error:
- rt_kprintf("CMSIS RTOS1 %s failed \r\n", __func__);
- return RT_NULL;
- #else /* RT_USING_MAILBOX */
- return RT_NULL;
- #endif /* not define RT_USING_MAILBOX */
- }
- /**
- * @brief Put a Message to a Queue.
- * @param queue_id message queue ID obtained with \ref osMessageCreate.
- * @param info message information.
- * @param millisec timeout value or 0 in case of no time-out.
- * @retval status code that indicates the execution status of the function.
- * @note MUST REMAIN UNCHANGED: \b osMessagePut shall be consistent in every CMSIS-RTOS.
- */
- osStatus osMessagePut(osMessageQId queue_id, uint32_t info, uint32_t millisec)
- {
- rt_err_t result;
- osStatus status;
- rt_mailbox_t mb_cb = (rt_mailbox_t)queue_id;
- rt_tick_t ticks = 0;
- if (RT_NULL == queue_id)
- {
- /* a parameter is invalid or outside of a permitted range */
- status = osErrorParameter;
- goto message_put_error;
- }
- if (osWaitForever == millisec)
- ticks = RT_WAITING_FOREVER;
- else if (0U != millisec)
- ticks = rt_tick_from_millisecond(millisec);
- /* when millisec is 0, the function returns instantly */
- if (0 == millisec)
- result = rt_mb_urgent(mb_cb, info);
- else
- result = rt_mb_send_wait(mb_cb, info, ticks);
- if (-RT_EFULL == result)
- {
- /* no memory in the queue was available */
- status = osErrorResource;
- goto message_put_error;
- }
- else if (-RT_ETIMEOUT == result)
- {
- /* no memory in the queue was available during the given time limit. */
- status = osErrorTimeoutResource;
- goto message_put_error;
- }
- if (RT_EOK != result)
- {
- status = osErrorOS;
- goto message_put_error;
- }
- return osOK;
- message_put_error:
- rt_kprintf("CMSIS RTOS1 %s failed error code is : 0x%x\r\n", __func__, status);
- return status;
- }
- /**
- * @brief Get a Message or Wait for a Message from a Queue.
- * @param queue_id message queue ID obtained with \ref osMessageCreate.
- * @param millisec timeout value or 0 in case of no time-out.
- * @retval event information that includes status code.
- * @note MUST REMAIN UNCHANGED: \b osMessageGet shall be consistent in every CMSIS-RTOS.
- */
- osEvent osMessageGet(osMessageQId queue_id, uint32_t millisec)
- {
- osEvent event;
- rt_err_t result;
- rt_tick_t ticks = 0;
- if (RT_NULL == queue_id)
- {
- /* a parameter is invalid or outside of a permitted range */
- event.status = osErrorParameter;
- goto message_get_error;
- }
- event.def.message_id = queue_id;
- event.value.v = 0;
- if (osWaitForever == millisec)
- ticks = RT_WAITING_FOREVER;
- else if (0U != millisec)
- ticks = rt_tick_from_millisecond(millisec);
- result = rt_mb_recv((rt_mailbox_t)queue_id, &(event.value.v), ticks);
- if (-RT_ETIMEOUT == result)
- {
- /* no message has arrived during the given timeout period */
- event.status = osEventTimeout;
- goto message_get_error;
- }
- else if (RT_EOK != result)
- {
- event.status = osErrorOS;
- goto message_get_error;
- }
- /* message received, value.p contains the pointer to message */
- event.status = osEventMessage;
- return event;
- message_get_error:
- rt_kprintf("CMSIS RTOS1 %s failed error code is : 0x%x\r\n", __func__, event.status);
- return event;
- }
- #endif /* Use Message Queues */
- /******************** Mail Queue Management Functions ***********************/
- #if (defined(osFeature_MailQ) && (osFeature_MailQ != 0)) /* Use Mail Queues */
- typedef struct os_mailQ_cb
- {
- rt_mp_t mp_id;
- rt_mailbox_t mb_id;
- } os_mailQ_cb_t;
- /**
- * @brief Create and Initialize mail queue
- * @param queue_def reference to the mail queue definition obtain with \ref osMailQ
- * @param thread_id thread ID (obtained by \ref osThreadCreate or \ref osThreadGetId) or NULL.
- * @retval mail queue ID for reference by other functions or NULL in case of error.
- * @note MUST REMAIN UNCHANGED: \b osMailCreate shall be consistent in every CMSIS-RTOS.
- */
- osMailQId osMailCreate(const osMailQDef_t *queue_def, osThreadId thread_id)
- {
- #if defined(RT_USING_MEMPOOL) && defined(RT_USING_MAILBOX)
- (void)thread_id;
- os_mailQ_cb_t *ptr = RT_NULL;
- char name[RT_NAME_MAX];
- static rt_uint16_t mail_cnt = 0U;
- rt_size_t block_size;
- /* Cannot be called from Interrupt Service Routines. */
- if (inHandlerMode())
- goto mail_create_failed;
- if (RT_NULL == queue_def || 0 == queue_def->queue_sz || 0 == queue_def->item_sz)
- goto mail_create_failed;
- rt_snprintf(name, sizeof(name), "mb%02d", mail_cnt++);
- block_size = RT_ALIGN(queue_def->item_sz, RT_ALIGN_SIZE);
- ptr = (void *)CMSIS_MEM_ALLOC(sizeof(struct os_mailQ_cb));
- if (RT_NULL == ptr)
- goto mail_create_failed;
- ptr->mp_id = rt_mp_create(name, queue_def->queue_sz, block_size);
- ptr->mb_id = rt_mb_create(name, queue_def->queue_sz, RT_IPC_FLAG_PRIO);
- if ((RT_NULL == ptr->mp_id) || (RT_NULL == ptr->mb_id))
- goto mail_create_failed;
- return ptr;
- mail_create_failed:
- if (ptr)
- CMSIS_MEM_FREE(ptr);
- if (RT_NULL != ptr->mp_id)
- rt_mp_delete(ptr->mp_id);
- if (RT_NULL != ptr->mb_id)
- rt_mb_delete(ptr->mb_id);
- rt_kprintf("CMSIS RTOS1 %s failed\r\n", __func__);
- return RT_NULL;
- #else /* RT_USING_MEMPOOL && RT_USING_MAILBOX */
- return RT_NULL;
- #endif /* not define RT_USING_MEMPOOL && RT_USING_MAILBOX */
- }
- /**
- * @brief Allocate a memory block from a mail
- * @param queue_id mail queue ID obtained with \ref osMailCreate.
- * @param millisec timeout value or 0 in case of no time-out.
- * @retval pointer to memory block that can be filled with mail or NULL in case error.
- * @note MUST REMAIN UNCHANGED: \b osMailAlloc shall be consistent in every CMSIS-RTOS.
- */
- void *osMailAlloc(osMailQId queue_id, uint32_t millisec)
- {
- os_mailQ_cb_t *ptr = (os_mailQ_cb_t *)queue_id;
- void *ret = NULL;
- rt_tick_t ticks = 0;
- if (RT_NULL == ptr)
- goto mail_alloc_error;
- if (osWaitForever == millisec)
- ticks = RT_WAITING_FOREVER;
- else if (0U != millisec)
- ticks = rt_tick_from_millisecond(millisec);
- ret = rt_mp_alloc(ptr->mp_id, ticks);
- if (RT_NULL == ret)
- goto mail_alloc_error;
- return ret;
- mail_alloc_error:
- rt_kprintf("CMSIS RTOS1 %s failed\r\n", __func__);
- return RT_NULL;
- }
- /**
- * @brief Allocate a memory block from a mail and set memory block to zero
- * @param queue_id mail queue ID obtained with \ref osMailCreate.
- * @param millisec timeout value or 0 in case of no time-out.
- * @retval pointer to memory block that can be filled with mail or NULL in case error.
- * @note MUST REMAIN UNCHANGED: \b osMailCAlloc shall be consistent in every CMSIS-RTOS.
- */
- void *osMailCAlloc(osMailQId queue_id, uint32_t millisec)
- {
- void *p = osMailAlloc(queue_id, millisec);
- if (p)
- rt_memset(p, 0, ((os_mailQ_cb_t *)queue_id)->mp_id->block_size);
- return p;
- }
- /**
- * @brief Put a mail to a queue
- * @param queue_id mail queue ID obtained with \ref osMailCreate.
- * @param mail memory block previously allocated with \ref osMailAlloc or \ref osMailCAlloc.
- * @retval status code that indicates the execution status of the function.
- * @note MUST REMAIN UNCHANGED: \b osMailPut shall be consistent in every CMSIS-RTOS.
- */
- osStatus osMailPut(osMailQId queue_id, void *mail)
- {
- osStatus status;
- os_mailQ_cb_t *ptr = (os_mailQ_cb_t *)queue_id;
- rt_err_t result;
- if (RT_NULL == ptr)
- {
- status = osErrorParameter;
- goto mail_put_error;
- }
- if (RT_NULL == mail)
- {
- status = osErrorValue;
- goto mail_put_error;
- }
- result = rt_mb_send((ptr->mb_id), (rt_ubase_t)mail);
- if (RT_EOK != result)
- {
- status = osErrorOS;
- goto mail_put_error;
- }
- return osOK;
- mail_put_error:
- rt_kprintf("CMSIS RTOS1 %s failed error code is : 0x%x\r\n", __func__, status);
- return status;
- }
- /**
- * @brief Get a mail from a queue
- * @param queue_id mail queue ID obtained with \ref osMailCreate.
- * @param millisec timeout value or 0 in case of no time-out
- * @retval event that contains mail information or error code.
- * @note MUST REMAIN UNCHANGED: \b osMailGet shall be consistent in every CMSIS-RTOS.
- */
- osEvent osMailGet(osMailQId queue_id, uint32_t millisec)
- {
- osEvent event;
- os_mailQ_cb_t *ptr = (os_mailQ_cb_t *)queue_id;
- rt_err_t result;
- rt_ubase_t value;
- rt_tick_t ticks = 0;
- if (RT_NULL == ptr)
- {
- event.status = osErrorParameter;
- goto mail_get_error;
- }
- if (osWaitForever == millisec)
- ticks = RT_WAITING_FOREVER;
- else if (0U != millisec)
- ticks = rt_tick_from_millisecond(millisec);
- result = rt_mb_recv((ptr->mb_id), &value, ticks);
- if (-RT_ETIMEOUT == result)
- {
- event.status = osEventTimeout;
- goto mail_get_error;
- }
- else if (RT_EOK != result)
- {
- event.status = osErrorOS;
- goto mail_get_error;
- }
- event.value.p = (void *)value;
- event.status = osEventMail;
- return event;
- mail_get_error:
- rt_kprintf("CMSIS RTOS1 %s failed error code is : 0x%x\r\n", __func__, event.status);
- return event;
- }
- /**
- * @brief Free a memory block from a mail
- * @param queue_id mail queue ID obtained with \ref osMailCreate.
- * @param mail pointer to the memory block that was obtained with \ref osMailGet.
- * @retval status code that indicates the execution status of the function.
- * @note MUST REMAIN UNCHANGED: \b osMailFree shall be consistent in every CMSIS-RTOS.
- */
- osStatus osMailFree(osMailQId queue_id, void *mail)
- {
- osStatus status;
- os_mailQ_cb_t *ptr = (os_mailQ_cb_t *)queue_id;
- if (RT_NULL == ptr)
- {
- status = osErrorParameter;
- goto mail_free_error;
- }
- if (RT_NULL == mail)
- {
- status = osErrorValue;
- goto mail_free_error;
- }
- rt_mp_free(mail);
- mail = RT_NULL;
- return osOK;
- mail_free_error:
- rt_kprintf("CMSIS RTOS1 %s failed error code is : 0x%x\r\n", __func__, status);
- return status;
- }
- #endif /* Use Mail Queues */
- /****************************** end of file ******************************/
|