volatile

References

volatile 키워드에 대해서 찾아보게 된 계기는 ‘Head First Design Patterns’의 싱글톤 패턴에서 volatile을 사용하고 있었기 때문이었다.

C언어 문법 중 완전히 이해되지 않은 부분이 volatile이었는데, 오늘에야 그 의미를 이해하게 되었다. volatile의 의미는 컴파일 최적화를 하지 않는다는 것이다. 그것은 컴파일러의 최적화 옵션과 관련이 있다.

  • 코드는 순서대로 실행되지 않는다.
  • 코드대로 기계어로 변환되지 않는다.

아래는 위키에서 가져온 코드이다.

static volatile int foo;

void bar (void)
{
    foo = 0;

    while (foo != 255);
}

사실 위 코드는 foo값이 255가 될때까지 기다린다. 그러나 volatile 키워드가 없다면, 컴파일러는 아래와 같이 최적화한다.

void bar_optimized(void)
{
    foo = 0;

    while (true);
}

사실 컴파일러 입장에서는 명백하다. foo는 0이고 변경되지 않기 때문에 항상 while은 참이 되므로, foo를 비교할 필요없다고 여기게 된다. 그러나, 실제로는 하드웨어 인터럽트등을 통해 값이 변경될 수 있다는 것이다.
‘Head First Design Patterns’에서는 멀티스레딩에 대한 내용을 서술하면서, 위의 코드에서와 비슷한 상황을 설명하고 있다. 그러나 References의 마지막 링크에서는 조금 다른 이야기를 하고 있으므로 참조할 필요가 있다.

Unity를 이용한 TDD

Reference
  • Unity 의 examples/example_1

Unity는 C언어를 이용한 TDD framework이다. Embedded에 적용할 수 있도록 header file 2개와 c파일 하나로 구성되어 있다.
다만, Test Runner하는 부분이 성가신데, 이는 ruby script를 이용하여 해결할 수 있다.

다음과 같이 단순한 예제를 구성하였다.

/* add.h */
#include <stdint.h>
int32_t add(int32_t a, int32_t b);
/* add.c */
#include <stdint.h>

int32_t add(int32_t a, int32_t b)
{
    return (a+b);
}
/* test_add.c */
#include "add.h"
#include "unity.h"

void setUp(void)
{
    /* 생략시 에러 발생 */
}

void tearDown(void)
{
    /* 생략시 에러 발생 */
}

void test_add(void)
{
    TEST_ASSERT_EQUAL(7, add(3,4));
}

파일은 Unity중 필수적으로 필요한 것만 복사하여 구성하였다.

.
├── add.c
├── add.h
├── test_add.c
└── unity
    ├── generate_test_runner.rb
    ├── unity.c
    ├── unity.h
    └── unity_internals.h

1 directory, 7 files

컴파일 및 실행하는 방법은 다음과 같다.

ruby unity/generate_test_runner.rb test_add.c
gcc -Iunity unity/unity.c add.c test_add_Runner.c
./a.out

test_add.c:11:test_add:PASS
-----------------------
1 Tests 0 Failures 0 Ignored
OK

이러한 방법은 실제로 사용하기에는 다소 불편하다.

  • Test Runner를 만드는 방법이 복잡하다. ruby script를 이용하면 되지만, 번거롭고 ruby가 설치되어 있어야 한다.
  • Test Case가 변경되면, Test Runner도 같이 변경해주어야 한다.
  • shell command에서 명령을 내리기에는 손이 많이 간다.

Unity example에 포함된 makefile을 다음과 같이 수정하였다.

/* makefile */
# ==========================================
#   Unity Project - A Test Framework for C
#   Copyright (c) 2007 Mike Karlesky, Mark VanderVoord, Greg Williams
#   [Released under MIT License. Please refer to license.txt for details]
# ==========================================

UNITY_ROOT=./unity
C_COMPILER=gcc
TARGET=testAdd
SRC_FILES=$(UNITY_ROOT)/unity.c add.c test_add.c test_add_Runner.c
INC_DIRS=-I$(UNITY_ROOT)

CLEANUP = rm -f *.o ; rm -f $(TARGET)

all: clean default

default:
        ruby $(UNITY_ROOT)/generate_test_runner.rb test_add.c
        $(C_COMPILER) $(INC_DIRS) $(SRC_FILES) -o $(TARGET)
        ./$(TARGET)

clean:
        $(CLEANUP)

디렉토리 구조나 makefile을 좀 더 적절하게 변경하는 것은 추후에 추가할 예정이다.

그런데 example_1을 따라해보니, 실제로 매우 불편했다.

  • 나 스스로는 Test Runner를 만들지 못하겠다. script를 써야만 했다.
  • Test Group하나만 가능하다. 즉 Test Case 모음은 하나의 파일에만 존재해야 했다. Test Runner를 만들기 위해서 ruby scriptt로 2개의 Test Case 파일을 시도하면 에러가 발생했다. ( main( ) 함수가 2개 생기기 때문이다. )

이러한 문제는 example_2에서 해결되었다.

tmux 사용법

reference

tmux는 좀 더 개선된 screen이라 생각하면 된다.

용어
  • session : tmux 실행시 생성
  • window : 하나의 session에 여러개의 window 생성 가능
  • pane : 하나의 window안에 여러개의 pane으로 분할 가능
사용법

다음은 실행과 종료 방법이다.

$ tmux
$ exit  # 종료  또는 ctrl + d

session 명령

$ tumx new -s 세션이름 # 세션이름으로 생성 

ctrl + b + d  # 셔션을 유지한채로 나오기

$ tmus ls  # 세션 목록 보이기
$ tmux attach -t 세션명 # 세션으로 다시 들어가기

window 명령

ctrl + b + c # 새 window 생성
ctrl + b + & # window 삭제
ctrl + b + , # window 이름 변경
ctrl + b + window 번호 # window 이동
ctrl + b + n # window 이동, next
ctrl + b + p # window 이동, previous
ctrl + b + l # window 이동, last

pane 명령

ctrl + b + % # 가로 나누기
ctrl + b + " # 세로 나누기
ctrl + b + q # 특정 pane 이동

ctrl + b + o # pane 이동
ctrl + b + 방향기 # pane 이동

$ exit # 삭제 또는 ctrl + d
ctrl + b + x # pane 삭제

ctrl + b + [Alt] + 방향키 # 크기 조절

copy mode
처음 실행시에 copy mode의 키가 제대로 동작하지 않았다. 기본으로 emacs style로 되어 있어서 그런것이었다. vi style로 변경하면 잘 된다.
vi style을 적용하면, copy mode에서 이동하는 방향키도 i,j,k,l, ctrl-f, ctrl-b 를 사용할 수 있다.

# ~/.tmux.conf
# set-window-option -g mode-keys vi

ctrl + b + [ # copy mode 진입
space # copy 시작
Enter # copy 완료
ctrl + b + ] # paste

'Linux' 카테고리의 다른 글

tmux 3.2 설치 및 설정파일  (0) 2022.01.06
makefile의 phony  (0) 2013.05.07

+ Recent posts