2011-03-10 7 views
0

제 목적에 맞게 함수를 수정하려고합니다.C on ARM - UART 수신 대기

int getc0 (void) 
{ 
    while ((U0LSR & 0x01) == 0); //Wait for character 
    return U0RBR; 
} 

위의 코드는 직렬 포트 0에서 문자를 수신 할 때까지 함수가 멈추게하고 반환합니다. 나는 이렇게 while 루프를 사용했다.

while((str = getc0())!='\r'){ 
    strcat(&route_buffer,&str); 
} 

그래서 지금은 반환 캐리지가 직렬 포트를 통해 수신되며,이 전에 각 문자가 버퍼에 복사 될 때까지 기다리고 있습니다. 내 문제는 현재 데이터를 읽는 중 일부 문제가 있습니다. 문제가있는 곳을 확인하지 못합니다. 리턴 마차 나 줄 바꿈을 정확하게 인식하지 못하는 경우도 있지만 출력에 따라 달라집니다. 일단 완성되면 모든 것을 파일로 저장해야하므로이 사실을 알고 있습니다.하지만이 작업을 수행하려면 while 루프에서 i! = 5를 갖고 5 문자 만 읽어야합니다. 내가 20에 그것을 다시 응답하지 않으며 다른 것을 읽지 않는 것처럼 보입니다. (비록 내가 uart를 통해 데이터를 보내고 있습니다.)

X 시간 동안 읽은 다음 계속하기 위해 수정할 수있는 방법이 있습니까? 나머지 기능 은요?

편집 :

char route_data[512], route_buffer[200]; 

편집 2 :

char *str; 

좋아, 여기에 내가 사용자 입력에 읽는 쓴 함수입니다;

char* readInput(void){ 

    userinput = 0; 
    str = 0; 

    while((str=getc0())!='\r'){ 
     strcat(&userinput,&str); 

    } 
    return &userinput; 

} 

이렇게 불린다.

strcat(config.nodeid,readInput()); 

이것은 많이 불리지 만 그것은 내가 어떻게 부르는지의 한 예입니다. 그 다음 파일로 출력하고 100 % 시간 동안 작동합니다.

아마도 전체적인 문제를 설명하는 데 도움이 될 것입니다. 직렬 포트 (RX 및 TX)에 무선 모듈이 연결된 ARM 보드가 있습니다. 위의 readInput 함수는 텔넷으로 무선 모듈에 연결 한 사용자의 입력을 읽는 데 사용되며 ARM 보드가 사용자의 모든 입력을 읽을 수 있도록합니다. 지금 달성하려는 것은 무선 모듈에서 명령을 실행 한 후 입력을 읽는 것입니다. printf 문을 사용하면 명령문을 명령문에 넣음으로써 명령을 실행할 수 있습니다. 실현하기 위해 필요한 것은 무선 모듈의 출력을 읽는 것입니다. 이것이 내가 어려움을 겪고있는 곳입니다. 나는 약간의 산출물을 얻고있다. 그러나 그것은 예상되는 것이 아니고 매우 제한적이지만 모듈로부터 명백하게 무언가이다.

+0

route_buffer에 대한 정의를 보여주십시오. – Throwback1986

+0

'str'은 어떻게 정의되어 있습니까? 'route_buffer'는 어떻게 정의되어 있습니까? 'str'은'int'이어야하고,'getc0()'함수와 호환 될 수 있고'int'를'strcat()'에 넘길 수 없습니다! – pmg

+0

요청한 정보를 포함하도록 위 내용을 수정했습니다. 5 분을 주면 위의 내용을 수행 한 이유와이를 확인하기 위해 수행 한 작업이 확장됩니다. – Draineh

답변

3

str은 strcat()에 주소를 전달하는 끝 문자가 아니므로 불확실한 양의 데이터를 route_buffer에 연결합니다.

strcat()를 사용하면 여러 가지 이유로 나쁜 생각 일 수 있으며 특히 사용법이 좋지 않습니다. 버퍼 오버런에 대한 보호가 없으므로 strcat()은 불필요하게 문자열이 호출 될 때마다 route_buffer에서 문자열의 길이를 불필요하게 재확인해야합니다.

은 소폭 더 나은 솔루션은 다음과 같습니다 route_buffer는 NUL은 문자열을 종료 사실상 같은

int index = strlen(route_buffer) ; 
int ch ; 
while(index < sizeof(route_buffer) - 1 && (ch = getc0()) != '\r') 
{ 
    route_buffer[index] = ch ; 
    index++ ; 
} 
route_buffer[index] = 0 ; 

나는 여기에 원래 코드에서 가정의 숫자를 만들었습니다. 그것들은 당신의 디자인 결정입니다. 그들은 정확하거나 좋은 것일 수도 아닐 수도 있습니다.

더 나은 해결책은 수신 된 문자를 UART Rx 인터럽트 핸들러의 링 버퍼에 넣은 다음 읽기 기능이 버퍼에서 데이터를 비동기 적으로 가져 오는 것입니다. 그런 다음 필요한 경우 차단, baulking 및 제한 시간 액세스를 쉽게 구현할 수 있습니다. 버퍼에서 사용할 수있는 행 수를 미리 알 수 있도록 ISR에 버퍼 된 개행 수를 계산할 수도 있습니다. 또한 버퍼링을 사용하면 문자 오버런 및 데이터 손실을 방지하기 위해 코드를 제 시간에 UART 서비스에 대해 걱정할 필요가 없습니다.

시간 초과 동작을 원할 경우 getc0()의 while 루프와 회선 입력 루프에서 일부 타이머 소스를 추가로 테스트해야합니다.

+0

안녕하세요, 고마워요. 나는 당신이 이것을 게시 한 이후에 방대한 편집을했습니다. 나는 버퍼 오버런의 가능성을 고려하지 않았다. 바보. 나는 노트북을 꺼내 이것을 몇 분간 생각할 것입니다. 모든 세부 사항을 주셔서 감사합니다 – Draineh

+0

@Draineh, 당신의 편집은'char *'로 선언 된'str'을 보여줍니다. 그러나'getc0()'는'int'를 반환합니다. 그런 다음 strcat()에'& str' ('char **')을 전달합니다. 제공된 암시 적 캐스트는 마술처럼이 코드를 올바르게 만들지 않습니다! 귀하의 컴파일러는 분명 경고조차 발생하지 않습니다!? 그렇지 않으면 경고 수준을 더 높게 설정해야합니다. 경고를 오류로 간주하고 (가장 자주 발생하며 가난한 코드 또는 의심스러운 코드를 나타냄) 형식 캐스트로 모든 경고를 해결하려는 유혹을받지 않습니다. 그 오류를 해결하지 않지만 오히려 컴파일러에 대해 알려주지 말라. – Clifford

+0

왜 strcat()의 사용법이 좋지 않은지에 대한 주제에서 [this] (http://www.joelonsoftware.com)을 읽으십시오. /articles/fog0000000319.html). – Clifford