📄 osal.c
字号:
// queue message
osal_msg_enqueue( &osal_qHead, msg_ptr );
// Signal the task that a message is waiting
osal_set_event( destination_task, SYS_EVENT_MSG );
return ( ZSUCCESS );
}
/*********************************************************************
* @fn osal_msg_receive
*
* @brief
*
* This function is called by a task to retrieve a received command
* message. The calling task must deallocate the message buffer after
* processing the message using the osal_msg_deallocate() call.
*
* @param byte task_id - receiving tasks ID
*
* @return *byte - message information or NULL if no message
*/
byte *osal_msg_receive( byte task_id )
{
osal_msg_hdr_t *listHdr;
osal_msg_hdr_t *prevHdr=0;
halIntState_t intState;
// Hold off interrupts
HAL_ENTER_CRITICAL_SECTION(intState);
// Point to the top of the queue
listHdr = osal_qHead;
// Look through the queue for a message that belongs to the asking task
while ( listHdr != NULL )
{
if ( (listHdr - 1)->dest_id == task_id )
{
break;
}
prevHdr = listHdr;
listHdr = OSAL_MSG_NEXT( listHdr );
}
// Did we find a message?
if ( listHdr == NULL )
{
// Release interrupts
HAL_EXIT_CRITICAL_SECTION(intState);
return NULL;
}
// Take out of the link list
osal_msg_extract( &osal_qHead, listHdr, prevHdr );
// Release interrupts
HAL_EXIT_CRITICAL_SECTION(intState);
return ( (byte*) listHdr );
}
/*********************************************************************
* @fn osal_msg_enqueue
*
* @brief
*
* This function enqueues an OSAL message into an OSAL queue.
*
* @param osal_msg_q_t *q_ptr - OSAL queue
* @param void *msg_ptr - OSAL message
*
* @return none
*/
void osal_msg_enqueue( osal_msg_q_t *q_ptr, void *msg_ptr )
{
void *list;
halIntState_t intState;
// Hold off interrupts
HAL_ENTER_CRITICAL_SECTION(intState);
// If first message in queue
if ( *q_ptr == NULL )
{
*q_ptr = msg_ptr;
}
else
{
// Find end of queue
for ( list = *q_ptr; OSAL_MSG_NEXT( list ) != NULL; list = OSAL_MSG_NEXT( list ) );
// Add message to end of queue
OSAL_MSG_NEXT( list ) = msg_ptr;
}
// Re-enable interrupts
HAL_EXIT_CRITICAL_SECTION(intState);
}
/*********************************************************************
* @fn osal_msg_dequeue
*
* @brief
*
* This function dequeues an OSAL message from an OSAL queue.
*
* @param osal_msg_q_t *q_ptr - OSAL queue
*
* @return void * - pointer to OSAL message or NULL of queue is empty.
*/
void *osal_msg_dequeue( osal_msg_q_t *q_ptr )
{
void *msg_ptr;
halIntState_t intState;
// Hold off interrupts
HAL_ENTER_CRITICAL_SECTION(intState);
if ( *q_ptr == NULL )
{
HAL_EXIT_CRITICAL_SECTION(intState);
return NULL;
}
// Dequeue message
msg_ptr = *q_ptr;
*q_ptr = OSAL_MSG_NEXT( msg_ptr );
OSAL_MSG_NEXT( msg_ptr ) = NULL;
OSAL_MSG_ID( msg_ptr ) = TASK_NO_TASK;
// Re-enable interrupts
HAL_EXIT_CRITICAL_SECTION(intState);
return msg_ptr;
}
/*********************************************************************
* @fn osal_msg_push
*
* @brief
*
* This function pushes an OSAL message to the head of an OSAL
* queue.
*
* @param osal_msg_q_t *q_ptr - OSAL queue
* @param void *msg_ptr - OSAL message
*
* @return none
*/
void osal_msg_push( osal_msg_q_t *q_ptr, void *msg_ptr )
{
halIntState_t intState;
// Hold off interrupts
HAL_ENTER_CRITICAL_SECTION(intState);
if ( *q_ptr == NULL )
{
*q_ptr = msg_ptr;
}
else
{
// Push message to head of queue
OSAL_MSG_NEXT( msg_ptr ) = *q_ptr;
*q_ptr = msg_ptr;
}
// Re-enable interrupts
HAL_EXIT_CRITICAL_SECTION(intState);
}
/*********************************************************************
* @fn osal_msg_extract
*
* @brief
*
* This function extracts and removes an OSAL message from the
* middle of an OSAL queue.
*
* @param osal_msg_q_t *q_ptr - OSAL queue
* @param void *msg_ptr - OSAL message to be extracted
* @param void *prev_ptr - OSAL message before msg_ptr in queue
*
* @return none
*/
void osal_msg_extract( osal_msg_q_t *q_ptr, void *msg_ptr, void *prev_ptr )
{
halIntState_t intState;
// Hold off interrupts
HAL_ENTER_CRITICAL_SECTION(intState);
if ( msg_ptr == *q_ptr )
{
// remove from first
*q_ptr = OSAL_MSG_NEXT( msg_ptr );
}
else
{
// remove from middle
OSAL_MSG_NEXT( prev_ptr ) = OSAL_MSG_NEXT( msg_ptr );
}
OSAL_MSG_NEXT( msg_ptr ) = NULL;
OSAL_MSG_ID( msg_ptr ) = TASK_NO_TASK;
// Re-enable interrupts
HAL_EXIT_CRITICAL_SECTION(intState);
}
/*********************************************************************
* @fn osal_msg_enqueue_max
*
* @brief
*
* This function enqueues an OSAL message into an OSAL queue if
* the length of the queue is less than max.
*
* @param osal_msg_q_t *q_ptr - OSAL queue
* @param void *msg_ptr - OSAL message
* @param byte max - maximum length of queue
*
* @return TRUE if message was enqueued, FALSE otherwise
*/
byte osal_msg_enqueue_max( osal_msg_q_t *q_ptr, void *msg_ptr, byte max )
{
void *list;
byte ret = FALSE;
halIntState_t intState;
// Hold off interrupts
HAL_ENTER_CRITICAL_SECTION(intState);
// If first message in queue
if ( *q_ptr == NULL )
{
*q_ptr = msg_ptr;
ret = TRUE;
}
else
{
// Find end of queue or max
list = *q_ptr;
max--;
while ( (OSAL_MSG_NEXT( list ) != NULL) && (max > 0) )
{
list = OSAL_MSG_NEXT( list );
max--;
}
// Add message to end of queue if max not reached
if ( max != 0 )
{
OSAL_MSG_NEXT( list ) = msg_ptr;
ret = TRUE;
}
}
// Re-enable interrupts
HAL_EXIT_CRITICAL_SECTION(intState);
return ret;
}
/*********************************************************************
* @fn osal_set_event
*
* @brief
*
* This function is called to set the event flags for a task. The
* event passed in is OR'd into the task's event variable.
*
* @param byte task_id - receiving tasks ID
* @param byte event_flag - what event to set
*
* @return ZSUCCESS, INVALID_TASK
*/
byte osal_set_event( byte task_id, UINT16 event_flag )
{
osalTaskRec_t *srchTask;
halIntState_t intState;
srchTask = osalFindTask( task_id );
if ( srchTask ) {
// Hold off interrupts
HAL_ENTER_CRITICAL_SECTION(intState);
// Stuff the event bit(s)
srchTask->events |= event_flag;
// Release interrupts
HAL_EXIT_CRITICAL_SECTION(intState);
}
else
return ( INVALID_TASK );
return ( ZSUCCESS );
}
/*********************************************************************
* @fn osal_isr_register
*
* @brief
*
* This function is called to register a service routine with an
* interrupt. When the interrupt occurs, this service routine is called.
*
* @param byte interrupt_id - Interrupt number
* @param void (*isr_ptr)( byte* ) - function pointer to ISR
*
* @return ZSUCCESS, INVALID_INTERRUPT_ID, or INVALID_ISR_PTR
*/
byte osal_isr_register( byte interrupt_id, void (*isr_ptr)( byte* ) )
{
return ( ZSUCCESS );
}
/*********************************************************************
* @fn osal_int_enable
*
* @brief
*
* This function is called to enable an interrupt. Once enabled,
* occurrence of the interrupt causes the service routine associated
* with that interrupt to be called.
*
* If INTS_ALL is the interrupt_id, interrupts (in general) are enabled.
* If a single interrupt is passed in, then interrupts still have
* to be enabled with another call to INTS_ALL.
*
* @param byte interrupt_id - Interrupt number
*
* @return ZSUCCESS or INVALID_INTERRUPT_ID
*/
byte osal_int_enable( byte interrupt_id )
{
if ( interrupt_id == INTS_ALL )
{
HAL_ENABLE_INTERRUPTS();
}
else
return ( INVALID_INTERRUPT_ID );
return ( ZSUCCESS );
}
/*********************************************************************
* @fn osal_int_disable
*
* @brief
*
* This function is called to disable an interrupt. When a disabled
* interrupt occurs, the service routine associated with that
* interrupt is not called.
*
* If INTS_ALL is the interrupt_id, interrupts (in general) are disabled.
* If a single interrupt is passed in, then just that interrupt is disabled.
*
* @param byte interrupt_id - Interrupt number
*
* @return ZSUCCESS or INVALID_INTERRUPT_ID
*/
byte osal_int_disable( byte interrupt_id )
{
if ( interrupt_id == INTS_ALL )
{
HAL_DISABLE_INTERRUPTS();
}
else
return ( INVALID_INTERRUPT_ID );
return ( ZSUCCESS );
}
/*********************************************************************
* @fn osal_init_system
*
* @brief
*
* This function initializes the "task" system by creating the
* tasks defined in the task table (OSAL_Tasks.h).
*
* @param void
*
* @return ZSUCCESS
*/
byte osal_init_system( void )
{
// Initialize the Memory Allocation System
osal_mem_init();
// Initialize the message queue
osal_qHead = NULL;
#if defined( OSAL_TOTAL_MEM )
osal_msg_cnt = 0;
#endif
// Initialize the timers
osalTimerInit();
// Initialize the Power Management System
osal_pwrmgr_init();
// Initialize the tasking system
osalTaskInit();
// add tasks
osalAddTasks();
osalInitTasks();
// Setup efficient search for the first free block of heap.
osal_mem_kick();
return ( ZSUCCESS );
}
/*********************************************************************
* @fn osal_start_system
*
* @brief
*
* This function is the main loop function of the task system. It
* will look through all task events and call the task_event_processor()
* function for the task with the event. If there are no events (for
* all tasks), this function puts the processor into Sleep.
* This Function doesn't return.
*
* @param void
*
* @return none
*/
void osal_start_system( void )
{
uint16 events;
uint16 retEvents;
byte activity;
halIntState_t intState;
// Forever Loop
#if !defined ( ZBIT )
for(;;)
#endif
{
/* This replaces MT_SerialPoll() and osal_check_timer() */
Hal_ProcessPoll();
activity = false;
activeTask = osalNextActiveTask();
if ( activeTask )
{
HAL_ENTER_CRITICAL_SECTION(intState);
events = activeTask->events;
// Clear the Events for this task
activeTask->events = 0;
HAL_EXIT_CRITICAL_SECTION(intState);
if ( events != 0 )
{
// Call the task to process the event(s)
if ( activeTask->pfnEventProcessor )
{
retEvents = (activeTask->pfnEventProcessor)( activeTask->taskID, events );
// Add back unprocessed events to the current task
HAL_ENTER_CRITICAL_SECTION(intState);
activeTask->events |= retEvents;
HAL_EXIT_CRITICAL_SECTION(intState);
activity = true;
}
}
}
// Complete pass through all task events with no activity?
if ( activity == false )
{
#if defined( POWER_SAVING )
// Put the processor/system into sleep
osal_pwrmgr_powerconserve();
#endif
}
}
}
/*********************************************************************
* @fn osal_self
*
* @brief
*
* This function returns the task ID of the calling (current) task.
*
* @param void
*
* @return byte task ID, 0xFF bad task ID
*/
byte osal_self( void )
{
if ( activeTask )
return ( activeTask->taskID );
else
return ( TASK_NO_TASK );
}
/*********************************************************************
*********************************************************************/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -