Example #1
0
int8_t fetcher_cancel(sos_pid_t req_id, sos_shm_t key)
{
    fetcher_state_t *tmp;
    fetcher_state_t *prev;
    if( fst == NULL ) return -EINVAL;
    if( fst->map.key == key ) {	
        tmp = fst;
        start_new_fetch();
        ker_free( tmp );
		/*
		 * Cancel sender as well
		 */
		if( (send_state.map != NULL) && (send_state.map->key == key)) {
			free_send_state_map();
		}
        return SOS_OK;
    }
    prev = fst;
    tmp = fst->next;
    while(tmp != NULL) {
        if( tmp->map.key == key ) {	
            prev->next = tmp->next;
            ker_free( tmp );
            return SOS_OK;	
        }
        prev = tmp;
        tmp = tmp->next;
    }
    return -EINVAL;
}
Example #2
0
static int tr_send_data(Data *s, Message *msg)
{
    void *hdr = ker_msg_take_data(42, msg); 
    int dup;
    int my_id = s->fieldB;
    
    if(hdr == 0) return -1;

    if(s->fieldA == 0) {
        if(my_id == 42) {
            post_net(42, 
                    42,
                    69, 
                    msg->len, 
                    msg->data,
                    0x04, 
                    255);
            // MEMORY LEAK HERE.  The above call to post should be realeasing
            // hdr rather than msg->data.
            return 0;
        } else {
            ker_free(hdr);
            return -1;
        }
    }

    if(s->fieldA >= ((int*)hdr)[0] ) {
        ker_free(hdr);
        return -1;
    }

    if(my_id != 18) {
        my_id += 4;
    } else {
        dup = 0;
    }

    if(dup == 0) {
        post_net(42, 
                42,
                69, 
                msg->len, 
                msg->data,
                0x04, 
                s->fieldA);
        return 0;
    } else {
        ker_free(hdr);
        return -1;
    }

}
Example #3
0
/**
 * @brief handle the process of creating senddone message
 * @param msg_sent  the Message just sent or delivered
 * @param succ      is the delivery successful?
 * @param msg_owner the owner of the message 
 * NOTE the implementation will need to improve
 */
void msg_send_senddone(Message *msg_sent, bool succ, sos_pid_t msg_owner)
{
  uint8_t flag;
  
  if(flag_msg_reliable(msg_sent->flag) == 0) {
	msg_dispose(msg_sent);
	return;
  }
  
  /*
   * Release the memory 
   */
  if(flag_msg_release(msg_sent->flag)){
	ker_free(msg_sent->data);
	msg_sent->flag &= ~(SOS_MSG_RELEASE);
	msg_sent->data = NULL;
  }

  if(succ == false) {
	flag = SOS_MSG_SEND_FAIL; 
  } else {
	flag = 0;
  }
  if(post_long(msg_sent->sid, msg_owner, MSG_PKT_SENDDONE, 
			   sizeof(Message), msg_sent, flag) < 0) {
	msg_dispose(msg_sent);
  } 
}
Example #4
0
/**
 * @brief Pre-allocate timers for a module at load time
 */
