Ejemplo n.º 1
0
// Sends a message to the process
int k_send_message (uint32_t pid, void *message) {
	MessageEnvelope *menv = (MessageEnvelope *)k_request_memory_block();

	if (message == 0)
		return;

	menv->sender_id 	= (current_process())->m_pid; 	// Field 1: Sender
	menv->receiver_id 	= pid; 							// Field 2: Receiver
	menv->message_type 	= 0; 							// Field 3: Message Type
	menv->message 		= message; 						// Field 4: Message

	enqueue_envelope(pid, menv);

	if ((get_process(pid))->m_state == MSG_BLOCKED)
		move_to_ready(pid);
}
Ejemplo n.º 2
0
void uart_i_proc(void) {
	uint8_t IIR_IntId;	    // Interrupt ID from IIR 		 
	LPC_UART_TypeDef *pUart = (LPC_UART_TypeDef *)LPC_UART0;
	ENVELOPE* msg;
	__disable_irq();
	uart_asm_preemption_flag = 0;
	
	/* Reading IIR automatically acknowledges the interrupt */
	IIR_IntId = (pUart->IIR) >> 1 ; // skip pending bit in IIR 
	
	if (IIR_IntId & IIR_RDA) { // Receive Data Available
		
		/* read UART. Read RBR will clear the interrupt */
		g_char_in = pUart->RBR;
		
		// Avoid interuption by only sending when mem blocks are avaliable
		// Sends input to crt display
		if (mem_empty() == 0)
		{
			int display_size;
			char display_msg[3];
			if (g_char_in == '\r')
			{
				display_size = 3;
				display_msg[0] = '\n';
				display_msg[1] = g_char_in;
				display_msg[2] = '\0';
			}
			else
			{
				display_size = 2;
				display_msg[0] = g_char_in;
				display_msg[1] = '\0';
			}
			
			msg = (ENVELOPE*) k_request_memory_block();
			msg->sender_pid = UART_IPROC_PID;
			msg->destination_pid = CRT_PID;
			msg->nextMsg = NULL;
			msg->message_type = MSG_CRT_DISPLAY;
			msg->delay = 0;
			set_message(msg, display_msg, display_size*sizeof(char));
			k_send_message(CRT_PID, msg);
			uart_asm_preemption_flag = 1;
		}
		
#ifdef DEBUG_HOTKEYS		
		if (g_char_in == DEBUG_HOTKEY_1)
			k_print_ready_queue();
		else if (g_char_in == DEBUG_HOTKEY_2)
			k_print_blocked_on_memory_queue();
		else if (g_char_in == DEBUG_HOTKEY_3)
			k_print_blocked_on_receive_queue();
#endif			
	
		if (g_char_in != '\r') // Any char not an enter
		{
#ifdef DEBUG_HOTKEYS
			if ((g_char_in != DEBUG_HOTKEY_1)&&(g_char_in != DEBUG_HOTKEY_2)&&(g_char_in != DEBUG_HOTKEY_3))
			{
				g_input_buffer[g_input_buffer_index] = g_char_in;
				g_input_buffer_index++;
			}
#else
			g_input_buffer[g_input_buffer_index] = g_char_in;
			g_input_buffer_index++;
#endif
		}
		else // Enter is pressed
		{
			g_input_buffer[g_input_buffer_index] = '\0';
			g_input_buffer_index++;
			
			// Avoid interuption by only sending when mem blocks are avaliable
			if (mem_empty() == 0)
			{
				msg = (ENVELOPE*) k_request_memory_block();
				msg->sender_pid = UART_IPROC_PID;
				msg->destination_pid = KCD_PID;
				msg->nextMsg = NULL;
				msg->message_type = MSG_CONSOLE_INPUT;
				msg->delay = 0;
				set_message(msg, g_input_buffer, g_input_buffer_index*sizeof(char));	
				k_send_message(KCD_PID, msg);
				g_input_buffer_index = 0;
				uart_asm_preemption_flag = 1;
			}
		}
		
		g_input_buffer[g_input_buffer_index] = g_char_in;

	} 
	else if (IIR_IntId & IIR_THRE) 
	{
			char* g_input;
			if (g_curr_p == NULL)
				g_curr_p = (ENVELOPE*) k_non_block_receive_message(UART_IPROC_PID);
			if (g_curr_p != NULL)
			{
				g_input = (char*) g_curr_p->message;
				if (g_input[g_char_out_index] != '\0')
				{
					// print normal char
					pUart->THR = g_input[g_char_out_index];
					g_char_out_index++;
				}
				else
				{
					// done printing
					if (gp_pcb_nodes[UART_IPROC_PID]->p_pcb->env_q.head == NULL)
						pUart->IER &= (~IER_THRE);
					pUart->THR = g_input[g_char_out_index];
					k_non_block_release_memory_block(g_curr_p);
					g_curr_p = NULL;
					g_char_out_index = 0;
				}
			}
	}    
	__enable_irq();
}
Ejemplo n.º 3
0
/**
 * @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();
}
Ejemplo n.º 4
0
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;
	}
}