void fake_cci () { trace(ALWAYS,"request envelopes and stuff."); MsgEnv *env = k_request_msg_env (); while (1) { trace(ALWAYS,"request delay of 5 sec."); k_request_delay( 500, 123 , env); k_receive_message (); trace(ALWAYS,"request delay of 2 sec."); k_request_delay( 200, 123 , env); k_receive_message (); trace(ALWAYS,"request delay of 1 sec."); k_request_delay( 100, 123 , env); k_receive_message (); trace(ALWAYS,"request delay of 0.5 sec."); k_request_delay( 50, 123 , env); k_receive_message (); trace(ALWAYS,"done"); } }
void k_kb_iProcess() { kernel->suspended_process = kernel->current_process; kernel->current_process = getPCB(KB_PID); //k_atomic(on); MsgEnv * msg_env = k_receive_message(); if(msg_env){ if(kb_share_mem->ok_flag == 1){ int i = 0; while((msg_env->msg[i] = kb_share_mem->value[i])) i++; msg_env->type = CONSOLE_INPUT; k_send_message(msg_env->senderID, msg_env); kb_share_mem->size = 0; kb_share_mem->ok_flag = 0; }else{ PCB * kb_pcb = getPCB(KB_PID); msg_env->nextMsgEnv = kb_pcb->msgEnvQueue->nextMsgEnv; kb_pcb->msgEnvQueue->nextMsgEnv = msg_env; } } kernel->current_process = kernel->suspended_process; //k_atomic(off); }
void kbd_i_proc(int signum) { int error = k_pseudo_process_switch(KB_I_PROCESS_ID); if (error != SUCCESS) { printf("Error! Context Switch failed in keyboard I process"); cleanup(); } MsgEnv* env = k_receive_message(); if (env != NULL) { // Loop until writing in shared memory is done while (in_mem_p_key->ok_flag==OKAY_TO_WRITE); memcpy(env->data,in_mem_p_key->indata,in_mem_p_key->length + 1); // Send message back to process that called us k_send_message(env->sender_pid ,env); in_mem_p_key->ok_flag = OKAY_TO_WRITE; // okay to write again k_return_from_switch(); return; } k_return_from_switch(); return; }
msg_envelope * receive_message() { msg_envelope *temp; atomic(ON); msg_envelope * msgEnv = k_receive_message(); atomic(OFF); return msgEnv; }
void crt_i_proc(int signum) { int error = k_pseudo_process_switch(CRT_I_PROCESS_ID); if (error != SUCCESS) { printf("Error! Process Switch failed in CRT I process"); cleanup(); return; } if (signum == SIGUSR2) { MsgEnv* envTemp = NULL; envTemp = MsgEnvQ_dequeue(displayQ); if (envTemp == NULL) { printf("Warning: Recieved a signal in CRT I process but there was no message."); return; } envTemp->msg_type = DISPLAY_ACK; k_send_message(P_PROCESS_ID, envTemp); k_return_from_switch(); return; } MsgEnv* env = k_receive_message(); outputbuf command; if (env==NULL) { env = k_receive_message(); } strcpy(in_mem_p_crt->outdata,env->data); MsgEnvQ_enqueue(displayQ,env); in_mem_p_crt->ok_flag = OKAY_DISPLAY; k_return_from_switch(); return; }
/**************************************************************************** * Function : key_i_proc ****************************************************************************** * Description : Keyboard I process only forwards user input if there is a message * : in its message received queue. It works with the get_console_chars * : command, and assumes that if any process wants user input, it * : has called this primitive and the primitive has sent a message * : envelope to the kb i-process. The kb I process, takes this message * : populates it with user input and sends it back to the sender. * * Assumptions : * *****************************************************************************/ void k_key_i_proc() { k_message_ptr input_msg; extern k_PCB_ptr k_interrupted_process; extern k_PCB_ptr k_current_process; extern k_io_buffer_ptr k_input_buf; while (1) //loop forever { //Only forward the kb input if there is a process that wants kb input (signified //by a msg in the received message queue if (k_current_process->k_received_message_queue->head != NULL) { //receive message envelope input_msg = k_receive_message(); //Copy contents of input buffer to message envelope /* int i; for (i =0; i<k_input_buf->length; i++) { input_msg->msg_text[i] = k_input_buf->bufdata[i]; } */ input_msg->msg_size = sprintf(input_msg->msg_text, "%s", k_input_buf->bufdata); //send message to process that requested input input_msg->receiver_pid = input_msg->sender_pid; input_msg->sender_pid = PID_I_KB; input_msg->msg_type = MSG_TYPE_CONSOLE_INPUT; input_msg->msg_size = k_input_buf->length; k_send_message (input_msg->receiver_pid, input_msg); } //If user is not waiting for kb input then discard contents of buffer //Discard contents of buffer after forwarding user input also k_input_buf->length = 0; //flag of 1 means i-process is to run. O means helper is to run k_input_buf->wait_flag = 0; //Restore context of interrupted process k_context_switch(k_current_process, k_interrupted_process); } }
//crt-iprocess check local buffer //if its ready, copy data to share memory and reset local buffer void k_crt_iProcess() { kernel->suspended_process = kernel->current_process; kernel->current_process = getPCB(CRT_PID); MsgEnv * msg_env = k_receive_message(); if(msg_env != NULL){ if (msg_env->senderID) if(crt_share_mem->ok_flag == 0){ int i = 0; while((crt_share_mem->value[i] = msg_env->msg[i])) i++; msg_env->type = DISPLAY_ACK; k_send_message(msg_env->senderID, msg_env); crt_share_mem->ok_flag = 1; crt_share_mem->size = i; }else{ //we send the env back to the beginnning of the msg queue PCB * crt_pcb = getPCB(CRT_PID); msg_env->nextMsgEnv = crt_pcb->msgEnvQueue; crt_pcb->msgEnvQueue = msg_env; } } kernel->current_process = kernel->suspended_process; }
/**************************************************************************** * Function : crt_i_proc ****************************************************************************** * Description : The crt iprocess is triggered by a signal sent from the crt helper * : process every 100msec. the iprocess receives output from processes * : and writes the bufdata to the output shared memory buffer. The * : iprocess checks for a message in its message received queue, * : and if there is it will attempt to copy the message to the output * : buffer. If the shared memory is busy, it switches back to the the * : interrupted process and waits until the next signal from the crt * : helper process. * * Assumptions : * *****************************************************************************/ void k_crt_i_proc() { k_message_ptr output_msg; extern k_PCB_ptr k_current_process; extern k_PCB_ptr k_interrupted_process; extern k_io_buffer_ptr k_output_buf; while (1) //loop forever { //Check if bufdata is waiting to be output to crt if (!k_message_queue_is_empty(k_current_process->k_received_message_queue)) { //flag of 1 means i-process is to run. O means helper is to run if (k_output_buf->wait_flag == 1) { output_msg = k_receive_message(); //write to output buffer /* int i; for (i=0; i<output_msg->msg_size; i++) { k_output_buf->bufdata[i] = output_msg->msg_text[i]; } */ k_output_buf->length = sprintf(k_output_buf->bufdata, "%s", output_msg->msg_text); //send message to process that requested input output_msg->receiver_pid = output_msg->sender_pid; output_msg->sender_pid = PID_I_CRT; output_msg->msg_type = MSG_TYPE_DISPLAY_ACK; output_msg->msg_size = 0; k_send_message(output_msg->receiver_pid, output_msg); k_output_buf->wait_flag = 0; } } // Restore context of interrupted process k_context_switch(k_current_process, k_interrupted_process); } }
/* * This function is called by the assembly STUB function */ void uart_i_process() { int i; BYTE temp; temp = SERIAL1_UCSR; // Ack the interrupt volatile BYTE CharIn = ' '; // There is data to be read if( temp & 1 ) { CharIn = SERIAL1_RD; if (pong_mode) { MsgEnv* message = k_request_msg_env(); message->msg_type = CONSOLE_INPUT; message->msg[0] = CharIn; k_send_message(PONG_PID, message); return; } if (CharIn == KB_LINE_END) { SERIAL1_IMR = 3; SERIAL1_WD = '\n'; SERIAL1_IMR = 2; #ifdef _CFSERVER_ inputIndex--; #endif InBuffer[inputIndex] = '\0'; inputIndex++; MsgEnv* message = k_request_msg_env(); if (message != NULL) { for (i = 0; i < inputIndex; i++) { message->msg[i] = InBuffer[i]; } message->msg_type = CONSOLE_INPUT; k_send_message(CCI_PID, message); } inputIndex = 0; } else if (inputIndex < INPUT_BUFFER_SIZE - 2) // enter in a character { if (!hotkey(CharIn)) { InBuffer[inputIndex] = CharIn; inputIndex++; SERIAL1_IMR = 3; SERIAL1_WD = CharIn; SERIAL1_IMR = 2; } } } // Check to see if data can be written out else if ( temp & 4 ) { if (outputIndex == 0 && output_print_char == FALSE) { MsgEnv* message = k_receive_message(); if (message != NULL) { i = 0; while (message->msg[i] != '\0') { OutBuffer[i] = message->msg[i]; i++; } OutBuffer[i] = '\0'; output_print_char = TRUE; if (message->msg_type == CONSOLE_OUTPUT) { k_release_msg_env(message); } else { message->msg_type = DISPLAY_ACK; k_send_message(message->send_pid, message); } } else { trace(ERROR, "Uart i process expected an env but received NULL"); } } if (output_print_char) { if (OutBuffer[outputIndex] == '\0') { outputIndex = 0; output_print_char = FALSE; MsgEnv* message = k_receive_message(); if (message != NULL) { i = 0; while (message->msg[i] != '\0') { OutBuffer[i] = message->msg[i]; i++; } OutBuffer[i] = '\0'; output_print_char = TRUE; if (message->msg_type == CONSOLE_OUTPUT) { k_release_msg_env(message); } else { message->msg_type = DISPLAY_ACK; k_send_message(message->send_pid, message); } } else { SERIAL1_IMR = 2; // Disable tx interrupt } } else { SERIAL1_WD = OutBuffer[outputIndex]; // Write data outputIndex++; } } } return; }
/** * @brief: c UART0 IRQ Handler */ void uart_iprocess(void) { uint8_t IIR_IntId; // Interrupt ID from IIR LPC_UART_TypeDef *pUart = (LPC_UART_TypeDef *)LPC_UART0; __disable_irq(); #ifdef DEBUG_0 //uart1_put_string("Entering c_UART0_IRQHandler\n\r"); #endif // DEBUG_0 /* Reading IIR automatically acknowledges the interrupt */ IIR_IntId = (pUart->IIR) >> 1 ; // skip pending bit in IIR if (IIR_IntId & IIR_RDA) { // Receive Data Avaialbe /* read UART. Read RBR will clear the interrupt */ // Perform a 'context switch' PCB *old_proc = gp_current_process; gp_current_process = k_get_process(PID_UART_IPROC); g_char_in = pUart->RBR; #ifdef DEBUG_0 uart1_put_string("Reading a char = "); uart1_put_char(g_char_in); uart1_put_string("\n\r"); #endif // DEBUG_0 // process the character. If it is a hotkey, call the corresponding function // If we are reading, fall through to default and add to the command buffer switch (g_char_in) { case '\r': case '\n': if (g_is_reading) { // We've finished reading a command, send it to the KCD process MSG_BUF *message; g_is_reading = 0; strcpy("\n\r", (char *)(g_in_buffer + g_in_index)); if (is_memory_available()) { message = k_request_memory_block(); message->mtype = DEFAULT; strcpy((char *)g_in_buffer, message->mtext); k_send_message(PID_KCD, message); } g_in_index = 0; } break; case '%': if (!g_is_reading) { // Start reading a command g_is_reading = 1; g_in_index = 1; g_in_buffer[0] = '%'; break; } #if defined(DEBUG_0) && defined(_DEBUG_HOTKEYS) case READY_Q_COMMAND: if (!g_is_reading) { print_ready(); break; } case MEMORY_Q_COMMAND: if (!g_is_reading) { print_mem_blocked(); break; } case RECEIVE_Q_COMMAND: if (!g_is_reading) { print_receive_blocked(); break; } case MESSAGE_COMMAND: if (!g_is_reading) { print_messages(); break; } #endif /* DEBUG HOTKEYS */ default: if (g_is_reading) { // TODO: check bounds g_in_buffer[g_in_index++] = g_char_in; } } gp_current_process = old_proc; } else if (IIR_IntId & IIR_THRE) { /* THRE Interrupt, transmit holding register becomes empty */ // Check for messages and load the buffer // Perform a 'context switch' to the i-process MSG_BUF *message; PCB *old_proc = gp_current_process; gp_current_process = k_get_process(PID_UART_IPROC); // Don't block waiting for a message while (is_message(PID_UART_IPROC)) { int sender = PID_CRT; char *c; // Receive message and copy it to the buffer message = k_receive_message(&sender); c = message->mtext; //dprintf("Copying message to buffer: %s\n\r", message->mtext); if (*c != '\0') { do { g_out_buffer[g_out_end] = *c; g_out_end = (g_out_end + 1) % OUTPUT_BUFF_SIZE; c++; } while (g_out_end != g_out_start && *c != '\0'); } k_release_memory_block(message); } // Check if there is something in the circular buffer if (g_out_start != g_out_end) { g_char_out = g_out_buffer[g_out_start]; pUart->THR = g_char_out; g_out_start = (g_out_start + 1) % OUTPUT_BUFF_SIZE; } else { // nothing to print, disable the THRE interrupt pUart->IER ^= IER_THRE; // toggle (disable) the IER_THRE bit } gp_current_process = old_proc; } else { /* not implemented yet */ #ifdef DEBUG_0 //uart1_put_string("Should not get here!\n\r"); #endif // DEBUG_0 __enable_irq(); return; } __enable_irq(); }