예제 #1
0
static int8_t handle_timeout( Message *msg )
{
	MsgParam* params = ( MsgParam * )( msg->data );

	switch( params->byte ) {
		case TOU_TID:
		{
			if( st.net_state != MAINTAIN ) {
				restartInterval( 0 );
			} else {
				restartInterval( st.tou + 1 );
			}
			break;
		}
		case TRAN_TID:
		{
			/*
			 * Transmit Version number
			 */
			if( st.blocked == 0 ) {
			version_t *v;
			v = ker_malloc( sizeof(version_t), KER_DFT_LOADER_PID );
			if( v == NULL ) return -ENOMEM;
			*v = version_hton(st.version_data->version);
			
			post_link(KER_DFT_LOADER_PID, KER_DFT_LOADER_PID, 
					MSG_VERSION_ADV, sizeof(version_t), v, 
					SOS_MSG_RELEASE | SOS_MSG_ALL_LINK_IO, 
					BCAST_ADDRESS);
			}
			break;
		}
		case DATA_TID:
		{
			msg_version_data_t *d;
			
			d = (msg_version_data_t *) ker_malloc(
				sizeof( msg_version_data_t ), 
				KER_DFT_LOADER_PID);

			if( d != NULL ) {
				memcpy(d, st.version_data, sizeof( msg_version_data_t ));

				d->version = version_hton( st.version_data->version );
				
				post_link(KER_DFT_LOADER_PID, KER_DFT_LOADER_PID, 
						MSG_VERSION_DATA, 
						sizeof( msg_version_data_t ),
						d, 
						SOS_MSG_RELEASE | SOS_MSG_ALL_LINK_IO, 
						BCAST_ADDRESS);
			}
			st.net_state &= ~SEND_DATA;
			break;
		}
	}
	return SOS_OK;
}
예제 #2
0
graph_t* __attribute__((sos_claim)) make_graph_return(int size) {
    point_t *points;
    edge_t *edges;
    graph_t *g;

    points = ker_malloc(sizeof(struct point) * size, 1);
    edges = ker_malloc(sizeof(struct edge) * size, 1);
    g = ker_malloc(sizeof(struct graph), 1);
    g->points = points;
    g->edges = edges;

    return g;
}
예제 #3
0
graph_t* __attribute__((sos_claim)) make_graph_return_bad_a(int size) {
    point_t *points;
    edge_t *edges;
    graph_t *g;

    points = ker_malloc(sizeof(struct point) * size, 1);
    edges = ker_malloc(sizeof(struct edge) * size, 1);
    
    // Note that memory for graph g is not allocated
    g->points = points;
    g->edges = edges;

    return g;
}
예제 #4
0
파일: uart.c 프로젝트: nesl/sos-2x
int8_t uart_startTransceiverRx( uint8_t rx_len, uint8_t flags) {

	if (state[RX].state != UART_IDLE) {
		return -EBUSY;
	}

	state[RX].flags = UART_SYS_SHARED_FLAGS_MSK & flags;  // get shared flags
	if (flags & UART_SOS_MSG_FLAG) {
		state[RX].msgHdr = msg_create();
		if (state[RX].msgHdr == NULL) {
			return -ENOMEM;
		}
	} else {
		state[RX].buff = ker_malloc(rx_len, UART_PID);
		if (state[RX].buff == NULL) {
			return -ENOMEM;
		}
	}
	state[RX].msgLen = rx_len;  // expected rx_len

	state[RX].idx = 0;
	state[RX].crc = 0;
	state[RX].state = UART_HDLC_START;
	state[RX].hdlc_state = HDLC_START;
	
	uart_enable_rx();
	
	return SOS_OK;
}
예제 #5
0
static int8_t handle_loader_ls_on_node( Message *msg )
{
	msg_ls_reply_t *reply;
	uint8_t i;

	reply = (msg_ls_reply_t *) ker_malloc( sizeof( msg_ls_reply_t ),
			KER_DFT_LOADER_PID );
	if( reply == NULL ) return -ENOMEM;

	for( i = 0; i < NUM_LOADER_PARAMS_ENTRIES; i ++ ) {
		sos_cam_t key = ker_cam_key( KER_DFT_LOADER_PID, i );
		loader_cam_t *cam;
		uint8_t buf[2];

		cam = ker_cam_lookup( key );
		if( cam != NULL && cam->fetcher.status == FETCHING_DONE 
				&& (ker_codemem_read( cam->fetcher.cm, KER_DFT_LOADER_PID, 
						buf, 2, 0) == SOS_OK)) {
			DEBUG_PID( KER_DFT_LOADER_PID, "Data(%d) = %d %d\n", i, buf[0], buf[1]);
			reply->pam_dst_pid[ i ] = buf[0];
			reply->pam_dst_subpid[ i ] = buf[1];
		} else {
			DEBUG_PID( KER_DFT_LOADER_PID, "Data(%d) = NULL\n", i);
			/*
			if( cam != NULL && cam->fetcher.status == FETCHING_DONE) {
				DEBUG_PID( KER_DFT_LOADER_PID, "ker_codemem_read failed...\n");
			}
			*/
			reply->pam_dst_pid[ i ] = NULL_PID;
			reply->pam_dst_subpid[ i ] = 0;
		}
	}
	for( i = 0; i < NUM_LOADER_MODULE_ENTRIES; i ++ ) {
		sos_cam_t key = ker_cam_key( KER_DFT_LOADER_PID, 
				NUM_LOADER_PARAMS_ENTRIES + i );
		loader_cam_t *cam;

		cam = ker_cam_lookup( key );

		if( cam != NULL && cam->fetcher.status == FETCHING_DONE ) {
			mod_header_ptr p;
			sos_code_id_t cid;
			// Get the address of the module header
			p = ker_codemem_get_header_address( cam->fetcher.cm );
			cid = sos_read_header_word( p, offsetof(mod_header_t, code_id));
			// warning: already netowrk order...
			reply->code_id[ i ] = cid;
		} else {
			reply->code_id[ i ] = 0;
		}
	}
	post_auto( KER_DFT_LOADER_PID,
			KER_DFT_LOADER_PID,
			MSG_LOADER_LS_REPLY,
			sizeof( msg_ls_reply_t ),
			reply,
			SOS_MSG_RELEASE,
			msg->saddr);
	return SOS_OK;
}
예제 #6
0
파일: slab.c 프로젝트: nesl/sos-2x
int8_t ker_slab_init( sos_pid_t pid, slab_t *slab, uint8_t item_size, uint8_t items_per_pool, uint8_t flag )
{
	uint8_t i;
	if( items_per_pool > 8 ) {
		return -EINVAL;
	}
	
	//
	// build empty vector
	//
	slab->head = NULL;
	slab->num_items_per_pool = items_per_pool;
	slab->empty_vector = 0;
	slab->item_size = item_size;
	slab->flag = flag;
	for( i = 0; i < items_per_pool; i++ ) {
		slab->empty_vector <<= 1;
		slab->empty_vector |= 0x01;
	}
	
	if( slab->flag & SLAB_LONGTERM ) {
		slab->head = malloc_longterm( sizeof( slab_item_t ) + items_per_pool * item_size, pid );
	} else {
		slab->head = ker_malloc( sizeof( slab_item_t ) + items_per_pool * item_size, pid );
	}
	
	if( slab->head == NULL ) {
		return -ENOMEM;
	}
	slab->head->next = NULL;
	slab->head->alloc = 0;
	slab->head->gc_mark = 0;
	return SOS_OK;
}
예제 #7
0
static inline void handle_request_timeout()
{
	if(fst == NULL) {
		return;
	}
	//sos_assert(fst != NULL);
	//DEBUG("handle request timeout, retx = %d\n", fst->retx);
	fst->retx++;
	if(fst->retx <= FETCHER_REQUEST_MAX_RETX) {
		fetcher_bitmap_t *m;
		uint8_t size = sizeof(fetcher_bitmap_t) + fst->map.bitmap_size;

		DEBUG_PID(KER_FETCHER_PID,"send request to %d\n", fst->src_addr);
		print_bitmap(&fst->map);

		m = (fetcher_bitmap_t *) ker_malloc( size, KER_FETCHER_PID);
		if( m != NULL ) {
			memcpy(m, &(fst->map), size);
			m->key = ehtons( m->key );
			post_auto(KER_FETCHER_PID,
					KER_FETCHER_PID,
					MSG_FETCHER_REQUEST,
					size,
					m,
					SOS_MSG_RELEASE,
					fst->src_addr);
		}
		restart_request_timer();
	} else {
		DEBUG_PID(KER_FETCHER_PID, "request failed!!!\n");
		//codemem_close(&fst->cm, false);
		send_fetcher_done();
	}
}
예제 #8
0
static int8_t handle_init()
{
	ker_permanent_timer_init((&st.tou_timer), KER_DFT_LOADER_PID, 
			TOU_TID, TIMER_ONE_SHOT);		
	ker_permanent_timer_init((&st.tran_timer), KER_DFT_LOADER_PID, 
			TRAN_TID, TIMER_ONE_SHOT);		
	ker_permanent_timer_init((&st.data_timer), KER_DFT_LOADER_PID, 
			DATA_TID, TIMER_ONE_SHOT);		
	st.net_state = MAINTAIN;
	st.tran_count = 0;
	st.data_count = 0;
	st.blocked    = 0;
	st.recent_neighbor = 0;
	st.version_data = ker_malloc(sizeof(msg_version_data_t), KER_DFT_LOADER_PID);
	if(st.version_data == NULL) return -ENOMEM;

	memset((uint8_t *) st.version_data, 0, sizeof(msg_version_data_t));
	/*
     * Use default version to be 1 so that loader_pc can probe loaded data
	 */
	st.version_data->version = 1;

	restartInterval( 0 );
	return SOS_OK;
}
예제 #9
0
int8_t fetcher_request(sos_pid_t req_id, sos_shm_t key, uint16_t size, uint16_t src)
{
    uint8_t bitmap_size;   //! size of the bitmap in bytes
    uint16_t num_fragments;
    uint8_t i;
    fetcher_state_t *f;
	fetcher_cam_t *cam;
	
	cam = (fetcher_cam_t *) ker_shm_get( KER_FETCHER_PID, key);
	if( cam == NULL ) return -EINVAL;

    //if(fst != NULL) return -EBUSY;
    DEBUG_PID(KER_FETCHER_PID, "fetcher_request, req_id = %d, size = %d, src = %d\n", req_id, size, src);

    num_fragments = ((size + (FETCHER_FRAGMENT_SIZE - 1))/ FETCHER_FRAGMENT_SIZE);
    bitmap_size = (uint8_t)((num_fragments + 7)/ 8);

    //DEBUG("size = %d\n", sizeof(fetcher_state_t) + bitmap_size);
    f = ker_malloc(sizeof(fetcher_state_t) + bitmap_size, KER_FETCHER_PID);
    if(f == NULL) {
        return -ENOMEM;
    }
    //DEBUG("num_fragments = %d, bitmap_zie = %d\n", num_fragments, bitmap_size);
    f->requester       = req_id;
    f->map.key         = key;
    f->map.bitmap_size = bitmap_size;
    f->src_addr        = src;
	f->num_funcs       = 0;
    f->next            = NULL;
	f->cm              = cam->cm;

    for(i = 0; i < bitmap_size; i++) {
        f->map.bitmap[i] = 0xff;
    }
    if((num_fragments) % 8) {
        f->map.bitmap[bitmap_size - 1] =
            (1 << (num_fragments % 8)) - 1;
    }
    print_bitmap(&f->map);

    //! backoff first!!!
    f->retx = 0;
    if(fst != NULL) {
        fetcher_state_t *tmp = fst;
		cam->status = FETCHING_QUEUED;

        while(tmp->next != NULL) { tmp = tmp->next; }
        tmp->next = f;
        return SOS_OK;
    }
	cam->status = FETCHING_STARTED;
    fst = f;
    //! setup timer
    ker_timer_start(KER_FETCHER_PID,
            FETCHER_REQUEST_TID,
            FETCHER_REQUEST_BACKOFF_SLOT * ((ker_rand() % FETCHER_REQUEST_MAX_SLOT) + 1));
    //DEBUG("request ret = %d\n", ret);
    return SOS_OK;
}
예제 #10
0
파일: spi_system.c 프로젝트: nesl/sos-2x
/**
 * Read data from the spi
 */
