OSAL.c 29 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186
  1. /**************************************************************************************************
  2. Filename: OSAL.c
  3. Revised: $Date: 2011-05-27 09:03:48 -0700 (Fri, 27 May 2011) $
  4. Revision: $Revision: 26134 $
  5. Description: This API allows the software components in the Z-stack to be written
  6. independently of the specifics of the operating system, kernel or tasking
  7. environment (including control loops or connect-to-interrupt systems).
  8. Copyright 2004-2011 Texas Instruments Incorporated. All rights reserved.
  9. IMPORTANT: Your use of this Software is limited to those specific rights
  10. granted under the terms of a software license agreement between the user
  11. who downloaded the software, his/her employer (which must be your employer)
  12. and Texas Instruments Incorporated (the "License"). You may not use this
  13. Software unless you agree to abide by the terms of the License. The License
  14. limits your use, and you acknowledge, that the Software may not be modified,
  15. copied or distributed unless embedded on a Texas Instruments microcontroller
  16. or used solely and exclusively in conjunction with a Texas Instruments radio
  17. frequency transceiver, which is integrated into your product. Other than for
  18. the foregoing purpose, you may not use, reproduce, copy, prepare derivative
  19. works of, modify, distribute, perform, display or sell this Software and/or
  20. its documentation for any purpose.
  21. YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE
  22. PROVIDED 揂S IS� WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED,
  23. INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY, TITLE,
  24. NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL
  25. TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT,
  26. NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER
  27. LEGAL EQUITABLE THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES
  28. INCLUDING BUT NOT LIMITED TO ANY INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE
  29. OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF PROCUREMENT
  30. OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY THIRD PARTIES
  31. (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS.
  32. Should you have any questions regarding your right to use this Software,
  33. contact Texas Instruments Incorporated at www.TI.com.
  34. **************************************************************************************************/
  35. /*********************************************************************
  36. * INCLUDES
  37. */
  38. #include <string.h>
  39. #include "comdef.h"
  40. #include "OSAL.h"
  41. #include "OSAL_Tasks.h"
  42. #include "OSAL_Memory.h"
  43. #include "OSAL_PwrMgr.h"
  44. #include "OSAL_Clock.h"
  45. #include "OnBoard.h"
  46. /* HAL */
  47. #include "hal_drivers.h"
  48. #ifdef IAR_ARMCM3_LM
  49. #include "FreeRTOSConfig.h"
  50. #include "osal_task.h"
  51. #endif
  52. /*********************************************************************
  53. * MACROS
  54. */
  55. /*********************************************************************
  56. * CONSTANTS
  57. */
  58. /*********************************************************************
  59. * TYPEDEFS
  60. */
  61. /*********************************************************************
  62. * GLOBAL VARIABLES
  63. */
  64. // Message Pool Definitions
  65. osal_msg_q_t osal_qHead;
  66. /*********************************************************************
  67. * EXTERNAL VARIABLES
  68. */
  69. /*********************************************************************
  70. * EXTERNAL FUNCTIONS
  71. */
  72. /*********************************************************************
  73. * LOCAL VARIABLES
  74. */
  75. // Index of active task
  76. static uint8 activeTaskID = TASK_NO_TASK;
  77. /*********************************************************************
  78. * LOCAL FUNCTION PROTOTYPES
  79. */
  80. /*********************************************************************
  81. * HELPER FUNCTIONS
  82. */
  83. /* very ugly stub so Keil can compile */
  84. #ifdef __KEIL__
  85. char * itoa ( int value, char * buffer, int radix )
  86. {
  87. return(buffer);
  88. }
  89. #endif
  90. /*********************************************************************
  91. * @fn osal_strlen
  92. *
  93. * @brief
  94. *
  95. * Calculates the length of a string. The string must be null
  96. * terminated.
  97. *
  98. * @param char *pString - pointer to text string
  99. *
  100. * @return int - number of characters
  101. */
  102. int osal_strlen( char *pString )
  103. {
  104. return (int)( strlen( pString ) );
  105. }
  106. /*********************************************************************
  107. * @fn osal_memcpy
  108. *
  109. * @brief
  110. *
  111. * Generic memory copy.
  112. *
  113. * Note: This function differs from the standard memcpy(), since
  114. * it returns the pointer to the next destination uint8. The
  115. * standard memcpy() returns the original destination address.
  116. *
  117. * @param dst - destination address
  118. * @param src - source address
  119. * @param len - number of bytes to copy
  120. *
  121. * @return pointer to end of destination buffer
  122. */
  123. void *osal_memcpy( void *dst, const void GENERIC *src, unsigned int len )
  124. {
  125. uint8 *pDst;
  126. const uint8 GENERIC *pSrc;
  127. pSrc = src;
  128. pDst = dst;
  129. while ( len-- )
  130. *pDst++ = *pSrc++;
  131. return ( pDst );
  132. }
  133. /*********************************************************************
  134. * @fn osal_revmemcpy
  135. *
  136. * @brief Generic reverse memory copy. Starts at the end of the
  137. * source buffer, by taking the source address pointer and moving
  138. * pointer ahead "len" bytes, then decrementing the pointer.
  139. *
  140. * Note: This function differs from the standard memcpy(), since
  141. * it returns the pointer to the next destination uint8. The
  142. * standard memcpy() returns the original destination address.
  143. *
  144. * @param dst - destination address
  145. * @param src - source address
  146. * @param len - number of bytes to copy
  147. *
  148. * @return pointer to end of destination buffer
  149. */
  150. void *osal_revmemcpy( void *dst, const void GENERIC *src, unsigned int len )
  151. {
  152. uint8 *pDst;
  153. const uint8 GENERIC *pSrc;
  154. pSrc = src;
  155. pSrc += (len-1);
  156. pDst = dst;
  157. while ( len-- )
  158. *pDst++ = *pSrc--;
  159. return ( pDst );
  160. }
  161. /*********************************************************************
  162. * @fn osal_memdup
  163. *
  164. * @brief Allocates a buffer [with osal_mem_alloc()] and copies
  165. * the src buffer into the newly allocated space.
  166. *
  167. * @param src - source address
  168. * @param len - number of bytes to copy
  169. *
  170. * @return pointer to the new allocated buffer, or NULL if
  171. * allocation problem.
  172. */
  173. void *osal_memdup( const void GENERIC *src, unsigned int len )
  174. {
  175. uint8 *pDst;
  176. pDst = osal_mem_alloc( len );
  177. if ( pDst )
  178. {
  179. VOID osal_memcpy( pDst, src, len );
  180. }
  181. return ( (void *)pDst );
  182. }
  183. /*********************************************************************
  184. * @fn osal_memcmp
  185. *
  186. * @brief
  187. *
  188. * Generic memory compare.
  189. *
  190. * @param src1 - source 1 addrexx
  191. * @param src2 - source 2 address
  192. * @param len - number of bytes to compare
  193. *
  194. * @return TRUE - same, FALSE - different
  195. */
  196. uint8 osal_memcmp( const void GENERIC *src1, const void GENERIC *src2, unsigned int len )
  197. {
  198. const uint8 GENERIC *pSrc1;
  199. const uint8 GENERIC *pSrc2;
  200. pSrc1 = src1;
  201. pSrc2 = src2;
  202. while ( len-- )
  203. {
  204. if( *pSrc1++ != *pSrc2++ )
  205. return FALSE;
  206. }
  207. return TRUE;
  208. }
  209. /*********************************************************************
  210. * @fn osal_memset
  211. *
  212. * @brief
  213. *
  214. * Set memory buffer to value.
  215. *
  216. * @param dest - pointer to buffer
  217. * @param value - what to set each uint8 of the message
  218. * @param size - how big
  219. *
  220. * @return pointer to destination buffer
  221. */
  222. void *osal_memset( void *dest, uint8 value, int len )
  223. {
  224. return memset( dest, value, len );
  225. }
  226. /*********************************************************************
  227. * @fn osal_build_uint16
  228. *
  229. * @brief
  230. *
  231. * Build a uint16 out of 2 bytes (0 then 1).
  232. *
  233. * @param swapped - 0 then 1
  234. *
  235. * @return uint16
  236. */
  237. uint16 osal_build_uint16( uint8 *swapped )
  238. {
  239. return ( BUILD_UINT16( swapped[0], swapped[1] ) );
  240. }
  241. /*********************************************************************
  242. * @fn osal_build_uint32
  243. *
  244. * @brief
  245. *
  246. * Build a uint32 out of sequential bytes.
  247. *
  248. * @param swapped - sequential bytes
  249. * @param len - number of bytes in the uint8 array
  250. *
  251. * @return uint32
  252. */
  253. uint32 osal_build_uint32( uint8 *swapped, uint8 len )
  254. {
  255. if ( len == 2 )
  256. return ( BUILD_UINT32( swapped[0], swapped[1], 0L, 0L ) );
  257. else if ( len == 3 )
  258. return ( BUILD_UINT32( swapped[0], swapped[1], swapped[2], 0L ) );
  259. else if ( len == 4 )
  260. return ( BUILD_UINT32( swapped[0], swapped[1], swapped[2], swapped[3] ) );
  261. else
  262. return ( (uint32)swapped[0] );
  263. }
  264. #if !defined ( ZBIT ) && !defined ( ZBIT2 ) && !defined (UBIT)
  265. /*********************************************************************
  266. * @fn _ltoa
  267. *
  268. * @brief
  269. *
  270. * convert a long unsigned int to a string.
  271. *
  272. * @param l - long to convert
  273. * @param buf - buffer to convert to
  274. * @param radix - 10 dec, 16 hex
  275. *
  276. * @return pointer to buffer
  277. */
  278. unsigned char * _ltoa(unsigned long l, unsigned char *buf, unsigned char radix)
  279. {
  280. #if defined( __GNUC__ )
  281. return ( (char*)ltoa( l, buf, radix ) );
  282. #else
  283. unsigned char tmp1[10] = "", tmp2[10] = "", tmp3[10] = "";
  284. unsigned short num1, num2, num3;
  285. unsigned char i;
  286. buf[0] = '\0';
  287. if ( radix == 10 )
  288. {
  289. num1 = l % 10000;
  290. num2 = (l / 10000) % 10000;
  291. num3 = (unsigned short)(l / 100000000);
  292. if (num3) _itoa(num3, tmp3, 10);
  293. if (num2) _itoa(num2, tmp2, 10);
  294. if (num1) _itoa(num1, tmp1, 10);
  295. if (num3)
  296. {
  297. strcpy((char*)buf, (char const*)tmp3);
  298. for (i = 0; i < 4 - strlen((char const*)tmp2); i++)
  299. strcat((char*)buf, "0");
  300. }
  301. strcat((char*)buf, (char const*)tmp2);
  302. if (num3 || num2)
  303. {
  304. for (i = 0; i < 4 - strlen((char const*)tmp1); i++)
  305. strcat((char*)buf, "0");
  306. }
  307. strcat((char*)buf, (char const*)tmp1);
  308. if (!num3 && !num2 && !num1)
  309. strcpy((char*)buf, "0");
  310. }
  311. else if ( radix == 16 )
  312. {
  313. num1 = l & 0x0000FFFF;
  314. num2 = l >> 16;
  315. if (num2) _itoa(num2, tmp2, 16);
  316. if (num1) _itoa(num1, tmp1, 16);
  317. if (num2)
  318. {
  319. strcpy((char*)buf,(char const*)tmp2);
  320. for (i = 0; i < 4 - strlen((char const*)tmp1); i++)
  321. strcat((char*)buf, "0");
  322. }
  323. strcat((char*)buf, (char const*)tmp1);
  324. if (!num2 && !num1)
  325. strcpy((char*)buf, "0");
  326. }
  327. else
  328. return NULL;
  329. return buf;
  330. #endif
  331. }
  332. #endif // !defined(ZBIT) && !defined(ZBIT2)
  333. /*********************************************************************
  334. * @fn osal_rand
  335. *
  336. * @brief Random number generator
  337. *
  338. * @param none
  339. *
  340. * @return uint16 - new random number
  341. */
  342. uint16 osal_rand( void )
  343. {
  344. return ( Onboard_rand() );
  345. }
  346. /*********************************************************************
  347. * API FUNCTIONS
  348. *********************************************************************/
  349. /*********************************************************************
  350. * @fn osal_msg_allocate
  351. *
  352. * @brief
  353. *
  354. * This function is called by a task to allocate a message buffer
  355. * into which the task will encode the particular message it wishes
  356. * to send. This common buffer scheme is used to strictly limit the
  357. * creation of message buffers within the system due to RAM size
  358. * limitations on the microprocessor. Note that all message buffers
  359. * are a fixed size (at least initially). The parameter len is kept
  360. * in case a message pool with varying fixed message sizes is later
  361. * created (for example, a pool of message buffers of size LARGE,
  362. * MEDIUM and SMALL could be maintained and allocated based on request
  363. * from the tasks).
  364. *
  365. *
  366. * @param uint8 len - wanted buffer length
  367. *
  368. *
  369. * @return pointer to allocated buffer or NULL if allocation failed.
  370. */
  371. uint8 * osal_msg_allocate( uint16 len )
  372. {
  373. osal_msg_hdr_t *hdr;
  374. if ( len == 0 )
  375. return ( NULL );
  376. hdr = (osal_msg_hdr_t *) osal_mem_alloc( (short)(len + sizeof( osal_msg_hdr_t )) );
  377. if ( hdr )
  378. {
  379. hdr->next = NULL;
  380. hdr->len = len;
  381. hdr->dest_id = TASK_NO_TASK;
  382. return ( (uint8 *) (hdr + 1) );
  383. }
  384. else
  385. return ( NULL );
  386. }
  387. /*********************************************************************
  388. * @fn osal_msg_deallocate
  389. *
  390. * @brief
  391. *
  392. * This function is used to deallocate a message buffer. This function
  393. * is called by a task (or processing element) after it has finished
  394. * processing a received message.
  395. *
  396. *
  397. * @param uint8 *msg_ptr - pointer to new message buffer
  398. *
  399. * @return SUCCESS, INVALID_MSG_POINTER
  400. */
  401. uint8 osal_msg_deallocate( uint8 *msg_ptr )
  402. {
  403. uint8 *x;
  404. if ( msg_ptr == NULL )
  405. return ( INVALID_MSG_POINTER );
  406. // don't deallocate queued buffer
  407. if ( OSAL_MSG_ID( msg_ptr ) != TASK_NO_TASK )
  408. return ( MSG_BUFFER_NOT_AVAIL );
  409. x = (uint8 *)((uint8 *)msg_ptr - sizeof( osal_msg_hdr_t ));
  410. osal_mem_free( (void *)x );
  411. return ( SUCCESS );
  412. }
  413. /*********************************************************************
  414. * @fn osal_msg_send
  415. *
  416. * @brief
  417. *
  418. * This function is called by a task to send a command message to
  419. * another task or processing element. The sending_task field must
  420. * refer to a valid task, since the task ID will be used
  421. * for the response message. This function will also set a message
  422. * ready event in the destination tasks event list.
  423. *
  424. *
  425. * @param uint8 destination task - Send msg to? Task ID
  426. * @param uint8 *msg_ptr - pointer to new message buffer
  427. * @param uint8 len - length of data in message
  428. *
  429. * @return SUCCESS, INVALID_TASK, INVALID_MSG_POINTER
  430. */
  431. uint8 osal_msg_send( uint8 destination_task, uint8 *msg_ptr )
  432. {
  433. if ( msg_ptr == NULL )
  434. return ( INVALID_MSG_POINTER );
  435. if ( destination_task >= tasksCnt )
  436. {
  437. osal_msg_deallocate( msg_ptr );
  438. return ( INVALID_TASK );
  439. }
  440. // Check the message header
  441. if ( OSAL_MSG_NEXT( msg_ptr ) != NULL ||
  442. OSAL_MSG_ID( msg_ptr ) != TASK_NO_TASK )
  443. {
  444. osal_msg_deallocate( msg_ptr );
  445. return ( INVALID_MSG_POINTER );
  446. }
  447. OSAL_MSG_ID( msg_ptr ) = destination_task;
  448. // queue message
  449. osal_msg_enqueue( &osal_qHead, msg_ptr );
  450. // Signal the task that a message is waiting
  451. osal_set_event( destination_task, SYS_EVENT_MSG );
  452. return ( SUCCESS );
  453. }
  454. /*********************************************************************
  455. * @fn osal_msg_receive
  456. *
  457. * @brief
  458. *
  459. * This function is called by a task to retrieve a received command
  460. * message. The calling task must deallocate the message buffer after
  461. * processing the message using the osal_msg_deallocate() call.
  462. *
  463. * @param uint8 task_id - receiving tasks ID
  464. *
  465. * @return *uint8 - message information or NULL if no message
  466. */
  467. uint8 *osal_msg_receive( uint8 task_id )
  468. {
  469. osal_msg_hdr_t *listHdr;
  470. osal_msg_hdr_t *prevHdr = NULL;
  471. osal_msg_hdr_t *foundHdr = NULL;
  472. halIntState_t intState;
  473. // Hold off interrupts
  474. HAL_ENTER_CRITICAL_SECTION(intState);
  475. // Point to the top of the queue
  476. listHdr = osal_qHead;
  477. // Look through the queue for a message that belongs to the asking task
  478. while ( listHdr != NULL )
  479. {
  480. if ( (listHdr - 1)->dest_id == task_id )
  481. {
  482. if ( foundHdr == NULL )
  483. {
  484. // Save the first one
  485. foundHdr = listHdr;
  486. }
  487. else
  488. {
  489. // Second msg found, stop looking
  490. break;
  491. }
  492. }
  493. if ( foundHdr == NULL )
  494. {
  495. prevHdr = listHdr;
  496. }
  497. listHdr = OSAL_MSG_NEXT( listHdr );
  498. }
  499. // Is there more than one?
  500. if ( listHdr != NULL )
  501. {
  502. // Yes, Signal the task that a message is waiting
  503. osal_set_event( task_id, SYS_EVENT_MSG );
  504. }
  505. else
  506. {
  507. // No more
  508. osal_clear_event( task_id, SYS_EVENT_MSG );
  509. }
  510. // Did we find a message?
  511. if ( foundHdr != NULL )
  512. {
  513. // Take out of the link list
  514. osal_msg_extract( &osal_qHead, foundHdr, prevHdr );
  515. }
  516. // Release interrupts
  517. HAL_EXIT_CRITICAL_SECTION(intState);
  518. return ( (uint8*) foundHdr );
  519. }
  520. /**************************************************************************************************
  521. * @fn osal_msg_find
  522. *
  523. * @brief This function finds in place an OSAL message matching the task_id and event
  524. * parameters.
  525. *
  526. * input parameters
  527. *
  528. * @param task_id - The OSAL task id that the enqueued OSAL message must match.
  529. * @param event - The OSAL event id that the enqueued OSAL message must match.
  530. *
  531. * output parameters
  532. *
  533. * None.
  534. *
  535. * @return NULL if no match, otherwise an in place pointer to the matching OSAL message.
  536. **************************************************************************************************
  537. */
  538. osal_event_hdr_t *osal_msg_find(uint8 task_id, uint8 event)
  539. {
  540. osal_msg_hdr_t *pHdr;
  541. halIntState_t intState;
  542. HAL_ENTER_CRITICAL_SECTION(intState); // Hold off interrupts.
  543. pHdr = osal_qHead; // Point to the top of the queue.
  544. // Look through the queue for a message that matches the task_id and event parameters.
  545. while (pHdr != NULL)
  546. {
  547. if (((pHdr-1)->dest_id == task_id) && (((osal_event_hdr_t *)pHdr)->event == event))
  548. {
  549. break;
  550. }
  551. pHdr = OSAL_MSG_NEXT(pHdr);
  552. }
  553. HAL_EXIT_CRITICAL_SECTION(intState); // Release interrupts.
  554. return (osal_event_hdr_t *)pHdr;
  555. }
  556. /*********************************************************************
  557. * @fn osal_msg_enqueue
  558. *
  559. * @brief
  560. *
  561. * This function enqueues an OSAL message into an OSAL queue.
  562. *
  563. * @param osal_msg_q_t *q_ptr - OSAL queue
  564. * @param void *msg_ptr - OSAL message
  565. *
  566. * @return none
  567. */
  568. void osal_msg_enqueue( osal_msg_q_t *q_ptr, void *msg_ptr )
  569. {
  570. void *list;
  571. halIntState_t intState;
  572. // Hold off interrupts
  573. HAL_ENTER_CRITICAL_SECTION(intState);
  574. OSAL_MSG_NEXT( msg_ptr ) = NULL;
  575. // If first message in queue
  576. if ( *q_ptr == NULL )
  577. {
  578. *q_ptr = msg_ptr;
  579. }
  580. else
  581. {
  582. // Find end of queue
  583. for ( list = *q_ptr; OSAL_MSG_NEXT( list ) != NULL; list = OSAL_MSG_NEXT( list ) );
  584. // Add message to end of queue
  585. OSAL_MSG_NEXT( list ) = msg_ptr;
  586. }
  587. // Re-enable interrupts
  588. HAL_EXIT_CRITICAL_SECTION(intState);
  589. }
  590. /*********************************************************************
  591. * @fn osal_msg_dequeue
  592. *
  593. * @brief
  594. *
  595. * This function dequeues an OSAL message from an OSAL queue.
  596. *
  597. * @param osal_msg_q_t *q_ptr - OSAL queue
  598. *
  599. * @return void * - pointer to OSAL message or NULL of queue is empty.
  600. */
  601. void *osal_msg_dequeue( osal_msg_q_t *q_ptr )
  602. {
  603. void *msg_ptr = NULL;
  604. halIntState_t intState;
  605. // Hold off interrupts
  606. HAL_ENTER_CRITICAL_SECTION(intState);
  607. if ( *q_ptr != NULL )
  608. {
  609. // Dequeue message
  610. msg_ptr = *q_ptr;
  611. *q_ptr = OSAL_MSG_NEXT( msg_ptr );
  612. OSAL_MSG_NEXT( msg_ptr ) = NULL;
  613. OSAL_MSG_ID( msg_ptr ) = TASK_NO_TASK;
  614. }
  615. // Re-enable interrupts
  616. HAL_EXIT_CRITICAL_SECTION(intState);
  617. return msg_ptr;
  618. }
  619. /*********************************************************************
  620. * @fn osal_msg_push
  621. *
  622. * @brief
  623. *
  624. * This function pushes an OSAL message to the head of an OSAL
  625. * queue.
  626. *
  627. * @param osal_msg_q_t *q_ptr - OSAL queue
  628. * @param void *msg_ptr - OSAL message
  629. *
  630. * @return none
  631. */
  632. void osal_msg_push( osal_msg_q_t *q_ptr, void *msg_ptr )
  633. {
  634. halIntState_t intState;
  635. // Hold off interrupts
  636. HAL_ENTER_CRITICAL_SECTION(intState);
  637. // Push message to head of queue
  638. OSAL_MSG_NEXT( msg_ptr ) = *q_ptr;
  639. *q_ptr = msg_ptr;
  640. // Re-enable interrupts
  641. HAL_EXIT_CRITICAL_SECTION(intState);
  642. }
  643. /*********************************************************************
  644. * @fn osal_msg_extract
  645. *
  646. * @brief
  647. *
  648. * This function extracts and removes an OSAL message from the
  649. * middle of an OSAL queue.
  650. *
  651. * @param osal_msg_q_t *q_ptr - OSAL queue
  652. * @param void *msg_ptr - OSAL message to be extracted
  653. * @param void *prev_ptr - OSAL message before msg_ptr in queue
  654. *
  655. * @return none
  656. */
  657. void osal_msg_extract( osal_msg_q_t *q_ptr, void *msg_ptr, void *prev_ptr )
  658. {
  659. halIntState_t intState;
  660. // Hold off interrupts
  661. HAL_ENTER_CRITICAL_SECTION(intState);
  662. if ( msg_ptr == *q_ptr )
  663. {
  664. // remove from first
  665. *q_ptr = OSAL_MSG_NEXT( msg_ptr );
  666. }
  667. else
  668. {
  669. // remove from middle
  670. OSAL_MSG_NEXT( prev_ptr ) = OSAL_MSG_NEXT( msg_ptr );
  671. }
  672. OSAL_MSG_NEXT( msg_ptr ) = NULL;
  673. OSAL_MSG_ID( msg_ptr ) = TASK_NO_TASK;
  674. // Re-enable interrupts
  675. HAL_EXIT_CRITICAL_SECTION(intState);
  676. }
  677. /*********************************************************************
  678. * @fn osal_msg_enqueue_max
  679. *
  680. * @brief
  681. *
  682. * This function enqueues an OSAL message into an OSAL queue if
  683. * the length of the queue is less than max.
  684. *
  685. * @param osal_msg_q_t *q_ptr - OSAL queue
  686. * @param void *msg_ptr - OSAL message
  687. * @param uint8 max - maximum length of queue
  688. *
  689. * @return TRUE if message was enqueued, FALSE otherwise
  690. */
  691. uint8 osal_msg_enqueue_max( osal_msg_q_t *q_ptr, void *msg_ptr, uint8 max )
  692. {
  693. void *list;
  694. uint8 ret = FALSE;
  695. halIntState_t intState;
  696. // Hold off interrupts
  697. HAL_ENTER_CRITICAL_SECTION(intState);
  698. // If first message in queue
  699. if ( *q_ptr == NULL )
  700. {
  701. *q_ptr = msg_ptr;
  702. ret = TRUE;
  703. }
  704. else
  705. {
  706. // Find end of queue or max
  707. list = *q_ptr;
  708. max--;
  709. while ( (OSAL_MSG_NEXT( list ) != NULL) && (max > 0) )
  710. {
  711. list = OSAL_MSG_NEXT( list );
  712. max--;
  713. }
  714. // Add message to end of queue if max not reached
  715. if ( max != 0 )
  716. {
  717. OSAL_MSG_NEXT( list ) = msg_ptr;
  718. ret = TRUE;
  719. }
  720. }
  721. // Re-enable interrupts
  722. HAL_EXIT_CRITICAL_SECTION(intState);
  723. return ret;
  724. }
  725. /*********************************************************************
  726. * @fn osal_set_event
  727. *
  728. * @brief
  729. *
  730. * This function is called to set the event flags for a task. The
  731. * event passed in is OR'd into the task's event variable.
  732. *
  733. * @param uint8 task_id - receiving tasks ID
  734. * @param uint8 event_flag - what event to set
  735. *
  736. * @return SUCCESS, INVALID_TASK
  737. */
  738. uint8 osal_set_event( uint8 task_id, uint16 event_flag )
  739. {
  740. if ( task_id < tasksCnt )
  741. {
  742. halIntState_t intState;
  743. HAL_ENTER_CRITICAL_SECTION(intState); // Hold off interrupts
  744. tasksEvents[task_id] |= event_flag; // Stuff the event bit(s)
  745. HAL_EXIT_CRITICAL_SECTION(intState); // Release interrupts
  746. return ( SUCCESS );
  747. }
  748. else
  749. {
  750. return ( INVALID_TASK );
  751. }
  752. }
  753. /*********************************************************************
  754. * @fn osal_clear_event
  755. *
  756. * @brief
  757. *
  758. * This function is called to clear the event flags for a task. The
  759. * event passed in is masked out of the task's event variable.
  760. *
  761. * @param uint8 task_id - receiving tasks ID
  762. * @param uint8 event_flag - what event to clear
  763. *
  764. * @return SUCCESS, INVALID_TASK
  765. */
  766. uint8 osal_clear_event( uint8 task_id, uint16 event_flag )
  767. {
  768. if ( task_id < tasksCnt )
  769. {
  770. halIntState_t intState;
  771. HAL_ENTER_CRITICAL_SECTION(intState); // Hold off interrupts
  772. tasksEvents[task_id] &= ~(event_flag); // Clear the event bit(s)
  773. HAL_EXIT_CRITICAL_SECTION(intState); // Release interrupts
  774. return ( SUCCESS );
  775. }
  776. else
  777. {
  778. return ( INVALID_TASK );
  779. }
  780. }
  781. /*********************************************************************
  782. * @fn osal_isr_register
  783. *
  784. * @brief
  785. *
  786. * This function is called to register a service routine with an
  787. * interrupt. When the interrupt occurs, this service routine is called.
  788. *
  789. * @param uint8 interrupt_id - Interrupt number
  790. * @param void (*isr_ptr)( uint8* ) - function pointer to ISR
  791. *
  792. * @return SUCCESS, INVALID_INTERRUPT_ID,
  793. */
  794. uint8 osal_isr_register( uint8 interrupt_id, void (*isr_ptr)( uint8* ) )
  795. {
  796. // Remove these statements when functionality is complete
  797. (void)interrupt_id;
  798. (void)isr_ptr;
  799. return ( SUCCESS );
  800. }
  801. /*********************************************************************
  802. * @fn osal_int_enable
  803. *
  804. * @brief
  805. *
  806. * This function is called to enable an interrupt. Once enabled,
  807. * occurrence of the interrupt causes the service routine associated
  808. * with that interrupt to be called.
  809. *
  810. * If INTS_ALL is the interrupt_id, interrupts (in general) are enabled.
  811. * If a single interrupt is passed in, then interrupts still have
  812. * to be enabled with another call to INTS_ALL.
  813. *
  814. * @param uint8 interrupt_id - Interrupt number
  815. *
  816. * @return SUCCESS or INVALID_INTERRUPT_ID
  817. */
  818. uint8 osal_int_enable( uint8 interrupt_id )
  819. {
  820. if ( interrupt_id == INTS_ALL )
  821. {
  822. HAL_ENABLE_INTERRUPTS();
  823. return ( SUCCESS );
  824. }
  825. else
  826. {
  827. return ( INVALID_INTERRUPT_ID );
  828. }
  829. }
  830. /*********************************************************************
  831. * @fn osal_int_disable
  832. *
  833. * @brief
  834. *
  835. * This function is called to disable an interrupt. When a disabled
  836. * interrupt occurs, the service routine associated with that
  837. * interrupt is not called.
  838. *
  839. * If INTS_ALL is the interrupt_id, interrupts (in general) are disabled.
  840. * If a single interrupt is passed in, then just that interrupt is disabled.
  841. *
  842. * @param uint8 interrupt_id - Interrupt number
  843. *
  844. * @return SUCCESS or INVALID_INTERRUPT_ID
  845. */
  846. uint8 osal_int_disable( uint8 interrupt_id )
  847. {
  848. if ( interrupt_id == INTS_ALL )
  849. {
  850. HAL_DISABLE_INTERRUPTS();
  851. return ( SUCCESS );
  852. }
  853. else
  854. {
  855. return ( INVALID_INTERRUPT_ID );
  856. }
  857. }
  858. /*********************************************************************
  859. * @fn osal_init_system
  860. *
  861. * @brief
  862. *
  863. * This function initializes the "task" system by creating the
  864. * tasks defined in the task table (OSAL_Tasks.h).
  865. *
  866. * @param void
  867. *
  868. * @return SUCCESS
  869. */
  870. uint8 osal_init_system( void )
  871. {
  872. // Initialize the Memory Allocation System
  873. osal_mem_init();
  874. // Initialize the message queue
  875. osal_qHead = NULL;
  876. // Initialize the timers
  877. osalTimerInit();
  878. // Initialize the Power Management System
  879. osal_pwrmgr_init();
  880. // Initialize the system tasks.
  881. osalInitTasks();
  882. // Setup efficient search for the first free block of heap.
  883. osal_mem_kick();
  884. return ( SUCCESS );
  885. }
  886. /*********************************************************************
  887. * @fn osal_start_system
  888. *
  889. * @brief
  890. *
  891. * This function is the main loop function of the task system (if
  892. * ZBIT and UBIT are not defined). This Function doesn't return.
  893. *
  894. * @param void
  895. *
  896. * @return none
  897. */
  898. void osal_start_system( void )
  899. {
  900. #if !defined ( ZBIT ) && !defined ( UBIT )
  901. for(;;) // Forever Loop
  902. #endif
  903. {
  904. osal_run_system();
  905. }
  906. }
  907. /*********************************************************************
  908. * @fn osal_run_system
  909. *
  910. * @brief
  911. *
  912. * This function will make one pass through the OSAL taskEvents table
  913. * and call the task_event_processor() function for the first task that
  914. * is found with at least one event pending. If there are no pending
  915. * events (all tasks), this function puts the processor into Sleep.
  916. *
  917. * @param void
  918. *
  919. * @return none
  920. */
  921. void osal_run_system( void )
  922. {
  923. uint8 idx = 0;
  924. osalTimeUpdate();
  925. Hal_ProcessPoll();
  926. do {
  927. if (tasksEvents[idx]) // Task is highest priority that is ready.
  928. {
  929. break;
  930. }
  931. } while (++idx < tasksCnt);//查找任务
  932. if (idx < tasksCnt)
  933. {
  934. uint16 events;
  935. halIntState_t intState;
  936. HAL_ENTER_CRITICAL_SECTION(intState);//进入临界区
  937. events = tasksEvents[idx];//找出当前任务
  938. tasksEvents[idx] = 0; // Clear the Events for this task. 清零
  939. HAL_EXIT_CRITICAL_SECTION(intState);//退出临界区
  940. activeTaskID = idx;
  941. events = (tasksArr[idx])( idx, events );//任务事件建立
  942. activeTaskID = TASK_NO_TASK;
  943. HAL_ENTER_CRITICAL_SECTION(intState);//进入临界区
  944. tasksEvents[idx] |= events; // Add back unprocessed events to the current task.将未处理的事件添加回当前任务列表
  945. HAL_EXIT_CRITICAL_SECTION(intState);//退出临界区
  946. }
  947. #if defined( POWER_SAVING )
  948. else // Complete pass through all task events with no activity?
  949. {
  950. osal_pwrmgr_powerconserve(); // Put the processor/system into sleep
  951. }
  952. #endif
  953. /* Yield in case cooperative scheduling is being used. */
  954. #if defined (configUSE_PREEMPTION) && (configUSE_PREEMPTION == 0)
  955. {
  956. osal_task_yield();
  957. }
  958. #endif
  959. }
  960. /*********************************************************************
  961. * @fn osal_buffer_uint32
  962. *
  963. * @brief
  964. *
  965. * Buffer an uint32 value - LSB first.
  966. *
  967. * @param buf - buffer
  968. * @param val - uint32 value
  969. *
  970. * @return pointer to end of destination buffer
  971. */
  972. uint8* osal_buffer_uint32( uint8 *buf, uint32 val )
  973. {
  974. *buf++ = BREAK_UINT32( val, 0 );
  975. *buf++ = BREAK_UINT32( val, 1 );
  976. *buf++ = BREAK_UINT32( val, 2 );
  977. *buf++ = BREAK_UINT32( val, 3 );
  978. return buf;
  979. }
  980. /*********************************************************************
  981. * @fn osal_buffer_uint24
  982. *
  983. * @brief
  984. *
  985. * Buffer an uint24 value - LSB first. Note that type uint24 is
  986. * typedef to uint32 in comdef.h
  987. *
  988. * @param buf - buffer
  989. * @param val - uint24 value
  990. *
  991. * @return pointer to end of destination buffer
  992. */
  993. uint8* osal_buffer_uint24( uint8 *buf, uint24 val )
  994. {
  995. *buf++ = BREAK_UINT32( val, 0 );
  996. *buf++ = BREAK_UINT32( val, 1 );
  997. *buf++ = BREAK_UINT32( val, 2 );
  998. return buf;
  999. }
  1000. /*********************************************************************
  1001. * @fn osal_isbufset
  1002. *
  1003. * @brief
  1004. *
  1005. * Is all of the array elements set to a value?
  1006. *
  1007. * @param buf - buffer to check
  1008. * @param val - value to check each array element for
  1009. * @param len - length to check
  1010. *
  1011. * @return TRUE if all "val"
  1012. * FALSE otherwise
  1013. */
  1014. uint8 osal_isbufset( uint8 *buf, uint8 val, uint8 len )
  1015. {
  1016. uint8 x;
  1017. if ( buf == NULL )
  1018. {
  1019. return ( FALSE );
  1020. }
  1021. for ( x = 0; x < len; x++ )
  1022. {
  1023. // Check for non-initialized value
  1024. if ( buf[x] != val )
  1025. {
  1026. return ( FALSE );
  1027. }
  1028. }
  1029. return ( TRUE );
  1030. }
  1031. /*********************************************************************
  1032. * @fn osal_self
  1033. *
  1034. * @brief
  1035. *
  1036. * This function returns the task ID of the current (active) task.
  1037. *
  1038. * @param void
  1039. *
  1040. * @return active task ID or TASK_NO_TASK if no task is active
  1041. */
  1042. uint8 osal_self( void )
  1043. {
  1044. return ( activeTaskID );
  1045. }
  1046. /*********************************************************************
  1047. */