Linux 시스템에서 bash를 사용하여 마이크로 컨트롤러에서 일부 문자열 데이터를 보내고 받으려고 합니다.
이 시점에서 내 마이크로 컨트롤러의 코드는 다음과 같습니다.
void UART_help_cmd_handler()
{
printf("Available commands:\n");
printf("search - starts search and returns device addresses\n");
printf("help - prints this help\n");
// these characters can't stop cat
EUSART2_Write(0);
EUSART2_Write(0x03);
EUSART2_Write(0x04);
}
이것은 리눅스 쪽입니다:
#!/bin/bash
echo -ne '\x02help\x03' > /dev/ttyUSB0; cat /dev/ttyUSB0;
나는 또한 다음을 시도했습니다.
echo -ne '\x02help\x03' > /dev/ttyUSB0; stdbuf -i 0 -o 0 cat /dev/ttyUSB0
문제는 cat
마이크로 컨트롤러 측에서 멈출 수 없다는 것입니다.
마이크로컨트롤러에서 문자 전송을 시도해 보았고 -1
0x03을 사용해 보았습니다.
답변1
알았어, 알아냈어. 원하는 동작(uart와 bash 간의 명령->응답)을 얻기 위해 다음과 같이 작성했습니다.
마이크로컨트롤러 측:
void UART_help_cmd_handler()
{
// this delay prevents buffer overflow on linux side if bash is too slow
// see "However" section below
__delay_ms(100);
printf("Available commands:\n");
printf("search - starts search and returns device addresses\n");
printf("help - prints this help\n");
// second newline to mark end of transmission
// that cat command can read
printf("\n");
}
**얼굴을 때리세요**
#!/bin/bash
# send-command-read-response.sh
# send command
# (in my case microcontroller needs 0x02 byte to find start of command
$ and 0x03 byte for end of command
echo -ne "\x02${1}\x03" > /dev/ttyUSB0;
# read lines one by one until "" (empty line)
file="/dev/ttyUSB0"
terminator=""
while IFS= read line
do
if [ "$line" = "$terminator" ]; then
break
else
echo "$line"
fi
done <"$file"
하지만:
- 마이크로 컨트롤러의 반응이 매우 빠른 경우 - 때로는 bash가 하드웨어 uart 버퍼가 가득 차기 전에 이를 소모할 만큼 빠르게 "읽기" 명령을 실행할 수 없으므로 더티 딜레이를 추가해야 합니다.
하드웨어 흐름 제어를 사용할 수 있다면 "빠른 마이크로 컨트롤러 응답" 문제가 해결될 수도 있지만 확실하지 않습니다.
bash에서 시간 초과를 처리하는 방법을 찾을 수 없습니다(마이크로 컨트롤러가 어떤 이유로 응답하지 않는 경우).
마침내
- @mosvy가 내 질문에 대한 의견에 썼듯이 bash는 직렬 통신에 적합한 도구가 아닙니다.
- 하드웨어 흐름 제어가 가능하다면 bash에서 양방향 직렬 통신을 처리할 수 있을 것이라고 생각합니다. 시간 초과를 설정할 수 있지만
stty
이를 구현하려면 너무 많은 노력이 필요할 것 같습니다. - 시간 초과 및 기타 오류를 처리하는 간단한 애플리케이션을 작성했습니다.
Bash 스크립트를 허용하는 일부 대형 웹 애플리케이션에서 bash 스크립트를 교체해야 하지만 추가 바이너리는 "반갑지 않습니다". 때문에 C/C++ 애플리케이션을 피하려고 합니다.