키보드를 만듭시다. 어때요~ 참 쉽죠? (8)

나빌레라의 이미지

키보드 핵심 기능을 하는 펌웨어는 모두 구현했다. 지금까지 펌웨어만으로도 키보드 사용에는 문제 없다. 앞으로는 부가 기능과 편의 기능 구현에 대한 이야기를 쓸 것이다. 없어도 되지만 있으면 좋은 그런 기능들이다. 첫 번째로 키맵 에디터다.

키맵 에디터를 어떻게 만들까

키보드 프로젝트를 구상 할 때부터 키맵은 변경 가능하도록 만들 생각이었다. 그래서 키맵 에디터를 어떻게 만들지 꽤 고민했다. 우선 키맵 에디터가 만족해야 할 조건은 다음과 같다.

  • 사용법이 직관적일것
  • 멀티 플랫폼 일것

위 두 조건을 먼저 세웠다. 사용법이 직관적이려면 당연히 마우스로 클릭 클릭해서 키맵을 구성할 수 있어야 한다. 멀티 플랫폼이 되려면 어떻게 해야 할까... 처음에는 파이썬으로 키맵 에디터를 만드는 방법을 고려해 봤다. 그런데 그러면 직관적인 사용법을 구현하기가 어려웠다. 파이썬에서 멀티 플랫폼 GUI를 만들 수도 있으나 그건 삽질이 너무 컷다. C#+.Net를 사용하는 방법도 생각해 봤다. 의외로 여러 플랫폼에서 잘 동작하는 GUI 어플을 가장 쉽게 만드는 방법은 C#+.Net으로 만드는 것이다. .Net이 Mono 프로젝트를 통해서 리눅스를 비롯해 유닛스, OSX등에서 실행되기 때문이다.

이런저런 옵션을 생각해 보다가 결국 HTML이 최선이라고 결론 내렸다. 쉽고 멀티 플랫폼이다.

Thank you TMK

펌웨어도 그렇지만 키 맵 에디터도 맨땅부터 만들 생각은 없다. 그래서 또 깃허브와 구글에서 기존에 구현된 적당한 키맵 에디터를 찾아 봤다. 몇 개 눈에 띄는 것들을 골라서 실행해 보고 코드도 살펴봤다. 그러다가 정말 괜찮은 것을 찾았다. TMK 프로젝트에서 서브 브랜치로 관리하는 키맵 에디터가 있었다. 완전히 딱 내 마음에 들었다. 심지어 구현도 직관적이고 간단했다. 게다가 오픈 소스다.

http://www.tmk-kbd.com/tmk_keyboard/editor/

위 링크를 누르면 어떻게 생긴 것인지 알 수 있다. 나는 TMK 키맵 에디터 소스 코드를 수정해서 내가 만든 키보드 키맵 에디터를 만들기로 결정했다.

키맵 에디터

내가 원하는 모습으로 키맵 에디터를 만들려면 HTML과 CSS와 자바 스크립트 코드를 조금 수정해야 한다. 재미 없는 웹 프로그래밍 과정이니 코드는 생략하겠다. 최종적으로 아래 같은 모습으로 키맵 에디터를 만들었다.

크게 상하단으로 인터페이스를 구분해서 본다. 상단에는 이제 몇번 나와서 익숙한 내가 만든 키보드 레이아웃이 있다. 하단에는 키 종류가 있다. 사용법은 직관적으로 어떻게 해야 할지 알것같지 않은가? 상단 키보드 레이아웃에서 변경하고 싶은 키를 선택하고 하단 키 종류에서 키를 누르면 바뀐다.

키맵 바이너리 설계

키맵 자료 구조는 2차원 배열 테이블 형태로 6x14 크기다. 바이너리로 직렬화(serialize)하면 그냥 84바이트짜리 연속 데이터다. 이게 키맵 본체고 키맵 본체 데이터 무결성 체크(integrity check) 용으로 CRC32 값을 붙이겠다.

typedef struct KeymapFile
{
    uint32_t    crc;
    uint8_t     keymap[NUM_LAYERS][TOTAL_KEY_MAP_SIZE];
} KeymapFile_t;

위와 같은 구조체가 도출된다. 그래서 키맵 업데이트 함수에서는 keymap 멤버 변수 값을 CRC32 계산 함수로 보내서 CRC32 값을 받고 그 값을 crc 멤버 변수 값과 비교해 같으면 키맵을 업데이트하고 다르면 키맵이 손상되었다고 간주하고 기본 키맵 값을 사용한다.

키맵 업데이트

키맵 데이터는 STM32F103의 내장 플래시 메모리에 저장한다. STM32F103은 모델별로 64KB ~ 128KB 크기의 NOR 플래시를 내장하고 있다. 이 플래시에 펌웨어를 저장하고 남는 공간은 이렇게 펌웨어 목적에 맞게 쓰는 것이다.

void LoadKeymap(void)
{
    KeymapFile_t saved_keymap = {0};
    uint32_t crc = 0;
 
    if (ReadKeyMapFromFlash(&saved_keymap, sizeof(KeymapFile_t)))
    {
        crc = GetCrc32((uint8_t*)saved_keymap.keymap, sizeof(saved_keymap.keymap));
        debug_printf("CRC(%x -- %x)\n", saved_keymap.crc, crc);
        if (saved_keymap.crc == crc)
        {
            memncpy((uint8_t*)sKeymap_buffer_layer0, (uint8_t*)saved_keymap.keymap[0], TOTAL_KEY_MAP_SIZE);
            memncpy((uint8_t*)sKeymap_buffer_layer1, (uint8_t*)saved_keymap.keymap[1], TOTAL_KEY_MAP_SIZE);
        }
    }
}

위 코드가 플래시에서 키맵 데이터를 읽어서 업데이트하는 함수 코드다. 간단하다. ReadKeyMapFromFlash() 함수로 플래시에서 키맵 데이터를 읽는다. GetCrc32() 함수로 saved_keymap.keymap 변수 포인터를 넘겨서 CRC32 값을 계산한다. 그리고 계산 결과를 saved_keymap.crc 값과 비교해서 같으면 플래시에서 읽은 키맵 데이터에 문제 없다고 보고 sKeymap_buffer_layer0과 sKeymap_buffer_layer1를 덮어 쓴다.

sKeymap_buffer_layer0과 sKeymap_buffer_layer1를 덮어쓰면 키맵 폴링 처리 과정에서 읽는 값이 변경되므로 호스트로 전달하는 키 스캔 코드 값도 달라진다. 결과적으로 키보드 키 맵을 사용자가 설정할 수 있다.

File attachments: 
첨부파일 크기
Image icon keymap_editer.png70.37 KB

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.