😎 κ³΅λΆ€ν•˜λŠ” μ§•μ§•μ•ŒνŒŒμΉ΄λŠ” μ²˜μŒμ΄μ§€?

[파일 μ²˜λ¦¬μ™€ ν‘œμ€€μž…μΆœλ ₯] 터미널 μ œμ–΄λ‘œ ν™”λ©΄ ν˜ΈμΆœν•˜κΈ° tcgetattr & fcsetattr λ³Έλ¬Έ

πŸ‘©‍πŸ’» IoT (Embedded)/Raspberry Pi

[파일 μ²˜λ¦¬μ™€ ν‘œμ€€μž…μΆœλ ₯] 터미널 μ œμ–΄λ‘œ ν™”λ©΄ ν˜ΈμΆœν•˜κΈ° tcgetattr & fcsetattr

μ§•μ§•μ•ŒνŒŒμΉ΄ 2024. 1. 4. 20:24
728x90
λ°˜μ‘ν˜•

<μ„œμ˜μ§„ λ‹˜μ˜ 사물인터넷을 μœ„ν•œ λ¦¬λˆ…μŠ€ ν”„λ‘œκ·Έλž˜λ° with λΌμ¦ˆλ² λ¦¬νŒŒμ΄ μ„œμ μ„ μ°Έκ³ ν•΄μ„œ μž‘μ„±ν•˜μ˜€μŠ΅λ‹ˆλ‹€ :-)>

 

⭐ ν„°λ―Έλ„μ˜ κΈ°λ³Έ μ œμ–΄

kbhit() ν•¨μˆ˜λŠ” ν‚€λ³΄λ“œμ˜ μž…λ ₯을 κ°μ§€ν•˜λŠ” ν•¨μˆ˜ (μœ λ‹‰μŠ€μ—μ„œ fcntl() ν•¨μˆ˜μ™€ ν„°λ―Έλ„ μ œμ–΄λ‘œ κ΅¬ν˜„ κ°€λŠ₯)

터미널은 λ‘œμ»¬μ΄λ‚˜ λ„€νŠΈμ›Œν¬λ₯Ό ν†΅ν•΄μ„œ μ›κ²©μœΌλ‘œ μ—°κ²°λ˜μ–΄ μœ λ‹‰μŠ€ μ‹œμŠ€ν…œκ³Όμ˜ λŒ€ν™”λ₯Ό μœ„ν•΄ μ‚¬μš©λ˜λŠ” λ””λ°”μ΄μŠ€λ‘œ /dev/tty λ””λ°”μ΄μŠ€ 파일 μ‚¬μš©ν•¨

ν„°λ―Έλ„μ˜ κΈ°λ³Έ μ œμ–΄λŠ” termios ꡬ쑰체와 κ΄€λ ¨ ν•¨μˆ˜λ“€μ„ μ‚¬μš©ν•¨

(화면에 좜λ ₯ν•  수 없도둝 터미널 μ œμ–΄ ν•¨μˆ˜μΈ tcgetattr, tcsetattr μ΄μš©ν•΄μ„œ 터미널에 λŒ€ν•œ 값을 κ°€μ Έμ˜€κ±°λ‚˜ 섀정함)

// kbhit() ν•¨μˆ˜λŠ” ν‚€λ³΄λ“œμ˜ μž…λ ₯을 κ°μ§€ν•˜λŠ” ν•¨μˆ˜ (μœ λ‹‰μŠ€μ—μ„œ fcntl() ν•¨μˆ˜μ™€ 터미널 μ œμ–΄λ‘œ κ΅¬ν˜„ κ°€λŠ₯)
// 터미널은 λ‘œμ»¬μ΄λ‚˜ λ„€νŠΈμ›Œν¬λ₯Ό ν†΅ν•΄μ„œ μ›κ²©μœΌλ‘œ μ—°κ²°λ˜μ–΄ μœ λ‹‰μŠ€ μ‹œμŠ€ν…œκ³Όμ˜ λŒ€ν™”λ₯Ό μœ„ν•΄ μ‚¬μš©λ˜λŠ” λ””λ°”μ΄μŠ€λ‘œ /dev/tty λ””λ°”μ΄μŠ€ 파일 μ‚¬μš©ν•¨
// ν„°λ―Έλ„μ˜ κΈ°λ³Έ μ œμ–΄λŠ” termios ꡬ쑰체와 κ΄€λ ¨ ν•¨μˆ˜λ“€μ„ μ‚¬μš©ν•¨
// (화면에 좜λ ₯ν•  수 없도둝 터미널 μ œμ–΄ ν•¨μˆ˜μΈ tcgetattr, tcsetattr μ΄μš©ν•΄μ„œ 터미널에 λŒ€ν•œ 값을 κ°€μ Έμ˜€κ±°λ‚˜ 섀정함)
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <termios.h>