int8_t timer_preallocate(sos_pid_t pid, uint8_t num_timers)
{
   // We have already checked if num_timer > 0 and pid is not NULL_PID

  uint8_t i, j;
  sos_timer_t* tt[MAX_PRE_ALLOCATED_TIMERS];
   
  //! We cannot allow a single module to pre allocate a lot of timers
  if (num_timers > MAX_PRE_ALLOCATED_TIMERS)
	return -EINVAL;
  
  //! First try to safely allocate memory blocks for all the pre-allocated timers
  for (i = 0; i < num_timers; i++){
	tt[i] = (sos_timer_t*)malloc_longterm(sizeof(sos_timer_t), TIMER_PID);
	if (tt[i] == NULL){
	  for (j = 0; j < i; j++){
		ker_free(tt[j]);
	  }
	  return -ENOMEM;
	}   
  }
  
   //! If we get here then we have all the memory allocated
   //! Now initialize all the data structures and just add them to the timer pool
  for (i = 0; i < num_timers; i++){
	timer_pre_alloc_block_init(tt[i], pid);
  }
  
  return SOS_OK;
}
Example #5
0
void msg_send_senddone(Message *msg_sent, int succ, int msg_owner)
{
    int flag;

    if(msg_sent->flag == 0) {
        ker_free(msg_sent);
        return;
    }

    if(msg_sent->flag) {
        ker_free(msg_sent->data);
        msg_sent->flag = 0;
    }

    return;
}
Example #6
0
File: slab.c Project: nesl/sos-2x
void slab_gc( slab_t *slab, sos_pid_t pid )
{
	slab_item_t *itr = slab->head;
	slab_item_t *prev = NULL;
	//
	// Detect memory leak while marking the memory to malloc
	//
	while( itr != NULL ) {
		if( itr->alloc != itr->gc_mark ) {
			// leak!
			DEBUG_GC("leak in slab %d %d\n", itr->alloc, itr->gc_mark);
			led_red_toggle();
			itr->alloc = itr->gc_mark;
			
			if( itr->alloc == 0 && itr != slab->head ) {
				prev->next = itr->next;
				ker_free( itr );
				itr = prev;
			} else {
				// mark it used to malloc
				itr->gc_mark = 0;
				ker_gc_mark( pid, itr );
			}
		} else {
			itr->gc_mark = 0;
			ker_gc_mark( pid, itr );
		}
		prev = itr;
		itr = itr->next;
	}
}
Example #7
0
// Post a message with payload and source address
int8_t post_longer(sos_pid_t did, sos_pid_t sid, uint8_t type, uint8_t len,
				   void *data, uint16_t flag, uint16_t saddr)
{
  Message *m = msg_create();
  if(m == NULL){
	if(flag_msg_release(flag)){
	  ker_free(data);
	}
	return -ENOMEM;
  }
  m->daddr = node_address;
  m->did = did;
  m->type = type;
  m->saddr = saddr;
  m->sid = sid;
  m->len = len;
  m->data = (uint8_t*)data;
#ifdef SOS_USE_PREEMPTION
  // assign priority based on priority of id
  m->priority = get_module_priority(did);
#endif
  m->flag = flag;
  sched_msg_alloc(m);
  ker_log( SOS_LOG_POST_LONG, sid, did ); 
  return SOS_OK;
}
Example #8
0
static int8_t handle_version_data( Message *msg ) 
{
	msg_version_data_t *pkt = (msg_version_data_t *) msg->data;

	if( st.net_state & SEND_DATA ) {
		/*
		 * We have data to send
		 */
		if( pkt->version == st.version_data->version) {
			st.data_count ++;
			if( st.data_count >= OVERHEARD_K ) {
				st.net_state &= ~SEND_DATA;
				ker_timer_stop( KER_DFT_LOADER_PID, DATA_TID );
			}
			return SOS_OK;
		}
	}
	if( pkt->version > st.version_data->version ) {
		restartInterval( 0 );
		ker_free(st.version_data);
		st.version_data = (msg_version_data_t*) ker_msg_take_data(KER_DFT_LOADER_PID, msg);
		process_version_data( st.version_data, msg->saddr );
	}
	return SOS_OK;
}
Example #9
0
File: vmac.c Project: nesl/sos-2x
/*************************************************************************
 * the callback fnction for reading data from cc2420                     *
 *************************************************************************/
