VPOS 에 대한 궁금증과 그 궁금증을 풀기 위해서 여러 테스트를 했고, 그에 대한 결과를 정리했다.

VPOS 수행 도중에 PC 값을 0x0 이나, 0x30000000 으로 지정하면 어떻게 될까?

0x0 나 0x30000000 이라 함은 초기화 루틴을 다시 수행하는 것이다.
하지만, 0x0 의 경우, vpos_bootloader.S 수행 도중에 'undefined_instruction' 인터럽트를 발생시킨다.

	mrc	p15, 0, r1, c1, c0, 0		@ read ctrl register    // 바로 여기!!
	orr	r1, r1, #0xc0000000			@ Asynchronous  
	mcr	p15, 0, r1, c1, c0, 0		@ write ctrl register

0x30000000 의 경우, HAL_arch_startup.S 수행 도중에 'undefined_instruction' 인터럽트가 발생한다.

        mcr     p15, 0, r0, c7, c7, 0       // 바로 여기!!
        mcr     p15, 0, r0, c8, c7, 0   
        mrc     p15, 0, r0, c1, c0, 0

두 군데, 모두 캐시 락다운 하는 부분이다.

두 개의 쓰레드를 시작했을 때, 어떻게 동작하는가?

현재의 VPOS 는 처음에 하나의 쓰레드(VPOS_SHELL)를 생성하고, 그 이후에 명령어를 통해서, 또 하나의 자식 쓰레드를 생성해서 수행하는 방식이다.
크게 우선순위가 동일한 경우와 다른 경우를 나누어서 설명하겠다.
두 개의 쓰레드의 우선순위가 동일하다면, 주기적으로 호출되는 vk_scheduler() 에 의해서 번갈아 가면서 수행된다.
두 개의 쓰레드의 우선순위가 다르다면, 우선순위가 높은 쓰레드만 수행이 된다.

컴파일 시의 옵션에 대해서 알고 싶다면?

Makefile 에서 아래의 부분이 컴파일 시에 자동으로 부여되는 옵션들이다.

CFLAGS  = -O0 -Wall -Wstrict-prototypes -fPIC -msoft-float -mshort-load-bytes -nostdinc -nostartfiles -nostdlib -march=armv4 -mtune=arm9tdmi -fomit-frame-pointer -fno-builtin -mapcs-32 $(INCLUDE)

현재 vpos 의 툴체인이 2.95.3 이기 때문에, 3.x 이나 4.x 에는 없는 옵션일 수 있다는 것을 염두하기 바란다.

