OSAL.c 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994
  1. /**************************************************************************************************
  2. Filename: OSAL.c
  3. Revised: $Date: 2009-03-12 16:25:22 -0700 (Thu, 12 Mar 2009) $
  4. Revision: $Revision: 19404 $
  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-2009 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 “AS 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. /*********************************************************************
  49. * MACROS
  50. */
  51. #define OSAL_MSG_LEN(msg_ptr) ((osal_msg_hdr_t *) (msg_ptr) - 1)->len
  52. #define OSAL_MSG_ID(msg_ptr) ((osal_msg_hdr_t *) (msg_ptr) - 1)->dest_id
  53. /*********************************************************************
  54. * CONSTANTS
  55. */
  56. /*********************************************************************
  57. * TYPEDEFS
  58. */
  59. /*********************************************************************
  60. * GLOBAL VARIABLES
  61. */
  62. // Message Pool Definitions
  63. osal_msg_q_t osal_qHead;
  64. #if defined( OSAL_TOTAL_MEM )
  65. uint16 osal_msg_cnt;
  66. #endif
  67. /*********************************************************************
  68. * EXTERNAL VARIABLES
  69. */
  70. /*********************************************************************
  71. * EXTERNAL FUNCTIONS
  72. */
  73. /*********************************************************************
  74. * LOCAL VARIABLES
  75. */
  76. /*********************************************************************
  77. * LOCAL FUNCTION PROTOTYPES
  78. */
  79. /*********************************************************************
  80. * HELPER FUNCTIONS
  81. */
  82. /* very ugly stub so Keil can compile */
  83. #ifdef __KEIL__
  84. char * itoa ( int value, char * buffer, int radix )
  85. {
  86. return(buffer);
  87. }
  88. #endif
  89. /*********************************************************************
  90. * @fn osal_strlen
  91. *
  92. * @brief
  93. *
  94. * Calculates the length of a string. The string must be null
  95. * terminated.
  96. *
  97. * @param char *pString - pointer to text string
  98. *
  99. * @return int - number of characters
  100. */
  101. int osal_strlen( char *pString )
  102. {
  103. return (int)( strlen( pString ) );
  104. }
  105. /*********************************************************************
  106. * @fn osal_memcpy
  107. *
  108. * @brief
  109. *
  110. * Generic memory copy.
  111. *
  112. * Note: This function differs from the standard memcpy(), since
  113. * it returns the pointer to the next destination uint8. The
  114. * standard memcpy() returns the original destination address.
  115. *
  116. * @param dst - destination address
  117. * @param src - source address
  118. * @param len - number of bytes to copy
  119. *
  120. * @return pointer to end of destination buffer
  121. */
  122. void *osal_memcpy( void *dst, const void GENERIC *src, unsigned int len )
  123. {
  124. uint8 *pDst;
  125. const uint8 GENERIC *pSrc;
  126. pSrc = src;
  127. pDst = dst;
  128. while ( len-- )
  129. *pDst++ = *pSrc++;
  130. return ( pDst );
  131. }
  132. /*********************************************************************
  133. * @fn osal_memcmp
  134. *
  135. * @brief
  136. *
  137. * Generic memory compare.
  138. *
  139. * @param src1 - source 1 addrexx
  140. * @param src2 - source 2 address
  141. * @param len - number of bytes to compare
  142. *
  143. * @return TRUE - same, FALSE - different
  144. */
  145. uint8 osal_memcmp( const void GENERIC *src1, const void GENERIC *src2, unsigned int len )
  146. {
  147. const uint8 GENERIC *pSrc1;
  148. const uint8 GENERIC *pSrc2;
  149. pSrc1 = src1;
  150. pSrc2 = src2;
  151. while ( len-- )
  152. {
  153. if( *pSrc1++ != *pSrc2++ )
  154. return FALSE;
  155. }
  156. return TRUE;
  157. }
  158. /*********************************************************************
  159. * @fn osal_memset
  160. *
  161. * @brief
  162. *
  163. * Set memory buffer to value.
  164. *
  165. * @param dest - pointer to buffer
  166. * @param value - what to set each uint8 of the message
  167. * @param size - how big
  168. *
  169. * @return value of next widget, 0 if no widget found
  170. */
  171. void *osal_memset( void *dest, uint8 value, int len )
  172. {
  173. return memset( dest, value, len );
  174. }
  175. /*********************************************************************
  176. * @fn osal_build_uint16
  177. *
  178. * @brief
  179. *
  180. * Build a uint16 out of 2 bytes (0 then 1).
  181. *
  182. * @param swapped - 0 then 1
  183. *
  184. * @return uint16
  185. */
  186. uint16 osal_build_uint16( uint8 *swapped )
  187. {
  188. return ( BUILD_UINT16( swapped[0], swapped[1] ) );
  189. }
  190. /*********************************************************************
  191. * @fn osal_build_uint32
  192. *
  193. * @brief
  194. *
  195. * Build a uint32 out of sequential bytes.
  196. *
  197. * @param swapped - sequential bytes
  198. * @param len - number of bytes in the uint8 array
  199. *
  200. * @return uint32
  201. */
  202. uint32 osal_build_uint32( uint8 *swapped, uint8 len )
  203. {
  204. if ( len == 2 )
  205. return ( BUILD_UINT32( swapped[0], swapped[1], 0L, 0L ) );
  206. else if ( len == 3 )
  207. return ( BUILD_UINT32( swapped[0], swapped[1], swapped[2], 0L ) );
  208. else if ( len == 4 )
  209. return ( BUILD_UINT32( swapped[0], swapped[1], swapped[2], swapped[3] ) );
  210. else
  211. return ( (uint32)swapped[0] );
  212. }
  213. #if !defined ( ZBIT ) && !defined ( ZBIT2 ) && !defined (UBIT)
  214. /*********************************************************************
  215. * @fn _ltoa
  216. *
  217. * @brief
  218. *
  219. * convert a long unsigned int to a string.
  220. *
  221. * @param l - long to convert
  222. * @param buf - buffer to convert to
  223. * @param radix - 10 dec, 16 hex
  224. *
  225. * @return pointer to buffer
  226. */
  227. unsigned char * _ltoa(unsigned long l, unsigned char *buf, unsigned char radix)
  228. {
  229. #if defined( __GNUC__ )
  230. return ( (char*)ltoa( l, buf, radix ) );
  231. #else
  232. unsigned char tmp1[10] = "", tmp2[10] = "", tmp3[10] = "";
  233. unsigned short num1, num2, num3;
  234. unsigned char i;
  235. buf[0] = '\0';
  236. if ( radix == 10 )
  237. {
  238. num1 = l % 10000;
  239. num2 = (l / 10000) % 10000;
  240. num3 = (unsigned short)(l / 100000000);
  241. if (num3) _itoa(num3, tmp3, 10);
  242. if (num2) _itoa(num2, tmp2, 10);
  243. if (num1) _itoa(num1, tmp1, 10);
  244. if (num3)
  245. {
  246. strcpy((char*)buf, (char const*)tmp3);
  247. for (i = 0; i < 4 - strlen((char const*)tmp2); i++)
  248. strcat((char*)buf, "0");
  249. }
  250. strcat((char*)buf, (char const*)tmp2);
  251. if (num3 || num2)
  252. {
  253. for (i = 0; i < 4 - strlen((char const*)tmp1); i++)
  254. strcat((char*)buf, "0");
  255. }
  256. strcat((char*)buf, (char const*)tmp1);
  257. if (!num3 && !num2 && !num1)
  258. strcpy((char*)buf, "0");
  259. }
  260. else if ( radix == 16 )
  261. {
  262. num1 = l & 0x0000FFFF;
  263. num2 = l >> 16;
  264. if (num2) _itoa(num2, tmp2, 16);
  265. if (num1) _itoa(num1, tmp1, 16);
  266. if (num2)
  267. {
  268. strcpy((char*)buf,(char const*)tmp2);
  269. for (i = 0; i < 4 - strlen((char const*)tmp1); i++)
  270. strcat((char*)buf, "0");
  271. }
  272. strcat((char*)buf, (char const*)tmp1);
  273. if (!num2 && !num1)
  274. strcpy((char*)buf, "0");
  275. }
  276. else
  277. return NULL;
  278. return buf;
  279. #endif
  280. }
  281. #endif // !defined(ZBIT) && !defined(ZBIT2)
  282. /*********************************************************************
  283. * @fn osal_rand
  284. *
  285. * @brief Random number generator
  286. *
  287. * @param none
  288. *
  289. * @return uint16 - new random number
  290. */
  291. uint16 osal_rand( void )
  292. {
  293. return ( Onboard_rand() );
  294. }
  295. /*********************************************************************
  296. * API FUNCTIONS
  297. *********************************************************************/
  298. /*********************************************************************
  299. * @fn osal_msg_allocate
  300. *
  301. * @brief
  302. *
  303. * This function is called by a task to allocate a message buffer
  304. * into which the task will encode the particular message it wishes
  305. * to send. This common buffer scheme is used to strictly limit the
  306. * creation of message buffers within the system due to RAM size
  307. * limitations on the microprocessor. Note that all message buffers
  308. * are a fixed size (at least initially). The parameter len is kept
  309. * in case a message pool with varying fixed message sizes is later
  310. * created (for example, a pool of message buffers of size LARGE,
  311. * MEDIUM and SMALL could be maintained and allocated based on request
  312. * from the tasks).
  313. *
  314. *
  315. * @param uint8 len - wanted buffer length
  316. *
  317. *
  318. * @return pointer to allocated buffer or NULL if allocation failed.
  319. */
  320. uint8 * osal_msg_allocate( uint16 len )
  321. {
  322. osal_msg_hdr_t *hdr;
  323. if ( len == 0 )
  324. return ( NULL );
  325. hdr = (osal_msg_hdr_t *) osal_mem_alloc( (short)(len + sizeof( osal_msg_hdr_t )) );
  326. if ( hdr )
  327. {
  328. hdr->next = NULL;
  329. hdr->len = len;
  330. hdr->dest_id = TASK_NO_TASK;
  331. #if defined( OSAL_TOTAL_MEM )
  332. osal_msg_cnt++;
  333. #endif
  334. return ( (uint8 *) (hdr + 1) );
  335. }
  336. else
  337. return ( NULL );
  338. }
  339. /*********************************************************************
  340. * @fn osal_msg_deallocate
  341. *
  342. * @brief
  343. *
  344. * This function is used to deallocate a message buffer. This function
  345. * is called by a task (or processing element) after it has finished
  346. * processing a received message.
  347. *
  348. *
  349. * @param uint8 *msg_ptr - pointer to new message buffer
  350. *
  351. * @return SUCCESS, INVALID_MSG_POINTER
  352. */
  353. uint8 osal_msg_deallocate( uint8 *msg_ptr )
  354. {
  355. uint8 *x;
  356. if ( msg_ptr == NULL )
  357. return ( INVALID_MSG_POINTER );
  358. // don't deallocate queued buffer
  359. if ( OSAL_MSG_ID( msg_ptr ) != TASK_NO_TASK )
  360. return ( MSG_BUFFER_NOT_AVAIL );
  361. x = (uint8 *)((uint8 *)msg_ptr - sizeof( osal_msg_hdr_t ));
  362. osal_mem_free( (void *)x );
  363. #if defined( OSAL_TOTAL_MEM )
  364. if ( osal_msg_cnt )
  365. osal_msg_cnt--;
  366. #endif
  367. return ( SUCCESS );
  368. }
  369. #if defined( OSAL_TOTAL_MEM )
  370. /*********************************************************************
  371. * @fn osal_num_msgs
  372. *
  373. * @brief
  374. *
  375. * This function returns the number of allocated messages
  376. *
  377. * @param void
  378. *
  379. * @return uint16 - number of msgs out
  380. */
  381. uint16 osal_num_msgs( void )
  382. {
  383. return ( osal_msg_cnt );
  384. }
  385. #endif
  386. /*********************************************************************
  387. * @fn osal_msg_send
  388. *
  389. * @brief
  390. *
  391. * This function is called by a task to send a command message to
  392. * another task or processing element. The sending_task field must
  393. * refer to a valid task, since the task ID will be used
  394. * for the response message. This function will also set a message
  395. * ready event in the destination tasks event list.
  396. *
  397. *
  398. * @param uint8 destination task - Send msg to? Task ID
  399. * @param uint8 *msg_ptr - pointer to new message buffer
  400. * @param uint8 len - length of data in message
  401. *
  402. * @return SUCCESS, INVALID_TASK, INVALID_MSG_POINTER
  403. */
  404. uint8 osal_msg_send( uint8 destination_task, uint8 *msg_ptr )
  405. {
  406. if ( msg_ptr == NULL )
  407. return ( INVALID_MSG_POINTER );
  408. if ( destination_task >= tasksCnt )
  409. {
  410. osal_msg_deallocate( msg_ptr );
  411. return ( INVALID_TASK );
  412. }
  413. // Check the message header
  414. if ( OSAL_MSG_NEXT( msg_ptr ) != NULL ||
  415. OSAL_MSG_ID( msg_ptr ) != TASK_NO_TASK )
  416. {
  417. osal_msg_deallocate( msg_ptr );
  418. return ( INVALID_MSG_POINTER );
  419. }
  420. OSAL_MSG_ID( msg_ptr ) = destination_task;
  421. // queue message
  422. osal_msg_enqueue( &osal_qHead, msg_ptr );
  423. // Signal the task that a message is waiting
  424. osal_set_event( destination_task, SYS_EVENT_MSG );
  425. return ( SUCCESS );
  426. }
  427. /*********************************************************************
  428. * @fn osal_msg_receive
  429. *
  430. * @brief
  431. *
  432. * This function is called by a task to retrieve a received command
  433. * message. The calling task must deallocate the message buffer after
  434. * processing the message using the osal_msg_deallocate() call.
  435. *
  436. * @param uint8 task_id - receiving tasks ID
  437. *
  438. * @return *uint8 - message information or NULL if no message
  439. */
  440. uint8 *osal_msg_receive( uint8 task_id )
  441. {
  442. osal_msg_hdr_t *listHdr;
  443. osal_msg_hdr_t *prevHdr=0;
  444. halIntState_t intState;
  445. // Hold off interrupts
  446. HAL_ENTER_CRITICAL_SECTION(intState);
  447. // Point to the top of the queue
  448. listHdr = osal_qHead;
  449. // Look through the queue for a message that belongs to the asking task
  450. while ( listHdr != NULL )
  451. {
  452. if ( (listHdr - 1)->dest_id == task_id )
  453. {
  454. break;
  455. }
  456. prevHdr = listHdr;
  457. listHdr = OSAL_MSG_NEXT( listHdr );
  458. }
  459. // Did we find a message?
  460. if ( listHdr == NULL )
  461. {
  462. // Release interrupts
  463. HAL_EXIT_CRITICAL_SECTION(intState);
  464. return NULL;
  465. }
  466. // Take out of the link list
  467. osal_msg_extract( &osal_qHead, listHdr, prevHdr );
  468. // Release interrupts
  469. HAL_EXIT_CRITICAL_SECTION(intState);
  470. return ( (uint8*) listHdr );
  471. }
  472. /*********************************************************************
  473. * @fn osal_msg_enqueue
  474. *
  475. * @brief
  476. *
  477. * This function enqueues an OSAL message into an OSAL queue.
  478. *
  479. * @param osal_msg_q_t *q_ptr - OSAL queue
  480. * @param void *msg_ptr - OSAL message
  481. *
  482. * @return none
  483. */
  484. void osal_msg_enqueue( osal_msg_q_t *q_ptr, void *msg_ptr )
  485. {
  486. void *list;
  487. halIntState_t intState;
  488. // Hold off interrupts
  489. HAL_ENTER_CRITICAL_SECTION(intState);
  490. OSAL_MSG_NEXT( msg_ptr ) = NULL;
  491. // If first message in queue
  492. if ( *q_ptr == NULL )
  493. {
  494. *q_ptr = msg_ptr;
  495. }
  496. else
  497. {
  498. // Find end of queue
  499. for ( list = *q_ptr; OSAL_MSG_NEXT( list ) != NULL; list = OSAL_MSG_NEXT( list ) );
  500. // Add message to end of queue
  501. OSAL_MSG_NEXT( list ) = msg_ptr;
  502. }
  503. // Re-enable interrupts
  504. HAL_EXIT_CRITICAL_SECTION(intState);
  505. }
  506. /*********************************************************************
  507. * @fn osal_msg_dequeue
  508. *
  509. * @brief
  510. *
  511. * This function dequeues an OSAL message from an OSAL queue.
  512. *
  513. * @param osal_msg_q_t *q_ptr - OSAL queue
  514. *
  515. * @return void * - pointer to OSAL message or NULL of queue is empty.
  516. */
  517. void *osal_msg_dequeue( osal_msg_q_t *q_ptr )
  518. {
  519. void *msg_ptr;
  520. halIntState_t intState;
  521. // Hold off interrupts
  522. HAL_ENTER_CRITICAL_SECTION(intState);
  523. if ( *q_ptr == NULL )
  524. {
  525. HAL_EXIT_CRITICAL_SECTION(intState);
  526. return NULL;
  527. }
  528. // Dequeue message
  529. msg_ptr = *q_ptr;
  530. *q_ptr = OSAL_MSG_NEXT( msg_ptr );
  531. OSAL_MSG_NEXT( msg_ptr ) = NULL;
  532. OSAL_MSG_ID( msg_ptr ) = TASK_NO_TASK;
  533. // Re-enable interrupts
  534. HAL_EXIT_CRITICAL_SECTION(intState);
  535. return msg_ptr;
  536. }
  537. /*********************************************************************
  538. * @fn osal_msg_push
  539. *
  540. * @brief
  541. *
  542. * This function pushes an OSAL message to the head of an OSAL
  543. * queue.
  544. *
  545. * @param osal_msg_q_t *q_ptr - OSAL queue
  546. * @param void *msg_ptr - OSAL message
  547. *
  548. * @return none
  549. */
  550. void osal_msg_push( osal_msg_q_t *q_ptr, void *msg_ptr )
  551. {
  552. halIntState_t intState;
  553. // Hold off interrupts
  554. HAL_ENTER_CRITICAL_SECTION(intState);
  555. // Push message to head of queue
  556. OSAL_MSG_NEXT( msg_ptr ) = *q_ptr;
  557. *q_ptr = msg_ptr;
  558. // Re-enable interrupts
  559. HAL_EXIT_CRITICAL_SECTION(intState);
  560. }
  561. /*********************************************************************
  562. * @fn osal_msg_extract
  563. *
  564. * @brief
  565. *
  566. * This function extracts and removes an OSAL message from the
  567. * middle of an OSAL queue.
  568. *
  569. * @param osal_msg_q_t *q_ptr - OSAL queue
  570. * @param void *msg_ptr - OSAL message to be extracted
  571. * @param void *prev_ptr - OSAL message before msg_ptr in queue
  572. *
  573. * @return none
  574. */
  575. void osal_msg_extract( osal_msg_q_t *q_ptr, void *msg_ptr, void *prev_ptr )
  576. {
  577. halIntState_t intState;
  578. // Hold off interrupts
  579. HAL_ENTER_CRITICAL_SECTION(intState);
  580. if ( msg_ptr == *q_ptr )
  581. {
  582. // remove from first
  583. *q_ptr = OSAL_MSG_NEXT( msg_ptr );
  584. }
  585. else
  586. {
  587. // remove from middle
  588. OSAL_MSG_NEXT( prev_ptr ) = OSAL_MSG_NEXT( msg_ptr );
  589. }
  590. OSAL_MSG_NEXT( msg_ptr ) = NULL;
  591. OSAL_MSG_ID( msg_ptr ) = TASK_NO_TASK;
  592. // Re-enable interrupts
  593. HAL_EXIT_CRITICAL_SECTION(intState);
  594. }
  595. /*********************************************************************
  596. * @fn osal_msg_enqueue_max
  597. *
  598. * @brief
  599. *
  600. * This function enqueues an OSAL message into an OSAL queue if
  601. * the length of the queue is less than max.
  602. *
  603. * @param osal_msg_q_t *q_ptr - OSAL queue
  604. * @param void *msg_ptr - OSAL message
  605. * @param uint8 max - maximum length of queue
  606. *
  607. * @return TRUE if message was enqueued, FALSE otherwise
  608. */
  609. uint8 osal_msg_enqueue_max( osal_msg_q_t *q_ptr, void *msg_ptr, uint8 max )
  610. {
  611. void *list;
  612. uint8 ret = FALSE;
  613. halIntState_t intState;
  614. // Hold off interrupts
  615. HAL_ENTER_CRITICAL_SECTION(intState);
  616. // If first message in queue
  617. if ( *q_ptr == NULL )
  618. {
  619. *q_ptr = msg_ptr;
  620. ret = TRUE;
  621. }
  622. else
  623. {
  624. // Find end of queue or max
  625. list = *q_ptr;
  626. max--;
  627. while ( (OSAL_MSG_NEXT( list ) != NULL) && (max > 0) )
  628. {
  629. list = OSAL_MSG_NEXT( list );
  630. max--;
  631. }
  632. // Add message to end of queue if max not reached
  633. if ( max != 0 )
  634. {
  635. OSAL_MSG_NEXT( list ) = msg_ptr;
  636. ret = TRUE;
  637. }
  638. }
  639. // Re-enable interrupts
  640. HAL_EXIT_CRITICAL_SECTION(intState);
  641. return ret;
  642. }
  643. /*********************************************************************
  644. * @fn osal_set_event
  645. *
  646. * @brief
  647. *
  648. * This function is called to set the event flags for a task. The
  649. * event passed in is OR'd into the task's event variable.
  650. *
  651. * @param uint8 task_id - receiving tasks ID
  652. * @param uint8 event_flag - what event to set
  653. *
  654. * @return SUCCESS, INVALID_TASK
  655. */
  656. uint8 osal_set_event( uint8 task_id, uint16 event_flag )
  657. {
  658. if ( task_id < tasksCnt )
  659. {
  660. halIntState_t intState;
  661. HAL_ENTER_CRITICAL_SECTION(intState); // Hold off interrupts
  662. tasksEvents[task_id] |= event_flag; // Stuff the event bit(s)
  663. HAL_EXIT_CRITICAL_SECTION(intState); // Release interrupts
  664. }
  665. else
  666. return ( INVALID_TASK );
  667. return ( SUCCESS );
  668. }
  669. /*********************************************************************
  670. * @fn osal_isr_register
  671. *
  672. * @brief
  673. *
  674. * This function is called to register a service routine with an
  675. * interrupt. When the interrupt occurs, this service routine is called.
  676. *
  677. * @param uint8 interrupt_id - Interrupt number
  678. * @param void (*isr_ptr)( uint8* ) - function pointer to ISR
  679. *
  680. * @return SUCCESS, INVALID_INTERRUPT_ID,
  681. */
  682. uint8 osal_isr_register( uint8 interrupt_id, void (*isr_ptr)( uint8* ) )
  683. {
  684. // Remove these statements when functionality is complete
  685. (void)interrupt_id;
  686. (void)isr_ptr;
  687. return ( SUCCESS );
  688. }
  689. /*********************************************************************
  690. * @fn osal_int_enable
  691. *
  692. * @brief
  693. *
  694. * This function is called to enable an interrupt. Once enabled,
  695. * occurrence of the interrupt causes the service routine associated
  696. * with that interrupt to be called.
  697. *
  698. * If INTS_ALL is the interrupt_id, interrupts (in general) are enabled.
  699. * If a single interrupt is passed in, then interrupts still have
  700. * to be enabled with another call to INTS_ALL.
  701. *
  702. * @param uint8 interrupt_id - Interrupt number
  703. *
  704. * @return SUCCESS or INVALID_INTERRUPT_ID
  705. */
  706. uint8 osal_int_enable( uint8 interrupt_id )
  707. {
  708. if ( interrupt_id == INTS_ALL )
  709. {
  710. HAL_ENABLE_INTERRUPTS();
  711. }
  712. else
  713. return ( INVALID_INTERRUPT_ID );
  714. return ( SUCCESS );
  715. }
  716. /*********************************************************************
  717. * @fn osal_int_disable
  718. *
  719. * @brief
  720. *
  721. * This function is called to disable an interrupt. When a disabled
  722. * interrupt occurs, the service routine associated with that
  723. * interrupt is not called.
  724. *
  725. * If INTS_ALL is the interrupt_id, interrupts (in general) are disabled.
  726. * If a single interrupt is passed in, then just that interrupt is disabled.
  727. *
  728. * @param uint8 interrupt_id - Interrupt number
  729. *
  730. * @return SUCCESS or INVALID_INTERRUPT_ID
  731. */
  732. uint8 osal_int_disable( uint8 interrupt_id )
  733. {
  734. if ( interrupt_id == INTS_ALL )
  735. {
  736. HAL_DISABLE_INTERRUPTS();
  737. }
  738. else
  739. return ( INVALID_INTERRUPT_ID );
  740. return ( SUCCESS );
  741. }
  742. /*********************************************************************
  743. * @fn osal_init_system
  744. *
  745. * @brief
  746. *
  747. * This function initializes the "task" system by creating the
  748. * tasks defined in the task table (OSAL_Tasks.h).
  749. *
  750. * @param void
  751. *
  752. * @return SUCCESS
  753. */
  754. uint8 osal_init_system( void )
  755. {
  756. // Initialize the Memory Allocation System
  757. osal_mem_init();
  758. // Initialize the message queue
  759. osal_qHead = NULL;
  760. #if defined( OSAL_TOTAL_MEM )
  761. osal_msg_cnt = 0;
  762. #endif
  763. // Initialize the timers
  764. osalTimerInit();
  765. // Initialize the Power Management System
  766. osal_pwrmgr_init();
  767. // Initialize the system tasks.
  768. osalInitTasks();
  769. // Setup efficient search for the first free block of heap.
  770. osal_mem_kick();
  771. return ( SUCCESS );
  772. }
  773. /*********************************************************************
  774. * @fn osal_start_system
  775. *
  776. * @brief
  777. *
  778. * This function is the main loop function of the task system. It
  779. * will look through all task events and call the task_event_processor()
  780. * function for the task with the event. If there are no events (for
  781. * all tasks), this function puts the processor into Sleep.
  782. * This Function doesn't return.
  783. *
  784. * @param void
  785. *
  786. * @return none
  787. */
  788. void osal_start_system( void )
  789. {
  790. #if !defined ( ZBIT ) && !defined ( UBIT )
  791. for(;;) // Forever Loop
  792. #endif
  793. {
  794. uint8 idx = 0;
  795. osalTimeUpdate();
  796. Hal_ProcessPoll(); // This replaces MT_SerialPoll() and osal_check_timer().
  797. do {
  798. if (tasksEvents[idx]) // Task is highest priority that is ready.
  799. {
  800. break;
  801. }
  802. } while (++idx < tasksCnt);
  803. if (idx < tasksCnt)
  804. {
  805. uint16 events;
  806. halIntState_t intState;
  807. HAL_ENTER_CRITICAL_SECTION(intState);
  808. events = tasksEvents[idx];
  809. tasksEvents[idx] = 0; // Clear the Events for this task.
  810. HAL_EXIT_CRITICAL_SECTION(intState);
  811. events = (tasksArr[idx])( idx, events );
  812. HAL_ENTER_CRITICAL_SECTION(intState);
  813. tasksEvents[idx] |= events; // Add back unprocessed events to the current task.
  814. HAL_EXIT_CRITICAL_SECTION(intState);
  815. }
  816. #if defined( POWER_SAVING )
  817. else // Complete pass through all task events with no activity?
  818. {
  819. osal_pwrmgr_powerconserve(); // Put the processor/system into sleep
  820. }
  821. #endif
  822. }
  823. }
  824. /*********************************************************************
  825. * @fn osal_buffer_uint32
  826. *
  827. * @brief
  828. *
  829. * Buffer an uint32 value - LSB first.
  830. *
  831. * @param buf - buffer
  832. * @param val - uint32 value
  833. *
  834. * @return pointer to end of destination buffer
  835. */
  836. uint8* osal_buffer_uint32( uint8 *buf, uint32 val )
  837. {
  838. *buf++ = BREAK_UINT32( val, 0 );
  839. *buf++ = BREAK_UINT32( val, 1 );
  840. *buf++ = BREAK_UINT32( val, 2 );
  841. *buf++ = BREAK_UINT32( val, 3 );
  842. return buf;
  843. }
  844. /*********************************************************************
  845. * @fn osal_buffer_uint24
  846. *
  847. * @brief
  848. *
  849. * Buffer an uint24 value - LSB first. Note that type uint24 is
  850. * typedef to uint32 in comdef.h
  851. *
  852. * @param buf - buffer
  853. * @param val - uint24 value
  854. *
  855. * @return pointer to end of destination buffer
  856. */
  857. uint8* osal_buffer_uint24( uint8 *buf, uint24 val )
  858. {
  859. *buf++ = BREAK_UINT32( val, 0 );
  860. *buf++ = BREAK_UINT32( val, 1 );
  861. *buf++ = BREAK_UINT32( val, 2 );
  862. return buf;
  863. }
  864. /*********************************************************************
  865. *********************************************************************/