/***********************************************************
 * Name: os_cond_signal
 *
 * Arguments:  OS_COND_T *cond
 *
 * Description: Routine to signal at least one thread
 *              waiting on a condition variable. The
 *              caller must say whether they have obtained
 *              the semaphore.
 *
 * Returns: int32_t - success == 0
 *
 ***********************************************************/
int32_t os_cond_signal( OS_COND_T *cond, bool_t sem_claimed )
{
   int32_t success = -1;
   
   if (cond)
   {
      COND_WAITER_T *w;
      
      // Ensure the condvar's semaphore is claimed for thread-safe access
      if (!sem_claimed)
      {
         success = os_semaphore_obtain((*cond)->semaphore);
         os_assert(success == 0);
      }
      w = (*cond)->waiters;
      if (w)
      {
         // Wake the first person waiting
         vcos_event_signal(&w->latch);
         (*cond)->waiters = w->next;
         
      }
      success = 0;
      if (!sem_claimed)
      {
         success = os_semaphore_release((*cond)->semaphore);
      }
      os_assert(success == 0);
   }

   return success;
}
int32_t ipc_vchi_msg_dequeue( /*VCHI_SERVICE_HANDLE_T*/int32_t handle,
                          void *data,
                          uint32_t max_data_size_to_read,
                          uint32_t *actual_msg_size,
                          VCHI_FLAGS_T flags )
{
	// vchi_msg_dequeue(handle,data,max_data_size_to_read,actual_msg_size,flags);
	uint32_t events;
	uint32_t read_size;
	int32_t success=0;

	os_assert(max_data_size_to_read<IPC_SHARED_MEM_SIZE);

	ipc_aquire(IPC_SEM_ACCESS);
	ipc->buffer[0] = set_vchi_handle(handle);
	ipc->buffer[1] = max_data_size_to_read;
	ipc->buffer[2] = flags;
	ipc->buffer[3] = 0xbabeface;
	ipc_signal(IPC_VCHI_MSG_DEQUEUE_EVENT);
	ipc_wait(&events);
	os_assert(events == (1<<IPC_VCHI_MSG_DEQUEUE_EVENT));

	read_size = ipc->buffer[1];
	os_assert(read_size <= max_data_size_to_read);

	memcpy(data,&ipc->buffer[4],read_size);
	*actual_msg_size = read_size;
	ipc_release(IPC_SEM_ACCESS);

	return success;
}
int32_t ipc_vchi_bulk_queue_receive(/*VCHI_SERVICE_HANDLE_T*/int32_t handle,
                                 void * data_dst,
                                 uint32_t data_size,
                                 VCHI_FLAGS_T flags,
                                 void * bulk_handle )
{
	// vchi_bulk_queue_receive(handle,data_dst,data_size,flags,bulk_handle);
	int32_t events;
	int32_t success=0;

	os_assert(data_size<IPC_SHARED_MEM_SIZE);

	ipc_aquire(IPC_SEM_ACCESS);
	ipc->buffer[0] = set_vchi_handle(handle);
	ipc->buffer[1] = data_size;
	ipc->buffer[2] = flags;
	ipc->buffer[3] = 0xbabeface;
	ipc_signal(IPC_VCHI_BULK_RECEIVE_EVENT);
	ipc_wait(&events);
	os_assert(events == (1<<IPC_VCHI_BULK_RECEIVE_EVENT));

	memcpy(data_dst,&ipc->buffer[4],data_size);
	ipc_release(IPC_SEM_ACCESS);

	return success;
}
/***********************************************************
 * Name: vchi_bulk_aux_service_init
 *
 * Arguments:  VCHI_CONNECTION_T *connections,
 *             const uint32_t num_connections
 *
 * Description: Routine to init the bulk auxiliary service
 *
 * Returns: int32_t - success == 0
 *
 ***********************************************************/
