## CAPL 변수, 데이터 타입, 상수, #define
- 지역변수:
변수가 선언된 종괄호 내부에서만 접근할 수 있는 변수입니다. - 예제 코드 설명:
예시 코드에서 ONKEY A 이벤트와 ONKEY B 이벤트 두 개의 서로 다른 이벤트가 있습니다.
이 두 이벤트 모두에서 접근할 수 있는 변수는 전역변수입니다. - 전역변수와 지역변수의 차이:
전역변수는 코드 전체에서 접근할 수 있는 반면, 지역변수는 각각의 종괄호 내에서만 접근 가능합니다. - 전역변수의 위치:
CAPL에서는 전역변수 선언 위치가 중요합니다. 전역변수는 특정한 코드 영역에 선언되어야 합니다. - CANoe 환경에서의 전역변수 선언:
CANoe 같은 환경에서는 별도의 코드 영역 없이 코드의 빈 공간에서 변수를 선언할 수 있습니다.
이러한 변수들은 variables 영역에 선언된 것으로 취급됩니다. - 전역변수 선언의 필수성:
전역변수는 반드시 variables 영역 안에 선언해야 하며, 그렇지 않을 경우 에러가 발생합니다.
int var_1;
var_1 = 0;
선언을 먼저 해야한다.
- 지역 변수 위치 규칙
- 지역 변수도 선언하는 위치가 정해져 있습니다.
- 이 규칙은 옛날 버전의 C 언어 규칙과 유사하며, 현재는 C에서는 사용되지 않지만 CAPL에서는 여전히 적용됩니다.
- 변수 선언 순서
- 함수나 이벤트 코드 작성 시 변수를 최상단에 먼저 선언해야 합니다.
- 예를 들어 test function()이라는 함수 안에서 1, 2, 3이라는 세 개의 변수를 사용한다고 할 때,
변수를 두 개 이상 선언한 후 다른 연산을 작성하면 CAPL은 이를 에러로 인식합니다.
- 변수 선언 규칙의 핵심
- 새로운 변수 선언은 항상 코드의 맨 앞에 위치해야 합니다.
- 중간에 연산이 들어가고 난 후에 변수를 선언하면 에러가 발생합니다.
- for문 안의 변수 선언
- CAPL에서는 for문 안에 변수를 선언할 수 있지만, 다른 언어와 달리 for문 안에서 직접 변수를 선언하면 에러가 발생할 수 있습니다.
- 이는 CAPL의 컴파일러가 변수를 선언하는 위치를 엄격히 관리하기 때문입니다.
- 변수 선언 유의사항
- 변수 선언은 항상 함수나 코드 블록의 가장 상단에 위치해야 하며, 다른 코드와 혼용하지 않아야 합니다.
- 잘못된 위치에 변수를 선언할 경우 코드 컴파일이 되지 않거나 에러가 발생합니다.
CAPL에서 변수 초기화 관련 규칙 정리
- 초기화되지 않은 변수의 기본값
- 지역 변수와 전역 변수 모두 초기 값을 명시적으로 지정하지 않으면 기본값으로 0이 할당됩니다.
- 컴파일러마다 다른 동작
- C 언어의 경우, 컴파일러에 따라 초기화되지 않은 변수에 쓰레기 값이 들어갈 수 있습니다.
- 그러나 CAPL에서는 초기화 값을 따로 지정하지 않으면 무조건 0으로 초기화됩니다.
- 초기화 습관의 중요성
- 명시적으로 초기화하지 않더라도 CAPL은 자동으로 0으로 설정하지만, 예측 가능한 코드 작성을 위해 초기화를 습관화하는 것이 좋습니다.
- 이는 코드의 가독성과 유지보수성을 높이는 데 도움이 됩니다.
CAPL에서 변수의 지역성과 초기화 규칙 정리
- CAPL에서 지역 변수와 전역 변수의 차이
- 지역 변수는 함수나 이벤트 안에서 호출될 때마다 0으로 초기화됩니다.
- 전역 변수는 프로그램이 시작될 때 한 번만 초기화되고 이후 값이 계속 유지됩니다.
- C 언어의 static 변수와 유사한 동작
- CAPL의 모든 지역 변수는 static 변수처럼 초기화됩니다. 즉, 매번 함수가 호출될 때마다 초기값으로 설정되지 않고, 프로그램 실행 동안 유지됩니다.
- 지역 변수와 전역 변수의 이름 충돌
- 전역 변수와 지역 변수의 이름이 같을 경우, 지역 변수가 우선적으로 적용됩니다.
- 서로 다른 함수나 이벤트 안에서도 동일한 이름의 지역 변수를 각각 사용할 수 있습니다, 이는 서로 독립된 변수로 동작합니다.
- 변수 선언 예제
- 예를 들어 testA 함수와 testB 함수에 동일한 이름의 변수를 선언하더라도, 두 변수는 서로 독립적으로 동작합니다.
- 전역 변수와 동일한 이름의 지역 변수가 있을 경우, 해당 함수나 이벤트에서는 지역 변수가 사용됩니다.
- CAPL의 for문과 변수 사용
- CAPL에서 for문 내부에서 변수를 선언하면 지역 변수처럼 동작하지만, 명시적으로 초기화되지 않으면 자동으로 0으로 초기화됩니다.
- 변수 사용 시 주의할 점
- CAPL에서의 변수 사용은 항상 명확한 범위와 초기화 규칙을 염두에 두어야 합니다.
- 특히 전역 변수와 지역 변수의 이름이 중복될 경우 우선순위에 주의해야 합니다.
- 예: 함수 안에서 전역 변수와 동일한 이름의 지역 변수를 선언하면, 해당 함수에서는 지역 변수가 사용됩니다.
- 실행 결과 예시
- 예를 들어, testA 함수에서 전역 변수와 동일한 이름의 지역 변수를 사용하고 A 키를 눌렀을 때 출력이 다르게 나타납니다. 지역 변수의 값이 200으로 설정된 경우, 해당 값이 우선 출력됩니다.
CAPL에서 지원되는 데이터 타입에 대한 정리
- CAPL의 정수형 타입
- 일반적인 C 언어에서는 int 타입이 4바이트 크기지만, CAPL에서는 2바이트입니다.
- 4바이트 정수를 사용하려면 **int32 또는 rom**을 사용해야 합니다.
- 8바이트 정수형 변수를 선언하려면 **int64_t**와 같은 타입을 사용합니다.
- 부호 없는 정수형 (Unsigned)
- CAPL에서는 unsigned 키워드가 따로 지원되지 않습니다.
대신, 부호 없는 데이터 타입을 명시적으로 사용해야 합니다.
예를 들어, unsigned int 대신 **uint16**와 같은 타입을 사용합니다.
- CAPL에서는 unsigned 키워드가 따로 지원되지 않습니다.
- 실수형 데이터 타입
- C 언어와 동일하게 **float와 double**을 사용할 수 있습니다.
- 그러나 CAPL에서 float는 4바이트, double은 8바이트로 C 언어와 동일합니다.
- 배열 및 고수준 데이터 타입 지원
- CAPL에서는 배열형 변수와 **고수준 데이터 타입(예: 문자열, 이넘)**도 사용할 수 있습니다.
- 포인터 타입의 부재
- CAPL은 C 언어와 다르게 포인터 타입을 지원하지 않습니다.
이는 메모리 접근과 관련된 기능이 제한됨을 의미합니다.
- CAPL은 C 언어와 다르게 포인터 타입을 지원하지 않습니다.
- CAPL의 주요 데이터 타입 정리
- 2바이트 정수: 기본 int 타입은 2바이트.
- 4바이트 정수: int32를 사용해야 함.
- 8바이트 정수: int64_t 사용.
- 부호 없는 정수: uint16, uint32 등 사용.
- 실수: float와 double 사용 가능.
- 핵심 요약
- int의 기본 크기가 2바이트인 점에 주의.
- unsigned 키워드 사용 불가 – 대신 명시적인 데이터 타입 사용.
- 포인터 타입 미지원으로 인해 메모리 관련 기능 제한.
struct 선언 및 사용 예제 (구조체)
capl
코드 복사
struct TestStruct { int data1; // 정수형 변수 float data2; // 실수형 변수 int arr[4]; // 정수 배열 (4개 원소) };
- struct는 여러 개의 변수를 하나의 그룹으로 묶는 데 사용됩니다. 여기서는 정수형 변수, 실수형 변수, 그리고 정수 배열로 구성된 구조체 TestStruct를 정의했습니다.
capl
코드 복사
variables { struct TestStruct var1 = {123, 40.123, {1, 2, 3, 4}}; // 초기화된 선언 struct TestStruct var2; // 초기화되지 않은 선언 }
- var1은 선언과 동시에 {123, 40.123, {1, 2, 3, 4}} 값으로 초기화되었습니다.
- var2는 선언만 하고 값을 할당하지 않은 상태입니다.
2. enum 선언 및 사용 예제 (열거형)
capl
코드 복사
enum EcuName { Steering, BMS, Brake, Engine };
- EcuName 열거형은 ECU 이름들을 정의합니다. 각 상수는 0부터 자동으로 순서대로 값이 할당됩니다.
예: Steering = 0, BMS = 1, Brake = 2, Engine = 3
capl
코드 복사
enum IgnState { Ign_Off = -1, Ign_On = 3 };
- IgnState 열거형은 시동 상태를 나타내며, 직접 값을 지정했습니다.
예: Ign_Off = -1, Ign_On = 3
capl
코드 복사
variables { enum EcuName test_var1; // EcuName 타입 변수 선언 enum IgnState test_var2; // IgnState 타입 변수 선언 }
- test_var1과 test_var2는 각각 EcuName과 IgnState 타입의 변수를 선언한 것입니다.
CAPL에서의 struct와 enum의 유용성
- struct: 복잡한 데이터 구조를 그룹화해 다룰 때 유용합니다. 예를 들어, ECU 데이터나 메시지 데이터를 묶어 관리할 수 있습니다.
- enum: 상태나 옵션을 정수 값으로 표현하여 코드의 가독성과 유지 보수를 높입니다. 시동 상태(IgnState)나 모듈 이름(EcuName) 같은 고정된 값들에 주로 사용됩니다.
CAPL의 특성
- CAPL은 이벤트 기반 프로그래밍이므로, 각 메시지나 타이머 이벤트에 따라 구조체 변수나 열거형 변수를 사용할 수 있습니다.
- 예를 들어 CAN 메시지를 수신할 때 메시지의 데이터 부분을 구조체로 파싱하거나, ECU 상태를 열거형을 통해 관리할 수 있습니다.
1. 사용 불가능한 예시
capl
코드 복사
#define VERSION 7 on message BMS { int test = VERSION; write("version is %d", test); }
- 이 코드가 작동하지 않는 이유:
- CAPL에서는 #define으로 정의된 매크로를 변수처럼 직접 대입하는 방식이 지원되지 않습니다.
- VERSION을 변수처럼 사용하고자 했으나, CAPL은 매크로를 이처럼 데이터 대입 목적으로 사용하지 못합니다.
- CAPL의 매크로는 주로 조건부 컴파일 제어에 사용됩니다.
2. 사용 가능한 예시
capl
코드 복사
variables
{
#define DEBUG 1
}
void test_function(void)
{
#if DEBUG
write("test sentence1");
#endif
#if DEBUG
write("test sentence2");
#endif
}
- 이 코드가 올바른 이유:
- 조건부 컴파일을 통해 DEBUG 값이 1일 때만 특정 코드가 실행되도록 작성되었습니다.
- #if와 #endif 구문으로 매크로를 활용해 코드 블록을 제어합니다.
- DEBUG가 1이면 write 함수들이 실행되고, 0이면 해당 블록들이 무시됩니다.
1. CAPL에서의 #define 매크로와 디버깅
- #define 매크로의 활용:
- #define을 사용하여 특정 코드를 활성화 또는 비활성화할 수 있습니다.
- 이 매크로는 디버깅 코드처럼 일시적으로 사용해야 하는 코드의 활성화/비활성화에 유용합니다.
예를 들어:capl코드 복사#define DEBUG 1 // 디버깅 활성화 #if DEBUG write("디버깅 코드 실행 중"); #endif - DEBUG 값에 따라 코드의 실행 여부가 결정됩니다. 나중에 이 코드를 비활성화하고 싶다면, #define DEBUG 0으로 변경하면 됩니다.
2. 비활성화와 주석 처리의 문제점
- 주석 처리 대신 매크로 사용:
- 많은 디버깅 코드를 주석 처리하면 코드가 복잡해지고 유지보수가 어려워질 수 있습니다.
- 매크로를 사용하면 코드 삭제 없이 조건부로 실행을 제어할 수 있어 효율적입니다.
- 코드가 많을 때 주석으로 관리하는 것보다 매크로로 관리하는 것이 편리합니다.
3. 디버깅 코드의 비활성화와 활성화
- 개발 중에는 디버깅을 통해 코드가 올바르게 작동하는지 확인해야 합니다. 그러나 개발이 완료된 후에는 디버깅 코드를 비활성화해야 코드가 깔끔해집니다.
- 매번 주석을 추가하고 제거하는 대신, #define 매크로를 통해 필요한 부분만 유동적으로 디버깅할 수 있습니다.
4. 매크로 사용 위치 및 전형적인 사용법
- #define 매크로는 코드의 최상단 또는 변수 선언 이후에 위치해야 합니다.
- 전형적인 사용법으로, 초기 코드의 조건에 따라 특정 부분의 코드만 실행하거나 무시할 수 있습니다.
'회사 > CAPL' 카테고리의 다른 글
섹션 7_CANoe - CAPL과 Panel 기본 (0) | 2024.10.20 |
---|---|
CAPL getProfileArray 사용법 (0) | 2024.10.19 |
섹션 6_CANoe - CAPL과 Panel 기본 (섹션 5) (0) | 2024.10.19 |
섹션 5_CANoe - CAPL과 Panel 기본 (섹션 5) (0) | 2024.10.19 |
CANoe - CAPL과 Panel 기본 (섹션 3_3 ~ 3_6) (1) | 2024.10.19 |