목표

함수 정리 및 개인적인 시간이 있을 때 설명 읽어두기.

각 함수 설명

sysGetVariableString

  • 시스템 변수(System Variable) 중 문자열(String, char[]) 타입의 값을 가져오는 함수입니다.
  • CANoe의 시스템 변수는 메시지, 신호, 내부 상태 관리 등에 사용되며, 이 함수는 문자열 값을 직접 읽어올 때 유용합니다.

함수의 반환값

반환값설명

0 정상적으로 실행됨 (성공)
1 네임스페이스를 찾을 수 없음 또는 동일한 네임스페이스를 중복 정의
2 변수를 찾을 수 없음 또는 동일한 변수를 중복 정의
3 네임스페이스에 대한 쓰기 권한 없음
4 변수의 타입이 char[]이 아님 (문자열이 아님)

form 1: 네임스페이스와 변수 이름을 문자열로 전달

long sysGetVariableString(char namespace[], char variable[], char buffer[], long bufferSize);
  • namespace → 시스템 변수가 속한 네임스페이스 이름
  • variable → 변수 이름
  • buffer → 가져온 문자열을 저장할 버퍼
  • bufferSize → 버퍼의 크기

예제

char buf[100];
sysGetVariableString("VehicleData", "SpeedText", buf, elcount(buf));
write("SpeedText: %s", buf);

➡️ “VehicleData” 네임스페이스의 “SpeedText” 시스템 변수를 읽어 “buf”에 저장한 후 출력.

form 2: 시스템 변수의 전체 경로를 직접 지정

long sysGetVariableString(SysVarName, char buffer[], long bufferSize);
  • SysVarName → 시스템 변수의 전체 이름 (네임스페이스 포함)
  • buffer → 값을 저장할 버퍼
  • bufferSize → 버퍼 크기

예제

char buf[100];
sysGetVariableString(sysvar::VehicleData::SpeedText, buf, elcount(buf));
write("SpeedText: %s", buf);

➡️ “VehicleData::SpeedText” 시스템 변수 값을 가져와 “buf”에 저장.

시스템 변수 포인터(sysvarString *)를 활용하여 동적으로 문자열 변수를 처리할 수도 있습니다.

예제

on key 'd'
{
  sysvarString * svString1;
  char buf[100];

  // getSysVarString 함수에서 시스템 변수 포인터 가져오기
  svString1 = getSysVarString(0);
  sysGetVariableString(svString1, buf, elcount(buf));
  write("Variable: %s, Value: %s", svString1.name, buf);

  // 값 변경
  sysSetVariableString(svString1, "OFF");
  sysGetVariableString(svString1, buf, elcount(buf));
  write("Variable: %s, Value is now: %s", svString1.name, buf);

  svString1 = getSysVarString(1);
  sysGetVariableString(svString1, buf, elcount(buf));
  write("Variable: %s, Value: %s", svString1.name, buf);
}

// 시스템 변수 선택 함수
sysvarString * getSysVarString(int cKey)
{
  switch (cKey)
  {
  case 0:
    return sysvar::FMW1::KeyString;
  case 1:
    return sysvar::DCM::SpeedSignalString;
  default:
    return sysvar::Engine::EngineStateString;
  }
}
블로그 이미지

RIsN

,

목표

함수 정리 및 개인적인 시간이 있을 때 설명 읽어두기.

각 함수 설명

elcount

배열(array)의 요소 개수를 반환하는 함수입니다.

하지만 배열의 사용 방식에 따라 반환값의 데이터 타입이 다릅니다.

예제

int numbers[5] = {1, 2, 3, 4, 5};

void example()
{
  dword size;
  size = elcount(numbers);  // 배열 크기 반환
  write("Array size: %d", size); // 출력: "Array size: 5"
}
블로그 이미지

RIsN

,

목표

함수 정리 및 개인적인 시간이 있을 때 설명 읽어두기.

각 함수 설명

on sysVar

🔹 기능

  • 시스템 변수의 값이 변경될 때 실행됨.
  • 동일한 시스템 변수에 대해 여러 CAPL 노드에서 독립적으로 반응 가능.