int32_t vchi_bulk_aux_service_init( VCHI_CONNECTION_T **connections,
                                    const uint32_t num_connections,
                                    void **state )
{
   int32_t success = 0;
   uint32_t count = 0;
   BULK_AUX_SERVICE_INFO_T *bulk_aux_info = (BULK_AUX_SERVICE_INFO_T *)*state;

   os_assert(num_connections <= VCHI_MAX_NUM_CONNECTIONS);

   if (!bulk_aux_info)
   {
      bulk_aux_info = (BULK_AUX_SERVICE_INFO_T *)os_malloc( VCHI_MAX_NUM_CONNECTIONS * sizeof(BULK_AUX_SERVICE_INFO_T), 0, "vchi:bulk_aux_info" );
      memset( bulk_aux_info, 0,VCHI_MAX_NUM_CONNECTIONS * sizeof(BULK_AUX_SERVICE_INFO_T) );

      for( count = 0; count < num_connections; count++ )
      {
         // record the connection info
         bulk_aux_info[count].connection = connections[count];

         // create the server (this is a misnomer as the the BULX service acts as both client and server
         success += (connections[count])->api->service_connect((connections[count])->state,MAKE_FOURCC("BULX"),0,0,VC_TRUE,bulk_aux_callback,&bulk_aux_info[count],VC_FALSE,VC_FALSE,VC_FALSE,&bulk_aux_info[count].open_handle);
         os_assert(success == 0);
      }
   }
   else
   {
      for( count = 0; count < num_connections; count++ )
      {
         os_assert( bulk_aux_info[count].connection == connections[count]);
      }
   }
   *state = bulk_aux_info;
   return success;
}
/* ----------------------------------------------------------------------
 * read data from the given non-wrap fifo, by copying out of the
 * fifo to the given address
 *
 * returns 0 on success, non-0 otherwise
 * -------------------------------------------------------------------- */
int32_t
non_wrap_fifo_read( VCHI_NWFIFO_T *_fifo, void *data, const uint32_t max_data_size )
{
   NON_WRAP_FIFO_HANDLE_T *fifo = (NON_WRAP_FIFO_HANDLE_T *)_fifo;
   int32_t  success = -1;
   uint8_t *address = NULL;
   uint32_t length;

   os_assert(0); // FIXME: will deadlock
   os_semaphore_obtain( &fifo->sem );
   os_assert( fifo->base_address );
   // request the address and length for this transfer
   if ( non_wrap_fifo_request_read_address(fifo,&address,&length) == 0 ) {
      if ( length <= max_data_size ){
         // there is enough space and the data has been written so we can copy it out
         memcpy(data,address,length);
         // now tidy up our information about what is in the FIFO
         if ( non_wrap_fifo_read_complete(fifo,address) == 0 ) {
            // success!
            success = 0;
         }
      }
   }
   os_semaphore_release( &fifo->sem );
   return success;
}
Exemple #6
0
/***********************************************************
 * Name: software_fifo_create
 *
 * Arguments: const uint32_t size            - size of FIFO (in bytes)
 *            int alignment                  - required alignment (bytes)
 *            SOFTWARE_FIFO_HANDLE_T *handle - handle to this FIFO
 *
 * Description: Allocates space for a FIFO and initialises it
 *
 * Returns: 0 if successful, any other value is failure
 *
 ***********************************************************/
int32_t software_fifo_create( const uint32_t size, int alignment, SOFTWARE_FIFO_HANDLE_T *handle )
{
int32_t success = -1;

   // check that the alignment is a power of 2 or 0
   os_assert((OS_COUNT(alignment) == 1) || (alignment == 0));

   // put the alignment into a form we can use (must be power of 2)
   alignment = alignment ? alignment-1 : 0;

   // check we have a valid pointer
   if(handle)
   {
      memset(handle,0,sizeof(SOFTWARE_FIFO_HANDLE_T));
      // allocate slightly more space than we need so that we can get the required alignment
      handle->malloc_address = (uint8_t *)os_malloc(size+alignment, OS_ALIGN_DEFAULT, "");
      if(handle->malloc_address)
      {
         handle->base_address = (uint8_t *)(((uint32_t)handle->malloc_address + alignment) & ~alignment);
         handle->read_ptr = handle->base_address;
         handle->write_ptr = handle->base_address;
         handle->size = size;
         handle->bytes_read = 0;
         handle->bytes_written = 0;
         success = os_semaphore_create(&handle->software_fifo_semaphore,OS_SEMAPHORE_TYPE_SUSPEND);
         // oops, unable to create the semaphore
         os_assert(success == 0);
      }
   }

   // oops, looks like you've run out of memory
   os_assert(success == 0);
   return(success);
}
/***********************************************************
 * Name: os_cond_broadcast
 *
 * Arguments:  OS_COND_T *cond
 *             bool_t sem_claimed
 *
 * Description: Routine to signal all threads waiting on
 *              a condition variable. The caller must
 *              say whether they have obtained the semaphore.
 *
 * Returns: int32_t - success == 0
 *
 ***********************************************************/