void _MacRecvCallBack(int16_t timestamp)
{
	VMAC_PPDU ppdu;
	vhal_data vd;

	mac_to_vhal(&ppdu, &vd);
	Radio_Disable_Interrupt();		//disable interrupt while reading data
	if( !Radio_Recv_Pack(&vd) ) {
		Radio_Enable_Interrupt();	//enable interrupt
		return;
	}
	Radio_Enable_Interrupt();		//enable interrupt

	vhal_to_mac(&vd, &ppdu);

	// Andreas - filter node ID here, even before allocating any new memory
	// if you're using sos/config/base you must comment this block out!
	if (net_to_host(ppdu.mpdu.daddr) != NODE_ADDR && net_to_host(ppdu.mpdu.daddr) != BCAST_ADDRESS) 
	{
		ker_free(vd.payload);
		return;
	}

	Message *msg = msg_create();
	if( msg == NULL ) {
		ker_free(vd.payload);
		return;
	}
	mac_to_sosmsg(&ppdu, msg);

	// Andreas - start debug
	#ifdef ENA_VMAC_UART_DEBUG
	uint8_t *payload;
	uint8_t msg_len;
	msg_len=msg->len;
	payload = msg->data;
 
	//post_uart(msg->sid, msg->did, msg->type, msg_len, payload, SOS_MSG_RELEASE, msg->daddr);

	// Swap daddr with saddr, because daddr is useless when debugging.
	// Of course, if sossrv says "dest addr: 15" that actually means the message SENDER was node 15
	post_uart(msg->sid, msg->did, msg->type, msg_len, payload, SOS_MSG_RELEASE, msg->saddr);
	#endif

	//if (msg->daddr == NODE_ADDR || msg->daddr == BCAST_ADDRESS)
		handle_incoming_msg(msg, SOS_MSG_RADIO_IO);
}
Example #10
0
/**
 * @brief remove timers for a particular pid
 */
int8_t timer_remove_all(sos_pid_t pid){
  list_link_t *link;
  
  for(link = deltaq.l_next;
	  link != (&deltaq); link = link->l_next) {
	sos_timer_t *h = (sos_timer_t*)link;         
	if(h->pid == pid) {
	  link = link->l_prev;
	  timer_remove_timer(h);
	  ker_free(h);
	  //	break; Ram - Why are we breaking from this loop ?
	}
  }
	
  for (link = timer_pool.l_next; link != (&timer_pool); link = link->l_next){
	sos_timer_t *h = (sos_timer_t*)link;
	if (h->pid == pid){
	  link = link->l_prev;
	  list_remove((list_link_t*)h);
	  ker_free(h);
	}
  }

  for (link = prealloc_timer_pool.l_next; link != (&prealloc_timer_pool); link = link->l_next){
	sos_timer_t *h = (sos_timer_t*)link;
	if (h->pid == pid){
	  link = link->l_prev;
	  list_remove((list_link_t*)h);
	  ker_free(h);
	}
  }

  for (link = periodic_pool.l_next; link != (&periodic_pool); link = link->l_next){
	sos_timer_t *h = (sos_timer_t*)link;
	if (h->pid == pid){
	  link = link->l_prev;
	  list_remove((list_link_t*)h);
	  ker_free(h);
	}
  }

  return SOS_OK;
}
Example #11
0
int post_net(int sid, 
        int mid, 
        int did, 
        int data_size, 
        void* data, 
        int flag,
        int address) {
    ker_free(data);
    return flag;
}
Example #12
0
/**
 * @brief dispose message
 * return message header back to message repostitary
 */