int8_t ker_spi_read_data(
		uint8_t *sharedBuf,
		uint8_t rx_len,
		uint8_t rx_cnt,
		uint8_t calling_id) {
	HAS_CRITICAL_SECTION;

	if (s.state == SPI_SYS_IDLE) {  // not reserved
		return -EINVAL;
	}	

	if ((s.calling_mod_id != calling_id) || 
			((s.state != SPI_SYS_WAIT) && (s.state != SPI_SYS_DMA_WAIT) && (s.state != SPI_SYS_RX_WAIT))) {
		return -EBUSY;
	}

	// get a handle to users buffer
	if (rx_len >= MAX_SPI_READ_LEN) {
		return -EINVAL;
	} else {
		s.len = rx_len;
	}

	// need to assert CS pin
	if (s.flags & SPI_SYS_CS_HIGH_FLAG) {
		spi_cs_high(s.addr);
	} else {
		spi_cs_low(s.addr);
	}

	// only get/malloc a buffer if we are not currently in a DMA sequence
	if ((s.flags & SPI_SYS_SHARED_MEM_FLAG)) {
		if (NULL == sharedBuf) {
			return -EINVAL;
		} else {
			s.cnt = rx_cnt;
			s.bufPtr = sharedBuf;
			if (!(s.state == SPI_SYS_DMA_WAIT)) {
				s.usrBuf = sharedBuf;
			}
		}
	} else {
		// ignore value of sharedBuf
		if (NULL == (s.bufPtr = s.usrBuf = ker_malloc(s.len, SPI_PID))) {
			return -ENOMEM;
		} else {
			s.cnt = 1;
		}
	}

	ENTER_CRITICAL_SECTION();
	s.state = SPI_SYS_RX;
	LEAVE_CRITICAL_SECTION();
	
	return spi_masterRxData(s.usrBuf, s.len, s.flags);
}
예제 #11
0
int main() {

    ads7828_state_t *s  __attribute__((__sos_store__));
    unsigned int __cil_tmp45 ;
    unsigned int __cil_tmp46 ;

    __cil_tmp45 = (unsigned int )s;
    __cil_tmp46 = __cil_tmp45 + 4;
    (*((uint8_t **)__cil_tmp46)) = (uint8_t *)ker_malloc(1U, (unsigned char)129);

    return 0;
}
예제 #12
0
int8_t i2c_startTransceiverRx(uint8_t addr,
		uint8_t rx_msg_len,
		uint8_t flags) {

	HAS_CRITICAL_SECTION;

	uint8_t alt_state = (i2c.flags & I2C_MASTER_FLAG)?I2C_MASTER_IDLE:I2C_SLAVE_IDLE;

	while (!((i2c.state == I2C_IDLE) || (i2c.state == alt_state))) {
		return -EBUSY;
	}
	if (flags & I2C_SOS_MSG_FLAG) {
		return -EINVAL;
	}
	i2c.flags = I2C_SYS_SHARED_FLAGS_MSK & flags;

	if (rx_msg_len >= I2C_MAX_MSG_LEN) {
		return -ENOMEM;
	}
 
  /** 
   * \bug Um, maybe this check is not such a good idea.  i2c.dataBuf needs to
   * be null.  This should be stronger and take the form of an assert such as:
   *
   * assert(i2c.dataBuf == NULL);
   *
   * But no asserts for us :-(
   */
  //if (i2c.dataBuf == NULL) {
    if ((i2c.dataBuf = ker_malloc(rx_msg_len, I2C_PID)) == NULL) { 
      return -ENOMEM; 
    }
  //}
  i2c.msgLen = rx_msg_len; i2c.idx = 0;

	ENTER_CRITICAL_SECTION();
	i2c.addr = (addr<<1);  // shift destination address once (and only once!)

	i2c.msg_state = SOS_MSG_WAIT;

	saveState(i2c.state);
	if (i2c.flags & I2C_MASTER_FLAG) {
		i2c.state = I2C_MASTER_ARB;
		i2c_setCtrlReg((1<<TWINT)|(1<<TWSTA)|(1<<TWEN)|(1<<TWIE));
	} else { // else sit and wait
		i2c.state = I2C_SLAVE_WAIT;
		i2c_setCtrlReg((1<<TWEA)|(1<<TWEN)|(1<<TWIE));
	}
	i2c.msg_state = SOS_MSG_RX_START;
	LEAVE_CRITICAL_SECTION();

	return SOS_OK;
}
예제 #13
0
char ker_cam_add(int key, void *value)
{
    int *cam; 

    cam = ker_malloc(sizeof(int) * 42, 69);

    if( cam == 0 ) { return -1; }

    cam[0] = 1;
    cam[2] = key;
    cam[3] = value;
    
    cam_bin[key] = cam;
    return 0;  
}
예제 #14
0
파일: slab.c 프로젝트: nesl/sos-2x
void* ker_slab_alloc( slab_t *slab, sos_pid_t pid )
{
	slab_item_t *itr = slab->head;
	slab_item_t *prev = slab->head;
	
	
	while( itr != NULL ) {
		DEBUG(" itr->alloc = %x\n", itr->alloc);
		if( itr->alloc != slab->empty_vector ) {
			break;
		}
		prev = itr;
		itr = itr->next;
	}
	
	if( itr == NULL ) {
		//
		// The pool is exhausted, create a new one
		//
		DEBUG("pool exhausted\n");
		if( slab->flag & SLAB_LONGTERM ) {
			prev->next = malloc_longterm( sizeof( slab_item_t ) + slab->num_items_per_pool * slab->item_size, pid );
		} else {
			prev->next = ker_malloc( sizeof( slab_item_t ) + slab->num_items_per_pool * slab->item_size, pid );
		}
		if( prev->next == NULL ) {
			DEBUG("alloc NULL\n");
			return NULL;
		}
		itr = prev->next;
		itr->next = NULL;
		itr->alloc = 0x01;
		itr->gc_mark = 0;
		return itr->mem;
	} else {
		uint8_t i;
		uint8_t mask = 0x01;
		
		DEBUG("find free slot in pool\n");
		for( i = 0; i < slab->num_items_per_pool; i++, mask<<=1 ) {
			if( (itr->alloc & mask)  == 0 ) {
				itr->alloc |= mask;
				return itr->mem + (i * slab->item_size);
			}
		}
	}
	return NULL;
}
예제 #15
0
파일: server.c 프로젝트: nesl/sos-2x
/**
 * @brief Server receiver side
 */
