//------------------------------------------------------------------------- // FUNCTION DECLARATION //------------------------------------------------------------------------- void hardware_init(void){ // Starting the evaluation EVAL_START(); // LEDS led_init(); // SYSTEM TIMER timer_hardware_init(DEFAULT_INTERVAL, DEFAULT_SCALE); // UART ker_push_current_pid(KER_UART_PID); uart_system_init(); ker_pop_current_pid(); #ifndef NO_SOS_UART //! Initalize uart comm channel ker_push_current_pid(KER_UART_PID); sos_uart_init(); ker_pop_current_pid(); #endif }
/** * @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 ); }
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); } } }
/** * @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; }