예제 #1
0
uint32_t OS_Task_create(task_start_t pstart, void* param, uint32_t pri, uint32_t stack_size, char* task_name, void* opt)
{
    _task_id task_id;
    TASK_TEMPLATE_STRUCT task_template;

    task_template.TASK_TEMPLATE_INDEX = 0;
    task_template.TASK_ADDRESS = (TASK_FPTR)pstart;
    task_template.TASK_STACKSIZE = stack_size;
    task_template.TASK_PRIORITY = pri;
    task_template.TASK_NAME = task_name;
    if (opt != NULL)
    {
        task_template.TASK_ATTRIBUTES = *((uint32_t*)opt);
    }
    else
    {
        task_template.TASK_ATTRIBUTES = 0;
    }
    
    task_template.CREATION_PARAMETER = (uint32_t)param;
    task_template.DEFAULT_TIME_SLICE = 0;

    task_id = _task_create_blocked(0, 0, (uint32_t)&task_template);
    
    if (task_id == MQX_NULL_TASK_ID) {
        return (uint32_t)OS_TASK_ERROR;
    }
    
    _task_ready(_task_get_td(task_id));
    return (uint32_t)task_id;
}
예제 #2
0
/** Initialise the Uart.
 *
 * BLEUART_Init()
 *	This function is called by the BLE stack (TRANSPORT layer) to initialise
 *	the UART layer.
 *  The user should uses this function to open and setup parameters for the
 *	UART line, eventually create Read Thread or setup RX and TX interrupts.
 *
 *	When this function succeeds, the UART layer shall be fully functional
 *
 *	This function is called during the BLESTCK_Init() process, failure here 
 *	will issue a failure in BLESTCK_Init()
 *
 * @todo implement this function
 *
 * @see BLESTCK_Init()
 *
 * @return The status of the operation:
 *	- BLESTATUS_SUCCESS indicates to the BLE stack that the UART have been
 *		successfully initialized
 *	- BLESTATUS_FAILED indicates to the BLE stack that the UART could not be
 *		initialized
 *	
 * @author Alexandre GIMARD
 */
BleStatus BLEUART_Init(void){
	// Add here specific code to execute during Stack Initialisation
	// in order to initialise the transport drivers
	//>
	_task_id	task_id;
	TASK_TEMPLATE_STRUCT	task_template;
	_mqx_uint priority;
    uint32_t para = 0x00;

    /*set up spi parameters*/
    spi_dev = fopen("spi1:", NULL);	   	
	ioctl (spi_dev, IO_IOCTL_SPI_SET_TRANSFER_MODE, &para);	
	ioctl (spi_dev, IO_IOCTL_SPI_SET_ATTRIBUTES, &para);
	ioctl (spi_dev, IO_IOCTL_SPI_SET_DUMMY_PATTERN, &para);
	para = 1000000;
	ioctl (spi_dev, IO_IOCTL_SPI_SET_BAUD, &para);

	/*create SPI read task*/
	task_template.TASK_TEMPLATE_INDEX = 0;
	task_template.TASK_ADDRESS = taskRead;
	task_template.TASK_STACKSIZE = 1000L;
	_task_get_priority(_task_get_id_from_name("main"), &priority);
	task_template.TASK_PRIORITY = priority - 1;
	task_template.TASK_NAME = "SPI read";
	task_template.TASK_ATTRIBUTES = 0;
	task_template.CREATION_PARAMETER = (uint32)spi_dev;
	task_template.DEFAULT_TIME_SLICE = 0;
	task_id = _task_create_blocked(0, 0, (uint32)&task_template);
	if(task_id == 0)
	{
		return BLESTATUS_FAILED;
	}	
	_task_ready(_task_get_td(task_id));

	/*power on and select pcs pin from 74HC595*/
	mux_74hc595_clear_bit(BSP_74HC595_0, BSP_74HC595_SPI_S0);
	mux_74hc595_clear_bit(BSP_74HC595_0, BSP_74HC595_SPI_S1);
	mux_74hc595_set_bit(BSP_74HC595_0, BSP_74HC595_VBLE_3V3);

	/*open flash file for system interface*/
	flash_file = fopen("flashx:bank1", NULL);
	if(flash_file == NULL)
	{
	#ifdef LOCAL_LOG
		SYSTEM_Log("open flash file error.\n");
	#endif
		return BLESTATUS_FAILED;
	}
	
	//<
	return BLESTATUS_SUCCESS;
}
예제 #3
0
파일: rtcscmd.c 프로젝트: gxliu/MQX_3.8.0
void RTCS_cmd_complete
   (
      TCPIP_PARM_PTR    parm_ptr,
      uint_32           error
   )
{ /* Body */

   if (error) {
      parm_ptr->ERROR = error;
   } /* Endif */

   if (parm_ptr->SYNC) {
      _task_ready(parm_ptr->SYNC);
   } /* Endif */

} /* Endbody */
예제 #4
0
uint32_t OS_Task_resume(uint32_t task_id)
{
    _task_ready(_task_get_td(task_id));
    return (uint32_t)OS_TASK_OK;
}
예제 #5
0
파일: cortex.c 프로젝트: Vinhuit/Freescale
/*!
 * \brief 	MQX API handler for usermode - part of wrapper around standard MQX API
 *  which require privilege mode.
 *
 * \param[in] api_no API number - number of wrapped function
 * \param[in] params generic parameter - direct use with called MQX API fn
 *
 * \return uint32_t return of called function
 */
