cmsis_os2.c 54 KB

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