2014-02-13 12 views
0

안녕하세요, Nios에서 인터럽트를 사용하여 Uart를 사용하는 방법을 배우고 있으며 시작하는 방법을 모르겠습니다. 폴링으로 만들었지 만 인터럽트를 사용하는 방법을 잘 모르겠습니다.Uart 수신 버퍼 인터럽트 대 폴링 확인

이 어떤 도움이

을 감상 할 수있다하는 것은 여기에 내가 대신 uart_checkRecvBuffer의 uart_RecvBufferIsr를 사용하는 가정하고

#include <stdio.h>     // for NULL 
#include <sys/alt_irq.h>    // for irq support function 
#include "system.h"     // for QSYS defines 
#include "nios_std_types.h"   // for standard embedded types 

#define JTAG_DATA_REG_OFFSET   0 
#define JTAG_CNTRL_REG_OFFSET   1 


#define JTAG_UART_WSPACE_MASK   0xFFFF0000 
#define JTAG_UART_RV_BIT_MASK   0x00008000 
#define JTAG_UART_DATA_MASK   0x000000FF 

volatile uint32* uartDataRegPtr = (uint32*)JTAG_UART_0_BASE; 
volatile uint32* uartCntrlRegPtr = ((uint32*)JTAG_UART_0_BASE + 
              JTAG_CNTRL_REG_OFFSET); 
void uart_SendByte (uint8 byte); 
void uart_SendString (uint8 * msg); 
//uint32 uart_checkRecvBuffer (uint8 *byte); 

uint32 done = FALSE; 

void uart_SendString (uint8 * msg) 
{ 
    int i = 0; 
    while(msg[i] != '\0') 
    { 
     uart_SendByte(msg[i]); 
     i++; 
    } 
} /* uart_SendString */ 

void uart_SendByte (uint8 byte) 
{ 
    uint32 WSPACE_Temp = *uartCntrlRegPtr; 

    while((WSPACE_Temp & JTAG_UART_WSPACE_MASK) == 0) 
    { 
     WSPACE_Temp = *uartCntrlRegPtr; 
    } 

    *uartDataRegPtr = byte; 

} /* uart_SendByte */ 

uint32 uart_checkRecvBuffer (uint8 *byte) 
{ 
    uint32 return_value; 
    uint32 DataReg = *uartDataRegPtr; 

    *byte = (uint8)(DataReg & JTAG_UART_DATA_MASK); 
    return_value = DataReg & JTAG_UART_RV_BIT_MASK; 


    return_value = return_value >> 15; 
    return return_value; 



} /* uart_checkRecvBuffer */ 

void uart_RecvBufferIsr (void* context) 
{ 


} /* uart_RecvBufferIsr */ 



int main(void) 
{ 
    uint8* test_msg = (uint8*)"This is a test message.\n"; 

    //alt_ic_isr_register (); // used for 2nd part when interrupts are enabled 

    uart_SendString (test_msg); 

    uart_SendString ((uint8*)"Enter a '.' to exist the program\n\n"); 

    while (!done) 
    { 
     uint8 character_from_uart; 
     if (uart_checkRecvBuffer(&character_from_uart)) 
     { 
      uart_SendByte(character_from_uart); 
     } 

    // do nothing 
    } /* while */ 

    uart_SendString((uint8*)"\n\nDetected '.'.\n"); 
    uart_SendString((uint8*)"Program existing....\n"); 
    return 0; 

} /* main */ 

내 코드입니다. 이 상황을 어떻게 해결할 수 있습니까?

답변

0

alt_ic_isr_register()를 사용하여 인터럽트 핸들러를 등록해야합니다.이 인터럽트 핸들러는 인터럽트가 발생할 때 호출됩니다. 알테라의 NIOS II PDF document에서 자세한 내용을 확인할 수 있습니다 (샘플 코드 포함).

지금까지 인터럽트를 사용하도록 코드를 수정로, 여기에 내가 무엇을 할 것이라고입니다 :

) (uart_checkRecvBuffer를 제거; 같은 뭔가

변경 uart_RecvBufferIsr() (미안 여기에는 컴파일러가 너무 문법/기능을 확인할 수 없습니다) :

volatile uint32 recv_flag = 0; 
volatile uint8 recv_char; 
void uart_RecvBufferIsr(void *context) 
{ 
    uint32 DataReg = *uartDataRegPtr; 

    recv_char = (uint8)(DataReg & JTAG_UART_DATA_MASK); 
    recv_flag = (DataReg & JTAG_UART_RV_BIT_MASK) >> 15; 
} 

위의 코드와 이야기의 교훈은 당신이로 인터럽트를 유지해야한다는 것입니다 가능한 짧게하고 엄격하게 외부에서 수행 할 필요가없는 모든 것을 보냅니다 (아마도 recv_char 및 recv_flag와 함께 사용 된 논리를 단순화함으로써).

그리고 다음과 같이 귀하의 루프를 변경 : 나는 당신의 포트의 속도에 따라 한 일에 문제가 될 수 있다고

while (!done) 
{ 
    if (recv_flag) 
    { 
     uart_SendByte(recv_byte); 
     recv_flag = 0; 
    } 
} 

주 - 문자는 "잠시 동안 너무 빨리 수신되는 경우 "위의 루프를 처리하면 일부 문자가 손실됩니다.

마지막으로 컴파일러가 예를 들어 while 루프에 레지스터를 유지하지 못하도록 일부 변수를 "휘발성"으로 선언했음을 유의하십시오.

하지만 잘하면이 일이 진행됩니다.

+0

그래, 내가 그걸 가지고 있고, 그냥 주석 처리했다. 하지만 내 큰 혼란은 실제로 기능을 만들고 그것을 메인에 배치하는 방법이라고 생각합니다. 나는 알테라의 PDF 파일을보고 있었지만 개인적으로 어떻게 이해할 수는 없다. (Newbie at Coding) – user3304099

+0

더 많은 정보가 추가되었습니다. – rfernandes

+0

감사합니다. 정말 도움이되었습니다. – user3304099