🛠 사용법

on sysVar 시스템변수_이름
{
  // 변경된 시스템 변수 값 가져오기
  int newValue = @this;
  write("New value: %d", newValue);
}

📌 예제

on sysVar Vehicle::Speed
{
  write("Speed Changed! New Value: %d", @this);
}

➡️ Vehicle::Speed 시스템 변수 값이 변경될 때마다 실행됨.

※메모: @this를 쓰려면 해당 변수가 int 혹은 float이어야 함

on sysVar_change

🔹 기능

  • 값이 변경될 때만 실행됨.
  • 같은 값이 연속해서 입력되면 실행되지 않음.

🛠 사용법

on sysVar_change 시스템변수_이름
{
  write("Value changed: %d", @this);
}

📌 예제

on sysVar_change Vehicle::RPM
{
  write("RPM Changed! New Value: %d", @this);
}

➡️ Vehicle::RPM 값이 변경될 때 실행됨.

➡️ 같은 값이 입력되면 실행되지 않음.

on sysVar_update

🔹 기능

  • 값이 변경되지 않아도, 업데이트가 발생하면 실행됨.
  • 센서 데이터나 주기적으로 업데이트되는 값 처리에 적합.

🛠 사용법

on sysVar_update 시스템변수_이름
{
  write("Variable Updated: %d", @this);
}

📌 예제

on sysVar_update Vehicle::Speed
{
  write("Speed Updated (Even if unchanged): %d", @this);
}

➡️ Vehicle::Speed가 변경되지 않아도 주기적으로 업데이트될 때 실행됨.

on sysVarMember

🔹 기능

  • 구조체(struct) 또는 배열(array)의 특정 멤버 값이 변경될 때 실행.
  • on sysVar과 같은 역할을 하지만, 특정 멤버 변수만 감지할 수 있음.

🛠 사용법

on sysVarMember 시스템변수_이름::멤버_이름
{
  write("Member value changed: %d", @this);
}

📌 예제

on sysVar Vehicle::Status::EngineTemp
{
  write("Engine Temperature Updated: %d", @this);
}

➡️ Vehicle::Status 구조체의 EngineTemp 값이 변경될 때 실행됨.

on sysVar (변수1 | 변수2 | …)

🔹 기능

  • 여러 개의 시스템 변수에 대한 감지를 한 번에 처리.
  • 모든 변수 타입이 동일해야 this 키워드 사용 가능.

🛠 사용법

on sysVar (변수1 | 변수2 | 변수3)
{
  write("Variable Changed: %s, New Value: %d", this.name, @this);
}

📌 예제

on sysVar (IO::DI_0 | IO::DI_1)
{
  write("Changed Variable: %s, New Value: %d", this.name, @this);
}

➡️ IO::DI_0 또는 IO::DI_1 값이 변경될 때 실행됨.

➡️ this.name을 사용하면 변경된 변수 이름을 출력할 수 있음.

블로그 이미지

RIsN

,

목표

CANoe에서 사용 가능한 UI에 대해서 시간을 들여서 좀 더 상세히 확인

제작

1. Home → Panel → New Panel로 새로운 UI Panel을 제작

  • 위의 화면에서 저장 후 연결

2. Panel이 나오는 지 확인

※Panel이 나오지 않을 경우 아래에서 확인

※Panel의 윈도우 형식을 바꾸고 싶으면 오른쪽 버튼으로 설정

  • MDI(Multiple Document Interface) Window
    • 기본 CANoe Window 안에서 전부 관리하는 Window로 다른 Window랑 자석처럼 붙어서 편함
    • 메모: 노트북이 작아서 기본적으로 이걸 사용할 때가 많음
  • Standard Window
    • Pop Up처럼 띄워서 관리하는 Window
  • Docking Window
    • 기본 CANoe Window 안에 다른 Window랑 별개로 관리하는 Window

3. Vector Tool Environment에서 Toolbox의 Start Stop Control을 드래그해서 놓고 싶은 위치에 위치 후 저장

