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(); }
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; } }