int32_t os_cond_broadcast( OS_COND_T *cond, bool_t sem_claimed )
{
   int32_t success = -1;
   
   if (cond)
   {
      COND_WAITER_T *w;
      
      // Ensure the condvar's semaphore is claimed for thread-safe access
      if (!sem_claimed)
      {
         success = os_semaphore_obtain((*cond)->semaphore);
         os_assert(success == 0);
      }
      for (w = (*cond)->waiters; w; w = w->next)
      {
         vcos_event_signal(&w->latch);
      }
      (*cond)->waiters = NULL;
      
      success = 0;
      if (!sem_claimed)
      {
         success = os_semaphore_release((*cond)->semaphore);
      }
      os_assert(success == 0);
   }
   
   return success;
}
/***********************************************************
 * Name: os_cond_wait
 *
 * Arguments:  OS_COND_T *cond,
 *             OS_SEMAPHORE_T *semaphore
 *
 * Description: Routine to wait for a condition variable
 *              to be signalled. Semaphore is released
 *              while waiting. The same semaphore must
 *              always be used.
 *
 * Returns: int32_t - success == 0
 *
 ***********************************************************/
int32_t os_cond_wait( OS_COND_T *cond, OS_SEMAPHORE_T *semaphore )
{
   int32_t success = -1;
    
   if (cond && semaphore)
   {
      COND_WAITER_T w;
      COND_WAITER_T *p, **prev;
       
      // Check the API is being followed
      os_assert((*cond)->semaphore == semaphore && os_semaphore_obtained(semaphore));
      
      // Fill in a new waiter structure allocated on our stack
      w.next = NULL;
      vcos_demand(vcos_event_create(&w.latch, NULL) == VCOS_SUCCESS);
      
      // Add it to the end of the condvar's wait queue (we wake first come, first served)
      prev = &(*cond)->waiters;
      p = (*cond)->waiters;
      while (p)
         prev = &p->next, p = p->next;
      *prev = &w;

      // Ready to go to sleep now
      success = os_semaphore_release(semaphore);
      os_assert(success == 0);

      vcos_event_wait(&w.latch);

      success = os_semaphore_obtain(semaphore);
      os_assert(success == 0);
   }
   
   return success;
}
Exemple #9
0
void os_task_wait_time_set( uint8_t tid, uint8_t id, uint16_t time ) {
    os_assert( tid < nTasks );
    os_assert( time > 0 );
    
    task_list[ tid ].clockId = id;
    task_list[ tid ].time = time;
    task_waiting_time_set( tid );
}
Exemple #10
0
/***********************************************************
 * Name: software_fifo_data_available
 *
 * Arguments: SOFTWARE_FIFO_HANDLE_T handle - handle to this FIFO
 *
 * Description: Returns the amount of data available to be read
 *
 * Returns: negative values are errors
 *
 ***********************************************************/
int32_t software_fifo_data_available( SOFTWARE_FIFO_HANDLE_T *handle )
{
int32_t data_available = (int32_t)(handle->bytes_written - handle->bytes_read);

   os_assert(handle->base_address);
   os_assert(data_available <= handle->size);

   return( data_available );
}
Exemple #11
0
/***********************************************************
 * Name: software_fifo_room_available
 *
 * Arguments: SOFTWARE_FIFO_HANDLE_T handle - handle to this FIFO
 *
 * Description: Returns the amount of space left in the FIFO
 *
 * Returns: negative values are errors
 *
 ***********************************************************/