void msg_dispose(Message *m)
{
	HAS_CRITICAL_SECTION;
	
	if(flag_msg_release(m->flag)) { 
		ker_free(m->data); 
	}

	ENTER_CRITICAL_SECTION();
	ker_slab_free( &msg_slab, m );
	
	LEAVE_CRITICAL_SECTION();
}
Example #13
0
File: sched.c Project: nesl/umpu
static int8_t do_register_module(mod_header_ptr h, sos_module_t *handle, 
																 void *init, uint8_t init_size, uint8_t flag)
{
  sos_pid_t pid;
  uint8_t st_size;
  int8_t ret;

  // Disallow usage of NULL_PID
  if (flag == SOS_CREATE_THREAD) {
	  pid = sched_get_pid_from_pool();
	  if (pid == NULL_PID) return -ENOMEM;
  } else {
	  pid = sos_read_header_byte(h, offsetof(mod_header_t, mod_id));
	  /*
	   * Disallow the usage of thread ID
	   */
	  if (pid > APP_MOD_MAX_PID) return -EINVAL;
  }


  // Read the state size and allocate a separate memory block for it
  st_size = sos_read_header_byte(h, offsetof(mod_header_t, state_size));
	//DEBUG("registering module pid %d with size %d\n", pid, st_size);
  if (st_size){
		//handle->handler_state = (uint8_t*)ker_malloc(st_size, pid);
		handle->handler_state = (uint8_t*)malloc_longterm(st_size, KER_SCHED_PID);
	// If there is no memory to store the state of the module
		if (handle->handler_state == NULL){
			return -ENOMEM;
		}
	} else {
		handle->handler_state = NULL;
	}

	// Initialize the data structure
	handle->header = h;
	handle->pid = pid;
  handle->flag = 0;
	handle->next = NULL;

  // add to the bin
  ret = sched_register_module(handle, h, init, init_size);
  if(ret != SOS_OK) {
	 ker_free(handle->handler_state); //! Free the memory block to hold module state
	return ret;
  }
  return SOS_OK;
}
Example #14
0
File: sched.c Project: nesl/umpu
sos_pid_t ker_spawn_module(mod_header_ptr h, void *init, uint8_t init_size, uint8_t flag)
{
	sos_module_t *handle;
	if(h == 0) return NULL_PID;
	// Allocate a memory block to hold the module list entry
	//handle = (sos_module_t*)ker_malloc(sizeof(sos_module_t), KER_SCHED_PID);
	handle = (sos_module_t*)malloc_longterm(sizeof(sos_module_t), KER_SCHED_PID);
	if (handle == NULL) {
		return NULL_PID;
	}
	if( do_register_module(h, handle, init, init_size, flag) != SOS_OK) {
		ker_free(handle);
		return NULL_PID;	
	}
	return handle->pid;
}
Example #15
0
File: sched.c Project: nesl/umpu
/**
 * @brief register new module
 * NOTE: this function cannot be called in the interrupt handler
 * That is, the function is not thread safe
 * NOTE: h is stored in program memory, which can be different from RAM
 * special access function is needed.
 */