uint32_t _mqx_api_call_handler
    (
        // [IN] API number - number of wrapped function
        MQX_API_NUMBER_ENUM api_no,
        // [IN] generic parameter - direct use with called MQX API fn
        MQX_API_CALL_PARAMS_PTR params
    )
{
    int32_t res = -1;
    uint32_t param0 = params->param0;
    uint32_t param1 = params->param1;
    uint32_t param2 = params->param2;
    uint32_t param3 = params->param3;
    uint32_t param4 = params->param4;

    switch (api_no) {

    // _lwsem
    case MQX_API_LWSEM_POLL:
        if (MQX_OK == (res = _lwsem_usr_check((LWSEM_STRUCT_PTR)param0)))
            res = (uint32_t)_lwsem_poll((LWSEM_STRUCT_PTR)param0);
        break;
    case MQX_API_LWSEM_POST:
        if (MQX_OK == (res = _lwsem_usr_check((LWSEM_STRUCT_PTR)param0)))
            res = _lwsem_post((LWSEM_STRUCT_PTR)param0);
        break;
    case MQX_API_LWSEM_WAIT:
        if (MQX_OK == (res = _lwsem_usr_check((LWSEM_STRUCT_PTR)param0)))
            res = _lwsem_wait((LWSEM_STRUCT_PTR)param0);
        break;
    case MQX_API_LWSEM_CREATE:
        res = _lwsem_create_internal((LWSEM_STRUCT_PTR)param0, (_mqx_int)param1, (bool)param2, TRUE);
        break;
#if MQX_HAS_TICK
    case MQX_API_LWSEM_WAIT_FOR:
        if (MQX_OK == (res = _lwsem_usr_check((LWSEM_STRUCT_PTR)param0)) && (!param1 || _psp_mem_check_access(param1, sizeof(MQX_TICK_STRUCT), MPU_UM_RW)))
            res = _lwsem_wait_for((LWSEM_STRUCT_PTR)param0, (MQX_TICK_STRUCT_PTR)param1);
        break;
    case MQX_API_LWSEM_WAIT_TICKS:
        if (MQX_OK == (res = _lwsem_usr_check((LWSEM_STRUCT_PTR)param0)))
            res = _lwsem_wait_ticks((LWSEM_STRUCT_PTR)param0, (_mqx_uint)param1);
        break;
    case MQX_API_LWSEM_WAIT_UNTIL:
        if (MQX_OK == (res = _lwsem_usr_check((LWSEM_STRUCT_PTR)param0)) && (!param1 || _psp_mem_check_access(param1, sizeof(MQX_TICK_STRUCT), MPU_UM_RW)))
            res = _lwsem_wait_until((LWSEM_STRUCT_PTR)param0, (MQX_TICK_STRUCT_PTR)param1);
        break;
    case MQX_API_LWSEM_DESTROY:
        if (MQX_OK == (res = _lwsem_usr_check((LWSEM_STRUCT_PTR)param0))) {
            res = _lwsem_destroy_internal((LWSEM_STRUCT_PTR)param0, TRUE);
        }
        break;

#endif // MQX_HAS_TICK

    // _lwevent
#if MQX_USE_LWEVENTS
    case MQX_API_LWEVENT_CLEAR:
        if (MQX_OK == (res = _lwevent_usr_check((LWEVENT_STRUCT_PTR)param0)))
            res = _lwevent_clear((LWEVENT_STRUCT_PTR)param0, (_mqx_uint)param1);
        break;
    case MQX_API_LWEVENT_SET:
        if (MQX_OK == (res = _lwevent_usr_check((LWEVENT_STRUCT_PTR)param0)))
            res = _lwevent_set((LWEVENT_STRUCT_PTR)param0, (_mqx_uint)param1);
        break;
    case MQX_API_LWEVENT_SET_AUTO_CLEAR:
        if (MQX_OK == (res = _lwevent_usr_check((LWEVENT_STRUCT_PTR)param0)))
            res = _lwevent_set_auto_clear((LWEVENT_STRUCT_PTR)param0, (_mqx_uint)param1);
        break;
    case MQX_API_LWEVENT_WAIT_FOR:
        if (MQX_OK == (res = _lwevent_usr_check((LWEVENT_STRUCT_PTR)param0)) && \
            (!param3 || _psp_mem_check_access(param3, sizeof(MQX_TICK_STRUCT), MPU_UM_RW))) {
            res = _lwevent_wait_for((LWEVENT_STRUCT_PTR)param0, (_mqx_uint)param1, (bool)param2, (MQX_TICK_STRUCT_PTR)param3);
        }
        break;
    case MQX_API_LWEVENT_WAIT_FOR_TICKS:
        if (MQX_OK == (res = _lwevent_usr_check((LWEVENT_STRUCT_PTR)param0))) {
            res = _lwevent_wait_ticks((LWEVENT_STRUCT_PTR)param0, (_mqx_uint)param1, (bool)param2, (_mqx_uint)param3);
        }
        break;
    case MQX_API_LWEVENT_WAIT_UNTIL:
        if (MQX_OK == (res = _lwevent_usr_check((LWEVENT_STRUCT_PTR)param0)) && \
            (!param3 || _psp_mem_check_access(param3, sizeof(MQX_TICK_STRUCT), MPU_UM_RW))) {
            res = _lwevent_wait_until((LWEVENT_STRUCT_PTR)param0, (_mqx_uint)param1, (bool)param2, (MQX_TICK_STRUCT_PTR)param3);
        }
        break;
    case MQX_API_LWEVENT_GET_SIGNALLED:
        res = _lwevent_get_signalled();
        break;

    case MQX_API_LWEVENT_CREATE:
        res = _lwevent_create_internal((LWEVENT_STRUCT_PTR)param0, (_mqx_uint)param1, TRUE);
        break;

    case MQX_API_LWEVENT_DESTROY:
        if (MQX_OK == (res = _lwevent_usr_check((LWEVENT_STRUCT_PTR)param0))) {
            res = _lwevent_destroy_internal((LWEVENT_STRUCT_PTR)param0, TRUE);
        }
        break;
#endif

#if MQX_USE_LWMSGQ
    case MQX_API_LWMSGQ_INIT:
        res = _lwmsgq_init_internal((void *)param0, (_mqx_uint)param1, (_mqx_uint)param2, TRUE);
        break;
    case MQX_API_LWMSGQ_RECEIVE:
        if (MQX_OK == (res = _lwmsgq_usr_check((LWMSGQ_STRUCT_PTR)param0)) && \
            _psp_mem_check_access(param1, ((LWMSGQ_STRUCT_PTR)param0)->MSG_SIZE, MPU_UM_RW) && \
            (!param4 || _psp_mem_check_access(param4, sizeof(MQX_TICK_STRUCT), MPU_UM_RW)))
            res = _lwmsgq_receive((void *)param0, (_mqx_max_type_ptr)param1, (_mqx_uint)param2, (_mqx_uint)param3, (MQX_TICK_STRUCT_PTR)param4);

        break;
    case MQX_API_LWMSGQ_SEND:
        if (MQX_OK == (res = _lwmsgq_usr_check((LWMSGQ_STRUCT_PTR)param0)) && \
            _psp_mem_check_access(param1, ((LWMSGQ_STRUCT_PTR)param0)->MSG_SIZE, MPU_UM_RW))
            res = _lwmsgq_send((void *)param0, (_mqx_max_type_ptr)param1, (_mqx_uint)param2);
        break;
#endif // MQX_USE_LWMSGQ

    case MQX_API_TASK_CREATE:
        res = _task_create_internal((_processor_number)param0, (_mqx_uint)param1, (uint32_t)param2, TRUE);
        break;
    case MQX_API_TASK_DESTROY:
        res = _task_destroy_internal((_task_id)param0, TRUE);
        break;
    case MQX_API_TASK_ABORT:
        res = _task_abort_internal((_task_id)param0, TRUE);
        break;
    case MQX_API_TASK_READY:
        _task_ready((void *)param0);
        res = MQX_OK;       // irelevant, function is without return value
        break;
    case MQX_API_TASK_SET_ERROR:
        res = _task_set_error((_mqx_uint)param0);
        break;
    case MQX_API_TASK_GET_TD:
        res = (uint32_t)_task_get_td((_task_id)param0);
        break;

#if MQX_USE_LWMEM
    case MQX_API_LWMEM_ALLOC:
        res = (uint32_t)_usr_lwmem_alloc_internal((_mem_size)param0);
        break;

    case MQX_API_LWMEM_ALLOC_FROM:
        if (_psp_mem_check_access(param0, sizeof(LWMEM_POOL_STRUCT), MPU_UM_RW) && \
            _psp_mem_check_access((uint32_t)(((LWMEM_POOL_STRUCT_PTR)param0)->POOL_ALLOC_START_PTR), (char*)(((LWMEM_POOL_STRUCT_PTR)param0)->POOL_ALLOC_END_PTR) - (char*)(((LWMEM_POOL_STRUCT_PTR)param0)->POOL_ALLOC_START_PTR), MPU_UM_RW))
            res = (uint32_t)_lwmem_alloc_from((_lwmem_pool_id)param0, (_mem_size)param1);
        else
            res = 0; // NULL, allocation failed
        break;

    case MQX_API_LWMEM_FREE:
        if (_psp_mem_check_access(param0, 4, MPU_UM_RW))
            res = _lwmem_free((void *)param0);
        break;

    case MQX_API_LWMEM_CREATE_POOL:\
        if (_psp_mem_check_access(param0, sizeof(LWMEM_POOL_STRUCT), MPU_UM_RW) && \
            _psp_mem_check_access(param1, param2, MPU_UM_RW))
            res = (uint32_t)_lwmem_create_pool((LWMEM_POOL_STRUCT_PTR)param0, (void *)param1, (_mem_size)param2);
        break;

    case MQX_API_LWMEM_REALLOC:
        if (_psp_mem_check_access(param0, 4, MPU_UM_RW))
          res = (uint32_t)_lwmem_realloc((void *)param0,(_mem_size)param1);
        break;
#endif // MQX_USE_LWMEM

    // _time
    case MQX_API_TIME_DELAY:
        _time_delay(param0);
        res = MQX_OK;       // irelevant, function is without return value
        break;

#if MQX_HAS_TICK
    case MQX_API_TIME_DELAY_TICKS:
        _time_delay_ticks(param0);
        res = MQX_OK;       // irelevant, function is without return value
        break;
    case MQX_API_TIME_GET_ELAPSED_TICKS:
        if (_psp_mem_check_access(param0, sizeof(MQX_TICK_STRUCT), MPU_UM_RW)) {
            _time_get_elapsed_ticks((MQX_TICK_STRUCT_PTR)param0);
            res = MQX_OK;       // irelevant, function is without return value
        }
        else {
            _task_set_error(MQX_ACCESS_ERROR);
        }

        break;
#endif // MQX_HAS_TICK
    default:
        while (1);
    }

    return res;
}
예제 #6
0
uint32_t TELNETCLN_connect(TELNETCLN_PARAM_STRUCT *params)
{
    TELNETCLN_ERROR   error;
    uint32_t          prio;
    TELNETCLN_CONTEXT *context;

    error = TELNETCLN_OK;
    context = telnetcln_create_context(params);
    if (context == NULL)
    {
        error = TELNETCLN_FAIL;
        goto EXIT;
    }
    /*
    ** Install device driver for socket and telnet
    */
    error = telnetcln_init_socket(context);
    if (error != TELNETCLN_OK)
    {
        error = TELNETCLN_FAIL;
        goto EXIT;
    }

    error = telnetcln_init_devices(context);
    if (error != TELNETCLN_OK)
    {
        error = TELNETCLN_FAIL;
        goto EXIT;
    }
   
    /* 
     * Create two processes:
     * 1. to read input and send read characters to socket
     * 2. to read from socket and write the received chars to output
     */
    if (MQX_OK != _task_get_priority(MQX_NULL_TASK_ID, &prio))
    {
        error = TELNETCLN_FAIL;
        goto EXIT;
    }

    if (RTCS_task_create(TELNETCLN_OUT_TASK_NAME, prio, TELNETCLN_STACK_SIZE, telnetcln_in_task, (void*)context) != RTCS_OK)
    {
        error = TELNETCLN_FAIL;
        goto EXIT;
    }
    if (RTCS_task_create(TELNETCLN_IN_TASK_NAME, prio, TELNETCLN_STACK_SIZE, telnetcln_out_task, (void*)context) != RTCS_OK)
    {
        error = TELNETCLN_FAIL;
        goto EXIT;
    }
    _task_ready(_task_get_td((_task_id) context->rx_tid));
    context->params.callbacks.on_connected(context->params.callbacks.param);
    EXIT:
    if (error != TELNETCLN_OK)
    {
        telnetcln_cleanup(context);
        _mem_free(context);
        context = NULL;
    }
    return((uint32_t) context);
}
예제 #7
0
_mqx_uint _task_abort
   (
      /* [IN] the task id of the task to abort */
      _task_id task_id
   )
{ /* Body */
   KERNEL_DATA_STRUCT_PTR    kernel_data;
   TD_STRUCT_PTR             td_ptr;
   pointer                   stack_ptr;
   _processor_number         processor;

   _GET_KERNEL_DATA(kernel_data);
   _KLOGE2(KLOG_task_abort, task_id);

   if (task_id != MQX_NULL_TASK_ID) {
      processor = PROC_NUMBER_FROM_TASKID(task_id);
      if (processor != (_processor_number)kernel_data->INIT.PROCESSOR_NUMBER ) {
#if MQX_IS_MULTI_PROCESSOR
         if ( kernel_data->IPC != NULL ) {
            _KLOGX2(KLOG_task_abort, MQX_OK);
            return( (*kernel_data->IPC)(FALSE, processor,
               KERNEL_MESSAGES, IPC_TASK_ABORT, 1, (_mqx_uint)task_id) );
         } else {
#endif
            _KLOGX2(KLOG_task_abort, MQX_INVALID_TASK_ID);
            return(MQX_INVALID_TASK_ID);
#if MQX_IS_MULTI_PROCESSOR
         } /* Endif */
#endif
      }/* Endif */
   }/* Endif */

   td_ptr = (TD_STRUCT_PTR)_task_get_td(task_id);

#if MQX_CHECK_ERRORS
   if ( (td_ptr == NULL) || (td_ptr == SYSTEM_TD_PTR(kernel_data)) ) {
      _KLOGX2(KLOG_task_abort, MQX_INVALID_TASK_ID);
      return( MQX_INVALID_TASK_ID );
   } /* Endif */
#endif

   if (td_ptr == kernel_data->ACTIVE_PTR) {
      if (kernel_data->IN_ISR) {
         stack_ptr = (pointer)td_ptr->STACK_PTR;
         _PSP_SET_PC_OF_INTERRUPTED_TASK(stack_ptr, 
            _task_exit_function_internal);
      } else {
         _task_exit_function_internal();
      }/* Endif */
   } else {

      _int_disable();
      /* Task is not running */
      stack_ptr = (pointer)td_ptr->STACK_PTR;
      _PSP_SET_PC_OF_BLOCKED_TASK(stack_ptr, 
         _task_exit_function_internal);
      /* Start CR 1222 */
      if (td_ptr->STATE & IS_ON_TIMEOUT_Q){
         /* Remove from time queue (uses NEXT, PREV field) */
         _TIME_DEQUEUE(td_ptr, kernel_data);
      /* End CR 1222 */
      } else if (td_ptr->STATE & TD_IS_ON_QUEUE) {
         _QUEUE_REMOVE(td_ptr->INFO, td_ptr);
      /* Begin CR 1223 */
      } else if((td_ptr->STATE & BLOCKED_ON_AUX_QUEUE) ==BLOCKED_ON_AUX_QUEUE){
         /* We need to remove it here because _task_ready() below will
            change its state to READY */
         _QUEUE_REMOVE(td_ptr->INFO, &td_ptr->AUX_QUEUE);
      } /* Endif */
      /* End CR 1223 */
      if (td_ptr->STATE & IS_BLOCKED) {
         _task_ready(td_ptr);
      } /* Endif */
      _int_enable();
   }/* Endif */

   _KLOGX2(KLOG_task_abort, MQX_OK);
   return(MQX_OK);
   
} /* Endbody */
예제 #8
0
_task_id _mmu_create_vtask
   (
      /* [IN] the task template number */
      _mqx_uint                template_number,

      /* [IN] the task creation parameter */
      _mqx_uint                parameter,

      /* [IN] the data address to copy initialization values from*/
      pointer                  data_init_ptr,

      /* [IN] the virtual address for the virtual memory */
      pointer                  vaddr,

      /* [IN] the size of the virtual memory */
      _mem_size                size,

      /* [IN] the MMU flags to use */
      _mqx_uint                flags
   )
{ /* Body */
   KERNEL_DATA_STRUCT_PTR kernel_data;
   TD_STRUCT_PTR          td_ptr;
   TD_STRUCT_PTR          my_td_ptr;
   uint_32                result;
   _task_id               task_id;

   _GET_KERNEL_DATA(kernel_data);
   my_td_ptr = kernel_data->ACTIVE_PTR;
   if (my_td_ptr->FLAGS & TASK_MMU_CONTEXT_EXISTS) {
      return(MQX_MMU_PARENT_TASK_CANNOT_BE_MMU);
   } /* Endif */

   task_id = _task_create_blocked(0, template_number, parameter);
   if (task_id == MQX_NULL_TASK_ID) {
      return(MQX_NULL_TASK_ID);
   } /* Endif */
   td_ptr = _task_get_td(task_id);
   result = _mmu_create_vcontext(task_id);
   if (result != MQX_OK) {
      _task_destroy(task_id);
      _task_set_error(result);
      return(MQX_NULL_TASK_ID);
   } /* Endif */
   result = _mmu_add_vcontext(task_id, vaddr, size, flags);
   if (result != MQX_OK) {
      _task_destroy(task_id);
      _task_set_error(result);
      return(MQX_NULL_TASK_ID);
   } /* Endif */

   if (data_init_ptr != NULL) {
      _int_disable();
      my_td_ptr->MMU_VIRTUAL_CONTEXT_PTR =
         td_ptr->MMU_VIRTUAL_CONTEXT_PTR;
      my_td_ptr->FLAGS |= TASK_MMU_CONTEXT_EXISTS;
      _mmu_set_vcontext_internal();
      _int_enable();
      _mem_copy(data_init_ptr, vaddr, size);
      _int_disable();
      _mmu_reset_vcontext_internal();
      my_td_ptr->FLAGS &= ~TASK_MMU_CONTEXT_EXISTS;
      my_td_ptr->MMU_VIRTUAL_CONTEXT_PTR = NULL;
      _int_enable();
   } /* Endif */

   _task_ready(td_ptr);
   return(task_id);

} /* Endbody */
예제 #9
0
void local_player_task(uint_32 para) 
{
	_mqx_int return_code, res;
	my_audio_format_t format;
	FILE_PTR stream_ptr = NULL, stream_ptr1 = NULL;      //device_ptr = NULL, 
	uint_32 mclk_freq, fs_freq, bit_width = 0;
	I2S_STATISTICS_STRUCT stats;
	int32_t numberOfSamples =0, sampleProduced, bufOut;
	file_meta_data_t * metadata = NULL;
	audio_stream_type_t stream_type;
	char_ptr mem_ptr = NULL;
	boolean shell_cmd = FALSE;
        CCI_Ctx ctx;
	int32_t strLen, i;
	uint32_t file_extension=0;
	
	_task_id pcm_flush_id = MQX_NULL_TASK_ID;
	uint_32 cnt = 0;
	int32_t max_audio_buf_size = 0;
	lp_param_t *  lpp_param =  (lp_param_t *)para;
        TASK_TEMPLATE_STRUCT task_template;

	printf("local_player_task.. Enter 1\n");
	if (msi_snd_init_with_periodbuffer(1024, 18) != 0) /* for SPI sd card play FLAC, 18K buffer is at least! */
	{
		LOCALPLAY_LOG("  Error: Unable to open the device \"%s\".\n",
				AUDIO_DIVECE_NAME_STR);
		return;
	}
	
	/* create semaphore must before pcm_flush_task */
	if(MQX_OK != _lwsem_create(&pcm_decoded_sem, 0))
	{
		LOCALPLAY_LOG("\n Error - Unable to creat lwsem: pcm_decoded_sem\n");
	}
	
	
        LOCALPLAY_LOG("Creating pcm flush task.........\n");

        task_template.TASK_TEMPLATE_INDEX  = 0;
        task_template.TASK_ADDRESS         = pcm_flush_task;
        task_template.TASK_STACKSIZE       = 2000;
        task_template.TASK_PRIORITY        = 12;
        task_template.TASK_NAME            = "pcm_flush";
        task_template.TASK_ATTRIBUTES      = 0;
        task_template.CREATION_PARAMETER   = 0;
        task_template.DEFAULT_TIME_SLICE   = 0;

        pcm_flush_id = _task_create_blocked(0, 0, (uint_32)&task_template);

        if (pcm_flush_id  == MQX_NULL_TASK_ID)
        {
            printf("local_player_task create pcm_flush_task failed \n");
            goto clean_up;
        }
        else{
            gPcmFlushTaskFinish = 0;
            _task_ready(_task_get_td(pcm_flush_id));
            _lwevent_set(&player_event, PLAYER_EVENT_MSK_SONG_RESUME);
        }


	metadata = (file_meta_data_t *) _mem_alloc_system_zero(sizeof(file_meta_data_t));
	if (NULL == metadata) 
	{
		LOCALPLAY_LOG("\n Failed to allocate memory for metadata.\n");
		return;
	}

        decoding = TRUE;
	
	while (1) {

#ifndef  USB_ACCESSORY_PLAY		
		_lwevent_wait_ticks(
				&player_event,
				PLAYER_EVENT_MSK_SONG_READY | PLAYER_EVENT_MSK_SD_FS_UNMOUNTED
						| PLAYER_EVENT_MSK_SHELL_COMMAND, FALSE, 0);
#else
_lwevent_wait_ticks(
				&player_event,
				PLAYER_EVENT_MSK_SONG_READY | PLAYER_EVENT_MSK_SD_FS_UNMOUNTED
						| PLAYER_EVENT_MSK_SHELL_COMMAND | PLAYER_EVENT_MSK_USB_ATTACHED, FALSE, 0);		
#endif
		shell_cmd = FALSE;


#ifdef USB_ACCESSORY_PLAY
		if (player_event.VALUE & PLAYER_EVENT_MSK_USB_ATTACHED) {
					_lwevent_clear(&player_event, PLAYER_EVENT_MSK_USB_ATTACHED);
					//LOCALPLAY_LOG("__guoyifang__: sd_player_task PLAYER_EVENT_MSK_USB_ACC_ATTACHED \n");
					break;
				}
#endif

		if (player_event.VALUE & PLAYER_EVENT_MSK_SD_FS_UNMOUNTED) {
			_lwevent_clear(&player_event, PLAYER_EVENT_MSK_SD_FS_UNMOUNTED);
			//LOCALPLAY_LOG("__guoyifang__: sd_player_task PLAYER_EVENT_MSK_SD_FS_UNMOUNTED \n");
			break;
		}	

		if (player_event.VALUE & PLAYER_EVENT_MSK_SONG_READY) {
			_lwevent_clear(&player_event, PLAYER_EVENT_MSK_SONG_READY);
		}

		if (player_event.VALUE & PLAYER_EVENT_MSK_SHELL_COMMAND) {
			_lwevent_clear(&player_event, PLAYER_EVENT_MSK_SHELL_COMMAND);
			shell_cmd = TRUE;
		}

		LOCALPLAY_LOG(" --------------------------------------------------------------\n");

	    printf("play lock umount at %d\n",lpp_param->lp_type);
	    _lwsem_wait(lpp_param->mfs_io_sem);
	    /******************decoding is a critical value, assume decoding is TRUE every time.*******************/    
	    printf("SET decoding.\n");
	    decoding = TRUE; // next/prev btn ISR may clear decoding to 0
	    /*******************************************/
		/*config the audio subsystem according metadata*/
		        		printf(
		        				"  Open stream file %s\n", full_path);
		        		stream_ptr = fopen(full_path, "r");
		        		if (stream_ptr == NULL) {
		        			printf("  Unable to open the file: %s\n", full_path);
		        			goto clean_up;
		        		}

		        		stream_ptr1 = fopen(full_path, "r");
		        		if (stream_ptr1 == NULL) {
		        			printf("  Unable to open the file: %s\n", full_path);
		        			goto clean_up;
		        		}
		        		
		                /* Determine the extension of the file */ 
		                i=0;
		                strLen= strlen((const char *)full_path);

		                if(strLen > 4){
		                    /* find the '.' */
		                    while(strLen--){
		                        if(full_path[i]=='.')
		                            break;
		                        i++;
		                    }
		                    if(strLen){
		                        char *p;
		                        /* Copy out the extension : 8.3 filename */
		                        memcpy(&file_extension, full_path+i+1, 3);
		                        p = (char *) (&file_extension);
		                        for(i = 0; i < 4; i++, p++){
		                            if((*p >= 'a') && (*p <= 'z')){
		                                *p -= ('a' - 'A');
		                            }
		                        }
		                    } 

		                    ctx.user_data = (void*) stream_ptr;
		                    ctx.cci_dec_read = get_file_data;;
		                    ctx.cci_dec_seek = seek_file_data;
		                    ctx.cci_dec_tell = get_file_position;

		                    /* Check if metadata was found. */
		                    return_code = cci_extract_meta_data(file_extension, metadata, &ctx);        
		        		    if (return_code != 0) {
		        			    printf("\n Metadata not found\n");
		        			    goto clean_up;
		        		    }

		        		    print_metadata(metadata); //todo

		                } else {
		        			printf("\n Metadata not found\n");
		        			goto clean_up;
		                }
		                if ( metadata->stream_type == STREAM_TYPE_MP3 ) {
		                	/* Seek from the beginning of the file */ 
		                    seek_file_data(0, metadata->start_pos, 0, stream_ptr);
		                } else {
		                	/* Seek from the beginning of the file */
		                	seek_file_data(0, 0, 0, stream_ptr);
		        		}
		        
		        
		        stream_type = metadata->stream_type;

#if 0	
		format.audio_format.ENDIAN = AUDIO_LITTLE_ENDIAN;
		format.audio_format.ALIGNMENT = AUDIO_ALIGNMENT_LEFT;
		if((streamType == kCodecStreamTypePcm) ||	// bitsPerSample Value is 8/16/24
				/*
				 * The demo not support kCodecStreamTypeImaAdpcm/kCodecStreamTypeMsAdpcm currently.
				 */
				(streamType == kCodecStreamTypeImaAdpcm) || // bitsPerSample Value is 4
				(streamType == kCodecStreamTypeMsAdpcm))	// bitsPerSample Value is 4
		{	
			format.audio_format.BITS = metadata->i32BitsPerSample;
		}else{
			format.audio_format.BITS = 16; 
		}
		
		// Currently, the wave decoder output 16bits only for kCodecStreamTypePcm.
		format.audio_format.BITS = 16;
		
		format.audio_format.SIZE = (format.audio_format.BITS + 7)/8;

		
		format.audio_format.CHANNELS = metadata->i32NumChannels;
		format.fs_freq = metadata->u32SampleRate;

		fs_freq = format.fs_freq;
		mclk_freq = fs_freq * CLK_MULT;
		// Setup audio data format in device 
		if (ioctl(device_ptr, IO_IOCTL_AUDIO_SET_IO_DATA_FORMAT,
				&format.audio_format) != I2S_OK) {
			LOCALPLAY_LOG("  Error: Input data format not supported.\n");
			goto clean_up;
		}
		// Setup rest of parameters - master clock, valid data bits and sampling frequency 
		if ((ioctl(device_ptr, IO_IOCTL_I2S_SET_MCLK_FREQ, &mclk_freq) != I2S_OK)
				|| (ioctl(device_ptr, IO_IOCTL_I2S_SET_DATA_BITS,
						&format.audio_format.BITS) != I2S_OK)
				|| (ioctl(device_ptr, IO_IOCTL_I2S_SET_FS_FREQ, &fs_freq)
						!= I2S_OK)) {
			LOCALPLAY_LOG("  Error: Unable to setup \"%s\" device driver.\n",
					AUDIO_DIVECE_NAME_STR);
			goto clean_up;
		}

		// Setup audio codec 
		return_code = SetupCodec(device_ptr);
		if (return_code != 0) {
			LOCALPLAY_LOG("  Audio codec configuration failed. Error 0x%X.\n",
					return_code);
			goto clean_up;
		}

		ioctl(device_ptr, IO_IOCTL_I2S_GET_FS_FREQ, &fs_freq);
		ioctl(device_ptr, IO_IOCTL_I2S_GET_DATA_BITS, &bit_width);
		LOCALPLAY_LOG("  Playback information\n");
		LOCALPLAY_LOG("  Sampling frequency:     %d Hz\n", fs_freq);
		LOCALPLAY_LOG("  Bit depth:              %d bits\n", (uint_8)bit_width);
		LOCALPLAY_LOG("  Channels:               ");
		
		if (format.audio_format.CHANNELS == 1) {
			LOCALPLAY_LOG("mono\n");
		} else {
			LOCALPLAY_LOG("stereo\n");
		}
#else
		if((stream_type == STREAM_TYPE_PCM) ||	// bitsPerSample Value is 8/16/24
		/*
		 * The demo not support kCodecStreamTypeImaAdpcm/kCodecStreamTypeMsAdpcm currently.
		 */
		(stream_type == STREAM_TYPE_IMAADPCM) || // bitsPerSample Value is 4
		(stream_type == STREAM_TYPE_MSADPCM))	// bitsPerSample Value is 4
		{	
			format.audio_format.BITS = metadata->bits_per_sample;
		}else{
			format.audio_format.BITS = 16; 
		}
		
		format.audio_format.CHANNELS = metadata->num_channels;
		// Currently, the wave decoder output 16bits only for kCodecStreamTypePcm.
		format.audio_format.BITS = 16;
#if 0
		if(audio_ioctl(setChNum, format.audio_format.CHANNELS)!= I2S_OK)
        {
		  LOCALPLAY_LOG("  Error: audio_ioctl setChNum failed.\n");
		  goto clean_up;
        }
		if(audio_ioctl(setBitWidth, format.audio_format.BITS)!= I2S_OK)
		{

		  LOCALPLAY_LOG("  Error: audio_ioctl setBitWidth failed.\n");
		  goto clean_up;
		}
#endif
		
		format.fs_freq = metadata->sample_rate;
		
#if 0
		if(audio_ioctl(setSamplerate, format.fs_freq)!= I2S_OK)
	    {
		  LOCALPLAY_LOG("  Error: audio_ioctl setSamplerate failed.\n");
		  goto clean_up;
	    }
#endif
		msi_snd_set_format(format.fs_freq, format.audio_format.BITS, format.audio_format.CHANNELS);
	

#endif

		mem_ptr = (char_ptr) _mem_alloc_system_zero(codec_get_mem_info(stream_type));
		if (NULL == mem_ptr) {
			LOCALPLAY_LOG("Failed to allocate memory for the decoder.\n");
			goto clean_up;
		}

		// MP4 decoder need two fd
		g_userData[0] = (int) stream_ptr;
		g_userData[1] = (int) stream_ptr1;
		if (metadata->audio_sub_type == MEDIA_SUBTYPE_ADTS)
			g_userData[2] = 1;
		else if (metadata->audio_sub_type == MEDIA_SUBTYPE_M4A)
			g_userData[2] = 2;
		else if ( metadata->stream_type == STREAM_TYPE_OPUS )
		{
			g_userData[2] = metadata->sample_rate;
			g_userData[3] = metadata->num_channels;
	    }
		else
			g_userData[2] = 0; 

		g_callbackFunctionArray[0] = (int32_t *) &get_file_data;
		g_callbackFunctionArray[1] = (int32_t *) &seek_file_data;
		g_callbackFunctionArray[2] = (int32_t *) &get_file_position;

		while (1) {
			res = codec_init(stream_type, (long **)&mem_ptr,g_callbackFunctionArray,
								&g_userData[0]);
			if (res == CODEC_INIT_ERROR) {
				LOCALPLAY_LOG("\n  Codec Init Failed with error code %d\n", res);
				decoding = FALSE; 
				goto clean_up;
			}
			if (res == CODEC_MORE_DATA_REQUIRED) {
				LOCALPLAY_LOG("\n  More Data Processing Required for Init \n");
			}
			if (res == CODEC_SUCCESS) {
				LOCALPLAY_LOG("\n  Codec Init Done Successfully \n\n");
				break;
			}
			else {
				printf("codec init other err\n");
				decoding = FALSE;
				goto clean_up;
			}
		}

		if (res == CODEC_SUCCESS) {
			LOCALPLAY_LOG("  Playing %s...\n\n", full_path);
		//	ioctl(device_ptr, IO_IOCTL_I2S_CLEAR_STATISTICS, NULL);
			/* Reset variables before every song's playbacking */
			
			//printf("SET decoding.\n");
			//decoding = TRUE; // next/prev btn ISR may clear decoding to 0
			cnt = 0;

			max_audio_buf_size = 0;
			g_audio_buf_ptr = NULL;
			//_lwevent_clear(&player_event, PLAYER_EVENT_MSK_AUDIO_BUF_FILLED);
			/* Clear pcm_decoded_sem for play next song */
			_lwsem_poll(&pcm_decoded_sem);
			_lwsem_poll(&pcm_decoded_sem);  
					
			if(MQX_OK != _lwsem_create(&pcm_flush_sem, AUDIO_BUF_CNT))
			{
				LOCALPLAY_LOG("\n Error - Unable to create lwsem: pcm_flush_sem\n");
			}
			
			/*
			 * umute
			 */
			msi_snd_umute();
			//sai_dma_output_init();
			
			while (decoding) {
				/*
				 * For FLAC decoder, it produced more than 18K bytes per frame, and takes about 30ms. 
				 * While take 44.1K/16bit/2ch/4Kbytes DMA buffer as example, the margin time is 4K/4/2/44100~=10ms. 
				 * We need bigger DMA buffer, or decode in a ping-pong way.
				 */		
				res = codec_decode(stream_type, (long **)&mem_ptr, &sampleProduced,
										&bufOut);
              
				if (res == CODEC_END_OF_DECODE) {					
					printf("\n  End of Decode \n");
					break;
				}
				else if (res == CODEC_DECODE_ERROR) {
					printf("\n  Codec Decode Failed \n");
					break;
				}
				else if(res != CODEC_SUCCESS){
					printf("codec_decode else err %d\n",res);
						break;
				}
				
				cnt += sampleProduced;
				
				while (decoding) 
				 {
					numberOfSamples = codec_get_pcm_samples(stream_type,
											(long **)&mem_ptr, &sampleProduced, &bufOut);
					if (numberOfSamples == 0)
						break;
					
#if 1
					if (max_audio_buf_size < sampleProduced) { //More bigger buffer needed
						max_audio_buf_size = sampleProduced;
						if (NULL != g_audio_buf_ptr) {
							LOCALPLAY_LOG(" Bigger buffer needed.\n");
							_mem_free(g_audio_buf_ptr);
						}
						g_audio_buf_ptr = (uchar_ptr) _mem_alloc_system_zero(max_audio_buf_size);
						if (NULL == g_audio_buf_ptr) {
							LOCALPLAY_LOG(" Failed to allocate g_audio_buf_ptr. max_audio_buf_size %d \n", max_audio_buf_size);
							decoding = 0;
							break;
						}	
#if 1
						//sai_dma_buffer_adjust(sampleProduced);			
#endif
					}
#endif
					
				    if (MQX_OK != _lwsem_wait(&pcm_flush_sem))
				    {
					  LOCALPLAY_LOG("\n Error: Wait for pcm_flush_sem failed.\n");
					 // _task_set_error(res);
				    }
				    
					_mem_copy((void *)bufOut, g_audio_buf_ptr, sampleProduced);
                                        //g_audio_buf_ptr = bufOut;
					g_buf_bytes_to_flush = sampleProduced;
		
					if (_lwsem_post(&pcm_decoded_sem) != MQX_OK)
					 {
					   LOCALPLAY_LOG("\n  pcm_flush : Error - Unable to set pcm_decoded_sem.");
					 }

					if (numberOfSamples == sampleProduced)
						sampleProduced = 0;
				 }//end while decoding
	 	  }//end while decoding
		}//end if res==kCodeSuccess
		
		#if 0
		fflush(device_ptr);
		#else
		msi_snd_mute();

                if (MQX_OK != _lwsem_wait(&pcm_flush_sem))
                    LOCALPLAY_LOG("\n Error: Wait for latest pcm_flush_sem failed.\n");
		msi_snd_flush();
		#endif
		
#if 1
		//sai_dma_output_stop();
#endif	
#if 0
		/* Print transfer statistics */
		if (ioctl(device_ptr, IO_IOCTL_I2S_GET_STATISTICS, &stats) != I2S_OK) {
			LOCALPLAY_LOG("  Error: Cannot read I2S statistics.\n");
		} else {
			LOCALPLAY_LOG("\n  Playback stats\n");
			LOCALPLAY_LOG("  Total interrupts:              %d\n", stats.INTERRUPTS);
			LOCALPLAY_LOG("  Bytes requested for transmit:  %d\n",
					stats.PACKETS_REQUESTED * format.audio_format.SIZE);
			LOCALPLAY_LOG("  Bytes transmitted:             %d\n",
					stats.TX_PACKETS * format.audio_format.SIZE);
			LOCALPLAY_LOG("  Underruns of hardware FIFO:    %d\n", stats.FIFO_ERROR);
			LOCALPLAY_LOG("  Software buffer empty:         %d\n", stats.BUFFER_ERROR);
		}
#endif
	        LOCALPLAY_LOG("\n  DONE\n");
			
		clean_up:
		printf("done to clean up,decoding %d \n",decoding);		
		/* Clean up for next song */
		if (NULL != mem_ptr) {
			_mem_free(mem_ptr);
			mem_ptr = NULL;
		}
		if (NULL != g_audio_buf_ptr) {
			_mem_free(g_audio_buf_ptr);
			g_audio_buf_ptr = NULL;
		}
		if (NULL != stream_ptr) {
			res = fclose(stream_ptr);
			if ((res != MQX_OK)&&(res != MFS_DISK_IS_WRITE_PROTECTED)) {
				/*LOCALPLAY_LOG*/printf("  Error: Unable to close file 0x%x.\n", res);
			}
			stream_ptr = NULL;
		}
		if (NULL != stream_ptr1) {
			res = fclose(stream_ptr1);
			if ((res != MQX_OK)&&(res != MFS_DISK_IS_WRITE_PROTECTED)) {
				/*LOCALPLAY_LOG*/printf("  Error: Unable to close file 0x%x.\n", res);
			}
			stream_ptr1 = NULL;
		}
		
		if(MQX_OK != _lwsem_destroy(&pcm_flush_sem))
		  {
			LOCALPLAY_LOG("\n Error - Unable to destroy lwsem: pcm_flush_sem\n");
		  }

		if (decoding == TRUE) { // playback finished in normal way, ie, next/prev not pressed
			if (!shell_cmd) { 	// and was not triggered by Shell
				// just like next btn being pressed
				_lwevent_set(&player_event, PLAYER_EVENT_MSK_NEXT_BTN_PRESSED);
			}
		}
		
	    /* if exit this task ,must route this point ! */
	    printf("play unlock umount at %d\n",lpp_param->lp_type);
	    _lwsem_post(lpp_param->mfs_io_sem);
	}//end while(1)
#if 0
	// clean up further
	if (NULL != device_ptr) {	
		if (fclose(device_ptr) != MQX_OK) {
			LOCALPLAY_LOG("  Error: Unable to close \"%s\" device driver.\n",
					full_path);
		}
	}
#else	
	msi_snd_deinit();
#endif
			
	if (NULL != metadata)
		_mem_free(metadata);	

	if (MQX_NULL_TASK_ID != pcm_flush_id)
	  {
            gPcmFlushTaskFinish = 1;
	    _lwsem_post(&pcm_decoded_sem);
            while(gPcmFlushTaskFinish == 1){
                _sched_yield();
            }

            //_task_destroy(pcm_flush_id);
	    pcm_flush_id = MQX_NULL_TASK_ID;
	    ///*LOCALPLAY_LOG*/printf(" pcm flush task destoryed \n");
	  }
	
	if(MQX_OK != _lwsem_destroy(&pcm_decoded_sem))
		  {
			LOCALPLAY_LOG("\n Error - Unable to destroy lwsem: pcm_decoded_sem\n");
		  }
	
  //printf("__guoyifang__: sd_player_task %d set PLAYER_TASK_KILLED.\n",lpp_param->lp_type);
  _lwevent_set(&player_event, PLAYER_EVENT_MSK_PLAYER_TASK_KILLED);
  
  printf("sd_player_task  exit.\n");
  //_task_block(); //wait for being destroyed
  
}