4. 버튼을 눌러서 실행 확인

블로그 이미지

RIsN

,

목표

  • Write를 통해 기본 실행 스크립트를 실행 확인

제작

1. 기본 CAPL Script에서 아래와 같은 코드를 사용
    ※내 경우는 Engine.can

// ::  Initializes variables, displays messages, and reads files before measurement starts (limited system functionality).
on preStart {
  write(":: Start the program");
}

// :: Executes at the start of measurement, enabling all system functions (e.g., timers, logging, bus messages).
on start {
}

// :: Handles pre-stop actions before measurement stops; DeferStop can delay the stop if needed.
on preStop { 
}

// :: Runs after measurement stops to perform final cleanup and logging (some settings may not take effect)
on stopMeasurement { 
}

2. 실행 확인

블로그 이미지

RIsN

,

목표

함수 정리 및 개인적인 시간이 있을 때 설명 읽어두기.

각 함수 설명

write

  • 기능
    • Write Window에 문자열을 출력할 때 사용됩니다.
    • C 언어의 printf와 유사하게 서식(format string)을 사용할 수 있습니다.예:→ Measurement started at 1234 ms 와 같은 출력이 나옴.
write("Measurement started at %d ms", getMsTime());
  • 제한사항
    • 컴파일러가 서식 문자열을 검사하지 않음 printf에서는 %d, %s 등과 함께 전달된 인자의 타입이 일치하지 않으면 경고 또는 오류를 발생시킵니다.→ 하지만 write에서는 이런 검사가 없기 때문에 잘못된 형식이 입력되면 예상치 못한 결과가 나올 수 있음.
    • 예를 들어, %d(정수) 자리에 문자열을 넣으면 예상할 수 없는 오류가 발생할 수 있음.
    • 메시지는 자동으로 개행(줄 바꿈)되어 출력됨→ 여러 개의 write 호출을 하면 자동으로 각각 새로운 줄에 출력됨.
  • 주의할 점
    • 사용자가 직접 형식이 올바른지 확인해야 함.
    • printf처럼 작동하지만, write는 출력 대상이 콘솔이 아니라 Write Window임.
    • 메시지 로깅이나 디버깅 용도로 적합함.
블로그 이미지

RIsN

,

목표

함수 정리 및 개인적인 시간이 있을 때 설명 읽어두기.

각 함수 설명

on preStart

  • 측정 시작 전에 실행됨
  • 변수 초기화, 메시지 출력, 파일 읽기 가능
  • 하지만 시스템이 완전히 활성화되지 않았으므로 버스 메시지 전송 불가능

on start

  • 측정이 실제로 시작될 때 실행됨
  • 타이머 시작, 로깅 초기화, 버스로 메시지 전송 가능
  • 이 시점에서는 모든 시스템 기능을 사용할 수 있음

on preStop

  • 측정 중지 요청이 들어온 후 실행되며, 측정이 실제로 중지되기 전에 처리됨
  • 마지막으로 정리해야 할 작업 수행 가능 (예: ECU 종료 메시지 전송, 로그 저장 등)
  • DeferStop을 호출하면 측정 중지를 지연할 수 있음
    • 예: deferStop (5000);

on stopMeasurement

  • 측정이 완전히 중지된 후 실행됨
  • 환경 변수 등의 변경이 반영되지 않을 수도 있음
  • 로그 정리 등 종료 후 수행할 작업을 처리해야 함
블로그 이미지

RIsN

,

목표

  • 전송 Configuration에 기본이 되는 실행 스크립트를 제작

제작

1. Simulation Setup에서 아래 선을 선택해서 오른쪽 클릭
※왜인지 저 선을 뭐라고 부르는 지 찾을 수가 없음.

2. Insert Network Node 선택

※원하면 아래와 같이 Node Configuration에서 이름 등을 수정

3. 아래의 연필 혹은 오른쪽 클릭해서 Edit을 누르고 새로운 스크립트를 해당 노드와 연결

4. 아래와 같이 VectorCAPL Browser가 나오면 준비 완료