int8_t ker_register_module(mod_header_ptr h)
{
	sos_module_t *handle;
	int8_t ret;
	if(h == 0) return -EINVAL;
	handle = (sos_module_t*)malloc_longterm(sizeof(sos_module_t), KER_SCHED_PID);
	if (handle == NULL) {
		return -ENOMEM;
	}
	ret = do_register_module(h, handle, NULL, 0, 0);
	if(ret != SOS_OK) {
		ker_free(handle);
	}
	ker_change_own(handle->handler_state, handle->pid);
	return ret;
}
Example #16
0
//! Free the first timer block beloning to pid in the timer_pool
int8_t ker_timer_release(sos_pid_t pid, uint8_t tid)
{
  sos_timer_t* tt;

  //! First stop the timer if it is running
  ker_timer_stop(pid, tid);

  //! Get the timer block from the pool
  tt = alloc_from_timer_pool(pid, tid);
  
  if (tt == NULL) 
	return -EINVAL;

  //! Deep free of the timer
  ker_free(tt); 
  
  return SOS_OK;   
}
Example #17
0
File: slab.c Project: nesl/sos-2x
void ker_slab_free( slab_t *slab, void* mem ) 
{
	slab_item_t *itr = slab->head;
	slab_item_t *prev = NULL;
	
	while( itr != NULL ) {
		if( ((uint8_t*)mem) >= itr->mem && ((uint8_t*)mem) < (itr->mem + slab->num_items_per_pool * slab->item_size) ) {
			uint8_t mask = 1 << ( ( ((uint8_t*)mem) - (itr->mem) ) / slab->item_size );
			
			itr->alloc &= ~mask;
			
			if( itr->alloc == 0 && itr != slab->head ) {
				prev->next = itr->next;
				ker_free( itr );
			}
			return;
		}
		prev = itr;
		itr = itr->next;
	}
	ker_panic();
}
Example #18
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();
	}
}
Example #19
0
static int8_t fetcher_handler(void *state, Message *msg)
{
    switch (msg->type) {
        case MSG_FETCHER_FRAGMENT:
        {
			fetcher_fragment_t *f;
			f = (fetcher_fragment_t*)msg->data;
			f->key = entohs( f->key );
			f->frag_id = entohs(f->frag_id);

			DEBUG_PID(KER_FETCHER_PID,"MSG_FETCHER_FRAGMENT:\n");
			handle_overheard_fragment(msg);
			if(fst == NULL) {
				DEBUG_PID(KER_FETCHER_PID, "NO Request!!!\n");
				return SOS_OK;  //!< no request
			}
			//DEBUG_PID(KER_FETCHER_PID,"calling restart_request_timer()\n");
			restart_request_timer();
			fst->retx = 0;
			//DEBUG_PID(KER_FETCHER_PID,"calling handle_data()\n");
			return handle_data(msg);
		}
		case MSG_FETCHER_REQUEST:
		{
			fetcher_bitmap_t *bmap =
				(fetcher_bitmap_t *) msg->data;
			bmap->key = entohs( bmap->key );

			//! received request from neighbors
			DEBUG("handling request to %d from %d\n", msg->daddr, msg->saddr);
			if(msg->daddr == ker_id()) {
				return handle_request(msg);
			}
			if(fst == NULL) return SOS_OK;  //!< no request
			restart_request_timer();
			fst->retx = 0;
			return SOS_OK;
		}
		case MSG_TIMER_TIMEOUT:
		{
			MsgParam *params = (MsgParam*)(msg->data);
			if(params->byte == FETCHER_REQUEST_TID) {
				//DEBUG("request timeout\n");
				if( no_mem_retry ) {
					send_fetcher_done();
					return SOS_OK;
				}
				handle_request_timeout();
			} else if(params->byte == FETCHER_TRANSMIT_TID) {
				//DEBUG("send fragment timeout\n");
				if( send_state.num_msg_in_queue < FETCHER_MAX_MSG_IN_QUEUE ) {
					send_fragment();
				}
			}
			return SOS_OK;
		}
		case MSG_PKT_SENDDONE:
		{
			if( send_state.num_msg_in_queue > 0 ) {
				send_state.num_msg_in_queue--;
			}
			return SOS_OK;
		}
#ifdef SOS_HAS_EXFLASH
		case MSG_EXFLASH_WRITEDONE:
		{
			ker_free(send_state.fragr);
			send_state.fragr = NULL;
			check_map_and_post();
			return SOS_OK;
		}
		case MSG_EXFLASH_READDONE:
		{

			post_auto(KER_FETCHER_PID,
					KER_FETCHER_PID,
					MSG_FETCHER_FRAGMENT,
					sizeof(fetcher_fragment_t),
					send_state.frag,
					SOS_MSG_RELEASE,
					send_state.dest);
			send_state.frag = NULL;
			return SOS_OK;
		}
#endif
		case MSG_INIT:
		{
			send_state.map = NULL;
			send_state.frag = NULL;
			send_state.fragr = NULL;
			send_state.num_msg_in_queue = 0;	
			ker_msg_change_rules(KER_FETCHER_PID, SOS_MSG_RULES_PROMISCUOUS);
			ker_permanent_timer_init(&(send_state.timer), KER_FETCHER_PID, FETCHER_TRANSMIT_TID, TIMER_REPEAT);
			ker_timer_init(KER_FETCHER_PID, FETCHER_REQUEST_TID, TIMER_ONE_SHOT);
			return SOS_OK;
		}

	}
	return -EINVAL;
}
Example #20
0
static void free_send_state_map()
{
	ker_free(send_state.map);
	send_state.map = NULL;
	ker_timer_stop(KER_FETCHER_PID, FETCHER_TRANSMIT_TID);
}
Example #21
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;
		}
	}
}
Example #22
0
/**
 * 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);
}
Example #23
0
int8_t timer_micro_reboot(sos_module_t *handle){
  sos_pid_t pid;
  list_link_t *link;
  mod_header_ptr hdr;
  uint8_t num_timers_left;
  
  pid = handle->pid;
  hdr = handle->header;
  num_timers_left = sos_read_header_byte(hdr, offsetof(mod_header_t, num_timers));
  DEBUG("Timer: Pre-alloc timers requested %d \n", num_timers_left);
  
  if (num_timers_left > 0){
	for (link = prealloc_timer_pool.l_next;
		 link != (&prealloc_timer_pool);
		 link = link->l_next){
	  sos_timer_t *h = (sos_timer_t*)link;
	  if (h->pid == pid)
		num_timers_left--; // Assert - This value should NEVER become negative
	}
  }
  DEBUG("Timer: Timers left to pre-allocate %d \n", num_timers_left);
  
  
  //! Stop all timers of pid
  //! Move timer blocks to the pre-allocated pool
  //! or free them
  for (link = deltaq.l_next;
	   link != (&deltaq);
	   link = link->l_next){
	sos_timer_t *h = (sos_timer_t*)link;
	if (h->pid == pid){
	  link = link->l_prev;
	  timer_remove_timer(h);
	  if (num_timers_left > 0){
		num_timers_left--;
		timer_pre_alloc_block_init(h, pid);
		DEBUG("Timer: Allocated active timer \n");
	  }
	  else
		ker_free(h);
	}
  }
  
  //! Remove all initialized timers
  //! Move timer blocks to the pre-allocated pool
  //! or free them
  for (link = timer_pool.l_next;
	   link != (&timer_pool);
	   link = link->l_next){
	sos_timer_t *h = (sos_timer_t*)link;
	if (h->pid == pid){
	  link = link->l_prev;
	  list_remove((list_link_t*)h);
	  if (num_timers_left > 0){
		num_timers_left--;
		timer_pre_alloc_block_init(h, pid);
		DEBUG("Timer: Allocated an initialzed but non-running timer\n");
	  }
	  else
		ker_free(h);
	}
  }
  
  //! If necessary, allocate memory for the pre-allocated timers
  if (num_timers_left > 0){ 
	DEBUG("Timer: Alloc more memory for timers\n");     
	if (timer_preallocate(pid, num_timers_left) != SOS_OK)
	  return -ENOMEM;
  }
  return SOS_OK;
}
Example #24
0
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;
}
Example #25
0
/**
 * Send MSG_SPI_READ_DONE
 */
