TASKING 사용자 가이드
목차
Overview
이 문서는 TASKING 컴파일러 사용자를 위한 매뉴얼로 TASKING Tricore VX-toolset 기반으로 작성되었습니다.
Tricore에서 정의하는 데이터 타입 및 타겟 메모리 관리를 위한 LSL 파일을 작성방법과 활용 예를 소개합니다.
버전에 따라, 사용법 및 적용 가능 옵션등에 차이가 있을 수 있으므로, 각 버전별 매뉴얼을 추가로 참고하시기 바랍니다.
(설치폴더/ctc/doc/ctc_user_guide.pdf)
Tricore의 C Language
데이터 타입
C Type |
Size (bit) |
Align |
Limit Range |
_Bool |
1 |
8 |
[0 or 1] |
signed char |
8 |
8 |
[-27, 27-1] |
unsigned char |
8 |
8 |
[0, 28-1] |
short |
16 |
16 |
[-215, 215-1] |
unsigned short |
16 |
16 |
[0, 216-1] |
int |
32 |
16 |
[-231, 231-1] |
unsigned int |
32 |
16 |
[0, 232-1] |
enum |
8 16 32 |
8 16 |
[-27, 27-1] or [0, 28-1] [-215, 215-1] or [0, 216-1] [-231, 231-1] |
long |
32 |
16 |
[-231, 231-1] |
unsigned long |
32 |
16 |
[0, 232-1] |
long long |
64 |
32 |
[-263, 263-1] |
unsigned long long |
64 |
32 |
[0, 264-1] |
_Float16 (10-bit mantissa) |
16 |
16 |
[-65504.0F,-6.103515625E-05] [+6.103515625E-05,+65504.0F] |
float (23-bit mantissa) |
32 |
16 |
[–3.402E+38, –1.175E-38] [+1.175E-38, +3.402E+38] |
double long double (52-bit mantissa) |
64 |
32 |
[-1.797E+308, -2.225E-308] [+2.225E-308, +1.797E+308] |
_Imaginary float |
32 |
16 |
[–3.402E+38i, –1.175E-38i] [+1.175E-38i, +3.402E+38i] |
_Imaginary double _Imaginary long double |
64 |
32 |
[-1.797E+308i, -2.225E-308i] [+2.225E-308i, +1.797E+308i] |
_Complex float |
64 |
32 |
real part + imaginary part |
_Complex double _Complex long double |
128 |
32 |
real part + imaginary part |
__sfract |
16 |
16 |
[-1, 1> |
__fract |
32 |
32 |
[-1, 1> |
__laccum |
64 |
64 |
[-131072, 131072> |
※ 열거형 상수 (enum) : 컴파일러는 정수형 자료형 (char, unsigned char, short, unsigned short or int) 중 가장 작고 적절한 자료형을 선택하여 사용한다. (예외 – C Compiler option중 --integer-enumeration 을 사용하면 항상 32-bit 정수 자료형을 사용한다.)
※ 복소수 ( _Complex [float, double, long double] )
- #include <complex.h> 로 complex.h 헤더파일 포함
- Imiginary 허수 표현 방법
자료형 |
double |
float |
long double |
허수 변환 함수 |
cimag |
cimagf |
cimagl |
(예) 3.5 + 2.1i 복소수 표현 방법
_Complex float tmp = 3.5 + cimagf(2.1);
※ 고정 소수점 연산 ( __sfract, __fract, __laccum )
1. __sfract 는 16비트 사이즈로 범위는 -1이상 1미만 표현 가능
2. __fract 는 32비트 사이즈로 범위는 -1이상 1미만 표현 가능
3. __laccum은 64비트 사이즈(18bit는 정수부, 46bit는 소수부) 로 -2^17이상 2^17미만 표현 가능
메모리 ACCESS 방식
한정자 |
설명 |
Location |
최대 사이즈 |
포인터 사이즈 |
섹션 타입(prefix) |
__near |
Near data, 직접 주소 지정 |
256MB블락 中 첫번째 16kB |
16KB |
32-bit |
neardata(.zdata) nearrom(.zrodata) nearbss(.zbss) nearnoclear(.zbss) |
__far |
Far data, 간접 주소 지정 |
Anywhere |
제한없음 |
32-bit |
fardata(.data) farrom(.rodata) farbss(.bss) farnoclear(.bss) |
__a0 |
초기화 / 비초기화, 상수 data |
Sign-Extended 16-bit offset, A0 Addr 기준 |
64KB |
32-bit |
a0data(.data_a0) a0bss(.bss_a0) a0rom(.rodata_a0) |
__a1 |
초기화 / 비초기화, 상수 data |
Sign-Extended 16-bit offset, A1 Addr 기준 |
64KB |
32-bit |
a1rom(.rodata_a1) a1data(.data_a1) a1bss(.bss_a1) |
__a8 |
초기화 / 비초기화, 상수 data |
Sign-Extended 16-bit offset, A8 Addr 기준 |
64KB |
32-bit |
a8data(.data_a8) a8rom(.rodata_a8) a8bss(.bss_a8) |
__a9 |
초기화 / 비초기화, 상수 data |
Sign-Extended 16-bit offset, A9 Addr 기준 |
64KB |
32-bit |
a9data(.data_a9) a9rom(.rodata_a9) a9bss(.bss_a9) |
※ TASKING 5.x 버전에서는 RAM은 a0만 사용 가능하고, ROM은 a1만 사용 가능하도록 분리되어 있음)
※ TASKING 6.x 버전부터는 a0, a1, a8, a9 모두 ROM과 RAM 영역으로 사용 가능하지만,
RAM과 ROM을 동시에 배치할 수는 없음 (Offset 크기가 제한되어 있기 때문)
※ 6.x에서 변경된 Prefix : (.sdata(5.x) →.data_a0(6.x) .ldata(5.x) → .rodata_a1(6.x))
Absolute Addressing (abs18)
Translation 규칙에 의해 18-bit Address를 32-bit Address로 변환 가능하기 때문에 직접 주소 접근 방식으로 1개의 Instruction만을 사용하여 메모리 접근이 가능
※ Translation 규칙 (Infineon Tricore Architecture 문서 참조)
① 처음 4bit : Segment 페이지(256MB)의 시작 번호 (Segment: 0~15 (4bit))
② 중간 14bit : 모두 0 으로 가정. 이 규칙을 통해 32-bit Full Address로 변환 가능
③ 끝 14bit : Near Data로 사용 가능한 주소의 크기 (14Bit = 16KB)
→ Near Data는 각 0~15의 Segement(256MB)별로 16KB 사용 가능
A0/ A1/ A8/ A9 Memory Access (Base + Offset(16bit) Addressing )
- Base + Offset(2Byte) Addressing : A0/A1/A8/A9 레지스터를 Base Address로 고정하고,
16-bit-Sign-Extended (64KB)의 오프셋으로 2개의 Instruction을 사용하여 접근할 수 있는 방식
예) A0의 Base Addr을 0x70010000로 맵핑하는 방법
: 링커 옵션에 -DA0_START_ADDRESS=0x70010000 을 설정
: A0 어드레스에 들어가는 값은 0x70018000이 된다.
(오프셋 (Signed-16bit) : ±0x8000 ( 64KB))
한정자를 이용한 메모리 접근 방식 정의
- 위 테이블의 Qualifier 참조
예) __near int var1 = 3; 으로 전역 변수를 선언 (test_project.c)
→ .zdata.test_project.var1 의 섹션 이름으로 생성되고, 직접 주소 접근 방식으로 메모리 Access
컴파일 옵션을 이용한 메모리 접근 방식 정의 (전역적으로)
* 전역적용: -default-near(a0/a1)-size=[value(Threshold)]
- 컴파일 옵션에 –default-near-size=[value] 적용하면 컴파일러가 자동으로 value와 같거나
작은 변수들을 Near 영역에 배치하게됨
- 이 옵션은 a0/ a1옵션보다 near옵션이 우선적으로 적용됨
예) -default-near-size=4, –default-a0-size=8 라면,
4바이트보다 작은 변수는 Near Data 방식으로
4바이트보다 크고 8바이트보다 작은 변수는 A0 방식의 메모리 접근방식을 사용하게됨
* 부분적용: #pragma default_near(a0/a1)_size [value(Threshold) | restore | default]
-사이즈 상관없이 모두 A0로 배치하는 방법
#pragma default_a0_size
#pragma default_a0_size restore
-#pragma 안의 모든 변수가 A0방식의 .sdata*와 .sbss*로 사용됨 (Test in TASKING 5.x)
- 지정한 사이즈보다 작거나 같을 경우에만 A0로 배치하는 방법
#pragma default_a0_size <value>
#pragma default_a0_size restore
- 지정한 값인 2보다 작은 test_char1만 A0방식인 .sbss* 섹션명으로 생성됨
메모리 접근 방식 성능 비교 (Instruction Level)
* FAR (일반적) 방식의 메모리 접근 방법 -> 간접 주소로의 메모리 접근 방식
* A0 방식의 메모리 접근 방법 -> A0기준 옵셋 주소로의 메모리 접근 방식
* NEAR 방식의 메모리 접근 방법 -> 직접 주소로의 메모리 접근 방식
※ 메모리 접근 수행 속도 (d15로의 데이터 로딩에 필요한 인스트럭션 수)
- FAR(3개) < A0(2개) < NEAR(1개)
- NEAR가 가장 접근속도 빠름 (Near Data는 직접 주소 접근 방식이 가능하기 때문)
- A0/1/8/9 방식은 [a0/1/8/9 어드레스 레지스터]에 저장된 값을 기준으로 sign-extended 16bit 오프셋으로 64kB(-32kB~+32kB)만큼 접근 가능하다.
데이터 타입의 한정자
Circular Buffers
- Circular Addressing을 이용한 원형 버퍼 접근시 사용
- 한정자 : __circ
- 사용방법 :
// Circular 버퍼 및 포인터 생성
int __circ circbuf[10]={0,1,2,3,4,5,6,7,8,9};
int __circ * ptr_circbuf = circbuf;
// Circular pointer를 이용하여 Circular Addressing 방식으로 원형 버퍼의 값을 접근 가능
while(1)
{
int tmp = *ptr_circbuf++;
printf(“tmp= %d ”, tmp);
}
※ 출력값 : 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 . . .
Special Function Registers Defining
- Special Function Register를 bitfild 타입으로 선언시 사용
- 한정자 : __sfrbit16, __sfrbit32
- 사용방법 :
typedef volatile union
{
struct
{
unsigned __sfrbit32 SRPN : 8; /* Service Priority Number */
unsigned __sfrbit32 : 2;
unsigned __sfrbit32 TOS : 2; /* Type-of-Service Control */
unsigned __sfrbit32 SRE : 1; /* Service Request Enable Control */
unsigned __sfrbit32 SRR : 1; /* Service Request Flag */
unsigned __sfrbit32 CLRR : 1; /* Request Flag Clear Bit */
unsigned __sfrbit32 SETR : 1; /* Request Flag Set Bit */
unsigned __sfrbit32 : 16;
}B;
int I;
unsigned int U;
} LBCU_SRC_type;
→ Special Function Register를 bitfild로 선언할 경우 사용됨
void set_sfr(void)
{
SBCU_SRC.I |= 0xb32a; /* access SBCU Service Request
Control register as a whole */
SBCU_SRC.B.SRE = 0x1; /* access SRE bit-field of SBCU
Service Request Control register */
}
Saturation
- 자료형 Overflow 제한 기능 (int 자료형만 사용가능)
- 한정자 : __sat
- 사용 방법 :
__sat int si = 0x7FFFFFFF;
int i = 0x12345;
unsigned int ui = 0xFFFFFFFF;
int tmp1 = 0;
int tmp2 = 0;
int tmp3 = 0;
int main(void)
{
tmp1 = si + i;
tmp2 = ui + si;
tmp3 = i + ui;
printf( "tmp1 : %d \n tmp2 : %d \n tmp3 : %d \n ", tmp1, tmp2, tmp3);
}
※출력값: tmp1 : 0x7FFFFFFF //int 타입에 포화되어 연산
tmp2 : 0xFFFFFFFF //unsigned int 타입에 포화되어 연산
tmp3 : 0x12344 //일반적인 Overflow 연산
C소스에서의 Assembly 사용법
- Instrinct Function : __asm()
- Syntax :
__asm( "instruction_template"
[ : output_param_list
[ : input_param_list
[ : register_reserve_list]]] );