static void server_recv_thread(int fd)
{
	uint8_t d[1024];
	int cnt;
	//sched_yield();
	while( 1 ) {
		cnt = read(fd, d, SOS_MSG_HEADER_SIZE);
		if (cnt == 0) {	// The socket is closed!
			interrupt_remove_read_fd(fd);
			close(fd);
			break;
		}
		if(cnt != SOS_MSG_HEADER_SIZE)
			break;
		Message *buf = (Message*)d;
		Message *m = msg_create();
		if (m == NULL)
			break;
		uint8_t *data = ker_malloc(buf->len,UART_PID);
		if (data == NULL) {
			msg_dispose(m);
			break;
		}
		memcpy(m,buf,SOS_MSG_HEADER_SIZE);
		m->daddr = entohs(m->daddr);
		m->saddr = entohs(m->saddr);
		m->data = data;
		m->flag = SOS_MSG_RELEASE;
		while ((cnt = read(fd, m->data, m->len)) < 0);
		if (cnt != m->len) {
			msg_dispose(m);
			break;
		}
		handle_incoming_msg(m, SOS_MSG_UART_IO);
	}
}
예제 #16
0
파일: message.c 프로젝트: nesl/sos-2x
uint8_t *ker_msg_take_data(sos_pid_t pid, Message *msg_in)
{
  uint8_t *ret;
  Message *msg;   //!< message we will be taking data out

  if(msg_in->type == MSG_PKT_SENDDONE) {
	msg = (Message*) (msg_in->data);
  } else {
	msg = msg_in;
  }
  if(flag_msg_release(msg->flag)) {
	ker_change_own((void*)msg->data, pid);
	ret = msg->data;
	msg->len = 0;
	msg->data = NULL;
	msg->flag &= ~(SOS_MSG_RELEASE);
	return ret;
  } else {
	ret = (uint8_t*)ker_malloc(msg->len, pid);
	if(ret == NULL) return NULL;
	memcpy(ret, msg->data, msg->len);
	return ret;
  }
}
예제 #17
0
static void start_experiment(uint16_t size)
{
	sos_cam_t key;
	loader_cam_t *cam;
	codemem_t cm;
	uint8_t buf[2];

	buf[0] = 128;
	buf[1] = 1;
	DEBUG_PID(KER_DFT_LOADER_PID, "start experiment: size = %d\n", size);
	cm = ker_codemem_alloc( size, CODEMEM_TYPE_EXECUTABLE);
	ker_codemem_write(cm, KER_DFT_LOADER_PID, buf, 2, 0);
	cam = ker_malloc(sizeof(loader_cam_t), KER_DFT_LOADER_PID);

	st.version_data->pam_ver[0]++;
	st.version_data->pam_size[0] = (size + (LOADER_SIZE_MULTIPLIER - 1)) / LOADER_SIZE_MULTIPLIER;
	st.version_data->version ++;

	key = ker_cam_key( KER_DFT_LOADER_PID, 0 );
	cam->fetcher.fetchtype = FETCHTYPE_DATA;
	cam->fetcher.cm = cm;
	ker_cam_add(key, cam);	
	restartInterval(0);
}
예제 #18
0
//-------------------------------------------------------
// MESSAGE HANDLER
//-------------------------------------------------------
static int8_t
matrix_arithmetic_msg_handler (void *state, Message * msg)
{
//  matrix_arithmetic_t *s = (matrix_arithmetic_t*)state;

  switch (msg->type)
    {
    case MSG_INIT:
      {
	break;
      }

    case MSG_FINAL:
      {
	break;
      }
      // int8_t add (const CYCLOPS_Matrix * A, const CYCLOPS_Matrix * B, CYCLOPS_Matrix * C) 
    case ADD:
      {
	matrix_math_t *m = (matrix_math_t *) (msg->data);
	CYCLOPS_Matrix *A = (CYCLOPS_Matrix *) (m->ImgPtrA);
	CYCLOPS_Matrix *B = (CYCLOPS_Matrix *) (m->ImgPtrB);
	CYCLOPS_Matrix *C =
	  (CYCLOPS_Matrix *) ker_malloc (sizeof (CYCLOPS_Matrix),
					 MATRIX_ARITHMETICS_PID);
	if (NULL == C)
	  {
	    return -ENOMEM;
	  }
	if (add (A, B, C) != SOS_OK)
	  {
	    return -EINVAL;
	  }
	//PUT_PORT();
	//post_long                     
	break;
      }
      // int8_t Sub (const CYCLOPS_Matrix * A, const CYCLOPS_Matrix * B, CYCLOPS_Matrix * C) 
    case SUB:
      {
	matrix_math_t *m = (matrix_math_t *) (msg->data);
	CYCLOPS_Matrix *A = (CYCLOPS_Matrix *) (m->ImgPtrA);
	CYCLOPS_Matrix *B = (CYCLOPS_Matrix *) (m->ImgPtrB);
	CYCLOPS_Matrix *C =
	  (CYCLOPS_Matrix *) ker_malloc (sizeof (CYCLOPS_Matrix),
					 MATRIX_ARITHMETICS_PID);
	if (NULL == C)
	  {
	    return -ENOMEM;
	  }
	if (Sub (A, B, C) != SOS_OK)
	  {
	    return -EINVAL;
	  }
	//PUT_PORT();
	//post_long     
	break;
      }
      // int8_t abssub (const CYCLOPS_Matrix * A, const CYCLOPS_Matrix * B, CYCLOPS_Matrix * C
    case ABS_SUB:
      {
	matrix_math_t *m = (matrix_math_t *) (msg->data);
	CYCLOPS_Matrix *A = (CYCLOPS_Matrix *) (m->ImgPtrA);
	CYCLOPS_Matrix *B = (CYCLOPS_Matrix *) (m->ImgPtrB);
	CYCLOPS_Matrix *C =
	  (CYCLOPS_Matrix *) ker_malloc (sizeof (CYCLOPS_Matrix),
					 MATRIX_ARITHMETICS_PID);
	if (NULL == C)
	  {
	    return -ENOMEM;
	  }
	if (abssub (A, B, C) != SOS_OK)
	  {
	    return -EINVAL;
	  }

	// Kevin - resulting Matrix will be put unto updateBackground, and abssub   => 2 ports
	//PUT_PORT();   
	//PUT_PORT();   
	//  Kevin -  if these are all sos modules, shouldnt is use self state s->M ???
//              post_long(MATRIX_ARITHMETICS_PID, MATRIX_IMAGE_PID, ABS_SUB, sizeof(CYCLOPS_Matrix), M, SOS_MSG_RELEASE);
//              post_long(MATRIX_ARITHMETICS_PID, MATRIX_IMAGE_PID, ABS_SUB, sizeof(CYCLOPS_Matrix), M, SOS_MSG_RELEASE);

	break;
      }

      // int8_t getRow (const CYCLOPS_Matrix * A, CYCLOPS_Matrix * res, uint16_t row) 
    case GET_ROW:
      {
	matrix_location_t *m = (matrix_location_t *) (msg->data);
	CYCLOPS_Matrix *A = (CYCLOPS_Matrix *) (m->matPtr);
	uint16_t row = (m->row);
	CYCLOPS_Matrix *res =
	  (CYCLOPS_Matrix *) ker_malloc (sizeof (CYCLOPS_Matrix),
					 MATRIX_ARITHMETICS_PID);
	if (NULL == res)
	  {
	    return -ENOMEM;
	  }
	if (getRow (A, res, row) != SOS_OK)
	  {
	    return -EINVAL;
	  }
	//PUT_PORT();
	//post_long                             
	break;
      }

      // int8_t getCol (const CYCLOPS_Matrix * A, CYCLOPS_Matrix * res, uint16_t col) 
    case GET_COLUMN:
      {
	matrix_location_t *m = (matrix_location_t *) (msg->data);
	CYCLOPS_Matrix *A = (CYCLOPS_Matrix *) (m->matPtr);
	uint16_t col = (m->col);
	CYCLOPS_Matrix *res =
	  (CYCLOPS_Matrix *) ker_malloc (sizeof (CYCLOPS_Matrix),
					 MATRIX_ARITHMETICS_PID);
	if (NULL == res)
	  {
	    return -ENOMEM;
	  }
	if (getCol (A, res, col) != SOS_OK)
	  {
	    return -EINVAL;
	  }
	//PUT_PORT();
	//post_long     
	break;
      }

      // int8_t getBit (const CYCLOPS_Matrix * A, uint16_t row, uint16_t col) 
    case GET_BIT:
      {
	matrix_location_t *m = (matrix_location_t *) (msg->data);
	CYCLOPS_Matrix *A = (CYCLOPS_Matrix *) (m->matPtr);
	uint16_t row = (m->row);
	uint16_t col = (m->col);
	CYCLOPS_Matrix *res =
	  (CYCLOPS_Matrix *) ker_malloc (sizeof (CYCLOPS_Matrix),
					 MATRIX_ARITHMETICS_PID);
	if (NULL == res)
	  {
	    return -ENOMEM;
	  }
	if (getBit (A, row, col) != SOS_OK)
	  {
	    return -EINVAL;
	  }
	//PUT_PORT();
	//post_long
	break;
      }

      // int8_t scale (const CYCLOPS_Matrix * A, CYCLOPS_Matrix * C, const uint32_t s) 
    case SCALE:
      {
	matrix_scale_t *m = (matrix_scale_t *) (msg->data);
	CYCLOPS_Matrix *A = (CYCLOPS_Matrix *) (m->matPtrA);
	CYCLOPS_Matrix *C = (CYCLOPS_Matrix *) (m->matPtrC);
	uint32_t s = (m->scale_value);
	if (scale (A, C, s) != SOS_OK)
	  {
	    return -EINVAL;
	  }
	//PUT_PORT();
	//post_long
	break;
      }
      // int8_t threshold (const CYCLOPS_Matrix * A, CYCLOPS_Matrix * B, uint32_t t) 
    case THRESHOLD:
      {
	matrix_thresh_t *m = (matrix_thresh_t *) (msg->data);
	CYCLOPS_Matrix *A = (CYCLOPS_Matrix *) (m->matPtr);
	uint32_t t = (m->threshhold_value);
	CYCLOPS_Matrix *B =
	  (CYCLOPS_Matrix *) ker_malloc (sizeof (CYCLOPS_Matrix),
					 MATRIX_ARITHMETICS_PID);
	if (NULL == B)
	  {
	    return -ENOMEM;
	  }
	if (threshold (A, B, t) != SOS_OK)
	  {
	    return -EINVAL;
	  }
	//PUT_PORT();
	//post_long             
	break;
      }
    default:
      return -EINVAL;
    }

  return SOS_OK;
}
예제 #19
0
파일: simple.c 프로젝트: nesl/lighthouse
static int8_t simple_msg_handler(void *state, Message *msg)
{
    app_state_t *s = (app_state_t*)state;

    /** Switch to the correct message handler
     *
     * This module handles three types of messages:
     *
     * \li MSG_INIT to start a timer and allocated a buffer
     *
     * \li MSG_TIMER_TIMEOUT to periodicly write a value to the buffer.  Note
     * that we are expecting that the timer will have timer with ID equal to
     * SIMPLE_TID
     *
     * \li MSG_FINAL to stop the timer and deallocate the buffer
     *
     */
    switch (msg->type){

        case MSG_INIT:
            {
                // I'm alive!
                LED_DBG(LED_GREEN_TOGGLE);

                s->pid = msg->did;
                s->state = (uint8_t *) ker_malloc(sizeof(uint8_t), s->pid);
                *(s->state) = 0;
                
                ker_timer_init(s->pid, SIMPLE_TID, TIMER_REPEAT);
                ker_timer_start(s->pid, SIMPLE_TID, 1000);
                break;
            }


        case MSG_FINAL:
            {
                // Bye bye!
                ker_free(s->state);
                ker_timer_stop(s->pid, SIMPLE_TID);
                break;
            }


        case MSG_TIMER_TIMEOUT:
            {
                MsgParam* params = (MsgParam*)(msg->data);

                if (params->byte == SIMPLE_TID)
                {

                    // Blink the LED
                    if (*(s->state) == 1) {
                        LED_DBG(LED_YELLOW_OFF);
                    } else {
                        LED_DBG(LED_YELLOW_ON);
                    }
                    
                    // Update the state
                    *(s->state) += 1;
                    if (*(s->state) > 1) {
                        *(s->state) = 0;
                    }

                }

                break;
            }

        default:
            return -EINVAL;
    }

    return SOS_OK;
}
예제 #20
0
파일: i2c_system.c 프로젝트: nesl/sos-2x
/**
 * Send MSG_I2C_READ_DONE
 */