int kbhit(void) {
    // 터미널에 λŒ€ν•œ ꡬ쑰체
    struct termios oldt, newt;
    int ch, oldf;
    
    // ν˜„μž¬ 터미널에 μ„€μ •λœ 정보 κ°€μ Έμ˜΄
    tcgetattr(0, &oldt);
    newt = oldt;
    // μ •κ·œ λͺ¨λ“œ μž…λ ₯κ³Ό 에코λ₯Ό ν•΄μ œ (ICANON μ •κ·œλͺ¨λ“œλ‘œ μž…λ ₯이 μ΄λ€„μ§€κ²Œ 함, ECHO λŠ” ν‚€λ³΄λ“œλ‘œ μž…λ ₯ν•œ λ‚΄μš©μ„ λͺ¨λ‹ˆν„°λ‘œ 좜λ ₯ν•˜λ„λ‘ 함)
    newt.c_lflag &= ~(ICANON | ECHO);
    // μƒˆλ‘œμš΄ κ°’μœΌλ‘œ 터미널 μ„€μ • (TCSANOW λ°”λ‘œ 터미널에 λ³€κ²½λœ 속성이 μ μš©λ˜λ„λ‘ 함)
    tcsetattr(0, TCSANOW, &newt);
    oldf = fcntl(0, F_GETFL, 0);
    // μž…λ ₯을 λ…ΌλΈ”λ‘œν‚Ή λͺ¨λ“œλ‘œ μ„€μ •
    fcntl(0, F_SETFL, oldf | O_NONBLOCK);
    // getchar() : ν‚€λ³΄λ“œλ‘œ μž…λ ₯된 λ¬Έμžκ°€ 화면에 μžλ™μœΌλ‘œ 좜λ ₯됨
    ch = getchar();

    if (ch != EOF) {
        // μ•žμ—μ„œ 읽으며 κΊΌλ‚Έ 문자λ₯Ό λ‹€μ‹œ λ„£λŠ”λ‹€
        ungetc(ch, stdin);
    }
    return 0;
}

int main(int argc, char **argv) {
    for (int i = 0;; i++) {
        if (kbhit()) {
            switch(getchar()) {
                case 'q':
                    goto END;
                    break;
            };
        }
        // ν˜„μž¬ μΉ΄μš΄νŠΈν•œ 숫자λ₯Ό 좜λ ₯
        printf("%20d\t\t\r", i);
        // 100λ°€λ¦¬μ΄ˆ λ™μ•ˆ μž μ‹œ μ‰°λ‹€
        usleep(1000);
    }
END:
    printf("Good Bye!\n");
    return 0;
}

// => μˆ«μžκ°€ μ œμžλ¦¬μ—μ„œ μ¦κ°€ν•œλ‹€
// ν•œ μ€„μ—μ„œλ§Œ 숫자의 증가λ₯Ό ν‘œμ‹œν•˜κΈ° μœ„ν•΄ "\r" μ‚¬μš©ν•¨

/*
gani@gani:~/raspi/File $ gcc -o hitkey hitkey.c
gani@gani:~/raspi/File $ ./hitkey
                8580
*/
gcc -o hitkey hitkey.c
./hitkey

μ˜€μž‰. q λˆ„λ₯΄λ©΄

Good Byte κ°€ λ‚˜μ™€μ•Όλ˜λŠ”λ°

μ™œ q 인식도 μ•ˆλ˜λŠ”κ±°μ₯¬~~? 클클클클

728x90
λ°˜μ‘ν˜•
Comments