옵션 설명
-O0 최적화 옵션 중(1~3) 에서 가장 낮은 수준인 0 으로 최적화됨
-Wall GCC 의 경고 옵션 대부분이 활성화됨
-Wstrict-prototypes GCC 는 부호 없는 형이나 열거형을 같은 크기의 부호 없는 형으로 변환하는게 아니라 부호 있는 형으로 변환하는 경우에 경고 메세지를 출력한다
-fPIC GCC 는 공유 라이브러리로 사용할 수 있는 위치에 무관한 코드를 만든다. 이 옵션은 동적 링킹을 지원하는 타겟 플랫폼에서만 의미가 있는데,응용프로그램의 전역 할당 테이블의 최대 크기로 기계 고유의 값(주로 16K, 32K)을 사용한다. 이 옵션이 제대로 동작하지 않는다는 것을 알려주는 에러 메세지가 나온다면 이 옵션 대신에 -fPIC 옵션을 사용해야 한다
-msoft-float GCC 는 부동 소수점에 대해 라이브러리 호출을 담고 있는 출력을 생산한다. 이 라이브러리는 GCC 의 일부분으로 포함되어 있지는 않지만, 보통 타겟 시스템에 있고, 사용 가능하다면 타겟 머신에서 C 로더에 의해 해결되어야 한다. 이 옵션과 함께 크로스 컴파일을 할 때, 호스트 시스템에서 함수 스터브를 가지고 있는 적절한 라이브러리를 제공해야 한다. 그렇지 않다면 함수 호출은 해결되지 않은 것으로 표시될 것이다
-mshort-load-bytes GCC 는 MMU 에서 정렬 트랩이 켜져 있을 때 정렬되지 않은 접근을 연속된 바이트 접근으로 바꿔서 트랩을 발생시키지 않는 코드를 생성한다. 이 옵션은 ARM 4 이전의 ARM 프로세서들만 관련이 있고, 그 이후 프로세서에서는 무시된다. ARM 4 이후 프로세서에는 메모리에서 직접 하프 워드를 접근할 수 있는 명령어가 있기 때문이다. ARM 4 이전의 ARM 아키텍처들은 메모리에 저장되어 있는 하프 워드 오브젝트들을 접근하는 명령어를 가지고 있지 않다. 그렇지만 ARM 아키텍처의 기능을 사용해서 주소가 정렬되어 있지 않는 경우에도 메모리에서 워드를 읽을 수 있다. 자료가 로드될 때 프로세서 코어가 자료를 회전시키기 때문이다. 이 옵션을 지정하면 GCC 는 그렇게 정렬되지 않은 접근이 MMU 트랩을 일으킨다는 것을 알고, 그것을 연속된 바이트 접근으로 바꾼다. 컴파일러는 주소가 워드 경계로 정렬되어 있다면 하프 워드 데이터를 읽기 위해서 워드를 접근하는 방식을 사용할 수 있다. GCC 3.x 기준으로 이 옵션은 -malignmet-traps 옵션에 대한 별칭인데, 더 이상 쓰이지 않는다
-nostdinc 이 C 언어 디렉토리 검색 옵션을 지정하면 전처리기가 #include <file> 구문을 사용해서 지정한 헤더 파일을 표준 시스템 디렉토리에서 검색하지 않도록 할 수 있다
-nostartfiles 링크할 때 표준 시스템 스타트업 파일을 사용하지 않는다. -nostdlib 를 함께 지정하지 않으면 시스템 라이브러리는 사용한다
-nostdlib 링크할 때 표준 시스템 스타트업 파일과 라이브러리를 사용하지 않는다(-nostartfiles - nodefaultlibs 를 지정한 것과 동일하다)
-march=armv4 이 옵션을 사용하면 컴파일하는 코드에 대해 시스템에서 사용하는 ARM 아키텍처를 지정할 수 있다. -mcpu 옵션처럼 GCC 는 어셈블리 코드를 생성할 때 사용할 수 있는 명령어를 결정하는 데 이 이름을 사용한다. 이 옵션은 -mcpu= 옵션과 함께 혹은 대신 사용할 수 있다. name 으로 가능한 값은 armv2, armv2a, armv3, armv3m, armv4, armv4t, armv5, armv5t, armv5te 이다
-mtune=arm9tdmi 이 옵션을 지정하면 GCC 는 생성된 코드를 -mcpu 옵션을 사용해서 지정한 ARM 프로세서에서 사용 가능한 명령어들만을 사용하면서 name 이라는 ARM 프로세서에 맞게 조정한다. 몇몇 ARM 기반의 시스템에서 이 두 개의 옵션을 함께 사용하면 더 나은 성능이 나올 수 있다
-fomit-frame-pointer 이 최적화 옵션을 지정하면 GCC 는 프레임 포인터가 필요하지 않는 함수에 대해서 프레임 포인터를 저장하지 않는다. 다른 코드에서 사용할 수 있는 추가적인 레지스터를 확보하는 것 이외에도, 이 옵션은 프레임 포인터를 저장하고 설정하고 복구하는 데 필요한 명령어를 제거해서 코드 사이즈와 실행 경로를 줄어준다. 이 옵션은 표준 함수 호출 방식에 프레임 포인터의 할당과 설정이 항상 포함되어 있는 경우에는 아무런 기능을 하지 않는다. 특별한 플랫폼을 위한 GCC 를 빌드할 때, FRAME_POINTER_REQUIRED 매크로가 특정 타겟 시스템에서 이 옵션이 의미가 있는지 아닌지를 결정한다
-fno-builtin 이 C 옵션을 지정하면 GCC 는 접두사로 builtin_ 으로 시작하지 않는 내장 함수를 인식하지 않는다. GCC 로 컴파일한 C++ 응용프로그램의 경우에는 항상 이러한 규칙이 적용된다. 직접 GCC 의 내부 함수를 호출하려면 builtin_ 접두사가 붙은 함수를 호출해야 한다
-mapcs-32 이 옵션을 지정하면 GCC 는 32 비트 프로그램 카운터를 가진 ARM 프로세서를 위한 코드를 생성한다. 생성된 코드는 APCS 32 비트 옵션에 대해 호출 표준을 따른다. -mapcs-32 옵션은 이전 GCC 배포판에서 제공 되었던 -m6 옵션을 대신한다

이 옵션을 지정하면 출력 파일에서 쓰는 함수 호출 방식도 바뀌게 된다. 그렇기 때문에 프로그램의 모든 코드와 참조하는 모든 라이브러리들을 이 옵션으로 컴파일해야 한다. 또 이 옵션을 사용하려면 GCC 와 함께 오는 libgcc.a 라이브러리도 이 옵션으로 컴파일 해야 한다.

보통 GCC 는 내장 함수를 좀 더 효율적으로 다루는 특별한 코드를 생성한다. 몇몇 경우에 내장 함수는 인라인 코드로 바뀌어서, 디버깅할 때 브레이크포인트를 잡거나 똑같은 함수를 제공하는 외부 라이브러리와 링킹할 때 어려운 경우가 있다.
C, Objective C 응용프로그램에서 덜 제한적인 -fno-builtin-function 옵션을 사용해서 특정 내장 함수를 선택적으로 사용하지 않을 수 있다. 이 옵션은 그러한 내장 함수가 없다면 무시된다. 비슷하게 -fno-builtin 옵션을 사용해서 모든 함수를 사용하지 않고, 다음 예처럼 함수 호출을 특정 내장 함수로 선택할 수 있다.

#define strcpy(d,s)         __builtin_strcpy((d),(s))

컴파일시 -g 옵션을 추가했는데도 불구하고, 디버깅 장비에서 소스 파일이 보이지 않을 때

이 때는 Makefile 의 -g 옵션의 위치가 중요하다. 무조건 아래와 같이

CFLAGS = -g -O0 ....

가장 앞에 적어준다.

  • computer/rtcclab/vpos_faq.txt
  • Last modified: 3 years ago
  • by likewind