void i2c_read_done(uint8_t *buff, uint8_t len, uint8_t status) {

	uint8_t *bufPtr = NULL;
	Message *msgPtr = NULL;

	// this is a problem that should be handled
	if (buff == NULL) {
		return;
	}

	if ((i2c_sys.calling_mod_id != NULL_PID) && (status & I2C_SYS_ERROR_FLAG)) {
		goto post_error_msg;
	}

	// the bus was reserved the read was of the length we requested
	if ((i2c_sys.calling_mod_id != NULL_PID) && (len == i2c_sys.rxLen) && 
			// the data was recieved in the correct mode
			(((i2c_sys.state == I2C_SYS_MASTER_RX) && (I2C_SYS_MASTER_FLAG & status)) ||
			 ((i2c_sys.state == I2C_SYS_SLAVE_RX) && !(I2C_SYS_MASTER_FLAG & status)))) {

		// reserved read done will only be raw reads, wrap in message and send
		post_long(
				i2c_sys.calling_mod_id,
				I2C_PID,
				MSG_I2C_READ_DONE,
				len,
				buff,
				SOS_MSG_RELEASE|SOS_MSG_HIGH_PRIORITY);
		i2c_sys.state = (i2c_sys.flags & I2C_SYS_MASTER_FLAG)?I2C_SYS_MASTER_WAIT:I2C_SYS_SLAVE_WAIT;
		return;
	}

	// there appers to be a bug in avr-gcc this a work around to make sure
	// the cast to message works correctly
	// the following code seems to cat the value 0x800008 independent of what
	// buff actually ii2c_sys.  this has no correlation to the data in buff or the 
	// value of the pointer the cast (along with many others that should) works
	// in gdb but fail to execute correctly when compilied
	/* bufPtr = &buff[HDLC_PROTOCOL_SIZE]; */

	// DO NOT CHANGE THIS SECTION OF CODE
	// start of section
	bufPtr = buff+1;
	// end of DO NOT CHANGE SECTION
		
	// if it passes sanity checks give it to the scheduler
	if (!(I2C_SYS_MASTER_FLAG & status) && (len >= SOS_MSG_HEADER_SIZE) && (buff[0] == HDLC_SOS_MSG)) {

		if ((len >= (HDLC_PROTOCOL_SIZE + SOS_MSG_HEADER_SIZE + ((Message*)bufPtr)->len + SOS_MSG_CRC_SIZE)) &&
				(len <= I2C_MAX_MSG_LEN)) {

			// please do not edit the next line
			bufPtr = buff;
			// we have enough bytes for it to be a message, lets start the copy out
			// XXX msgPtr = (Message*)ker_malloc(sizeof(Message), I2C_PID);
			msgPtr = msg_create();
			if (msgPtr !=NULL) {
				uint8_t i=0;
				uint16_t runningCRC=0, crc_in=0;

				// extract the protocol field
				for (i=0; i<HDLC_PROTOCOL_SIZE; i++) {
					runningCRC = crcByte(runningCRC, bufPtr[i]);
				}

				// extract the header
				bufPtr = &buff[HDLC_PROTOCOL_SIZE];
				for (i=0; i<SOS_MSG_HEADER_SIZE; i++) {
					((uint8_t*)msgPtr)[i] = bufPtr[i];
					runningCRC = crcByte(runningCRC, bufPtr[i]);
				}

				// extract the data if it exists
				if (msgPtr->len != 0) {
					uint8_t *dataPtr;
					dataPtr = ker_malloc(((Message*)msgPtr)->len, I2C_PID);

					if (dataPtr != NULL) {

						msgPtr->data = dataPtr;

						bufPtr = &buff[HDLC_PROTOCOL_SIZE+SOS_MSG_HEADER_SIZE];
						for (i=0; i<msgPtr->len; i++) {
							msgPtr->data[i] = bufPtr[i];
							runningCRC = crcByte(runningCRC, bufPtr[i]);
						}
					} else { // -ENOMEM
						ker_free(msgPtr);
						goto post_error_msg;
					}
				} else {
					msgPtr->data = NULL;
				}

				// get the CRC and check it
				bufPtr = &buff[HDLC_PROTOCOL_SIZE+SOS_MSG_HEADER_SIZE+msgPtr->len];
				crc_in = bufPtr[0] | (bufPtr[1]<<8);

				if (crc_in == runningCRC) {
					// message passed all sanity checks including crc
					LED_DBG(LED_YELLOW_TOGGLE);
					if(msgPtr->data != NULL ) {
						msgPtr->flag = SOS_MSG_RELEASE;
					}
					handle_incoming_msg(msgPtr, SOS_MSG_I2C_IO);
					return;
				} else { // clean up
					ker_free(msgPtr->data);
					ker_free(msgPtr);
				}
			}
		}
	}

	// if we make it to here return error message
post_error_msg:
	post_short(
			i2c_sys.calling_mod_id,
			I2C_PID,
			MSG_ERROR,
			READ_ERROR,
			0,
			SOS_MSG_HIGH_PRIORITY);
}
예제 #21
0
int8_t i2c_initTransceiver(uint8_t ownAddress, uint8_t flags) {
	HAS_CRITICAL_SECTION;

    // Set own TWI slave address. Accept TWI General Calls.
	i2c.ownAddr = ((ownAddress<<1)&0xFE);

	if (ownAddress != 0x7f) {
		// 1111xxx is reserved addres space so 0x7f is an
		// invalid address and it is safe to use it as a flag
		// we will also enable the general call recognition bit
		TWAR = i2c.ownAddr|(1<<TWGCE);
	} else {
		if (!(flags&I2C_MASTER_FLAG)){
			// can not give a slave an invalid address
			return -EINVAL;
		}
	}

	// get flag settings from the upper layer
	i2c.flags = I2C_SYS_SHARED_FLAGS_MSK & flags;

	// do some clean up
	i2c.msgLen = 0;
	i2c.txPending = 0;
	i2c.idx = 0;

	// free all allocated buffers
	if (i2c.msgBuf != NULL) {
		i2c.dataBuf = NULL;
		i2c.msgBuf = NULL;
	}
	i2c.msg_state = SOS_MSG_NO_STATE;
	

  /**
   * \bug I2C system may want to NULL the i2c.dataBuf after i2c_send_done,
   * i2c_read_done, and any error.  We could then verify that i2c.dataBuf is
   * null in i2c_initTranceiver and call ker_panic if it is not null.  Same
   * goes for the rxDataBuf
   */
  // Roy: This results in a hard to track bug.  If the user frees I2C data
  // after the I2C sends a MSG_I2C_SEND_DONE, this will free it a second time.
  // Kernel messaging avoids this by explitily setting i2c.dataBuff to null.
  // Well, maybe.  Maybe not...  Regardless, this is bad!  
  //
  // if (i2c.dataBuf != NULL) {
  //  ker_free(i2c.dataBuf);
	//}

  // The problem described abave is NOT a problem with the i2c.rxDataBuf.  A
  // call to i2c_read_done creates a deep copy of the rxDataBuf that is
  // SOS_MSG_RELEASE'ed.  Thus, the rxDataBuff can hang around.  A down side
  // to the current implementation is that the rxDataBuf is not released with
  // when the buffer is released.  We do not leak this data, but it is not
  // made availible to the system. 
  //
  // pre allocate recieve buffer
  if (i2c.rxDataBuf != NULL) {
    ker_free(i2c.rxDataBuf);
	}
  
	i2c.rxDataBuf = ker_malloc(I2C_MAX_MSG_LEN, I2C_PID);
	if (i2c.rxDataBuf == NULL) {
		return -ENOMEM;
	}

	ENTER_CRITICAL_SECTION();
	if (i2c.flags & I2C_MASTER_FLAG) {
		i2c.state = I2C_MASTER_IDLE;
	} else {
		i2c.state = I2C_SLAVE_IDLE;
	}
	// enable TWI interrupt and ack
	i2c_setCtrlReg((1<<TWINT)|(1<<TWEA)|(1<<TWEN)|(1<<TWIE));
	LEAVE_CRITICAL_SECTION();

	return SOS_OK;
}
예제 #22
0
    points = ker_malloc(sizeof(struct point) * size, 1);
    edges = ker_malloc(sizeof(struct edge) * size, 1);
    g = ker_malloc(sizeof(struct graph), 1);
    g->points = points;
    g->edges = edges;

    return g;
}