int32_t software_fifo_room_available( SOFTWARE_FIFO_HANDLE_T *handle )
{
int32_t room_available = (int32_t)handle->size - (int32_t)((handle->bytes_written - handle->bytes_read));

   os_assert(handle->base_address);
   os_assert((room_available <= handle->size) && (room_available >= 0));

   return( room_available );
}
int32_t ipc_wait(int32_t *events)
{
	int32_t status;
    int32_t success=0;
	
	os_assert(myIPC);

	status = os_eventgroup_retrieve( &myIPC->s2c_event,events);
	os_assert( status == 0 );

    return success;
}
int32_t ipc_signal(int32_t event_mask)
{
	int32_t status;
    int32_t success=0;
	
	os_assert(myIPC);
	//myIPC->buffer[3] = IPC_CLIENT_SIG;

	status = os_eventgroup_signal( &myIPC->c2s_event,event_mask);
	os_assert( status == 0 );
	
	return success;
}
Exemple #14
0
/***********************************************************
 * Name: os_init
 *
 * Arguments: void
 *
 * Description: Routine to init the local OS stack - called from vchi_init
 *
 * Returns: int32_t - success == 0
 *
 ***********************************************************/
int32_t os_init( void )
{
   int success;

   vcos_init();
   os_cond_init();


   os_assert(!vcos_os_inited++);   /* should only be called once now */
   success = os_semaphore_create(&os_mutex_global, OS_SEMAPHORE_TYPE_SUSPEND);
   os_assert(success == 0);

   return success;
}
size_t vchi_bulk_aux_service_form_header( void *dest,
                                          size_t dest_len,
                                          fourcc_t service_id,
                                          MESSAGE_TX_CHANNEL_T channel,
                                          uint32_t total_size,
                                          uint32_t chunk_size,
                                          uint32_t crc,
                                          uint32_t data_size,
                                          int16_t data_shift,
                                          uint16_t head_bytes,
                                          uint16_t tail_bytes )
{
   uint8_t *message = (uint8_t *)dest;
   if ( dest_len < BULX_HEADER_SIZE )
   {
      os_assert( 0 );
      return 0;
   }

   vchi_writebuf_fourcc( &message[BULX_SERVICE_OFFSET],    service_id );
   vchi_writebuf_uint32( &message[BULX_SIZE_OFFSET],       total_size );
   vchi_writebuf_uint32( &message[BULX_CHUNKSIZE_OFFSET],  chunk_size );
   vchi_writebuf_uint32( &message[BULX_CRC_OFFSET],        crc        );
   vchi_writebuf_uint32( &message[BULX_DATA_SIZE_OFFSET],  data_size  );
   vchi_writebuf_uint16( &message[BULX_DATA_SHIFT_OFFSET], data_shift ); // actually int16
   message[BULX_CHANNEL_OFFSET] = channel;
   message[BULX_RESERVED_OFFSET] = 0;
   vchi_writebuf_uint16( &message[BULX_HEAD_SIZE_OFFSET],  head_bytes );
   vchi_writebuf_uint16( &message[BULX_TAIL_SIZE_OFFSET],  tail_bytes );

   return BULX_HEADER_SIZE;
}
int32_t ipc_vchi_msg_hold( /*VCHI_SERVICE_HANDLE_T*/int32_t handle,
                       void **data,
                       uint32_t *msg_size,
                       VCHI_FLAGS_T flags,
                       VCHI_HELD_MSG_T *message_handle )
{
	//vchi_msg_hold(handle,data,msg_size,flags,message_handle);
	int32_t events;
    int32_t success=0;

	//myIPC->buffer[1] = 0; 
	myIPC->buffer[2] = flags;
	myIPC->buffer[3] = handle;

	ipc_signal(IPC_VCHI_MSG_HOLD_EVENT);

	ipc_wait(&events);
	os_assert(events == (1<<IPC_VCHI_MSG_HOLD_EVENT));

    *msg_size = myIPC->buffer[0];
	//message_handle = (VCHI_HELD_MSG_T*)myIPC->buffer[2];
	*data     = (void*)myIPC->buffer[4];

	return success;
}
/* ----------------------------------------------------------------------
 * remove the slot with the given address from the given non-wrap fifo.
 * intended for out-of-order operations
 *
 * the given address must belong to a slot between the read and write
 * slots, and be in the 'ready' state
 *
 * returns 0 on success, non-0 otherwise
 * -------------------------------------------------------------------- */