void spi_read_done(uint8_t *buff, uint8_t length, uint8_t status) {
	
	if (s.flags & SPI_SYS_CS_HIGH_FLAG) {
		spi_cs_release_high(s.addr);
	} else {
		spi_cs_release_low(s.addr);
	}

	if((NULL == buff) && (NULL_PID != s.calling_mod_id)) {
		post_short(
				s.calling_mod_id,
				SPI_PID,
				MSG_ERROR,
				SPI_READ_ERROR,
				0,
				SOS_MSG_HIGH_PRIORITY);
		return;
	}

	if (NULL == buff) {
		return;
	}

	if (s.len == length) {
		s.cnt--;
		if (s.cnt > 0) {
			s.bufPtr += s.len;
			s.state = SPI_SYS_DMA_WAIT;
		} else {
			// read done send response
			if (s.flags & SPI_SYS_READ_DONE_CB_FLAG) {
				s.read_done_cb(s.usrBuf, length, s.cnt, status);
			} else {

				if (s.flags & SPI_SYS_SHARED_MEM_FLAG) {
					post_long(
							s.calling_mod_id,
							SPI_PID,
							MSG_SPI_READ_DONE,
							length, // read length
							s.usrBuf, // return the buffer pointer
							SOS_MSG_HIGH_PRIORITY);

				} else {
					// dont trust the user to free the memory to message only if not shared
					post_long(
							s.calling_mod_id,
							SPI_PID,
							MSG_SPI_READ_DONE,
							length, // byte length
							s.usrBuf,
							SOS_MSG_RELEASE|SOS_MSG_HIGH_PRIORITY);
				}
			}
			/*if (s.flags & SPI_SYS_SHARED_MEM_FLAG) {
				ker_free(s.usrBuf);
			}*/
			s.usrBuf = NULL;
			s.bufPtr = NULL;
		}
		s.state = SPI_SYS_WAIT;
	} else { // short message
		post_short(
				s.calling_mod_id,
				SPI_PID,
				MSG_ERROR,
				SPI_READ_ERROR,
				0,
				SOS_MSG_HIGH_PRIORITY);

		if (!(s.flags & SPI_SYS_SHARED_MEM_FLAG)) {
			ker_free(s.usrBuf);
		}
		spi_system_init();
	}

	if (!(s.flags & SPI_SYS_LOCK_BUS_FLAG)) {
		ker_spi_release_bus(s.calling_mod_id);
	}
}
Example #26
0
File: uart.c Project: 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
}
Example #27
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;
}
Example #28
0
File: sched.c Project: nesl/umpu
/**
 * @brief de-register a task (module)
 * @param pid task id to be removed
 * Note that this function cannot be used inside interrupt handler
 */
