Esempio n. 1
0
File: monitor.c Progetto: nesl/umpu
void monitor_deliver_outgoing_msg_to_monitor(Message *m)
{
	monitor_cb *curr;
#ifdef MSG_TRACE
#ifdef PC_PLATFORM
	msg_trace(m, true);
#endif
#endif
	if(cb_list == NULL) return;
	curr = cb_list;
	while(curr) {
		/**
		 * We only deliver the message if the source is not
		 * the monitor.  It does not make sense to deliver 
		 * the message sent by the monitor.
		 */
		if((curr->type & MON_NET_OUTGOING) != 0 &&
			curr->mod_handle->pid != m->sid) {
			msg_handler_t handler = 
				(msg_handler_t)sos_read_header_ptr(
							curr->mod_handle->header,
							offsetof(mod_header_t,module_handler));
			void *handler_state = curr->mod_handle->handler_state;
			handler(handler_state, m);
		}
		curr = curr->next;
	}
}
Esempio n. 2
0
void monitor_deliver_incoming_msg_to_monitor(Message *m)
{
	uint8_t type;
	monitor_cb *curr;

#ifdef MSG_TRACE
#ifdef PC_PLATFORM
	msg_trace(m, false);
#endif
#endif
	if(cb_list == NULL) return;
	/**
	 * in SOS, incoming message can be both local and 
	 * from the network
	 */
	if(m->saddr == node_address) {
		/**
		 * local message
		 */
		type = MON_LOCAL;
	} else {
		/**
		 * from network
		 */
		type = MON_NET_INCOMING;
	}
	curr = cb_list;
	while(curr) {
		/**
		 * We only deliver the message if the destination is 
		 * not the monitor.  It does not make sense to 
		 * deliver the message twice
		 */
		if((curr->type & type) != 0 && 
			curr->mod_handle->pid != m->did) {
			msg_handler_t handler = 
				(msg_handler_t)sos_read_header_ptr(
							curr->mod_handle->header,
							offsetof(mod_header_t,module_handler));
			void *handler_state = curr->mod_handle->handler_state;
#ifdef SOS_USE_PREEMPTION
			// push the old pid and priority
			*pid_sp++ = curr_pid;
			*pri_sp++ - curr_pri;
			// set the new priority
			curr_pri = get_module_priority(curr->mod_handle->pid);
#endif
			curr_pid = curr->mod_handle->pid;
			handler(handler_state, m);
#ifdef SOS_USE_PREEMPTION
			// pop the old pid and priority
			curr_pid = *(--pid_sp);
			curr_pri = *(--pri_sp);
#endif
		}
		curr = curr->next;
	}
}
Esempio n. 3
0
void monitor_deliver_outgoing_msg_to_monitor(Message *m)
{
	monitor_cb *curr;
#ifndef SOS_USE_PREEMPTION
	sos_pid_t prev_pid;
#endif
#ifdef MSG_TRACE
#ifdef PC_PLATFORM
	msg_trace(m, true);
#endif
#endif
	if(cb_list == NULL) return;
	curr = cb_list;
	while(curr) {
		/**
		 * We only deliver the message if the source is not
		 * the monitor.  It does not make sense to deliver 
		 * the message sent by the monitor.
		 */
		if((curr->type & MON_NET_OUTGOING) != 0 &&
			curr->mod_handle->pid != m->sid) {
			msg_handler_t handler = 
				(msg_handler_t)sos_read_header_ptr(
							curr->mod_handle->header,
							offsetof(mod_header_t,module_handler));
			void *handler_state = curr->mod_handle->handler_state;
#ifdef SOS_USE_PREEMPTION
			// push the old pid and priority
			*pid_sp++ = curr_pid;
			*pri_sp++ = curr_pri;
			curr_pri = get_module_priority(curr->mod_handle->pid);
#else
			prev_pid = curr_pid;
#endif
			curr_pid = curr->mod_handle->pid;
			handler(handler_state, m);
#ifdef SOS_USE_PREEMPTION
			// pop the old pid and priority
			curr_pri = *(--pri_sp);
			curr_pid = *(--pid_sp);
#else
			curr_pid = prev_pid;
#endif
		}
		curr = curr->next;
	}
}
Esempio n. 4
0
File: sched.c Progetto: nesl/umpu
/**
 * @brief dispatch short message
 * This is used by the callback that was register by interrupt handler
 */