int32_t
non_wrap_fifo_remove( VCHI_NWFIFO_T *_fifo, void *address )
{
   NON_WRAP_FIFO_HANDLE_T *fifo = (NON_WRAP_FIFO_HANDLE_T *)_fifo;
   int32_t success = -1;
   uint32_t slot;

   os_semaphore_obtain( &fifo->sem );

   slot = fifo->read_slot;
   os_assert( fifo->base_address );

   while( slot != fifo->write_slot ) {

      if ( fifo->slot_info[slot].address == address && fifo->slot_info[slot].state == NON_WRAP_READY ) {
         // mark this as no longer being in use
         fifo->slot_info[slot].state = NON_WRAP_NOT_IN_USE;
         success = 0;
         break;
      }
      // increment and wrap our slot number
      slot = next_slot( fifo, slot );
   }

   // if the entry to be removed was the current read slot then we need to move on
   if ( slot == fifo->read_slot && success == 0 )
      fifo->read_slot = next_read_slot( fifo, slot );

   os_semaphore_release( &fifo->sem );
   return success;
}
/* ----------------------------------------------------------------------
 * fetch the address and length of the oldest message in the given
 * non-wrap fifo
 *
 * NOTE: on success, this routine will leave the fifo locked!
 *
 * returns 0 on success, non-0 otherwise
 * -------------------------------------------------------------------- */
int32_t
non_wrap_fifo_request_read_address( VCHI_NWFIFO_T *_fifo, const void **address, uint32_t *length )
{
   NON_WRAP_FIFO_HANDLE_T *fifo = (NON_WRAP_FIFO_HANDLE_T *)_fifo;
   int32_t success = -1;

   os_semaphore_obtain( &fifo->sem );
   os_assert( fifo->base_address );

   // check that this slot is ready to be read from
   if ( fifo->slot_info[fifo->read_slot].state == NON_WRAP_READY ) {

      *address = fifo->slot_info[fifo->read_slot].address;
      *length  = fifo->slot_info[fifo->read_slot].length;

      // mark this slot as being in the process of being read
      fifo->slot_info[fifo->read_slot].state = NON_WRAP_READING;

      // success!
      success = 0;
   }

   // on success, the fifo is left locked
   if ( success != 0 )
      os_semaphore_release( &fifo->sem );
   return success;
}
/***********************************************************
 * Name: bulk_aux_callback
 *
 * Arguments: void *callback_param
 *            const VCHI_CALLBACK_REASON_T reason
 *            void *handle
 *
 * Description: Handles callbacks for received messages
 *
 * Returns: -
 *
 ***********************************************************/