int8_t ker_deregister_module(sos_pid_t pid)
{
  HAS_CRITICAL_SECTION;
  uint8_t bins = hash_pid(pid);
  sos_module_t *handle;
  sos_module_t *prev_handle = NULL;
  msg_handler_t handler;

  /**
   * Search the bins while save previous node
   * Once found the module, connect next module to previous one
   * put module back to freelist
   */
  handle = mod_bin[bins];
  while(handle != NULL) {
		if(handle->pid == pid) {
			break;
		} else {
			prev_handle = handle;
			handle = handle->next;
		}
	}
	if(handle == NULL) {
		// unable to find the module
		return -EINVAL;
	}
	handler = (msg_handler_t)sos_read_header_ptr(handle->header,
			offsetof(mod_header_t,
				module_handler));

	if(handler != NULL) {
		void *handler_state = handle->handler_state;
		Message msg;
		//		sos_pid_t prev_pid = curr_pid;

		//curr_pid = handle->pid;
		ker_push_current_pid(handle->pid);
		msg.did = handle->pid;
		msg.sid = KER_SCHED_PID;
		msg.type = MSG_FINAL;
		msg.len = 0;
		msg.data = NULL;
		msg.flag = 0;
		handler(handler_state, &msg);
		ker_pop_current_pid();
		//		curr_pid = prev_pid;
	}

	// First remove handler from the list.
	// link the bin back
	ENTER_CRITICAL_SECTION();
	if(prev_handle == NULL) {
		mod_bin[bins] = handle->next;
	} else {
		prev_handle->next = handle->next;
	}
	LEAVE_CRITICAL_SECTION();

	// remove the thread pid allocation
	if(handle->pid >= SCHED_MIN_THREAD_PID) {
		uint8_t i = handle->pid - SCHED_MIN_THREAD_PID;
		pid_pool[i/8] &= ~(1 << (i % 8));
  }


  // remove system services
  timer_remove_all(pid);
	//  sensor_remove_all(pid);
	//  ker_timestamp_deregister(pid);
  fntable_remove_all(handle);

  // free up memory
  // NOTE: we can only free up memory at the last step
  // because fntable is using the state
  if((SOS_KER_STATIC_MODULE & (handle->flag)) == 0) {
		ker_free(handle);
  }
  mem_remove_all(pid);

  return 0;
}