cmsis_os2.c 59 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482
  1. /* --------------------------------------------------------------------------
  2. * Copyright (c) 2013-2020 Arm Limited. All rights reserved.
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Licensed under the Apache License, Version 2.0 (the License); you may
  7. * not use this file except in compliance with the License.
  8. * You may obtain a copy of the License at
  9. *
  10. * www.apache.org/licenses/LICENSE-2.0
  11. *
  12. * Unless required by applicable law or agreed to in writing, software
  13. * distributed under the License is distributed on an AS IS BASIS, WITHOUT
  14. * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  15. * See the License for the specific language governing permissions and
  16. * limitations under the License.
  17. *
  18. * Name: cmsis_os2.c
  19. * Purpose: CMSIS RTOS2 wrapper for FreeRTOS
  20. *
  21. *---------------------------------------------------------------------------*/
  22. #include <string.h>
  23. #include "cmsis_os2.h" // ::CMSIS:RTOS2
  24. #include "cmsis_compiler.h" // Compiler agnostic definitions
  25. #include "FreeRTOS.h" // ARM.FreeRTOS::RTOS:Core
  26. #include "task.h" // ARM.FreeRTOS::RTOS:Core
  27. #include "event_groups.h" // ARM.FreeRTOS::RTOS:Event Groups
  28. #include "semphr.h" // ARM.FreeRTOS::RTOS:Core
  29. #include "freertos_mpool.h" // osMemoryPool definitions
  30. #include "freertos_os2.h" // Configuration check and setup
  31. /*---------------------------------------------------------------------------*/
  32. #ifndef __ARM_ARCH_6M__
  33. #define __ARM_ARCH_6M__ 0
  34. #endif
  35. #ifndef __ARM_ARCH_7M__
  36. #define __ARM_ARCH_7M__ 0
  37. #endif
  38. #ifndef __ARM_ARCH_7EM__
  39. #define __ARM_ARCH_7EM__ 0
  40. #endif
  41. #ifndef __ARM_ARCH_8M_MAIN__
  42. #define __ARM_ARCH_8M_MAIN__ 0
  43. #endif
  44. #ifndef __ARM_ARCH_7A__
  45. #define __ARM_ARCH_7A__ 0
  46. #endif
  47. #if ((__ARM_ARCH_7M__ == 1U) || \
  48. (__ARM_ARCH_7EM__ == 1U) || \
  49. (__ARM_ARCH_8M_MAIN__ == 1U))
  50. #define IS_IRQ_MASKED() ((__get_PRIMASK() != 0U) || (__get_BASEPRI() != 0U))
  51. #elif (__ARM_ARCH_6M__ == 1U)
  52. #define IS_IRQ_MASKED() (__get_PRIMASK() != 0U)
  53. #elif (__ARM_ARCH_7A__ == 1U)
  54. /* CPSR mask bits */
  55. #define CPSR_MASKBIT_I 0x80U
  56. #define IS_IRQ_MASKED() ((__get_CPSR() & CPSR_MASKBIT_I) != 0U)
  57. #else
  58. #define IS_IRQ_MASKED() (__get_PRIMASK() != 0U)
  59. #endif
  60. #if (__ARM_ARCH_7A__ == 1U)
  61. /* CPSR mode bitmasks */
  62. #define CPSR_MODE_USER 0x10U
  63. #define CPSR_MODE_SYSTEM 0x1FU
  64. #define IS_IRQ_MODE() ((__get_mode() != CPSR_MODE_USER) && (__get_mode() != CPSR_MODE_SYSTEM))
  65. #else
  66. #define IS_IRQ_MODE() (__get_IPSR() != 0U)
  67. #endif
  68. #define IS_IRQ() IS_IRQ_MODE()
  69. #define SVCall_IRQ_NBR (IRQn_Type) -5 /* SVCall_IRQ_NBR added as SV_Call handler name is not the same for CM0 and for all other CMx */
  70. /* Limits */
  71. #define MAX_BITS_TASK_NOTIFY 31U
  72. #define MAX_BITS_EVENT_GROUPS 24U
  73. #define THREAD_FLAGS_INVALID_BITS (~((1UL << MAX_BITS_TASK_NOTIFY) - 1U))
  74. #define EVENT_FLAGS_INVALID_BITS (~((1UL << MAX_BITS_EVENT_GROUPS) - 1U))
  75. /* Kernel version and identification string definition (major.minor.rev: mmnnnrrrr dec) */
  76. #define KERNEL_VERSION (((uint32_t)tskKERNEL_VERSION_MAJOR * 10000000UL) | \
  77. ((uint32_t)tskKERNEL_VERSION_MINOR * 10000UL) | \
  78. ((uint32_t)tskKERNEL_VERSION_BUILD * 1UL))
  79. #define KERNEL_ID ("FreeRTOS " tskKERNEL_VERSION_NUMBER)
  80. /* Timer callback information structure definition */
  81. typedef struct {
  82. osTimerFunc_t func;
  83. void *arg;
  84. } TimerCallback_t;
  85. /* Kernel initialization state */
  86. static osKernelState_t KernelState = osKernelInactive;
  87. /*
  88. Heap region definition used by heap_5 variant
  89. Define configAPPLICATION_ALLOCATED_HEAP as nonzero value in FreeRTOSConfig.h if
  90. heap regions are already defined and vPortDefineHeapRegions is called in application.
  91. Otherwise vPortDefineHeapRegions will be called by osKernelInitialize using
  92. definition configHEAP_5_REGIONS as parameter. Overriding configHEAP_5_REGIONS
  93. is possible by defining it globally or in FreeRTOSConfig.h.
  94. */
  95. #if defined(USE_FreeRTOS_HEAP_5)
  96. #if (configAPPLICATION_ALLOCATED_HEAP == 0)
  97. /*
  98. FreeRTOS heap is not defined by the application.
  99. Single region of size configTOTAL_HEAP_SIZE (defined in FreeRTOSConfig.h)
  100. is provided by default. Define configHEAP_5_REGIONS to provide custom
  101. HeapRegion_t array.
  102. */
  103. #define HEAP_5_REGION_SETUP 1
  104. #ifndef configHEAP_5_REGIONS
  105. #define configHEAP_5_REGIONS xHeapRegions
  106. static uint8_t ucHeap[configTOTAL_HEAP_SIZE];
  107. static HeapRegion_t xHeapRegions[] = {
  108. { ucHeap, configTOTAL_HEAP_SIZE },
  109. { NULL, 0 }
  110. };
  111. #else
  112. /* Global definition is provided to override default heap array */
  113. extern HeapRegion_t configHEAP_5_REGIONS[];
  114. #endif
  115. #else
  116. /*
  117. The application already defined the array used for the FreeRTOS heap and
  118. called vPortDefineHeapRegions to initialize heap.
  119. */
  120. #define HEAP_5_REGION_SETUP 0
  121. #endif /* configAPPLICATION_ALLOCATED_HEAP */
  122. #endif /* USE_FreeRTOS_HEAP_5 */
  123. #if defined(SysTick)
  124. #undef SysTick_Handler
  125. /* CMSIS SysTick interrupt handler prototype */
  126. extern void SysTick_Handler (void);
  127. /* FreeRTOS tick timer interrupt handler prototype */
  128. extern void xPortSysTickHandler (void);
  129. /*
  130. SysTick handler implementation that also clears overflow flag.
  131. */
  132. #if (USE_CUSTOM_SYSTICK_HANDLER_IMPLEMENTATION == 0)
  133. void SysTick_Handler (void) {
  134. /* Clear overflow flag */
  135. SysTick->CTRL;
  136. if (xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED) {
  137. /* Call tick handler */
  138. xPortSysTickHandler();
  139. }
  140. }
  141. #endif
  142. #endif /* SysTick */
  143. /*
  144. Setup SVC to reset value.
  145. */
  146. __STATIC_INLINE void SVC_Setup (void) {
  147. #if (__ARM_ARCH_7A__ == 0U)
  148. /* Service Call interrupt might be configured before kernel start */
  149. /* and when its priority is lower or equal to BASEPRI, svc intruction */
  150. /* causes a Hard Fault. */
  151. NVIC_SetPriority (SVCall_IRQ_NBR, 0U);
  152. #endif
  153. }
  154. /*
  155. Function macro used to retrieve semaphore count from ISR
  156. */
  157. #ifndef uxSemaphoreGetCountFromISR
  158. #define uxSemaphoreGetCountFromISR( xSemaphore ) uxQueueMessagesWaitingFromISR( ( QueueHandle_t ) ( xSemaphore ) )
  159. #endif
  160. /* Get OS Tick count value */
  161. static uint32_t OS_Tick_GetCount (void);
  162. /* Get OS Tick overflow status */
  163. static uint32_t OS_Tick_GetOverflow (void);
  164. /* Get OS Tick interval */
  165. static uint32_t OS_Tick_GetInterval (void);
  166. /*---------------------------------------------------------------------------*/
  167. osStatus_t osKernelInitialize (void) {
  168. osStatus_t stat;
  169. if (IS_IRQ()) {
  170. stat = osErrorISR;
  171. }
  172. else {
  173. if (KernelState == osKernelInactive) {
  174. #if defined(USE_TRACE_EVENT_RECORDER)
  175. EvrFreeRTOSSetup(0U);
  176. #endif
  177. #if defined(USE_FreeRTOS_HEAP_5) && (HEAP_5_REGION_SETUP == 1)
  178. vPortDefineHeapRegions (configHEAP_5_REGIONS);
  179. #endif
  180. KernelState = osKernelReady;
  181. stat = osOK;
  182. } else {
  183. stat = osError;
  184. }
  185. }
  186. return (stat);
  187. }
  188. osStatus_t osKernelGetInfo (osVersion_t *version, char *id_buf, uint32_t id_size) {
  189. if (version != NULL) {
  190. /* Version encoding is major.minor.rev: mmnnnrrrr dec */
  191. version->api = KERNEL_VERSION;
  192. version->kernel = KERNEL_VERSION;
  193. }
  194. if ((id_buf != NULL) && (id_size != 0U)) {
  195. if (id_size > sizeof(KERNEL_ID)) {
  196. id_size = sizeof(KERNEL_ID);
  197. }
  198. memcpy(id_buf, KERNEL_ID, id_size);
  199. }
  200. return (osOK);
  201. }
  202. osKernelState_t osKernelGetState (void) {
  203. osKernelState_t state;
  204. switch (xTaskGetSchedulerState()) {
  205. case taskSCHEDULER_RUNNING:
  206. state = osKernelRunning;
  207. break;
  208. case taskSCHEDULER_SUSPENDED:
  209. state = osKernelLocked;
  210. break;
  211. case taskSCHEDULER_NOT_STARTED:
  212. default:
  213. if (KernelState == osKernelReady) {
  214. state = osKernelReady;
  215. } else {
  216. state = osKernelInactive;
  217. }
  218. break;
  219. }
  220. return (state);
  221. }
  222. osStatus_t osKernelStart (void) {
  223. osStatus_t stat;
  224. if (IS_IRQ()) {
  225. stat = osErrorISR;
  226. }
  227. else {
  228. if (KernelState == osKernelReady) {
  229. /* Ensure SVC priority is at the reset value */
  230. SVC_Setup();
  231. /* Change state to enable IRQ masking check */
  232. KernelState = osKernelRunning;
  233. /* Start the kernel scheduler */
  234. vTaskStartScheduler();
  235. stat = osOK;
  236. } else {
  237. stat = osError;
  238. }
  239. }
  240. return (stat);
  241. }
  242. int32_t osKernelLock (void) {
  243. int32_t lock;
  244. if (IS_IRQ()) {
  245. lock = (int32_t)osErrorISR;
  246. }
  247. else {
  248. switch (xTaskGetSchedulerState()) {
  249. case taskSCHEDULER_SUSPENDED:
  250. lock = 1;
  251. break;
  252. case taskSCHEDULER_RUNNING:
  253. vTaskSuspendAll();
  254. lock = 0;
  255. break;
  256. case taskSCHEDULER_NOT_STARTED:
  257. default:
  258. lock = (int32_t)osError;
  259. break;
  260. }
  261. }
  262. return (lock);
  263. }
  264. int32_t osKernelUnlock (void) {
  265. int32_t lock;
  266. if (IS_IRQ()) {
  267. lock = (int32_t)osErrorISR;
  268. }
  269. else {
  270. switch (xTaskGetSchedulerState()) {
  271. case taskSCHEDULER_SUSPENDED:
  272. lock = 1;
  273. if (xTaskResumeAll() != pdTRUE) {
  274. if (xTaskGetSchedulerState() == taskSCHEDULER_SUSPENDED) {
  275. lock = (int32_t)osError;
  276. }
  277. }
  278. break;
  279. case taskSCHEDULER_RUNNING:
  280. lock = 0;
  281. break;
  282. case taskSCHEDULER_NOT_STARTED:
  283. default:
  284. lock = (int32_t)osError;
  285. break;
  286. }
  287. }
  288. return (lock);
  289. }
  290. int32_t osKernelRestoreLock (int32_t lock) {
  291. if (IS_IRQ()) {
  292. lock = (int32_t)osErrorISR;
  293. }
  294. else {
  295. switch (xTaskGetSchedulerState()) {
  296. case taskSCHEDULER_SUSPENDED:
  297. case taskSCHEDULER_RUNNING:
  298. if (lock == 1) {
  299. vTaskSuspendAll();
  300. }
  301. else {
  302. if (lock != 0) {
  303. lock = (int32_t)osError;
  304. }
  305. else {
  306. if (xTaskResumeAll() != pdTRUE) {
  307. if (xTaskGetSchedulerState() != taskSCHEDULER_RUNNING) {
  308. lock = (int32_t)osError;
  309. }
  310. }
  311. }
  312. }
  313. break;
  314. case taskSCHEDULER_NOT_STARTED:
  315. default:
  316. lock = (int32_t)osError;
  317. break;
  318. }
  319. }
  320. return (lock);
  321. }
  322. uint32_t osKernelGetTickCount (void) {
  323. TickType_t ticks;
  324. if (IS_IRQ()) {
  325. ticks = xTaskGetTickCountFromISR();
  326. } else {
  327. ticks = xTaskGetTickCount();
  328. }
  329. return (ticks);
  330. }
  331. uint32_t osKernelGetTickFreq (void) {
  332. return (configTICK_RATE_HZ);
  333. }
  334. /* Get OS Tick count value */
  335. static uint32_t OS_Tick_GetCount (void) {
  336. uint32_t load = SysTick->LOAD;
  337. return (load - SysTick->VAL);
  338. }
  339. /* Get OS Tick overflow status */
  340. static uint32_t OS_Tick_GetOverflow (void) {
  341. return ((SysTick->CTRL >> 16) & 1U);
  342. }
  343. /* Get OS Tick interval */
  344. static uint32_t OS_Tick_GetInterval (void) {
  345. return (SysTick->LOAD + 1U);
  346. }
  347. uint32_t osKernelGetSysTimerCount (void) {
  348. uint32_t irqmask = IS_IRQ_MASKED();
  349. TickType_t ticks;
  350. uint32_t val;
  351. __disable_irq();
  352. ticks = xTaskGetTickCount();
  353. val = OS_Tick_GetCount();
  354. if (OS_Tick_GetOverflow() != 0U) {
  355. val = OS_Tick_GetCount();
  356. ticks++;
  357. }
  358. val += ticks * OS_Tick_GetInterval();
  359. if (irqmask == 0U) {
  360. __enable_irq();
  361. }
  362. return (val);
  363. }
  364. uint32_t osKernelGetSysTimerFreq (void) {
  365. return (configCPU_CLOCK_HZ);
  366. }
  367. /*---------------------------------------------------------------------------*/
  368. osThreadId_t osThreadNew (osThreadFunc_t func, void *argument, const osThreadAttr_t *attr) {
  369. const char *name;
  370. uint32_t stack;
  371. TaskHandle_t hTask;
  372. UBaseType_t prio;
  373. int32_t mem;
  374. hTask = NULL;
  375. if (!IS_IRQ() && (func != NULL)) {
  376. stack = configMINIMAL_STACK_SIZE;
  377. prio = (UBaseType_t)osPriorityNormal;
  378. name = NULL;
  379. mem = -1;
  380. if (attr != NULL) {
  381. if (attr->name != NULL) {
  382. name = attr->name;
  383. }
  384. if (attr->priority != osPriorityNone) {
  385. prio = (UBaseType_t)attr->priority;
  386. }
  387. if ((prio < osPriorityIdle) || (prio > osPriorityISR) || ((attr->attr_bits & osThreadJoinable) == osThreadJoinable)) {
  388. return (NULL);
  389. }
  390. if (attr->stack_size > 0U) {
  391. /* In FreeRTOS stack is not in bytes, but in sizeof(StackType_t) which is 4 on ARM ports. */
  392. /* Stack size should be therefore 4 byte aligned in order to avoid division caused side effects */
  393. stack = attr->stack_size / sizeof(StackType_t);
  394. }
  395. if ((attr->cb_mem != NULL) && (attr->cb_size >= sizeof(StaticTask_t)) &&
  396. (attr->stack_mem != NULL) && (attr->stack_size > 0U)) {
  397. mem = 1;
  398. }
  399. else {
  400. if ((attr->cb_mem == NULL) && (attr->cb_size == 0U) && (attr->stack_mem == NULL)) {
  401. mem = 0;
  402. }
  403. }
  404. }
  405. else {
  406. mem = 0;
  407. }
  408. if (mem == 1) {
  409. #if (configSUPPORT_STATIC_ALLOCATION == 1)
  410. hTask = xTaskCreateStatic ((TaskFunction_t)func, name, stack, argument, prio, (StackType_t *)attr->stack_mem,
  411. (StaticTask_t *)attr->cb_mem);
  412. #endif
  413. }
  414. else {
  415. if (mem == 0) {
  416. #if (configSUPPORT_DYNAMIC_ALLOCATION == 1)
  417. if (xTaskCreate ((TaskFunction_t)func, name, (uint16_t)stack, argument, prio, &hTask) != pdPASS) {
  418. hTask = NULL;
  419. }
  420. #endif
  421. }
  422. }
  423. }
  424. return ((osThreadId_t)hTask);
  425. }
  426. const char *osThreadGetName (osThreadId_t thread_id) {
  427. TaskHandle_t hTask = (TaskHandle_t)thread_id;
  428. const char *name;
  429. if (IS_IRQ() || (hTask == NULL)) {
  430. name = NULL;
  431. } else {
  432. name = pcTaskGetName (hTask);
  433. }
  434. return (name);
  435. }
  436. osThreadId_t osThreadGetId (void) {
  437. osThreadId_t id;
  438. id = (osThreadId_t)xTaskGetCurrentTaskHandle();
  439. return (id);
  440. }
  441. osThreadState_t osThreadGetState (osThreadId_t thread_id) {
  442. TaskHandle_t hTask = (TaskHandle_t)thread_id;
  443. osThreadState_t state;
  444. if (IS_IRQ() || (hTask == NULL)) {
  445. state = osThreadError;
  446. }
  447. else {
  448. switch (eTaskGetState (hTask)) {
  449. case eRunning: state = osThreadRunning; break;
  450. case eReady: state = osThreadReady; break;
  451. case eBlocked:
  452. case eSuspended: state = osThreadBlocked; break;
  453. case eDeleted: state = osThreadTerminated; break;
  454. case eInvalid:
  455. default: state = osThreadError; break;
  456. }
  457. }
  458. return (state);
  459. }
  460. uint32_t osThreadGetStackSpace (osThreadId_t thread_id) {
  461. TaskHandle_t hTask = (TaskHandle_t)thread_id;
  462. uint32_t sz;
  463. if (IS_IRQ() || (hTask == NULL)) {
  464. sz = 0U;
  465. } else {
  466. sz = (uint32_t)(uxTaskGetStackHighWaterMark(hTask) * sizeof(StackType_t));
  467. }
  468. return (sz);
  469. }
  470. osStatus_t osThreadSetPriority (osThreadId_t thread_id, osPriority_t priority) {
  471. TaskHandle_t hTask = (TaskHandle_t)thread_id;
  472. osStatus_t stat;
  473. if (IS_IRQ()) {
  474. stat = osErrorISR;
  475. }
  476. else if ((hTask == NULL) || (priority < osPriorityIdle) || (priority > osPriorityISR)) {
  477. stat = osErrorParameter;
  478. }
  479. else {
  480. stat = osOK;
  481. vTaskPrioritySet (hTask, (UBaseType_t)priority);
  482. }
  483. return (stat);
  484. }
  485. osPriority_t osThreadGetPriority (osThreadId_t thread_id) {
  486. TaskHandle_t hTask = (TaskHandle_t)thread_id;
  487. osPriority_t prio;
  488. if (IS_IRQ() || (hTask == NULL)) {
  489. prio = osPriorityError;
  490. } else {
  491. prio = (osPriority_t)((int32_t)uxTaskPriorityGet (hTask));
  492. }
  493. return (prio);
  494. }
  495. osStatus_t osThreadYield (void) {
  496. osStatus_t stat;
  497. if (IS_IRQ()) {
  498. stat = osErrorISR;
  499. } else {
  500. stat = osOK;
  501. taskYIELD();
  502. }
  503. return (stat);
  504. }
  505. #if (configUSE_OS2_THREAD_SUSPEND_RESUME == 1)
  506. osStatus_t osThreadSuspend (osThreadId_t thread_id) {
  507. TaskHandle_t hTask = (TaskHandle_t)thread_id;
  508. osStatus_t stat;
  509. if (IS_IRQ()) {
  510. stat = osErrorISR;
  511. }
  512. else if (hTask == NULL) {
  513. stat = osErrorParameter;
  514. }
  515. else {
  516. stat = osOK;
  517. vTaskSuspend (hTask);
  518. }
  519. return (stat);
  520. }
  521. osStatus_t osThreadResume (osThreadId_t thread_id) {
  522. TaskHandle_t hTask = (TaskHandle_t)thread_id;
  523. osStatus_t stat;
  524. if (IS_IRQ()) {
  525. stat = osErrorISR;
  526. }
  527. else if (hTask == NULL) {
  528. stat = osErrorParameter;
  529. }
  530. else {
  531. stat = osOK;
  532. vTaskResume (hTask);
  533. }
  534. return (stat);
  535. }
  536. #endif /* (configUSE_OS2_THREAD_SUSPEND_RESUME == 1) */
  537. __NO_RETURN void osThreadExit (void) {
  538. #ifndef USE_FreeRTOS_HEAP_1
  539. vTaskDelete (NULL);
  540. #endif
  541. for (;;);
  542. }
  543. osStatus_t osThreadTerminate (osThreadId_t thread_id) {
  544. TaskHandle_t hTask = (TaskHandle_t)thread_id;
  545. osStatus_t stat;
  546. #ifndef USE_FreeRTOS_HEAP_1
  547. eTaskState tstate;
  548. if (IS_IRQ()) {
  549. stat = osErrorISR;
  550. }
  551. else if (hTask == NULL) {
  552. stat = osErrorParameter;
  553. }
  554. else {
  555. tstate = eTaskGetState (hTask);
  556. if (tstate != eDeleted) {
  557. stat = osOK;
  558. vTaskDelete (hTask);
  559. } else {
  560. stat = osErrorResource;
  561. }
  562. }
  563. #else
  564. stat = osError;
  565. #endif
  566. return (stat);
  567. }
  568. uint32_t osThreadGetCount (void) {
  569. uint32_t count;
  570. if (IS_IRQ()) {
  571. count = 0U;
  572. } else {
  573. count = uxTaskGetNumberOfTasks();
  574. }
  575. return (count);
  576. }
  577. #if (configUSE_OS2_THREAD_ENUMERATE == 1)
  578. uint32_t osThreadEnumerate (osThreadId_t *thread_array, uint32_t array_items) {
  579. uint32_t i, count;
  580. TaskStatus_t *task;
  581. if (IS_IRQ() || (thread_array == NULL) || (array_items == 0U)) {
  582. count = 0U;
  583. } else {
  584. vTaskSuspendAll();
  585. count = uxTaskGetNumberOfTasks();
  586. task = pvPortMalloc (count * sizeof(TaskStatus_t));
  587. if (task != NULL) {
  588. count = uxTaskGetSystemState (task, count, NULL);
  589. for (i = 0U; (i < count) && (i < array_items); i++) {
  590. thread_array[i] = (osThreadId_t)task[i].xHandle;
  591. }
  592. count = i;
  593. }
  594. (void)xTaskResumeAll();
  595. vPortFree (task);
  596. }
  597. return (count);
  598. }
  599. #endif /* (configUSE_OS2_THREAD_ENUMERATE == 1) */
  600. #if (configUSE_OS2_THREAD_FLAGS == 1)
  601. uint32_t osThreadFlagsSet (osThreadId_t thread_id, uint32_t flags) {
  602. TaskHandle_t hTask = (TaskHandle_t)thread_id;
  603. uint32_t rflags;
  604. BaseType_t yield;
  605. if ((hTask == NULL) || ((flags & THREAD_FLAGS_INVALID_BITS) != 0U)) {
  606. rflags = (uint32_t)osErrorParameter;
  607. }
  608. else {
  609. rflags = (uint32_t)osError;
  610. if (IS_IRQ()) {
  611. yield = pdFALSE;
  612. (void)xTaskNotifyFromISR (hTask, flags, eSetBits, &yield);
  613. (void)xTaskNotifyAndQueryFromISR (hTask, 0, eNoAction, &rflags, NULL);
  614. portYIELD_FROM_ISR (yield);
  615. }
  616. else {
  617. (void)xTaskNotify (hTask, flags, eSetBits);
  618. (void)xTaskNotifyAndQuery (hTask, 0, eNoAction, &rflags);
  619. }
  620. }
  621. /* Return flags after setting */
  622. return (rflags);
  623. }
  624. uint32_t osThreadFlagsClear (uint32_t flags) {
  625. TaskHandle_t hTask;
  626. uint32_t rflags, cflags;
  627. if (IS_IRQ()) {
  628. rflags = (uint32_t)osErrorISR;
  629. }
  630. else if ((flags & THREAD_FLAGS_INVALID_BITS) != 0U) {
  631. rflags = (uint32_t)osErrorParameter;
  632. }
  633. else {
  634. hTask = xTaskGetCurrentTaskHandle();
  635. if (xTaskNotifyAndQuery (hTask, 0, eNoAction, &cflags) == pdPASS) {
  636. rflags = cflags;
  637. cflags &= ~flags;
  638. if (xTaskNotify (hTask, cflags, eSetValueWithOverwrite) != pdPASS) {
  639. rflags = (uint32_t)osError;
  640. }
  641. }
  642. else {
  643. rflags = (uint32_t)osError;
  644. }
  645. }
  646. /* Return flags before clearing */
  647. return (rflags);
  648. }
  649. uint32_t osThreadFlagsGet (void) {
  650. TaskHandle_t hTask;
  651. uint32_t rflags;
  652. if (IS_IRQ()) {
  653. rflags = (uint32_t)osErrorISR;
  654. }
  655. else {
  656. hTask = xTaskGetCurrentTaskHandle();
  657. if (xTaskNotifyAndQuery (hTask, 0, eNoAction, &rflags) != pdPASS) {
  658. rflags = (uint32_t)osError;
  659. }
  660. }
  661. return (rflags);
  662. }
  663. uint32_t osThreadFlagsWait (uint32_t flags, uint32_t options, uint32_t timeout) {
  664. uint32_t rflags, nval;
  665. uint32_t clear;
  666. TickType_t t0, td, tout;
  667. BaseType_t rval;
  668. if (IS_IRQ()) {
  669. rflags = (uint32_t)osErrorISR;
  670. }
  671. else if ((flags & THREAD_FLAGS_INVALID_BITS) != 0U) {
  672. rflags = (uint32_t)osErrorParameter;
  673. }
  674. else {
  675. if ((options & osFlagsNoClear) == osFlagsNoClear) {
  676. clear = 0U;
  677. } else {
  678. clear = flags;
  679. }
  680. rflags = 0U;
  681. tout = timeout;
  682. t0 = xTaskGetTickCount();
  683. do {
  684. rval = xTaskNotifyWait (0, clear, &nval, tout);
  685. if (rval == pdPASS) {
  686. rflags &= flags;
  687. rflags |= nval;
  688. if ((options & osFlagsWaitAll) == osFlagsWaitAll) {
  689. if ((flags & rflags) == flags) {
  690. break;
  691. } else {
  692. if (timeout == 0U) {
  693. rflags = (uint32_t)osErrorResource;
  694. break;
  695. }
  696. }
  697. }
  698. else {
  699. if ((flags & rflags) != 0) {
  700. break;
  701. } else {
  702. if (timeout == 0U) {
  703. rflags = (uint32_t)osErrorResource;
  704. break;
  705. }
  706. }
  707. }
  708. /* Update timeout */
  709. td = xTaskGetTickCount() - t0;
  710. if (td > tout) {
  711. tout = 0;
  712. } else {
  713. tout -= td;
  714. }
  715. }
  716. else {
  717. if (timeout == 0) {
  718. rflags = (uint32_t)osErrorResource;
  719. } else {
  720. rflags = (uint32_t)osErrorTimeout;
  721. }
  722. }
  723. }
  724. while (rval != pdFAIL);
  725. }
  726. /* Return flags before clearing */
  727. return (rflags);
  728. }
  729. #endif /* (configUSE_OS2_THREAD_FLAGS == 1) */
  730. osStatus_t osDelay (uint32_t ticks) {
  731. osStatus_t stat;
  732. if (IS_IRQ()) {
  733. stat = osErrorISR;
  734. }
  735. else {
  736. stat = osOK;
  737. if (ticks != 0U) {
  738. vTaskDelay(ticks);
  739. }
  740. }
  741. return (stat);
  742. }
  743. osStatus_t osDelayUntil (uint32_t ticks) {
  744. TickType_t tcnt, delay;
  745. osStatus_t stat;
  746. if (IS_IRQ()) {
  747. stat = osErrorISR;
  748. }
  749. else {
  750. stat = osOK;
  751. tcnt = xTaskGetTickCount();
  752. /* Determine remaining number of ticks to delay */
  753. delay = (TickType_t)ticks - tcnt;
  754. /* Check if target tick has not expired */
  755. if((delay != 0U) && (0 == (delay >> (8 * sizeof(TickType_t) - 1)))) {
  756. vTaskDelayUntil (&tcnt, delay);
  757. }
  758. else
  759. {
  760. /* No delay or already expired */
  761. stat = osErrorParameter;
  762. }
  763. }
  764. return (stat);
  765. }
  766. /*---------------------------------------------------------------------------*/
  767. #if (configUSE_OS2_TIMER == 1)
  768. static void TimerCallback (TimerHandle_t hTimer) {
  769. TimerCallback_t *callb;
  770. callb = (TimerCallback_t *)pvTimerGetTimerID (hTimer);
  771. if (callb != NULL) {
  772. callb->func (callb->arg);
  773. }
  774. }
  775. osTimerId_t osTimerNew (osTimerFunc_t func, osTimerType_t type, void *argument, const osTimerAttr_t *attr) {
  776. const char *name;
  777. TimerHandle_t hTimer;
  778. TimerCallback_t *callb;
  779. UBaseType_t reload;
  780. int32_t mem;
  781. hTimer = NULL;
  782. if (!IS_IRQ() && (func != NULL)) {
  783. /* Allocate memory to store callback function and argument */
  784. callb = pvPortMalloc (sizeof(TimerCallback_t));
  785. if (callb != NULL) {
  786. callb->func = func;
  787. callb->arg = argument;
  788. if (type == osTimerOnce) {
  789. reload = pdFALSE;
  790. } else {
  791. reload = pdTRUE;
  792. }
  793. mem = -1;
  794. name = NULL;
  795. if (attr != NULL) {
  796. if (attr->name != NULL) {
  797. name = attr->name;
  798. }
  799. if ((attr->cb_mem != NULL) && (attr->cb_size >= sizeof(StaticTimer_t))) {
  800. mem = 1;
  801. }
  802. else {
  803. if ((attr->cb_mem == NULL) && (attr->cb_size == 0U)) {
  804. mem = 0;
  805. }
  806. }
  807. }
  808. else {
  809. mem = 0;
  810. }
  811. if (mem == 1) {
  812. #if (configSUPPORT_STATIC_ALLOCATION == 1)
  813. hTimer = xTimerCreateStatic (name, 1, reload, callb, TimerCallback, (StaticTimer_t *)attr->cb_mem);
  814. #endif
  815. }
  816. else {
  817. if (mem == 0) {
  818. #if (configSUPPORT_DYNAMIC_ALLOCATION == 1)
  819. hTimer = xTimerCreate (name, 1, reload, callb, TimerCallback);
  820. #endif
  821. }
  822. }
  823. if ((hTimer == NULL) && (callb != NULL)) {
  824. vPortFree (callb);
  825. }
  826. }
  827. }
  828. return ((osTimerId_t)hTimer);
  829. }
  830. const char *osTimerGetName (osTimerId_t timer_id) {
  831. TimerHandle_t hTimer = (TimerHandle_t)timer_id;
  832. const char *p;
  833. if (IS_IRQ() || (hTimer == NULL)) {
  834. p = NULL;
  835. } else {
  836. p = pcTimerGetName (hTimer);
  837. }
  838. return (p);
  839. }
  840. osStatus_t osTimerStart (osTimerId_t timer_id, uint32_t ticks) {
  841. TimerHandle_t hTimer = (TimerHandle_t)timer_id;
  842. osStatus_t stat;
  843. if (IS_IRQ()) {
  844. stat = osErrorISR;
  845. }
  846. else if (hTimer == NULL) {
  847. stat = osErrorParameter;
  848. }
  849. else {
  850. if (xTimerChangePeriod (hTimer, ticks, 0) == pdPASS) {
  851. stat = osOK;
  852. } else {
  853. stat = osErrorResource;
  854. }
  855. }
  856. return (stat);
  857. }
  858. osStatus_t osTimerStop (osTimerId_t timer_id) {
  859. TimerHandle_t hTimer = (TimerHandle_t)timer_id;
  860. osStatus_t stat;
  861. if (IS_IRQ()) {
  862. stat = osErrorISR;
  863. }
  864. else if (hTimer == NULL) {
  865. stat = osErrorParameter;
  866. }
  867. else {
  868. if (xTimerIsTimerActive (hTimer) == pdFALSE) {
  869. stat = osErrorResource;
  870. }
  871. else {
  872. if (xTimerStop (hTimer, 0) == pdPASS) {
  873. stat = osOK;
  874. } else {
  875. stat = osError;
  876. }
  877. }
  878. }
  879. return (stat);
  880. }
  881. uint32_t osTimerIsRunning (osTimerId_t timer_id) {
  882. TimerHandle_t hTimer = (TimerHandle_t)timer_id;
  883. uint32_t running;
  884. if (IS_IRQ() || (hTimer == NULL)) {
  885. running = 0U;
  886. } else {
  887. running = (uint32_t)xTimerIsTimerActive (hTimer);
  888. }
  889. return (running);
  890. }
  891. osStatus_t osTimerDelete (osTimerId_t timer_id) {
  892. TimerHandle_t hTimer = (TimerHandle_t)timer_id;
  893. osStatus_t stat;
  894. #ifndef USE_FreeRTOS_HEAP_1
  895. TimerCallback_t *callb;
  896. if (IS_IRQ()) {
  897. stat = osErrorISR;
  898. }
  899. else if (hTimer == NULL) {
  900. stat = osErrorParameter;
  901. }
  902. else {
  903. callb = (TimerCallback_t *)pvTimerGetTimerID (hTimer);
  904. if (xTimerDelete (hTimer, 0) == pdPASS) {
  905. vPortFree (callb);
  906. stat = osOK;
  907. } else {
  908. stat = osErrorResource;
  909. }
  910. }
  911. #else
  912. stat = osError;
  913. #endif
  914. return (stat);
  915. }
  916. #endif /* (configUSE_OS2_TIMER == 1) */
  917. /*---------------------------------------------------------------------------*/
  918. osEventFlagsId_t osEventFlagsNew (const osEventFlagsAttr_t *attr) {
  919. EventGroupHandle_t hEventGroup;
  920. int32_t mem;
  921. hEventGroup = NULL;
  922. if (!IS_IRQ()) {
  923. mem = -1;
  924. if (attr != NULL) {
  925. if ((attr->cb_mem != NULL) && (attr->cb_size >= sizeof(StaticEventGroup_t))) {
  926. mem = 1;
  927. }
  928. else {
  929. if ((attr->cb_mem == NULL) && (attr->cb_size == 0U)) {
  930. mem = 0;
  931. }
  932. }
  933. }
  934. else {
  935. mem = 0;
  936. }
  937. if (mem == 1) {
  938. #if (configSUPPORT_STATIC_ALLOCATION == 1)
  939. hEventGroup = xEventGroupCreateStatic (attr->cb_mem);
  940. #endif
  941. }
  942. else {
  943. if (mem == 0) {
  944. #if (configSUPPORT_DYNAMIC_ALLOCATION == 1)
  945. hEventGroup = xEventGroupCreate();
  946. #endif
  947. }
  948. }
  949. }
  950. return ((osEventFlagsId_t)hEventGroup);
  951. }
  952. uint32_t osEventFlagsSet (osEventFlagsId_t ef_id, uint32_t flags) {
  953. EventGroupHandle_t hEventGroup = (EventGroupHandle_t)ef_id;
  954. uint32_t rflags;
  955. BaseType_t yield;
  956. if ((hEventGroup == NULL) || ((flags & EVENT_FLAGS_INVALID_BITS) != 0U)) {
  957. rflags = (uint32_t)osErrorParameter;
  958. }
  959. else if (IS_IRQ()) {
  960. #if (configUSE_OS2_EVENTFLAGS_FROM_ISR == 0)
  961. (void)yield;
  962. /* Enable timers and xTimerPendFunctionCall function to support osEventFlagsSet from ISR */
  963. rflags = (uint32_t)osErrorResource;
  964. #else
  965. yield = pdFALSE;
  966. if (xEventGroupSetBitsFromISR (hEventGroup, (EventBits_t)flags, &yield) == pdFAIL) {
  967. rflags = (uint32_t)osErrorResource;
  968. } else {
  969. rflags = flags;
  970. portYIELD_FROM_ISR (yield);
  971. }
  972. #endif
  973. }
  974. else {
  975. rflags = xEventGroupSetBits (hEventGroup, (EventBits_t)flags);
  976. }
  977. return (rflags);
  978. }
  979. uint32_t osEventFlagsClear (osEventFlagsId_t ef_id, uint32_t flags) {
  980. EventGroupHandle_t hEventGroup = (EventGroupHandle_t)ef_id;
  981. uint32_t rflags;
  982. if ((hEventGroup == NULL) || ((flags & EVENT_FLAGS_INVALID_BITS) != 0U)) {
  983. rflags = (uint32_t)osErrorParameter;
  984. }
  985. else if (IS_IRQ()) {
  986. #if (configUSE_OS2_EVENTFLAGS_FROM_ISR == 0)
  987. /* Enable timers and xTimerPendFunctionCall function to support osEventFlagsSet from ISR */
  988. rflags = (uint32_t)osErrorResource;
  989. #else
  990. rflags = xEventGroupGetBitsFromISR (hEventGroup);
  991. if (xEventGroupClearBitsFromISR (hEventGroup, (EventBits_t)flags) == pdFAIL) {
  992. rflags = (uint32_t)osErrorResource;
  993. }
  994. #endif
  995. }
  996. else {
  997. rflags = xEventGroupClearBits (hEventGroup, (EventBits_t)flags);
  998. }
  999. return (rflags);
  1000. }
  1001. uint32_t osEventFlagsGet (osEventFlagsId_t ef_id) {
  1002. EventGroupHandle_t hEventGroup = (EventGroupHandle_t)ef_id;
  1003. uint32_t rflags;
  1004. if (ef_id == NULL) {
  1005. rflags = 0U;
  1006. }
  1007. else if (IS_IRQ()) {
  1008. rflags = xEventGroupGetBitsFromISR (hEventGroup);
  1009. }
  1010. else {
  1011. rflags = xEventGroupGetBits (hEventGroup);
  1012. }
  1013. return (rflags);
  1014. }
  1015. uint32_t osEventFlagsWait (osEventFlagsId_t ef_id, uint32_t flags, uint32_t options, uint32_t timeout) {
  1016. EventGroupHandle_t hEventGroup = (EventGroupHandle_t)ef_id;
  1017. BaseType_t wait_all;
  1018. BaseType_t exit_clr;
  1019. uint32_t rflags;
  1020. if ((hEventGroup == NULL) || ((flags & EVENT_FLAGS_INVALID_BITS) != 0U)) {
  1021. rflags = (uint32_t)osErrorParameter;
  1022. }
  1023. else if (IS_IRQ()) {
  1024. rflags = (uint32_t)osErrorISR;
  1025. }
  1026. else {
  1027. if (options & osFlagsWaitAll) {
  1028. wait_all = pdTRUE;
  1029. } else {
  1030. wait_all = pdFAIL;
  1031. }
  1032. if (options & osFlagsNoClear) {
  1033. exit_clr = pdFAIL;
  1034. } else {
  1035. exit_clr = pdTRUE;
  1036. }
  1037. rflags = xEventGroupWaitBits (hEventGroup, (EventBits_t)flags, exit_clr, wait_all, (TickType_t)timeout);
  1038. if (options & osFlagsWaitAll) {
  1039. if ((flags & rflags) != flags) {
  1040. if (timeout > 0U) {
  1041. rflags = (uint32_t)osErrorTimeout;
  1042. } else {
  1043. rflags = (uint32_t)osErrorResource;
  1044. }
  1045. }
  1046. }
  1047. else {
  1048. if ((flags & rflags) == 0U) {
  1049. if (timeout > 0U) {
  1050. rflags = (uint32_t)osErrorTimeout;
  1051. } else {
  1052. rflags = (uint32_t)osErrorResource;
  1053. }
  1054. }
  1055. }
  1056. }
  1057. return (rflags);
  1058. }
  1059. osStatus_t osEventFlagsDelete (osEventFlagsId_t ef_id) {
  1060. EventGroupHandle_t hEventGroup = (EventGroupHandle_t)ef_id;
  1061. osStatus_t stat;
  1062. #ifndef USE_FreeRTOS_HEAP_1
  1063. if (IS_IRQ()) {
  1064. stat = osErrorISR;
  1065. }
  1066. else if (hEventGroup == NULL) {
  1067. stat = osErrorParameter;
  1068. }
  1069. else {
  1070. stat = osOK;
  1071. vEventGroupDelete (hEventGroup);
  1072. }
  1073. #else
  1074. stat = osError;
  1075. #endif
  1076. return (stat);
  1077. }
  1078. /*---------------------------------------------------------------------------*/
  1079. #if (configUSE_OS2_MUTEX == 1)
  1080. osMutexId_t osMutexNew (const osMutexAttr_t *attr) {
  1081. SemaphoreHandle_t hMutex;
  1082. uint32_t type;
  1083. uint32_t rmtx;
  1084. int32_t mem;
  1085. #if (configQUEUE_REGISTRY_SIZE > 0)
  1086. const char *name;
  1087. #endif
  1088. hMutex = NULL;
  1089. if (!IS_IRQ()) {
  1090. if (attr != NULL) {
  1091. type = attr->attr_bits;
  1092. } else {
  1093. type = 0U;
  1094. }
  1095. if ((type & osMutexRecursive) == osMutexRecursive) {
  1096. rmtx = 1U;
  1097. } else {
  1098. rmtx = 0U;
  1099. }
  1100. if ((type & osMutexRobust) != osMutexRobust) {
  1101. mem = -1;
  1102. if (attr != NULL) {
  1103. if ((attr->cb_mem != NULL) && (attr->cb_size >= sizeof(StaticSemaphore_t))) {
  1104. mem = 1;
  1105. }
  1106. else {
  1107. if ((attr->cb_mem == NULL) && (attr->cb_size == 0U)) {
  1108. mem = 0;
  1109. }
  1110. }
  1111. }
  1112. else {
  1113. mem = 0;
  1114. }
  1115. if (mem == 1) {
  1116. #if (configSUPPORT_STATIC_ALLOCATION == 1)
  1117. if (rmtx != 0U) {
  1118. #if (configUSE_RECURSIVE_MUTEXES == 1)
  1119. hMutex = xSemaphoreCreateRecursiveMutexStatic (attr->cb_mem);
  1120. #endif
  1121. }
  1122. else {
  1123. hMutex = xSemaphoreCreateMutexStatic (attr->cb_mem);
  1124. }
  1125. #endif
  1126. }
  1127. else {
  1128. if (mem == 0) {
  1129. #if (configSUPPORT_DYNAMIC_ALLOCATION == 1)
  1130. if (rmtx != 0U) {
  1131. #if (configUSE_RECURSIVE_MUTEXES == 1)
  1132. hMutex = xSemaphoreCreateRecursiveMutex ();
  1133. #endif
  1134. } else {
  1135. hMutex = xSemaphoreCreateMutex ();
  1136. }
  1137. #endif
  1138. }
  1139. }
  1140. #if (configQUEUE_REGISTRY_SIZE > 0)
  1141. if (hMutex != NULL) {
  1142. if (attr != NULL) {
  1143. name = attr->name;
  1144. } else {
  1145. name = NULL;
  1146. }
  1147. vQueueAddToRegistry (hMutex, name);
  1148. }
  1149. #endif
  1150. if ((hMutex != NULL) && (rmtx != 0U)) {
  1151. hMutex = (SemaphoreHandle_t)((uint32_t)hMutex | 1U);
  1152. }
  1153. }
  1154. }
  1155. return ((osMutexId_t)hMutex);
  1156. }
  1157. osStatus_t osMutexAcquire (osMutexId_t mutex_id, uint32_t timeout) {
  1158. SemaphoreHandle_t hMutex;
  1159. osStatus_t stat;
  1160. uint32_t rmtx;
  1161. hMutex = (SemaphoreHandle_t)((uint32_t)mutex_id & ~1U);
  1162. rmtx = (uint32_t)mutex_id & 1U;
  1163. stat = osOK;
  1164. if (IS_IRQ()) {
  1165. stat = osErrorISR;
  1166. }
  1167. else if (hMutex == NULL) {
  1168. stat = osErrorParameter;
  1169. }
  1170. else {
  1171. if (rmtx != 0U) {
  1172. #if (configUSE_RECURSIVE_MUTEXES == 1)
  1173. if (xSemaphoreTakeRecursive (hMutex, timeout) != pdPASS) {
  1174. if (timeout != 0U) {
  1175. stat = osErrorTimeout;
  1176. } else {
  1177. stat = osErrorResource;
  1178. }
  1179. }
  1180. #endif
  1181. }
  1182. else {
  1183. if (xSemaphoreTake (hMutex, timeout) != pdPASS) {
  1184. if (timeout != 0U) {
  1185. stat = osErrorTimeout;
  1186. } else {
  1187. stat = osErrorResource;
  1188. }
  1189. }
  1190. }
  1191. }
  1192. return (stat);
  1193. }
  1194. osStatus_t osMutexRelease (osMutexId_t mutex_id) {
  1195. SemaphoreHandle_t hMutex;
  1196. osStatus_t stat;
  1197. uint32_t rmtx;
  1198. hMutex = (SemaphoreHandle_t)((uint32_t)mutex_id & ~1U);
  1199. rmtx = (uint32_t)mutex_id & 1U;
  1200. stat = osOK;
  1201. if (IS_IRQ()) {
  1202. stat = osErrorISR;
  1203. }
  1204. else if (hMutex == NULL) {
  1205. stat = osErrorParameter;
  1206. }
  1207. else {
  1208. if (rmtx != 0U) {
  1209. #if (configUSE_RECURSIVE_MUTEXES == 1)
  1210. if (xSemaphoreGiveRecursive (hMutex) != pdPASS) {
  1211. stat = osErrorResource;
  1212. }
  1213. #endif
  1214. }
  1215. else {
  1216. if (xSemaphoreGive (hMutex) != pdPASS) {
  1217. stat = osErrorResource;
  1218. }
  1219. }
  1220. }
  1221. return (stat);
  1222. }
  1223. osThreadId_t osMutexGetOwner (osMutexId_t mutex_id) {
  1224. SemaphoreHandle_t hMutex;
  1225. osThreadId_t owner;
  1226. hMutex = (SemaphoreHandle_t)((uint32_t)mutex_id & ~1U);
  1227. if (IS_IRQ() || (hMutex == NULL)) {
  1228. owner = NULL;
  1229. } else {
  1230. owner = (osThreadId_t)xSemaphoreGetMutexHolder (hMutex);
  1231. }
  1232. return (owner);
  1233. }
  1234. osStatus_t osMutexDelete (osMutexId_t mutex_id) {
  1235. osStatus_t stat;
  1236. #ifndef USE_FreeRTOS_HEAP_1
  1237. SemaphoreHandle_t hMutex;
  1238. hMutex = (SemaphoreHandle_t)((uint32_t)mutex_id & ~1U);
  1239. if (IS_IRQ()) {
  1240. stat = osErrorISR;
  1241. }
  1242. else if (hMutex == NULL) {
  1243. stat = osErrorParameter;
  1244. }
  1245. else {
  1246. #if (configQUEUE_REGISTRY_SIZE > 0)
  1247. vQueueUnregisterQueue (hMutex);
  1248. #endif
  1249. stat = osOK;
  1250. vSemaphoreDelete (hMutex);
  1251. }
  1252. #else
  1253. stat = osError;
  1254. #endif
  1255. return (stat);
  1256. }
  1257. #endif /* (configUSE_OS2_MUTEX == 1) */
  1258. /*---------------------------------------------------------------------------*/
  1259. osSemaphoreId_t osSemaphoreNew (uint32_t max_count, uint32_t initial_count, const osSemaphoreAttr_t *attr) {
  1260. SemaphoreHandle_t hSemaphore;
  1261. int32_t mem;
  1262. #if (configQUEUE_REGISTRY_SIZE > 0)
  1263. const char *name;
  1264. #endif
  1265. hSemaphore = NULL;
  1266. if (!IS_IRQ() && (max_count > 0U) && (initial_count <= max_count)) {
  1267. mem = -1;
  1268. if (attr != NULL) {
  1269. if ((attr->cb_mem != NULL) && (attr->cb_size >= sizeof(StaticSemaphore_t))) {
  1270. mem = 1;
  1271. }
  1272. else {
  1273. if ((attr->cb_mem == NULL) && (attr->cb_size == 0U)) {
  1274. mem = 0;
  1275. }
  1276. }
  1277. }
  1278. else {
  1279. mem = 0;
  1280. }
  1281. if (mem != -1) {
  1282. if (max_count == 1U) {
  1283. if (mem == 1) {
  1284. #if (configSUPPORT_STATIC_ALLOCATION == 1)
  1285. hSemaphore = xSemaphoreCreateBinaryStatic ((StaticSemaphore_t *)attr->cb_mem);
  1286. #endif
  1287. }
  1288. else {
  1289. #if (configSUPPORT_DYNAMIC_ALLOCATION == 1)
  1290. hSemaphore = xSemaphoreCreateBinary();
  1291. #endif
  1292. }
  1293. if ((hSemaphore != NULL) && (initial_count != 0U)) {
  1294. if (xSemaphoreGive (hSemaphore) != pdPASS) {
  1295. vSemaphoreDelete (hSemaphore);
  1296. hSemaphore = NULL;
  1297. }
  1298. }
  1299. }
  1300. else {
  1301. if (mem == 1) {
  1302. #if (configSUPPORT_STATIC_ALLOCATION == 1)
  1303. hSemaphore = xSemaphoreCreateCountingStatic (max_count, initial_count, (StaticSemaphore_t *)attr->cb_mem);
  1304. #endif
  1305. }
  1306. else {
  1307. #if (configSUPPORT_DYNAMIC_ALLOCATION == 1)
  1308. hSemaphore = xSemaphoreCreateCounting (max_count, initial_count);
  1309. #endif
  1310. }
  1311. }
  1312. #if (configQUEUE_REGISTRY_SIZE > 0)
  1313. if (hSemaphore != NULL) {
  1314. if (attr != NULL) {
  1315. name = attr->name;
  1316. } else {
  1317. name = NULL;
  1318. }
  1319. vQueueAddToRegistry (hSemaphore, name);
  1320. }
  1321. #endif
  1322. }
  1323. }
  1324. return ((osSemaphoreId_t)hSemaphore);
  1325. }
  1326. osStatus_t osSemaphoreAcquire (osSemaphoreId_t semaphore_id, uint32_t timeout) {
  1327. SemaphoreHandle_t hSemaphore = (SemaphoreHandle_t)semaphore_id;
  1328. osStatus_t stat;
  1329. BaseType_t yield;
  1330. stat = osOK;
  1331. if (hSemaphore == NULL) {
  1332. stat = osErrorParameter;
  1333. }
  1334. else if (IS_IRQ()) {
  1335. if (timeout != 0U) {
  1336. stat = osErrorParameter;
  1337. }
  1338. else {
  1339. yield = pdFALSE;
  1340. if (xSemaphoreTakeFromISR (hSemaphore, &yield) != pdPASS) {
  1341. stat = osErrorResource;
  1342. } else {
  1343. portYIELD_FROM_ISR (yield);
  1344. }
  1345. }
  1346. }
  1347. else {
  1348. if (xSemaphoreTake (hSemaphore, (TickType_t)timeout) != pdPASS) {
  1349. if (timeout != 0U) {
  1350. stat = osErrorTimeout;
  1351. } else {
  1352. stat = osErrorResource;
  1353. }
  1354. }
  1355. }
  1356. return (stat);
  1357. }
  1358. osStatus_t osSemaphoreRelease (osSemaphoreId_t semaphore_id) {
  1359. SemaphoreHandle_t hSemaphore = (SemaphoreHandle_t)semaphore_id;
  1360. osStatus_t stat;
  1361. BaseType_t yield;
  1362. stat = osOK;
  1363. if (hSemaphore == NULL) {
  1364. stat = osErrorParameter;
  1365. }
  1366. else if (IS_IRQ()) {
  1367. yield = pdFALSE;
  1368. if (xSemaphoreGiveFromISR (hSemaphore, &yield) != pdTRUE) {
  1369. stat = osErrorResource;
  1370. } else {
  1371. portYIELD_FROM_ISR (yield);
  1372. }
  1373. }
  1374. else {
  1375. if (xSemaphoreGive (hSemaphore) != pdPASS) {
  1376. stat = osErrorResource;
  1377. }
  1378. }
  1379. return (stat);
  1380. }
  1381. uint32_t osSemaphoreGetCount (osSemaphoreId_t semaphore_id) {
  1382. SemaphoreHandle_t hSemaphore = (SemaphoreHandle_t)semaphore_id;
  1383. uint32_t count;
  1384. if (hSemaphore == NULL) {
  1385. count = 0U;
  1386. }
  1387. else if (IS_IRQ()) {
  1388. count = uxQueueMessagesWaitingFromISR (hSemaphore);
  1389. } else {
  1390. count = (uint32_t)uxSemaphoreGetCount (hSemaphore);
  1391. }
  1392. return (count);
  1393. }
  1394. osStatus_t osSemaphoreDelete (osSemaphoreId_t semaphore_id) {
  1395. SemaphoreHandle_t hSemaphore = (SemaphoreHandle_t)semaphore_id;
  1396. osStatus_t stat;
  1397. #ifndef USE_FreeRTOS_HEAP_1
  1398. if (IS_IRQ()) {
  1399. stat = osErrorISR;
  1400. }
  1401. else if (hSemaphore == NULL) {
  1402. stat = osErrorParameter;
  1403. }
  1404. else {
  1405. #if (configQUEUE_REGISTRY_SIZE > 0)
  1406. vQueueUnregisterQueue (hSemaphore);
  1407. #endif
  1408. stat = osOK;
  1409. vSemaphoreDelete (hSemaphore);
  1410. }
  1411. #else
  1412. stat = osError;
  1413. #endif
  1414. return (stat);
  1415. }
  1416. /*---------------------------------------------------------------------------*/
  1417. osMessageQueueId_t osMessageQueueNew (uint32_t msg_count, uint32_t msg_size, const osMessageQueueAttr_t *attr) {
  1418. QueueHandle_t hQueue;
  1419. int32_t mem;
  1420. #if (configQUEUE_REGISTRY_SIZE > 0)
  1421. const char *name;
  1422. #endif
  1423. hQueue = NULL;
  1424. if (!IS_IRQ() && (msg_count > 0U) && (msg_size > 0U)) {
  1425. mem = -1;
  1426. if (attr != NULL) {
  1427. if ((attr->cb_mem != NULL) && (attr->cb_size >= sizeof(StaticQueue_t)) &&
  1428. (attr->mq_mem != NULL) && (attr->mq_size >= (msg_count * msg_size))) {
  1429. mem = 1;
  1430. }
  1431. else {
  1432. if ((attr->cb_mem == NULL) && (attr->cb_size == 0U) &&
  1433. (attr->mq_mem == NULL) && (attr->mq_size == 0U)) {
  1434. mem = 0;
  1435. }
  1436. }
  1437. }
  1438. else {
  1439. mem = 0;
  1440. }
  1441. if (mem == 1) {
  1442. #if (configSUPPORT_STATIC_ALLOCATION == 1)
  1443. hQueue = xQueueCreateStatic (msg_count, msg_size, attr->mq_mem, attr->cb_mem);
  1444. #endif
  1445. }
  1446. else {
  1447. if (mem == 0) {
  1448. #if (configSUPPORT_DYNAMIC_ALLOCATION == 1)
  1449. hQueue = xQueueCreate (msg_count, msg_size);
  1450. #endif
  1451. }
  1452. }
  1453. #if (configQUEUE_REGISTRY_SIZE > 0)
  1454. if (hQueue != NULL) {
  1455. if (attr != NULL) {
  1456. name = attr->name;
  1457. } else {
  1458. name = NULL;
  1459. }
  1460. vQueueAddToRegistry (hQueue, name);
  1461. }
  1462. #endif
  1463. }
  1464. return ((osMessageQueueId_t)hQueue);
  1465. }
  1466. osStatus_t osMessageQueuePut (osMessageQueueId_t mq_id, const void *msg_ptr, uint8_t msg_prio, uint32_t timeout) {
  1467. QueueHandle_t hQueue = (QueueHandle_t)mq_id;
  1468. osStatus_t stat;
  1469. BaseType_t yield;
  1470. (void)msg_prio; /* Message priority is ignored */
  1471. stat = osOK;
  1472. if (IS_IRQ()) {
  1473. if ((hQueue == NULL) || (msg_ptr == NULL) || (timeout != 0U)) {
  1474. stat = osErrorParameter;
  1475. }
  1476. else {
  1477. yield = pdFALSE;
  1478. if (xQueueSendToBackFromISR (hQueue, msg_ptr, &yield) != pdTRUE) {
  1479. stat = osErrorResource;
  1480. } else {
  1481. portYIELD_FROM_ISR (yield);
  1482. }
  1483. }
  1484. }
  1485. else {
  1486. if ((hQueue == NULL) || (msg_ptr == NULL)) {
  1487. stat = osErrorParameter;
  1488. }
  1489. else {
  1490. if (xQueueSendToBack (hQueue, msg_ptr, (TickType_t)timeout) != pdPASS) {
  1491. if (timeout != 0U) {
  1492. stat = osErrorTimeout;
  1493. } else {
  1494. stat = osErrorResource;
  1495. }
  1496. }
  1497. }
  1498. }
  1499. return (stat);
  1500. }
  1501. osStatus_t osMessageQueueGet (osMessageQueueId_t mq_id, void *msg_ptr, uint8_t *msg_prio, uint32_t timeout) {
  1502. QueueHandle_t hQueue = (QueueHandle_t)mq_id;
  1503. osStatus_t stat;
  1504. BaseType_t yield;
  1505. (void)msg_prio; /* Message priority is ignored */
  1506. stat = osOK;
  1507. if (IS_IRQ()) {
  1508. if ((hQueue == NULL) || (msg_ptr == NULL) || (timeout != 0U)) {
  1509. stat = osErrorParameter;
  1510. }
  1511. else {
  1512. yield = pdFALSE;
  1513. if (xQueueReceiveFromISR (hQueue, msg_ptr, &yield) != pdPASS) {
  1514. stat = osErrorResource;
  1515. } else {
  1516. portYIELD_FROM_ISR (yield);
  1517. }
  1518. }
  1519. }
  1520. else {
  1521. if ((hQueue == NULL) || (msg_ptr == NULL)) {
  1522. stat = osErrorParameter;
  1523. }
  1524. else {
  1525. if (xQueueReceive (hQueue, msg_ptr, (TickType_t)timeout) != pdPASS) {
  1526. if (timeout != 0U) {
  1527. stat = osErrorTimeout;
  1528. } else {
  1529. stat = osErrorResource;
  1530. }
  1531. }
  1532. }
  1533. }
  1534. return (stat);
  1535. }
  1536. uint32_t osMessageQueueGetCapacity (osMessageQueueId_t mq_id) {
  1537. StaticQueue_t *mq = (StaticQueue_t *)mq_id;
  1538. uint32_t capacity;
  1539. if (mq == NULL) {
  1540. capacity = 0U;
  1541. } else {
  1542. /* capacity = pxQueue->uxLength */
  1543. capacity = mq->uxDummy4[1];
  1544. }
  1545. return (capacity);
  1546. }
  1547. uint32_t osMessageQueueGetMsgSize (osMessageQueueId_t mq_id) {
  1548. StaticQueue_t *mq = (StaticQueue_t *)mq_id;
  1549. uint32_t size;
  1550. if (mq == NULL) {
  1551. size = 0U;
  1552. } else {
  1553. /* size = pxQueue->uxItemSize */
  1554. size = mq->uxDummy4[2];
  1555. }
  1556. return (size);
  1557. }
  1558. uint32_t osMessageQueueGetCount (osMessageQueueId_t mq_id) {
  1559. QueueHandle_t hQueue = (QueueHandle_t)mq_id;
  1560. UBaseType_t count;
  1561. if (hQueue == NULL) {
  1562. count = 0U;
  1563. }
  1564. else if (IS_IRQ()) {
  1565. count = uxQueueMessagesWaitingFromISR (hQueue);
  1566. }
  1567. else {
  1568. count = uxQueueMessagesWaiting (hQueue);
  1569. }
  1570. return ((uint32_t)count);
  1571. }
  1572. uint32_t osMessageQueueGetSpace (osMessageQueueId_t mq_id) {
  1573. StaticQueue_t *mq = (StaticQueue_t *)mq_id;
  1574. uint32_t space;
  1575. uint32_t isrm;
  1576. if (mq == NULL) {
  1577. space = 0U;
  1578. }
  1579. else if (IS_IRQ()) {
  1580. isrm = taskENTER_CRITICAL_FROM_ISR();
  1581. /* space = pxQueue->uxLength - pxQueue->uxMessagesWaiting; */
  1582. space = mq->uxDummy4[1] - mq->uxDummy4[0];
  1583. taskEXIT_CRITICAL_FROM_ISR(isrm);
  1584. }
  1585. else {
  1586. space = (uint32_t)uxQueueSpacesAvailable ((QueueHandle_t)mq);
  1587. }
  1588. return (space);
  1589. }
  1590. osStatus_t osMessageQueueReset (osMessageQueueId_t mq_id) {
  1591. QueueHandle_t hQueue = (QueueHandle_t)mq_id;
  1592. osStatus_t stat;
  1593. if (IS_IRQ()) {
  1594. stat = osErrorISR;
  1595. }
  1596. else if (hQueue == NULL) {
  1597. stat = osErrorParameter;
  1598. }
  1599. else {
  1600. stat = osOK;
  1601. (void)xQueueReset (hQueue);
  1602. }
  1603. return (stat);
  1604. }
  1605. osStatus_t osMessageQueueDelete (osMessageQueueId_t mq_id) {
  1606. QueueHandle_t hQueue = (QueueHandle_t)mq_id;
  1607. osStatus_t stat;
  1608. #ifndef USE_FreeRTOS_HEAP_1
  1609. if (IS_IRQ()) {
  1610. stat = osErrorISR;
  1611. }
  1612. else if (hQueue == NULL) {
  1613. stat = osErrorParameter;
  1614. }
  1615. else {
  1616. #if (configQUEUE_REGISTRY_SIZE > 0)
  1617. vQueueUnregisterQueue (hQueue);
  1618. #endif
  1619. stat = osOK;
  1620. vQueueDelete (hQueue);
  1621. }
  1622. #else
  1623. stat = osError;
  1624. #endif
  1625. return (stat);
  1626. }
  1627. /*---------------------------------------------------------------------------*/
  1628. #ifdef FREERTOS_MPOOL_H_
  1629. /* Static memory pool functions */
  1630. static void FreeBlock (MemPool_t *mp, void *block);
  1631. static void *AllocBlock (MemPool_t *mp);
  1632. static void *CreateBlock (MemPool_t *mp);
  1633. osMemoryPoolId_t osMemoryPoolNew (uint32_t block_count, uint32_t block_size, const osMemoryPoolAttr_t *attr) {
  1634. MemPool_t *mp;
  1635. const char *name;
  1636. int32_t mem_cb, mem_mp;
  1637. uint32_t sz;
  1638. if (IS_IRQ()) {
  1639. mp = NULL;
  1640. }
  1641. else if ((block_count == 0U) || (block_size == 0U)) {
  1642. mp = NULL;
  1643. }
  1644. else {
  1645. mp = NULL;
  1646. sz = MEMPOOL_ARR_SIZE (block_count, block_size);
  1647. name = NULL;
  1648. mem_cb = -1;
  1649. mem_mp = -1;
  1650. if (attr != NULL) {
  1651. if (attr->name != NULL) {
  1652. name = attr->name;
  1653. }
  1654. if ((attr->cb_mem != NULL) && (attr->cb_size >= sizeof(MemPool_t))) {
  1655. /* Static control block is provided */
  1656. mem_cb = 1;
  1657. }
  1658. else if ((attr->cb_mem == NULL) && (attr->cb_size == 0U)) {
  1659. /* Allocate control block memory on heap */
  1660. mem_cb = 0;
  1661. }
  1662. if ((attr->mp_mem == NULL) && (attr->mp_size == 0U)) {
  1663. /* Allocate memory array on heap */
  1664. mem_mp = 0;
  1665. }
  1666. else {
  1667. if (attr->mp_mem != NULL) {
  1668. /* Check if array is 4-byte aligned */
  1669. if (((uint32_t)attr->mp_mem & 3U) == 0U) {
  1670. /* Check if array big enough */
  1671. if (attr->mp_size >= sz) {
  1672. /* Static memory pool array is provided */
  1673. mem_mp = 1;
  1674. }
  1675. }
  1676. }
  1677. }
  1678. }
  1679. else {
  1680. /* Attributes not provided, allocate memory on heap */
  1681. mem_cb = 0;
  1682. mem_mp = 0;
  1683. }
  1684. if (mem_cb == 0) {
  1685. mp = pvPortMalloc (sizeof(MemPool_t));
  1686. } else {
  1687. mp = attr->cb_mem;
  1688. }
  1689. if (mp != NULL) {
  1690. /* Create a semaphore (max count == initial count == block_count) */
  1691. #if (configSUPPORT_STATIC_ALLOCATION == 1)
  1692. mp->sem = xSemaphoreCreateCountingStatic (block_count, block_count, &mp->mem_sem);
  1693. #elif (configSUPPORT_DYNAMIC_ALLOCATION == 1)
  1694. mp->sem = xSemaphoreCreateCounting (block_count, block_count);
  1695. #else
  1696. mp->sem == NULL;
  1697. #endif
  1698. if (mp->sem != NULL) {
  1699. /* Setup memory array */
  1700. if (mem_mp == 0) {
  1701. mp->mem_arr = pvPortMalloc (sz);
  1702. } else {
  1703. mp->mem_arr = attr->mp_mem;
  1704. }
  1705. }
  1706. }
  1707. if ((mp != NULL) && (mp->mem_arr != NULL)) {
  1708. /* Memory pool can be created */
  1709. mp->head = NULL;
  1710. mp->mem_sz = sz;
  1711. mp->name = name;
  1712. mp->bl_sz = block_size;
  1713. mp->bl_cnt = block_count;
  1714. mp->n = 0U;
  1715. /* Set heap allocated memory flags */
  1716. mp->status = MPOOL_STATUS;
  1717. if (mem_cb == 0) {
  1718. /* Control block on heap */
  1719. mp->status |= 1U;
  1720. }
  1721. if (mem_mp == 0) {
  1722. /* Memory array on heap */
  1723. mp->status |= 2U;
  1724. }
  1725. }
  1726. else {
  1727. /* Memory pool cannot be created, release allocated resources */
  1728. if ((mem_cb == 0) && (mp != NULL)) {
  1729. /* Free control block memory */
  1730. vPortFree (mp);
  1731. }
  1732. mp = NULL;
  1733. }
  1734. }
  1735. return (mp);
  1736. }
  1737. const char *osMemoryPoolGetName (osMemoryPoolId_t mp_id) {
  1738. MemPool_t *mp = (osMemoryPoolId_t)mp_id;
  1739. const char *p;
  1740. if (IS_IRQ()) {
  1741. p = NULL;
  1742. }
  1743. else if (mp_id == NULL) {
  1744. p = NULL;
  1745. }
  1746. else {
  1747. p = mp->name;
  1748. }
  1749. return (p);
  1750. }
  1751. void *osMemoryPoolAlloc (osMemoryPoolId_t mp_id, uint32_t timeout) {
  1752. MemPool_t *mp;
  1753. void *block;
  1754. uint32_t isrm;
  1755. if (mp_id == NULL) {
  1756. /* Invalid input parameters */
  1757. block = NULL;
  1758. }
  1759. else {
  1760. block = NULL;
  1761. mp = (MemPool_t *)mp_id;
  1762. if ((mp->status & MPOOL_STATUS) == MPOOL_STATUS) {
  1763. if (IS_IRQ()) {
  1764. if (timeout == 0U) {
  1765. if (xSemaphoreTakeFromISR (mp->sem, NULL) == pdTRUE) {
  1766. if ((mp->status & MPOOL_STATUS) == MPOOL_STATUS) {
  1767. isrm = taskENTER_CRITICAL_FROM_ISR();
  1768. /* Get a block from the free-list */
  1769. block = AllocBlock(mp);
  1770. if (block == NULL) {
  1771. /* List of free blocks is empty, 'create' new block */
  1772. block = CreateBlock(mp);
  1773. }
  1774. taskEXIT_CRITICAL_FROM_ISR(isrm);
  1775. }
  1776. }
  1777. }
  1778. }
  1779. else {
  1780. if (xSemaphoreTake (mp->sem, (TickType_t)timeout) == pdTRUE) {
  1781. if ((mp->status & MPOOL_STATUS) == MPOOL_STATUS) {
  1782. taskENTER_CRITICAL();
  1783. /* Get a block from the free-list */
  1784. block = AllocBlock(mp);
  1785. if (block == NULL) {
  1786. /* List of free blocks is empty, 'create' new block */
  1787. block = CreateBlock(mp);
  1788. }
  1789. taskEXIT_CRITICAL();
  1790. }
  1791. }
  1792. }
  1793. }
  1794. }
  1795. return (block);
  1796. }
  1797. osStatus_t osMemoryPoolFree (osMemoryPoolId_t mp_id, void *block) {
  1798. MemPool_t *mp;
  1799. osStatus_t stat;
  1800. uint32_t isrm;
  1801. BaseType_t yield;
  1802. if ((mp_id == NULL) || (block == NULL)) {
  1803. /* Invalid input parameters */
  1804. stat = osErrorParameter;
  1805. }
  1806. else {
  1807. mp = (MemPool_t *)mp_id;
  1808. if ((mp->status & MPOOL_STATUS) != MPOOL_STATUS) {
  1809. /* Invalid object status */
  1810. stat = osErrorResource;
  1811. }
  1812. else if ((block < (void *)&mp->mem_arr[0]) || (block > (void*)&mp->mem_arr[mp->mem_sz-1])) {
  1813. /* Block pointer outside of memory array area */
  1814. stat = osErrorParameter;
  1815. }
  1816. else {
  1817. stat = osOK;
  1818. if (IS_IRQ()) {
  1819. if (uxSemaphoreGetCountFromISR (mp->sem) == mp->bl_cnt) {
  1820. stat = osErrorResource;
  1821. }
  1822. else {
  1823. isrm = taskENTER_CRITICAL_FROM_ISR();
  1824. /* Add block to the list of free blocks */
  1825. FreeBlock(mp, block);
  1826. taskEXIT_CRITICAL_FROM_ISR(isrm);
  1827. yield = pdFALSE;
  1828. xSemaphoreGiveFromISR (mp->sem, &yield);
  1829. portYIELD_FROM_ISR (yield);
  1830. }
  1831. }
  1832. else {
  1833. if (uxSemaphoreGetCount (mp->sem) == mp->bl_cnt) {
  1834. stat = osErrorResource;
  1835. }
  1836. else {
  1837. taskENTER_CRITICAL();
  1838. /* Add block to the list of free blocks */
  1839. FreeBlock(mp, block);
  1840. taskEXIT_CRITICAL();
  1841. xSemaphoreGive (mp->sem);
  1842. }
  1843. }
  1844. }
  1845. }
  1846. return (stat);
  1847. }
  1848. uint32_t osMemoryPoolGetCapacity (osMemoryPoolId_t mp_id) {
  1849. MemPool_t *mp;
  1850. uint32_t n;
  1851. if (mp_id == NULL) {
  1852. /* Invalid input parameters */
  1853. n = 0U;
  1854. }
  1855. else {
  1856. mp = (MemPool_t *)mp_id;
  1857. if ((mp->status & MPOOL_STATUS) != MPOOL_STATUS) {
  1858. /* Invalid object status */
  1859. n = 0U;
  1860. }
  1861. else {
  1862. n = mp->bl_cnt;
  1863. }
  1864. }
  1865. /* Return maximum number of memory blocks */
  1866. return (n);
  1867. }
  1868. uint32_t osMemoryPoolGetBlockSize (osMemoryPoolId_t mp_id) {
  1869. MemPool_t *mp;
  1870. uint32_t sz;
  1871. if (mp_id == NULL) {
  1872. /* Invalid input parameters */
  1873. sz = 0U;
  1874. }
  1875. else {
  1876. mp = (MemPool_t *)mp_id;
  1877. if ((mp->status & MPOOL_STATUS) != MPOOL_STATUS) {
  1878. /* Invalid object status */
  1879. sz = 0U;
  1880. }
  1881. else {
  1882. sz = mp->bl_sz;
  1883. }
  1884. }
  1885. /* Return memory block size in bytes */
  1886. return (sz);
  1887. }
  1888. uint32_t osMemoryPoolGetCount (osMemoryPoolId_t mp_id) {
  1889. MemPool_t *mp;
  1890. uint32_t n;
  1891. if (mp_id == NULL) {
  1892. /* Invalid input parameters */
  1893. n = 0U;
  1894. }
  1895. else {
  1896. mp = (MemPool_t *)mp_id;
  1897. if ((mp->status & MPOOL_STATUS) != MPOOL_STATUS) {
  1898. /* Invalid object status */
  1899. n = 0U;
  1900. }
  1901. else {
  1902. if (IS_IRQ()) {
  1903. n = uxSemaphoreGetCountFromISR (mp->sem);
  1904. } else {
  1905. n = uxSemaphoreGetCount (mp->sem);
  1906. }
  1907. n = mp->bl_cnt - n;
  1908. }
  1909. }
  1910. /* Return number of memory blocks used */
  1911. return (n);
  1912. }
  1913. uint32_t osMemoryPoolGetSpace (osMemoryPoolId_t mp_id) {
  1914. MemPool_t *mp;
  1915. uint32_t n;
  1916. if (mp_id == NULL) {
  1917. /* Invalid input parameters */
  1918. n = 0U;
  1919. }
  1920. else {
  1921. mp = (MemPool_t *)mp_id;
  1922. if ((mp->status & MPOOL_STATUS) != MPOOL_STATUS) {
  1923. /* Invalid object status */
  1924. n = 0U;
  1925. }
  1926. else {
  1927. if (IS_IRQ()) {
  1928. n = uxSemaphoreGetCountFromISR (mp->sem);
  1929. } else {
  1930. n = uxSemaphoreGetCount (mp->sem);
  1931. }
  1932. }
  1933. }
  1934. /* Return number of memory blocks available */
  1935. return (n);
  1936. }
  1937. osStatus_t osMemoryPoolDelete (osMemoryPoolId_t mp_id) {
  1938. MemPool_t *mp;
  1939. osStatus_t stat;
  1940. if (mp_id == NULL) {
  1941. /* Invalid input parameters */
  1942. stat = osErrorParameter;
  1943. }
  1944. else if (IS_IRQ()) {
  1945. stat = osErrorISR;
  1946. }
  1947. else {
  1948. mp = (MemPool_t *)mp_id;
  1949. taskENTER_CRITICAL();
  1950. /* Invalidate control block status */
  1951. mp->status = mp->status & 3U;
  1952. /* Wake-up tasks waiting for pool semaphore */
  1953. while (xSemaphoreGive (mp->sem) == pdTRUE);
  1954. mp->head = NULL;
  1955. mp->bl_sz = 0U;
  1956. mp->bl_cnt = 0U;
  1957. if ((mp->status & 2U) != 0U) {
  1958. /* Memory pool array allocated on heap */
  1959. vPortFree (mp->mem_arr);
  1960. }
  1961. if ((mp->status & 1U) != 0U) {
  1962. /* Memory pool control block allocated on heap */
  1963. vPortFree (mp);
  1964. }
  1965. taskEXIT_CRITICAL();
  1966. stat = osOK;
  1967. }
  1968. return (stat);
  1969. }
  1970. /*
  1971. Create new block given according to the current block index.
  1972. */
  1973. static void *CreateBlock (MemPool_t *mp) {
  1974. MemPoolBlock_t *p = NULL;
  1975. if (mp->n < mp->bl_cnt) {
  1976. /* Unallocated blocks exist, set pointer to new block */
  1977. p = (void *)(mp->mem_arr + (mp->bl_sz * mp->n));
  1978. /* Increment block index */
  1979. mp->n += 1U;
  1980. }
  1981. return (p);
  1982. }
  1983. /*
  1984. Allocate a block by reading the list of free blocks.
  1985. */
  1986. static void *AllocBlock (MemPool_t *mp) {
  1987. MemPoolBlock_t *p = NULL;
  1988. if (mp->head != NULL) {
  1989. /* List of free block exists, get head block */
  1990. p = mp->head;
  1991. /* Head block is now next on the list */
  1992. mp->head = p->next;
  1993. }
  1994. return (p);
  1995. }
  1996. /*
  1997. Free block by putting it to the list of free blocks.
  1998. */
  1999. static void FreeBlock (MemPool_t *mp, void *block) {
  2000. MemPoolBlock_t *p = block;
  2001. /* Store current head into block memory space */
  2002. p->next = mp->head;
  2003. /* Store current block as new head */
  2004. mp->head = p;
  2005. }
  2006. #endif /* FREERTOS_MPOOL_H_ */
  2007. /*---------------------------------------------------------------------------*/
  2008. /* Callback function prototypes */
  2009. extern void vApplicationIdleHook (void);
  2010. extern void vApplicationTickHook (void);
  2011. extern void vApplicationMallocFailedHook (void);
  2012. extern void vApplicationDaemonTaskStartupHook (void);
  2013. extern void vApplicationStackOverflowHook (TaskHandle_t xTask, signed char *pcTaskName);
  2014. /**
  2015. Dummy implementation of the callback function vApplicationIdleHook().
  2016. */
  2017. #if (configUSE_IDLE_HOOK == 1)
  2018. __WEAK void vApplicationIdleHook (void){}
  2019. #endif
  2020. /**
  2021. Dummy implementation of the callback function vApplicationTickHook().
  2022. */
  2023. #if (configUSE_TICK_HOOK == 1)
  2024. __WEAK void vApplicationTickHook (void){}
  2025. #endif
  2026. /**
  2027. Dummy implementation of the callback function vApplicationMallocFailedHook().
  2028. */
  2029. #if (configUSE_MALLOC_FAILED_HOOK == 1)
  2030. __WEAK void vApplicationMallocFailedHook (void){}
  2031. #endif
  2032. /**
  2033. Dummy implementation of the callback function vApplicationDaemonTaskStartupHook().
  2034. */
  2035. #if (configUSE_DAEMON_TASK_STARTUP_HOOK == 1)
  2036. __WEAK void vApplicationDaemonTaskStartupHook (void){}
  2037. #endif
  2038. /**
  2039. Dummy implementation of the callback function vApplicationStackOverflowHook().
  2040. */
  2041. #if (configCHECK_FOR_STACK_OVERFLOW > 0)
  2042. __WEAK void vApplicationStackOverflowHook (TaskHandle_t xTask, signed char *pcTaskName) {
  2043. (void)xTask;
  2044. (void)pcTaskName;
  2045. configASSERT(0);
  2046. }
  2047. #endif
  2048. /*---------------------------------------------------------------------------*/
  2049. #if (configSUPPORT_STATIC_ALLOCATION == 1)
  2050. /* External Idle and Timer task static memory allocation functions */
  2051. extern void vApplicationGetIdleTaskMemory (StaticTask_t **ppxIdleTaskTCBBuffer, StackType_t **ppxIdleTaskStackBuffer, uint32_t *pulIdleTaskStackSize);
  2052. extern void vApplicationGetTimerTaskMemory (StaticTask_t **ppxTimerTaskTCBBuffer, StackType_t **ppxTimerTaskStackBuffer, uint32_t *pulTimerTaskStackSize);
  2053. /*
  2054. vApplicationGetIdleTaskMemory gets called when configSUPPORT_STATIC_ALLOCATION
  2055. equals to 1 and is required for static memory allocation support.
  2056. */
  2057. __WEAK void vApplicationGetIdleTaskMemory (StaticTask_t **ppxIdleTaskTCBBuffer, StackType_t **ppxIdleTaskStackBuffer, uint32_t *pulIdleTaskStackSize) {
  2058. /* Idle task control block and stack */
  2059. static StaticTask_t Idle_TCB;
  2060. static StackType_t Idle_Stack[configMINIMAL_STACK_SIZE];
  2061. *ppxIdleTaskTCBBuffer = &Idle_TCB;
  2062. *ppxIdleTaskStackBuffer = &Idle_Stack[0];
  2063. *pulIdleTaskStackSize = (uint32_t)configMINIMAL_STACK_SIZE;
  2064. }
  2065. /*
  2066. vApplicationGetTimerTaskMemory gets called when configSUPPORT_STATIC_ALLOCATION
  2067. equals to 1 and is required for static memory allocation support.
  2068. */
  2069. __WEAK void vApplicationGetTimerTaskMemory (StaticTask_t **ppxTimerTaskTCBBuffer, StackType_t **ppxTimerTaskStackBuffer, uint32_t *pulTimerTaskStackSize) {
  2070. /* Timer task control block and stack */
  2071. static StaticTask_t Timer_TCB;
  2072. static StackType_t Timer_Stack[configTIMER_TASK_STACK_DEPTH];
  2073. *ppxTimerTaskTCBBuffer = &Timer_TCB;
  2074. *ppxTimerTaskStackBuffer = &Timer_Stack[0];
  2075. *pulTimerTaskStackSize = (uint32_t)configTIMER_TASK_STACK_DEPTH;
  2076. }
  2077. #endif