static void bulk_aux_callback( void *callback_param, //my service local param
                               const VCHI_CALLBACK_REASON_T reason,
                               void *handle )
{
BULK_AUX_SERVICE_INFO_T * service_info = (BULK_AUX_SERVICE_INFO_T *)callback_param;

   switch(reason)
   {
      case VCHI_CALLBACK_MSG_AVAILABLE:
#if defined VCHI_COARSE_LOCKING
         os_semaphore_obtain(&service_info->connection->sem);
#endif
         service_info->connection->api->bulk_aux_received(service_info->connection->state);
#if defined VCHI_COARSE_LOCKING
         os_semaphore_release(&service_info->connection->sem);
#endif
         break;
      case VCHI_CALLBACK_MSG_SENT:
#if defined VCHI_COARSE_LOCKING
         os_semaphore_obtain(&service_info->connection->sem);
#endif
         service_info->connection->api->bulk_aux_transmitted(service_info->connection->state, handle);
#if defined VCHI_COARSE_LOCKING
         os_semaphore_release(&service_info->connection->sem);
#endif
         break;
      case VCHI_CALLBACK_BULK_RECEIVED:
      case VCHI_CALLBACK_BULK_DATA_READ:
      case VCHI_CALLBACK_BULK_SENT:      // bulk auxiliary service doesn't use bulk transfers(!)
         os_assert(0);
         break;
   }
}
int32_t ipc_vchi_msg_hold( /*VCHI_SERVICE_HANDLE_T*/int32_t handle,
                       void **data,
                       uint32_t *msg_size,
                       VCHI_FLAGS_T flags,
                       VCHI_HELD_MSG_T *message_handle )
{
	//vchi_msg_hold(handle,data,msg_size,flags,message_handle);
	int32_t events;
	int32_t success=0;

	ipc_aquire(IPC_SEM_ACCESS);
	ipc->buffer[0] = set_vchi_handle(handle);
	ipc->buffer[1] = 0;
	ipc->buffer[2] = flags;
	ipc->buffer[3] = 0xbabeface;
	ipc_signal(IPC_VCHI_MSG_HOLD_EVENT);
	ipc_wait(&events);
	os_assert(events == (1<<IPC_VCHI_MSG_HOLD_EVENT));

	*msg_size = ipc->buffer[1];
	// message_handle = (VCHI_HELD_MSG_T*)ipc->buffer[2];
	*data = &ipc->buffer[4];
	// ipc_release(IPC_SEM_ACCESS);

	return success;
}
Exemple #21
0
/* Sets the task to wait for semaphore state */
void os_task_wait_sem_set( uint8_t tid, Sem_t sem ) {
    os_assert( tid < nTasks );
    task_wait_sem_set( tid, sem );
	
	/* The time is ticked to measure waiting time */
	task_list[ tid ].time = 0;
}
/***********************************************************
 * Name: vchi_control_service_close
 *
 * Arguments:  VCHI_CONNECTION_T *connections,
 *             const uint32_t num_connections
 *
 * Description: Routine to init the control service
 *
 * Returns: int32_t - success == 0
 *
 ***********************************************************/
int32_t vchi_control_service_close( void )
{
   int32_t success = 0;
#if 1
   os_assert(0);
#else
   uint32_t count = 0;

   for( count = 0; count < VCHI_MAX_NUM_CONNECTIONS; count++ )
   {
      if( control_info[count].initialised == VC_TRUE)
      {
         // we have previously initialised this connection
         // so set it all as uninitialised
         // HACK HACK TBD FIXME - do we need to signal to the other end of the connections that we are closing this end??????
         // similarly we would need to respond to such requests ourselves......
         control_info[count].initialised = VC_FALSE;
         control_info[count].connection = NULL;
         success += os_semaphore_release( &control_info[count].connected_semaphore );
      }

   }
#endif
   // close the timer
   os_time_term();
   // reset the timer offset
   time_offset = 0;
   return(success);
}
Exemple #23
0
/***********************************************************
 * Name: software_fifo_write
 *
 * Arguments: SOFTWARE_FIFO_HANDLE_T *handle - handle to this FIFO
 *            uint8_t * data - data to write
 *            uint32_t data_size - how much data to write (in bytes)
 *
 * Description: Writes the required amount of data to the FIFO
 *
 * Returns: 0 if successful, any other value is failure
 *
 ***********************************************************/
