VOID c_serial_handler(VOID)
{
  //atomic_on();
 //rtx_dbug_outs((CHAR *)"IN SERIAL current running process: ");
  //rtx_dbug_out_number(get_running_process()->pid);
  //rtx_dbug_outs((CHAR *)"current caller: ");
  //rtx_dbug_out_number(get_running_process()->pid);
  context_switch(get_uart_pcb());
  process_switch_if_there_is_a_higher_priority_process(); 

  //atomic_off();
}
Exemple #2
0
void irq_handler(irq_type type) {

	assert(pCurrentProcessPCB->currentState != NEW,"A new process has been interrupted.");

	pCurrentProcessPCB->currentState = INTERRUPTED;

	switch (type) {
		case TIMER_IRQ:
			context_switch(pCurrentProcessPCB, get_timer_pcb());
			break;
		case UART0_IRQ:
			context_switch(pCurrentProcessPCB, get_uart_pcb()); 
			break;
		default:
			break;
		
	}

	k_release_processor();
}
void execute_uart() {

	char c;
	/*
	IER - Interrupt Enable Register. Contains individual interrupt enable bits for the 7 potential UART interrupts.
	IIR - Interrupt ID Register. Identifies which interrupt(s) are pending.
	LSR - Line Status Register. Contains flags for transmit and receive status, including line errors.
	*/

	//  Information about the interrupt
    uint8_t IIR_IntId;	    // Interrupt ID from IIR
	// Line Status Register value		
	uint8_t LSR_Val;	    // LSR Value
	uint8_t dummy = dummy;	// dummy variable to clear interrupt upon LSR error
	LPC_UART_TypeDef * pUart = (LPC_UART_TypeDef *)LPC_UART0;

	// Reading IIR automatically acknowledges the interrupt
	IIR_IntId = (pUart->IIR) >> 1 ; // skip pending bit in IIR

	if (IIR_IntId & IIR_Receive_Data_Available) {  // Receive Data Available
		 Envelope * message = 0;
		 int hot_key_exec = 0;
		// Note: read RBR will clear the interrupt
		c =   pUart->RBR; // read from the uart

		buffer[0] = c;
		i++;
		buffer[1] = 0;

		hot_key_exec = do_hot_key(*buffer);
		if (hot_key_exec == 0) {
			/* If we have space, parse and echo the buffer contents
			Sending the messages takes 2 blocks so we need at least that many
			*/
			if(numberOfMemoryBlocksCurrentlyAllocated < MAX_ALLOWED_MEMORY_BLOCKS -1){
				message = k_request_memory_block();
				message->sender_pid = get_uart_pcb()->processId;
				message->receiver_pid = get_kcd_pcb()->processId;
				message->message_type = KEYBOARD_INPUT;
				set_message_bytes(message, buffer, 2);
				k_send_message(message->receiver_pid, message);
			}else{
				// Otherwise just use polling since we have no choice
				uart0_polling_put_string(buffer);
				uart0_polling_put_string("Insufficient memory: Unable to pass message to KCD.\r\n");
			}
		}
	} else if (IIR_IntId & IIR_THR_Empty) {  // THRE Interrupt, transmit holding register empty
	    LSR_Val = pUart->LSR;
	    if(LSR_Val & LSR_THR_Empty) {
	        g_UART0_TX_empty = 1;	// UART is ready to transmit 
	    } else {  
	        g_UART0_TX_empty = 0;  // UART is not ready to transmit yet
		}
	} else if (IIR_IntId & IIR_Receive_Line_Status) {
	    LSR_Val = pUart->LSR;
		if (LSR_Val  & (LSR_OE|LSR_PE|LSR_FE|LSR_RXFE|LSR_BI) ) {
		    // There are errors or break interrupt 
	        // Read LSR will clear the interrupt 
	        dummy = pUart->RBR; //Dummy read on RX to clear interrupt, then bail out
			return ;    // error occurs, return
		}
		// If no error on RLS, normal ready, save into the data buffer.
	    // Note: read RBR will clear the interrupt 
		if (LSR_Val & LSR_Unread_Character) { // Receive Data Ready
		    g_UART0_buffer[g_UART0_count++] = pUart->RBR; // read from the uart
	        if ( g_UART0_count == BUFSIZE ) {
		        g_UART0_count = 0;  // buffer overflow
	        }	
		}	    
	} else {  // IIR_CTI and reserved combination are not implemented yet
	    return;
	}
}