블로그 이미지

RIsN

,

목표

어떤 Window가 사라졌을 때 해당 Window를 띄우기.

방법

  1. Home → Write 선택

블로그 이미지

RIsN

,

1. Tester Present 서비스 개요

UDS(ISO 14229) 프로토콜에서 Tester Present(0x3E) 서비스는 ECU가 진단 세션을 유지하도록 하는 역할을 합니다. 진단 장치(테스터)가 특정 시간 동안 ECU에 진단 메시지를 보내지 않으면 ECU는 진단 세션을 자동으로 종료하고 기본 모드(default session)로 돌아가게 됩니다. 이를 방지하기 위해 주기적으로 Tester Present 메시지를 보내야 합니다.

2. Tester Present 서비스의 목적

  • ECU가 특정 진단 세션을 유지하도록 함
  • ECU가 세션 타임아웃을 하지 않도록 주기적으로 신호 전송
  • ECU가 특정 모드(예: extended session 또는 programming session)에서 계속 동작할 수 있도록 보장

3. 메시지 구조

Tester Present 서비스는 단순한 메시지 구조를 가지고 있습니다.

Byte설명

0x3E Tester Present 서비스 ID
0x00 또는 0x80 서브 기능(sub-function)
(응답) 0x7E 응답 메시지 (Positive Response)
(응답) 0x7F 0x3E 0x12 Negative Response (Subfunction Not Supported)
(응답) 0x7F 0x3E 0x78 Negative Response (Response Pending)

서브 기능 (Subfunction)

  • 0x00 (Zero Subfunction): 기본 Tester Present 메시지 (응답 필수)
  • 0x80 (Suppress Positive Response Bit 설정됨): ECU에서 응답을 보내지 않도록 설정 (Silent mode)

예제 요청/응답

  1. 기본 Tester Present 요청
    • 요청: 3E 00
    • 응답: 7E (Positive Response)
  2. Suppress Positive Response 요청
    • 요청: 3E 80
    • 응답 없음 (ECU가 응답하지 않음)
  3. Negative Response 예제
    • 요청: 3E 00
    • 응답: 7F 3E 12 (Subfunction Not Supported)
    • 응답: 7F 3E 78 (Response Pending, ECU가 처리 중)

4. Tester Present의 동작 방식

  1. 진단 장치(Tester)는 특정 진단 세션(예: ExtendedDiagnosticSession, ProgrammingSession)을 시작함.
  2. ECU는 특정 타임아웃(보통 5초~10초) 내에 새로운 진단 요청을 받지 않으면 기본 세션(default session)으로 돌아감.
  3. 이를 방지하기 위해 진단 장치는 주기적으로(예: 2~3초마다) Tester Present 메시지를 전송.
  4. ECU가 메시지를 받으면 타이머를 리셋하고 현재 세션을 유지.
  5. 특정 상황에서는 ECU가 바쁜 경우 0x7F 3E 78 (Response Pending)으로 응답할 수도 있음.

5. 주요 고려 사항

  • 진단 세션 유지: Extended 또는 Programming 세션에서는 주기적으로 3E 00을 보내야 세션이 종료되지 않음.
  • Suppress Positive Response: 3E 80을 사용하면 ECU가 응답하지 않으므로 통신 트래픽을 줄일 수 있음.
  • Response Pending: ECU가 바쁜 경우(예: Flashing 중) 0x7F 3E 78을 반환할 수 있음.
  • 세션별 필요 여부: Default Diagnostic Session에서는 Tester Present가 필요하지 않음.

6. 실무 적용 예시

차량 ECU Flashing 시나리오

  • ECU의 Flash Programming Mode(10 02 Programming Session)로 진입 후
  • 3E 00 메시지를 일정 간격으로 보내면서 세션 유지
  • Flashing 완료 후, 11 01 (ECU Reset)으로 리부팅

이처럼 Tester Present는 ECU와의 장기적인 진단 세션을 유지하는 핵심적인 역할을 합니다.

블로그 이미지

RIsN

,