int32_t software_fifo_write( SOFTWARE_FIFO_HANDLE_T *handle, const void *data, const uint32_t data_size )
{
uint32_t bytes_left;

   os_assert(handle->base_address);
   // check that there is enough room in the FIFO to fulfill this request
   if( software_fifo_room_available(handle) < data_size )
      return(-1);
   bytes_left = (handle->base_address+handle->size) - handle->write_ptr;
   if(bytes_left >= data_size)
   {
      memcpy(handle->write_ptr,data,data_size);
	  handle->write_ptr += data_size;
	  if(handle->write_ptr >= handle->base_address+handle->size)
         handle->write_ptr = handle->base_address;
   }
   else
   {
      memcpy(handle->write_ptr,data,bytes_left);
      handle->write_ptr = handle->base_address;
      memcpy(handle->write_ptr,data,data_size - bytes_left);
      handle->write_ptr += data_size - bytes_left;
   }
   handle->bytes_written += data_size;
   return(0);
}
void vchi_control_reply_sub_service(void *handle, fourcc_t service_id)
{
  CONTROL_SERVICE_INFO_T * service_info = (CONTROL_SERVICE_INFO_T *)handle;
  uint32_t ii;

  for (ii=0;ii<VCHI_MAX_SERVICES_PER_CONNECTION;ii++)
  {
     if (service_info->control_reply[ii].service_id == service_id)
     { 
        service_info->control_reply[ii].reply_to_send--;
        os_assert(service_info->control_reply[ii].reply_to_send >=0);
        service_info->server_available_replies_to_send--;
        os_assert(service_info->server_available_replies_to_send >=0);
     }
   }

}
Exemple #25
0
void os_task_resume( uint8_t tid ) {
    
    os_assert( tid < nTasks );

    if ( task_list[ tid ].state == SUSPENDED ) {
	    task_list[ tid ].state = task_list[ tid ].savedState;
    }
}
Exemple #26
0
static void eeprom_test_setup(void)
{
	int i;

	i2c_master_enable(I2C1, I2C_BUS_RESET);

	buffer_r = (uint8 *) zalloc(BUFFER_SIZE);
	os_assert(buffer_r != NULL);
	buffer_w = (uint8 *) zalloc(BUFFER_SIZE + 1);
	os_assert(buffer_w != NULL);

	buffer_w[0] = 0x0;
	for (i = 1; i < BUFFER_SIZE + 1; i++)
		buffer_w[i] = i - 1;
	os_log(LOG_DEBUG, "buffers are ready: r: 0x%x, w: 0x%x\n",
	       buffer_r, buffer_w);
}
/* ----------------------------------------------------------------------
 * allocate space for a new non-wrap fifo, and return pointer to
 * opaque handle.  returns NULL on failure
 * -------------------------------------------------------------------- */
VCHI_NWFIFO_T *
non_wrap_fifo_create( const char *name, const uint32_t size, int alignment, int no_of_slots )
{
   int32_t success = -1;
   NON_WRAP_FIFO_HANDLE_T *fifo;

   // check that the alignment is a power of 2 or 0
#ifndef WIN32
   os_assert((OS_COUNT(alignment) == 1) || (alignment == 0));
#endif

   // put the alignment into a form we can use (must be power of 2)
   alignment = alignment ? alignment - 1 : 0;

   // create new non-wrap fifo struct
   fifo = (NON_WRAP_FIFO_HANDLE_T *)os_malloc( sizeof(NON_WRAP_FIFO_HANDLE_T), OS_ALIGN_DEFAULT, "" );
   os_assert( fifo );
   if (!fifo) return NULL;
   
   memset( fifo, 0, sizeof(NON_WRAP_FIFO_HANDLE_T) );
   fifo->name = name;

   // allocate slightly more space than we need so that we can get the required alignment
   fifo->malloc_address = (uint8_t *)os_malloc(size+alignment, OS_ALIGN_DEFAULT, "");
   if ( fifo->malloc_address ) {
      fifo->base_address = (uint8_t *)(((size_t)fifo->malloc_address + alignment) & ~alignment);
      fifo->read_ptr = fifo->base_address;
      fifo->write_ptr = fifo->base_address;
      // now allocate the space for the slot_info structures
      fifo->slot_info = (NON_WRAP_SLOT_T *)os_malloc(no_of_slots*sizeof(NON_WRAP_SLOT_T), OS_ALIGN_DEFAULT, "");
      memset( fifo->slot_info, 0, no_of_slots * sizeof(NON_WRAP_SLOT_T) );
      fifo->size = size;
      fifo->num_of_slots = no_of_slots;
      success = os_semaphore_create( &fifo->sem, OS_SEMAPHORE_TYPE_SUSPEND );
      os_assert(success == 0);
      success = os_cond_create( &fifo->space_available_cond, &fifo->sem );
      os_assert(success == 0);
   }
   else {
      os_free(fifo);
      fifo = NULL;
   }

   return (VCHI_NWFIFO_T *)fifo;
}
// -----------------------------------------------------------------------------
// 
// -----------------------------------------------------------------------------
//
TDataBuffer* RFrameXferBlockProtocolStack::GetTxFrame(
    const TWhaTxQueueState& aWhaTxQueueState,
    TBool& aMore )
    {
    TraceDump( NWSA_TX_DETAILS, 
        ("WLANLDD: RFrameXferBlockProtocolStack::GetTxFrame"));
    TraceDump( NWSA_TX_DETAILS, (("WLANLDD: VO: %d packets"), 
        iVoiceTxQueue.GetLength()));
    TraceDump( NWSA_TX_DETAILS, (("WLANLDD: VI: %d packets"), 
        iVideoTxQueue.GetLength()));
    TraceDump( NWSA_TX_DETAILS, (("WLANLDD: BE: %d packets"), 
        iBestEffortTxQueue.GetLength()));
    TraceDump( NWSA_TX_DETAILS, (("WLANLDD: BG: %d packets"), 
        iBackgroundTxQueue.GetLength()));
    
    TDataBuffer* packet = NULL;
    TQueueId queueId ( EQueueIdMax );
    
    if ( TxPossible( aWhaTxQueueState, queueId ) )
        {
        switch ( queueId )
            {
            case EVoice:
                packet = iVoiceTxQueue.GetPacket();
                break;
            case EVideo:
                packet = iVideoTxQueue.GetPacket();
                break;
            case ELegacy:
                packet = iBestEffortTxQueue.GetPacket();
                break;
            case EBackGround:
                packet = iBackgroundTxQueue.GetPacket();
                break;
#ifndef NDEBUG
            default:
                TraceDump(ERROR_LEVEL, (("WLANLDD: queueId: %d"), queueId));
                os_assert( 
                    (TUint8*)("WLANLDD: panic"), 
                    (TUint8*)(WLAN_FILE), 
                    __LINE__ );
#endif                
            }
        
        aMore = TxPossible( aWhaTxQueueState, queueId );
        }
    else
        {
        aMore = EFalse;        
        }

    TraceDump( NWSA_TX_DETAILS, (("WLANLDD: krn meta hdr: 0x%08x"), 
        reinterpret_cast<TUint32>(packet)));
    
    return packet;
    }