void make_graph_formal(int size, graph_t *new_graph __attribute__((sos_claim))) {
    point_t *points;
    edge_t *edges;
    graph_t *g;

    points = ker_malloc(sizeof(struct point) * size, 1);
    edges = ker_malloc(sizeof(struct edge) * size, 1);
    g = ker_malloc(sizeof(struct graph), 1);
    g->points = points;
    g->edges = edges;

    new_graph = g;
    return;
}

void free_graph(struct graph * g __attribute__((sos_release))) {
    free((void *) (g->points));
    free((void *) (g->edges));
    free((void *) g);
}
예제 #23
0
static inline void send_fragment()
{
	uint16_t frag_id;
	uint8_t i, j;
	uint8_t mask = 1;
	uint8_t ret;
	fetcher_fragment_t *out_pkt;
	fetcher_cam_t *cam;

	if ( send_state.map == NULL ) {
		ker_timer_stop(KER_FETCHER_PID, FETCHER_TRANSMIT_TID);
		return;
	}

	cam = (fetcher_cam_t *) ker_shm_get( KER_FETCHER_PID, send_state.map->key);

	if ( cam == NULL ) {
		// file got deleted. give up!
		free_send_state_map();
		return;
	}

	if ( send_state.frag != NULL) {
		//! timer fires faster than data reading.  Highly unlikely...
		//! but we still handle it.
		return;
	}

	//! search map and find one fragment to send
	for(i = 0; i < send_state.map->bitmap_size; i++) {
		//! for each byte
		if(send_state.map->bitmap[i] != 0) {
			break;
		}
	}
	if(i == send_state.map->bitmap_size) {
		/*
		 * Did not find any block...
		 */
		free_send_state_map();
		return;
	}

	//sos_assert(i < send_state.map->bitmap_size);

	frag_id = i * 8;
	mask = 1;
	for(j = 0; j < 8; j++, mask = mask << 1) {
		if(mask & (send_state.map->bitmap[i])) {
			send_state.map->bitmap[i] &= ~(mask);
			break;
		}
	}
	//sos_assert(j < 8);
	frag_id += j;
	print_bitmap(send_state.map);
	out_pkt = (fetcher_fragment_t*)ker_malloc(sizeof(fetcher_fragment_t), KER_FETCHER_PID);
	if(out_pkt == NULL){
		DEBUG_PID(KER_FETCHER_PID,"malloc fetcher_fragment_t failed\n");
		goto send_fragment_postproc;
	}
	out_pkt->frag_id = ehtons(frag_id);
	out_pkt->key = ehtons(send_state.map->key);

	ret = ker_codemem_read(cam->cm, KER_FETCHER_PID,
			out_pkt->fragment, FETCHER_FRAGMENT_SIZE,
			frag_id * (code_addr_t)FETCHER_FRAGMENT_SIZE);
	if(ret == SOS_SPLIT) {
		send_state.frag = out_pkt;
	} else if(ret != SOS_OK){
		DEBUG_PID(KER_FETCHER_PID, "codemem_read failed\n");
		ker_free(out_pkt);
		goto send_fragment_postproc;
	}


	//DEBUG("out_pkt has addr %x\n", (int)out_pkt);
	DEBUG_PID(KER_FETCHER_PID, "send_fragment: frag_id = %d to %d\n", frag_id, send_state.dest);
	ret = post_auto(KER_FETCHER_PID,
			KER_FETCHER_PID,
			MSG_FETCHER_FRAGMENT,
			sizeof(fetcher_fragment_t),
			out_pkt,
			SOS_MSG_RELEASE | SOS_MSG_RELIABLE,
			send_state.dest);
	if( ret == SOS_OK ) {
		send_state.num_msg_in_queue++;	
	}
send_fragment_postproc:
	if(check_map(send_state.map)) {
		//! no more fragment to send
		free_send_state_map();
	}
}
예제 #24
0
static void process_version_data( msg_version_data_t *v, uint16_t saddr ) 
{
	uint8_t i;
	for( i = 0; i < NUM_LOADER_PARAMS_ENTRIES + NUM_LOADER_MODULE_ENTRIES; i++ ) {
		sos_cam_t key = ker_cam_key( KER_DFT_LOADER_PID, i);
		loader_cam_t *cam;
		uint8_t type;
		uint8_t size;
		uint8_t ver;

		if( i < NUM_LOADER_PARAMS_ENTRIES) {
			size = (v->pam_size[i]);
			ver = (v->pam_ver[i]);
			type = FETCHTYPE_DATA;
		} else {
			size = (v->mod_size[i - NUM_LOADER_PARAMS_ENTRIES]);
			ver = (v->mod_ver[i - NUM_LOADER_PARAMS_ENTRIES]);
			type = FETCHTYPE_MODULE;
		}

		cam = ker_cam_lookup( key );

		if( cam == NULL && size == 0 ) {
			// We cannot find entry and the size is zero
			// skip this slot
			continue;
		}


		if( cam == NULL ) {
			// we need to add a new module
			cam = (loader_cam_t*) ker_malloc(sizeof(loader_cam_t), KER_DFT_LOADER_PID);
			if( cam == NULL) {
				return;
			}
			if( ker_cam_add( key, cam ) != SOS_OK ) {
				ker_free( cam );
				return;
			}
		} else {
			// we need to replace a module
			if( cam->version == ver ) {
				continue;
			}
			//! new version of module found...
			if( cam->fetcher.status != FETCHING_DONE ) {
				if( cam->fetcher.status == FETCHING_STARTED ) {
					st.blocked = 0;
					restartInterval( 0 );
				}
				fetcher_cancel( KER_DFT_LOADER_PID, key );	
				ker_codemem_free(cam->fetcher.cm);
			} else /* if( cam->fetcher.status == FETCHING_DONE ) */ {
				ker_codemem_free(cam->fetcher.cm);
			}
			if( size == 0 ) {
				//! an rmmod case
				ker_cam_remove( key );
				ker_free( cam );
				continue;
			} 
			//! an insmod case with cam
		} 
		if( request_new_module( key, cam, size, saddr, type) != SOS_OK ) {
			ker_cam_remove( key );
			ker_free( cam );
		} else {
			// another insmod case
			cam->version = ver;
			// only do one fetching
			return;
		}
	}
}
예제 #25
0
파일: uart.c 프로젝트: nesl/sos-2x
/**
 * @brief ISR for reception
 * This is the writer of rx_queue.
 */