void sched_dispatch_short_message(sos_pid_t dst, sos_pid_t src,
		uint8_t type, uint8_t byte,
		uint16_t word, uint16_t flag)
{
	sos_module_t *handle;
	msg_handler_t handler;
	void *handler_state;

	MsgParam *p;

	handle = ker_get_module(dst);
	if( handle == NULL ) { return; }

	handler = (msg_handler_t)sos_read_header_ptr(handle->header,
			offsetof(mod_header_t,
				module_handler));
	handler_state = handle->handler_state;

	p = (MsgParam*)(short_msg.data);	

	short_msg.did = dst;
	short_msg.sid = src;
	short_msg.type = type;
	p->byte = byte;
	p->word = word;
	short_msg.flag = flag;

	/*
	 * Update current pid
	 */
	//	curr_pid = dst;
	ker_log( SOS_LOG_HANDLE_MSG, curr_pid, type );
	ker_push_current_pid(dst);
	handler(handler_state, &short_msg);
	ker_pop_current_pid();
	ker_log( SOS_LOG_HANDLE_MSG_END, curr_pid, type );
}
Esempio n. 5
0
File: sched.c Progetto: nesl/umpu
static void do_dispatch()
{
  Message *e;                                // Current message being dispatched
  sos_module_t *handle;                      // Pointer to the control block of the destination module
  Message *inner_msg = NULL;                 // Message sent as a payload in MSG_PKT_SENDDONE
  sos_pid_t senddone_dst_pid = NULL_PID;     // Destination module ID for the MSG_PKT_SENDDONE
  uint8_t senddone_flag = SOS_MSG_SEND_FAIL; // Status information for the MSG_PKT_SENDDONE

  SOS_MEASUREMENT_DEQUEUE_START();
  e = mq_dequeue(&schedpq);
  SOS_MEASUREMENT_DEQUEUE_END();
  handle = ker_get_module(e->did);
  // Destination module might muck around with the
  // type field. So we check type before dispatch
	if(e->type == MSG_PKT_SENDDONE) {
		inner_msg = (Message*)(e->data);
	}
	// Check for reliable message delivery
	if(flag_msg_reliable(e->flag)) {
		senddone_dst_pid = e->sid;	
	}
	// Deliver message to the monitor
	// Ram - Modules might access kernel domain here
	monitor_deliver_incoming_msg_to_monitor(e);

	if(handle != NULL) {
		if(sched_message_filtered(handle, e) == false) {
			int8_t ret;
			msg_handler_t handler;
			void *handler_state;

			DEBUG("###################################################################\n");
			DEBUG("MESSAGE FROM %d TO %d OF TYPE %d\n", e->sid, e->did, e->type);
			DEBUG("###################################################################\n");


			// Get the function pointer to the message handler
			handler = (msg_handler_t)sos_read_header_ptr(handle->header,
					offsetof(mod_header_t,
						module_handler));
			// Get the pointer to the module state
			handler_state = handle->handler_state;
			// Change ownership if the release flag is set
			// Ram - How to deal with memory blocks that are not released ?
			if(flag_msg_release(e->flag)){
				ker_change_own(e->data, e->did);
			}

			DEBUG("RUNNING HANDLER OF MODULE %d \n", handle->pid);
			//			curr_pid = handle->pid;
			ker_log( SOS_LOG_HANDLE_MSG, curr_pid, e->type );
			ker_push_current_pid(handle->pid);
			ret = handler(handler_state, e);
			ker_pop_current_pid();
			ker_log( SOS_LOG_HANDLE_MSG_END, curr_pid, e->type );
			DEBUG("FINISHED HANDLER OF MODULE %d \n", handle->pid);
			if (ret == SOS_OK) senddone_flag = 0;
		}
	} else {
		//XXX no error notification for now.
		DEBUG("Scheduler: Unable to find module\n");
	}
	if(inner_msg != NULL) {
		//! this is SENDDONE message
		msg_dispose(inner_msg);
		msg_dispose(e);
	} else {
		if(senddone_dst_pid != NULL_PID) {
			if(post_long(senddone_dst_pid,
						KER_SCHED_PID,
						MSG_PKT_SENDDONE,
						sizeof(Message), e,
						senddone_flag) < 0) {
				msg_dispose(e);
			}
		} else {
			//! return message back to the pool
			msg_dispose(e);
		}
	}
}
Esempio n. 6
0
File: sched.c Progetto: 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;
}
Esempio n. 7
0
static int8_t handle_fetcher_done( Message *msg ) 
{
	fetcher_state_t *f = (fetcher_state_t*) msg->data;
	if( is_fetcher_succeed( f ) == true ) {
		//mod_header_ptr p;
		loader_cam_t *cam;
		fetcher_commit(f, true);

		st.blocked = 0;
		restartInterval( 0 );

		cam = ker_cam_lookup( f->map.key );
		if( cam->fetcher.fetchtype == FETCHTYPE_DATA) {
			uint8_t buf[2];
			ker_codemem_read( cam->fetcher.cm, KER_DFT_LOADER_PID, buf, 2, 0);
			post_short(buf[0], KER_DFT_LOADER_PID, MSG_LOADER_DATA_AVAILABLE,
					buf[1], cam->fetcher.cm, 0);
			DEBUG_PID(KER_DFT_LOADER_PID, "Data Ready\n" );
#ifdef LOADER_NET_EXPERIMENT
			ker_led(LED_GREEN_TOGGLE);
#endif
		} else {
		  uint8_t mcu_type;
#ifndef SOS_SIM
		  uint8_t plat_type;
#endif
		  mod_header_ptr p;
#ifdef MINIELF_LOADER
		  // Link and load the module here
		  melf_load_module(cam->fetcher.cm);
#endif//MINIELF_LOADER		  
		  // Get the address of the module header
		  p = ker_codemem_get_header_address( cam->fetcher.cm ); 

		  // get processor type and platform type
		  mcu_type = sos_read_header_byte(p, 
										  offsetof( mod_header_t, processor_type )); 
#ifdef SOS_SIM
		  if( (mcu_type == MCU_TYPE) )
			// In simulation, we don't check for platform
#else
			plat_type = sos_read_header_byte(p, 
											 offsetof( mod_header_t, platform_type )); 
		  if( (mcu_type == MCU_TYPE) && 
			  ( plat_type == HW_TYPE || plat_type == PLATFORM_ANY) )
#endif
			{
			  
			  /*
			   * If MCU is matched, this means we are using the same 
			   * instruction set.
			   * And if this module is for this *specific* platform or 
			   * simply for all platform with the same MCU
			   */
			  // mark module executable
			  ker_codemem_mark_executable( cam->fetcher.cm );
			  if (cam->version & 0x80) {
#ifdef SOS_SFI
#ifdef MINIELF_LOADER
				sfi_modtable_register(cam->fetcher.cm);
				if (SOS_OK == ker_verify_module(cam->fetcher.cm)){
				  sfi_modtable_flash(p);
				  ker_register_module(p);
				}
				else
				  sfi_exception(KER_VERIFY_FAIL_EXCEPTION);
#else				
				uint16_t init_offset, code_size, handler_addr;
				uint32_t handler_byte_addr, module_start_byte_addr;
				uint16_t handler_sfi_addr;
				handler_sfi_addr = sos_read_header_ptr(p, offsetof(mod_header_t, module_handler));
				handler_addr = sfi_modtable_get_real_addr(handler_sfi_addr);				
				handler_byte_addr = (handler_addr * 2);
				module_start_byte_addr = (p * 2);
				init_offset = (uint16_t)(handler_byte_addr - module_start_byte_addr);
				code_size = cam->code_size * LOADER_SIZE_MULTIPLIER;
				if (SOS_OK == ker_verify_module(cam->fetcher.cm, init_offset, code_size)){
				  sfi_modtable_flash(p);				  
				  ker_register_module(p);
				}
				else
				  sfi_exception(KER_VERIFY_FAIL_EXCEPTION);
#endif //MINIELF_LOADER
#else
				ker_register_module(p);
#endif //SOS_SFI
			  }
			}

		}
		process_version_data( st.version_data, st.recent_neighbor);
	} else {
	  DEBUG_PID( KER_DFT_LOADER_PID, "Fetch failed!, request %d\n", st.recent_neighbor);
	  f = (fetcher_state_t*) ker_msg_take_data(KER_DFT_LOADER_PID, msg);
	  fetcher_restart( f, st.recent_neighbor );
	}
	return SOS_OK;
}