Exemple #29
0
uint8_t task_create( taskproctype taskproc, uint8_t prio, Msg_t *msgPool, uint8_t poolSize, uint16_t msgSize ) {
    uint8_t taskId;
    tcb *task;

    os_assert( os_running() == 0 );
    os_assert( nTasks < N_TASKS );
    os_assert( taskproc != NULL );

    taskId = nTasks;

    /* Check that no other task has the same prio */
    while ( taskId != 0 ) {
        --taskId;
        os_assert( task_list[ taskId ].prio != prio );
    } 
    
    
    task = &task_list[ nTasks ];

    task->tid = nTasks;
    task->prio = prio;
    task->state = READY;
    task->savedState = READY;
    task->semaphore = 0;
    task->internal_state = 0;
    task->taskproc = taskproc;
    task->waitSingleEvent = 0;
    task->time = 0;
    if ( poolSize > 0 ) {
        task->msgQ = os_msgQ_create( msgPool, poolSize, msgSize );
    }
    else {
        task->msgQ = NO_QUEUE;
    }

    os_task_clear_wait_queue( nTasks );
    
    nTasks++;
    return task->tid;
}
/***********************************************************
 * Name: os_cond_create
 *
 * Arguments:  OS_COND_T *condition
 *             OS_SEMAPHORE_T *semaphore
 *
 * Description: Routine to create a condition variable
 *
 * Returns: int32_t - success == 0
 *
 ***********************************************************/
int32_t os_cond_create( OS_COND_T *condition, OS_SEMAPHORE_T *semaphore )
{
   int32_t success = -1;
   int i;
   
   os_assert(vcos_cv_inited);

   if( condition && semaphore )
   {
      uint32_t n;
      vcos_mutex_lock(&cond_latch);

      // start searching from os_cond_next
      n = os_cond_next;
      for (i=0; i<MAX_COND; i++)
      {
         if ( os_cond[n].semaphore == NULL )
            break;
         if ( ++n == MAX_COND )
            n = 0;
      }

      if ( i < MAX_COND )
      {
         OS_COND_T cond = &os_cond[n];
         cond->waiters = NULL;
         cond->semaphore = semaphore;
         *condition = cond;
         success = 0;
         if ( ++n == MAX_COND )
            n = 0;
         os_cond_next = n;
      }

      os_assert( success == 0 );
      vcos_mutex_unlock( &cond_latch );
   }
   
   return success;
}