uart_recv_interrupt() {
#ifdef SOS_USE_PREEMPTION
	HAS_PREEMPTION_SECTION;
	DISABLE_PREEMPTION();
#endif
	
	uint8_t err;
	uint8_t byte_in;
	static uint16_t crc_in;
	static uint8_t saved_state;
	SOS_MEASUREMENT_IDLE_END()
	LED_DBG(LED_YELLOW_TOGGLE);
	//! NOTE that the order has to be this in AVR
	err = uart_checkError();
	byte_in = uart_getByte();

	//DEBUG("uart_recv_interrupt... %d %d %d %d %d\n", byte_in, err, 
	//		state[RX].state, state[RX].msg_state, state[RX].hdlc_state);
	switch (state[RX].state) {
		case UART_IDLE:
			if ((err != 0) || (byte_in != HDLC_FLAG)) {
				break;
			}
			state[RX].state = UART_HDLC_START;
			break;

		case UART_HDLC_START:
		case UART_PROTOCOL:
			if (err != 0) {
				uart_reset_recv();
				break;
			}

			switch (byte_in) {
				//! ignore repeated start symbols
				case HDLC_FLAG:
					state[RX].state = UART_HDLC_START;
					break;

				case HDLC_SOS_MSG:
					if(state[RX].msgHdr == NULL) {
						state[RX].msgHdr = msg_create();
					} else {
						if((state[RX].msgHdr->data != NULL) &&
								(flag_msg_release(state[RX].msgHdr->flag))){
							ker_free(state[RX].msgHdr->data);
							state[RX].msgHdr->flag &= ~SOS_MSG_RELEASE;
						}
					}
					if(state[RX].msgHdr != NULL) {
						state[RX].msg_state = SOS_MSG_RX_HDR;
						state[RX].crc = crcByte(0, byte_in);
						state[RX].flags |= UART_SOS_MSG_FLAG;
						state[RX].idx = 0;
						state[RX].state = UART_DATA;
						state[RX].hdlc_state = HDLC_DATA;
					} else {
						// need to generate no mem error
						uart_reset_recv();
					}
					break;

				case HDLC_RAW:
					if ((state[RX].buff = ker_malloc(UART_MAX_MSG_LEN, UART_PID)) != NULL) {
						state[RX].msg_state = SOS_MSG_RX_RAW;
						if (state[RX].flags & UART_CRC_FLAG) {
							state[RX].crc = crcByte(0, byte_in);
						}
						state[RX].state = UART_DATA;
						state[RX].hdlc_state = HDLC_DATA;
					} else {
						uart_reset_recv();
					}
					state[RX].idx = 0;
					break;

				default:
					uart_reset_recv();
					break;
				}
				break;

		case UART_DATA:
				if (err != 0) {
					uart_reset_recv();
					break;
				}

				// recieve an escape byte, wait for next byte
				if (byte_in  == HDLC_CTR_ESC) {
					saved_state = state[RX].hdlc_state;
					state[RX].hdlc_state = HDLC_ESCAPE;
					break;
				}

				if (byte_in == HDLC_FLAG) { // got an end of message symbol
					/*
					if (state[RX].msg_state == SOS_MSG_RX_RAW) {
						// end of raw recieve
						// should bundle and send off
						// trash for now
							 state[RX].hdlc_state = HDLC_IDLE;
							 state[RX].state = UART_IDLE;
							 state[RX].flags |= UART_DATA_RDY_FLAG;
							 uart_read_done(state[RX].idx, 0);
					} else {
						// got an end of message symbol early
						*/
						uart_reset_recv();
					//}
					break;
				}

				if (state[RX].hdlc_state == HDLC_ESCAPE) {
					byte_in ^= 0x20;
					state[RX].hdlc_state = saved_state;
				}

				switch (state[RX].msg_state) {
					case SOS_MSG_RX_HDR:
						if (byte_in == HDLC_FLAG) {  // got an end of message symbol
							uart_reset_recv();
							break;
						}
						uint8_t *tmpPtr = (uint8_t*)(state[RX].msgHdr);
						tmpPtr[state[RX].idx++] = byte_in;

						state[RX].crc = crcByte(state[RX].crc, byte_in);

						if (state[RX].idx == SOS_MSG_HEADER_SIZE) {
							// if (state[RX].msgLen != state[RX].msgHdr->len) ????????
							state[RX].msgLen = state[RX].msgHdr->len;

							if (state[RX].msgLen < UART_MAX_MSG_LEN) {
								if (state[RX].msgLen != 0) {
									state[RX].buff = (uint8_t*)ker_malloc(state[RX].msgLen, UART_PID);
									if (state[RX].buff != NULL) {
										state[RX].msgHdr->data = state[RX].buff;
										state[RX].msgHdr->flag = SOS_MSG_RELEASE;
										state[RX].msg_state = SOS_MSG_RX_DATA;
										state[RX].idx = 0;
									} else {
										uart_reset_recv();
									}
								} else { // 0 length packet go straight to crc
									state[RX].msgHdr->flag &= ~SOS_MSG_RELEASE;
									state[RX].msgHdr->data = NULL;
									state[RX].msg_state = SOS_MSG_RX_CRC_LOW;
								}
							} else { // invalid msg length
								uart_reset_recv();
							}
						}
						break;

					case SOS_MSG_RX_RAW:
					case SOS_MSG_RX_DATA:
						if (err != 0) {
							uart_reset_recv();
							return;
						}
						state[RX].buff[state[RX].idx++] = byte_in;
						if (state[RX].flags & UART_CRC_FLAG) {
							state[RX].crc = crcByte(state[RX].crc, byte_in);
						}
						if (state[RX].idx == state[RX].msgLen) {
							if (state[RX].flags & UART_SOS_MSG_FLAG) {
								state[RX].hdlc_state = HDLC_CRC;
								state[RX].msg_state = SOS_MSG_RX_CRC_LOW;
							} else {
								// rx buffer overflow
								uart_reset_recv();
							}
						}
						break;

					case SOS_MSG_RX_CRC_LOW:
						crc_in = byte_in;
						state[RX].msg_state = SOS_MSG_RX_CRC_HIGH;
						break;

					case SOS_MSG_RX_CRC_HIGH:
						crc_in |= ((uint16_t)(byte_in) << 8);
						state[RX].hdlc_state = HDLC_PADDING;
						state[RX].msg_state = SOS_MSG_RX_END;
						state[RX].state = UART_HDLC_STOP;
						break;

					case SOS_MSG_RX_END:  // should never get here
					default:
						uart_reset_recv();
						break;
				}
				break;

		case UART_HDLC_STOP:
				if (byte_in != HDLC_FLAG) {
					// silently drop until hdlc stop symbol
					break;
				} else { // sos msg rx done
					state[RX].hdlc_state = HDLC_IDLE;
					if(crc_in == state[RX].crc) {
#ifndef NO_SOS_UART_MGR
						set_uart_address(entohs(state[RX].msgHdr->saddr));
#endif
            if(state[RX].msgHdr->type == MSG_TIMESTAMP){
              uint32_t timestp = ker_systime32();
              memcpy(((uint8_t*)(state[RX].msgHdr->data) + sizeof(uint32_t)),(uint8_t*)(&timestp),sizeof(uint32_t));

            }
						handle_incoming_msg(state[RX].msgHdr, SOS_MSG_UART_IO);
						state[RX].msgHdr = NULL;
					} else {
						msg_dispose(state[RX].msgHdr);
						state[RX].msgHdr = NULL;
					}
					state[RX].state = UART_IDLE;
					state[RX].msg_state = SOS_MSG_NO_STATE;
					state[RX].hdlc_state = HDLC_IDLE;
					//uart_reset_recv();

					//state[RX].msg_state = SOS_MSG_NO_STATE;
					//state[RX].state = UART_HDLC_START;
				}
				break;
				// XXX fall through

		default:
				uart_reset_recv();
				break;
	} // state[RX].state

#ifdef SOS_USE_PREEMPTION
  // enable interrupts because 
  // enabling preemption can cause one to occur
  ENABLE_GLOBAL_INTERRUPTS();
  // enable preemption
  ENABLE_PREEMPTION(NULL);
#endif
}
예제 #26
0
파일: radio.c 프로젝트: nesl/sos-2x
/**
 * @brief receiver thread
 */
