예제 #1
0
파일: sched.c 프로젝트: 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;
}
예제 #2
0
파일: sched.c 프로젝트: nesl/umpu
/**
 * @brief register task with handle
 * Here we assume the state has been initialized.
 * We just need to link to the bin
 */
static int8_t sched_register_module(sos_module_t *h, mod_header_ptr p,
		void *init, uint8_t init_size)
{
  HAS_CRITICAL_SECTION;
  uint8_t num_timers;
  uint8_t bins = hash_pid(h->pid);

  if(ker_get_module(h->pid) != NULL) {
		return -EEXIST;
	//ker_deregister_module(h->pid);
	DEBUG("Module %d is already registered\n", h->pid);
  }

  //! Read the number of timers to be pre-allocated
  num_timers = sos_read_header_byte(p, offsetof(mod_header_t, num_timers));
  if (num_timers > 0){
	//! If there is no memory to pre-allocate the requested timers
	if (timer_preallocate(h->pid, num_timers) < 0){
		return -ENOMEM;
	}
  }

  // link the functions
  fntable_link(h);
  ENTER_CRITICAL_SECTION();
  /**
   * here is critical section.
   * We need to prevent others to search this module
   */
  // add to the bin
  h->next = mod_bin[bins];
  mod_bin[bins] = h;
  LEAVE_CRITICAL_SECTION();
  DEBUG("Register %d, Code ID %d,  Handle = %x\n", h->pid,
		  sos_read_header_byte(h, offsetof(mod_header_t, mod_id)),
		  (unsigned int)h);


  // send an init message to application
  // XXX : need to check the failure
  if(post_long(h->pid, KER_SCHED_PID, MSG_INIT, init_size, init, SOS_MSG_RELEASE | SOS_MSG_SYSTEM_PRIORITY) != SOS_OK) {
	  timer_remove_all(h->pid);
	  return -ENOMEM;
  }
  return SOS_OK;
}
예제 #3
0
파일: sched.c 프로젝트: nesl/umpu
int8_t sched_register_kernel_module(sos_module_t *handle, mod_header_ptr h, void *state_ptr)
{
  sos_pid_t pid;

  if(h == 0) return -EINVAL;

  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;

  handle->handler_state = state_ptr;
  handle->pid = pid;
  handle->header = h;
  handle->flag = SOS_KER_STATIC_MODULE;
	handle->next = NULL;

  return sched_register_module(handle, h, NULL, 0);
}
예제 #4
0
//----------------------------------------------------------
int8_t sfi_get_domain_id(sos_pid_t pid)
{
#ifdef SFI_DOMS_2
  return MOD_DOM_ID;
#endif
#ifdef SFI_DOMS_8
  int8_t retdomid;
  // Ram - For the time being assign all kernel PIDs to be
  // KER_DOM_ID
  sos_module_t* handle;
  if (pid < APP_MOD_MIN_PID){
    retdomid = KER_DOM_ID;
  }
  else{
    handle = ker_get_module(pid);
    if (NULL == handle)
      return -EINVAL;
    retdomid = sos_read_header_byte(handle->header, offsetof(mod_header_t, dom_id));
  }
  return retdomid;
#endif
}
예제 #5
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;
}
예제 #6
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;
}