static void recv_thread(int fd)
{
	DEBUG("radio: receiver start\n");
	while(1)
	{
		uint8_t read_buf[SEND_BUF_SIZE];
		Message *recv_msg = NULL;
		int cnt;

		//sched_yield();
		DEBUG("Radio: Receiver Idle ... \n");
		cnt = read(topo_self.sock, read_buf, SEND_BUF_SIZE);
		// XXX Using recvfrom will cause problem on Cygwin
		//cnt = recvfrom(topo_self.sock, read_buf, SEND_BUF_SIZE, 0, &fromaddr, &fromaddrlen);
		DEBUG("Radio: Read %d bytes\n", cnt);
		if(cnt < 0 && cnt != -1) {
			DEBUG("Radio: unable to read, exiting...\n");
			exit(1);
		}
		if( cnt == 0 || cnt == -1) {
			return;
		}
		if(cnt < SOS_MSG_HEADER_SIZE) {
			DEBUG("Radio: get incomplete header\n");
			//! something is wrong...
			return;
		}
		if((((Message*)read_buf)->len) != (cnt - SOS_MSG_HEADER_SIZE)) {
			DEBUG("Radio: invalid data payload size\n");
			return;
		}
		recv_msg = msg_create();
		if(recv_msg == NULL) {
			DEBUG("Radio: no message header\n");
			return;
		}
		memcpy(recv_msg, read_buf, SOS_MSG_HEADER_SIZE);

		if(recv_msg->len != 0) {
			recv_msg->data = ker_malloc(recv_msg->len, RADIO_PID);
			if(recv_msg->data != NULL) {
				recv_msg->flag = SOS_MSG_RELEASE;
				memcpy(recv_msg->data, read_buf + SOS_MSG_HEADER_SIZE, recv_msg->len);
				if(recv_msg->type == MSG_TIMESTAMP)
				{
					uint32_t timestamp = ker_systime32();
					memcpy(&recv_msg->data[4], (uint8_t *)(&timestamp), sizeof(uint32_t));
				}

				if(bTsEnable) {
					timestamp_incoming(recv_msg, ker_systime32());
				}
				DEBUG("handle incoming msg \n");
				handle_incoming_msg(recv_msg, SOS_MSG_RADIO_IO);
			} else {
				msg_dispose(recv_msg);
			}
		} else {
			recv_msg->data = NULL;
			recv_msg->flag = 0;
			if(bTsEnable) {
				timestamp_incoming(recv_msg, ker_systime32());
			}
			handle_incoming_msg(recv_msg, SOS_MSG_RADIO_IO);
		}
	}
}