Skip to content

AUTOSAR CAN#

1. AUTOSAR CP의 네트워크 스택#

1.1 AUTOSAR CAN 통신 개요#

CAN 네트워크 스택#

  • AUTOSAR(Classic Platform)에서 CAN 통신은 모듈화된 계층적 구조로 구성되어 있으며, 상위 애플리케이션에서부터 하드웨어까지 여러 모듈을 거쳐 데이터가 송수신된다.

CAN 통신은 아래와 같은 3가지 주요 스택을 포함한다.

  • CAN 통신 스택 (Communication Stack): 데이터 송수신을 담당하는 모듈

  • CAN 상태 관리 스택 (Status Stack): Bus Off 처리, 오류 관리 기능 포함

  • CAN 네트워크 관리 스택 (Network Management Stack): 네트워크 상태 및 Sleep/Wake 관리

이러한 계층 구조를 통해 CAN 통신의 확장성 및 유지보수성을 높일 수 있다.

1.2 AUTOSAR CAN 네트워크 스택 아키텍처#

CAN 통신 스택 (Communication Stack)#

CAN 데이터 송수신 과정에서 주요 역할을 수행하는 모듈은 다음과 같다.

  • Com : 애플리케이션이 PDU 데이터를 Signal 단위로 읽고 쓸 수 있도록 인터페이스 제공

  • PduR : PDU 라우팅 담당, Source 모듈에서 Destination 모듈로 데이터 전달

  • CanIf : 상위 모듈과 CAN Driver 간 인터페이스 역할 수행

  • Can : CAN Controller의 활성화/비활성화 및 인터럽트 처리

  • CanTrcv : CAN Transceiver 상태 제어 (Normal, Sleep, Standby)

CAN 상태 관리 스택 (Status Stack)#

CAN 네트워크에서 오류 발생 시 복구를 위한 모듈을 포함한다.

  • BswM : 특정 조건에 따라 Action을 수행

  • ComM : 통신 제어 요청 인터페이스 제공

  • CanSM : Bus Off 발생 시 복구 절차 실행 및 상태 통보

CAN 네트워크 관리 스택 (Network Management Stack)#

네트워크 활성화 및 Sleep 모드 관리를 담당한다.

  • Nm : 네트워크 활성화 및 Release 요청 수행

  • OsekNm : 네트워크 상태 감시 및 동기화 제어

1.3 CAN 메시지 처리 과정#

CAN 프레임 송수신#

CAN 프레임의 송수신 과정은 아래와 같다.

송신 과정

  • Application → Com → PduR → CanIf → CAN Driver → CAN Controller → CAN Bus

  • PDU를 Hardware Object로 매핑 후 전송

수신 과정

  • CAN Bus → CAN Controller → CAN Driver → CanIf → PduR → Com → Application

2. AUTOSAR CP의 CAN 통신 동작 구조#

2.1CAN 데이터 통신 방식#

주기적 송수신 (Timing Communication)#

  • 주기적인 데이터 송수신을 위한 흐름

  • Timing Task에서 Runnable 실행

  • RTE API를 통해 Signal Read/Write
  • COM에서 PDU 업데이트 및 송신

이벤트 기반 송수신 (Event Communication)#

  • 이벤트 발생 시 CAN 프레임을 송신하는 방식

  • 특정 조건에서 이벤트 발생

  • Data Received Event를 통해 Task 실행
  • RTE API를 통해 Signal Read/Write

2.2 AUTOSAR CAN 게이트웨이 기능#

PDU to PDU Gateway#

  • PDU를 직접 다른 ECU로 전달하는 방식이다.

  • PduR 모듈에서 처리되며, 메시지 변형 없이 그대로 전송된다.

Signal to Signal Gateway#

  • 특정 신호를 받아 다른 PDU로 전달한다.

  • Com 모듈에서 Signal을 변경할 수 있으며, 게이트웨이 기능 수행한다.

2.3 AUTOSAR CAN의 동작 구조 예시#

아래 그림과 같이 AUTOSAT CAN은 사용자가 설계를 할 당시에는 SWC간의 연결이 SRI(Sender Receiver Interface)와 동일한 구조처럼 나타낼 수 있다.

ex

  • AUTOSAR에서 초기 설계를 위 그림처럼 했다고 가정한다.

  • SeatSwitch가 ECU1에, HeatingElement(실제는 LED)는 ECU2에 있다고 했을 때 SWC는 각각의 ECU로 분리되어 들어가게 된다.

  • 이 때 실제 구조는 아래 그림과 같다.

ex2

  • RTE 실습 3번에서는 직접 If_SeatSwitch라는 Interface를 생성한 후 P_SeatSwith, R_SeatSwitch라는 Port를 만들고 연결해 주었다. 이번 실습에서는 CAN DB import, CAN Harmonize 작업과 추후에 Data Mapping 작업을 통해 Port를 생성하고 연결 해줄것이다.

  • Odin Studio에서는 하나의 ECU에 대한 설정만 가능하므로 각각의 프로잭트를 생성한다.

  • ECU1 프로잭트에는 suffix로 _ECU1을, ECU2 프로잭트에는 _ECU2를 붙여주어 구분한다.

3. AUTOSAR CP 기반 CAN 통신 설정 실습#

  • 위 CAN 동작 구조의 예시를 토대로 실습을 진행한다.

3.1 DB 파일 구성#

  • DBC 파일은 크게보면 노드에 관한 정보와 CAN 메시지 정의로 구성되어 있다.

노드#

  • 네트워크에 존재하는 ECU (Electronic Control Unit) 노드를 정의하며 현재 파일에는 TestClient, ECU4, ECU3, ECU1, ECU2 다섯 개의 노드가 존재한다.

노드info

CAN 메시지#

  • CAN 메시지는 BO_ (Bus Object) 섹션에서 정의되며 크게 CAN 메시지 ID, 메시지 이름, 데이터 길이, 송신 노드, Signal에 대해 정의한다.

  • 아래의 사진은 앞으로 실습에서 사용할 메시지의 DBC 정보이다. 이를 통해 어떻게 구성되어 있는지 알아보자.

DBCfile

  1. 메시지 정의 시작을 정의하는 부분이다.
  2. CAN 메시지 ID (decimal)를 정의하는 부분으로 우리가 사용할 CAN 메시지의 ID는 0x2임을 알 수 있다.
  3. 메시지 이름을 정의하는 부분으로 우리가 사용할 CAN 메시지의 이름은 ECU1_Msg_OE2임을 알 수 있다.
  4. 데이터 길이 (바이트 단위)로 사용할 메시지의 길이는 8Byte임을 알 수 있다.
  5. 송신 노드를 정의하는 부분으로 ECU1에서 송신하는 메시지임을 알 수 있다.
  6. 신호 정의 시작을 정의하는 부분이다.
  7. 신호 이름을 정의하는 부분으로 사용할 신호의 이름은 ECU1_Msg_OE2_Sig1임을 알 수 있다.
  8. 신호 수신 노드를 정의하는 부분으로 ECU2에서 수신하는 메시지임을 알 수 있다.

위와같은 파일에서 메시지의 관해 정의한 것을 토대로 아래의 과정을 통해 Import와 Harmonize를 하며 메시지의 설정을 수정할 수 있다.

3.2 DB 파일 Import 및 Harmonize#

Step 1) CANDB Import#

  1. 프로잭트를 선택한다.

  2. 보라색 아이콘(EcuExtract)을 클릭한다.

아이콘

  1. 기존 DBC 내용 삭제

    • Editor에서 Communication and Topology 탭 클릭한다.
    • 기존 DBC 내용(Project)을 선택한다.
    • X 표시를 클릭해 삭제한다.

DBC제거

  1. Overview Tap을 선택한 다음 Reference>DB>Project.dbc 경로로 DBC 파일을 선택한 후 Import DBC 쪽으로 드래그&드롭한다.

ImportDBC

  1. Next 버튼을 누른 후 상단의 Select ECU 부분이 ECU1인 것을 확인한 후 맞으면 Next-Finish 버튼을, 아니면 ECU1으로 수정한 뒤 Next-Finish 버튼을 클릭한다.

Step 2) ECU Harmonize#

  1. 상단의 초록색 아이콘(Config ECU and Generate Code)을 클릭한다.

  2. 우측의 Convert ECU and Generate Code 부분에 Generate ECU Configuration을 클릭한다.

Config

  1. 이후 창에서 Next를 클릭 후 그림과 같이 Modules에서 Can Stack, Com Stack, Ecuc, Miscellaneous(OsekNm 제외), Mode Management(NM 제외)를 선택한 후 'Next-Finish' 버튼을 클릭한다.

Modules

  1. 좌측 상단의 망치 모양의 버튼을 클릭하여 build 시킨 후 오류없이 정상적으로 빌드 되는 모습을 확인한다.

Build

Step 3) ECU1 Configuration#

  1. 'Configuration - System - Swcd_App'에서 우클릭 후 'New - AUTOSAR file'을 클릭하여 File name을 App_CANTest로 설정한 후 Finish를 클릭한다.

AUTOSARfile filename

  1. 아래 생성한 파일을 열어 ArPackage를 선택하고 마우스 우클릭하여, 'New - ApplicationSwComponentType'을 선택한다.

  2. 생성한 Component Type의 Short Name을 SWC_SeatSwitch로 변경 및 SupportsMultipleInstantiation을 false로 설정 후 저장한다.

SWCname

  1. 'Build - SCons.arxml - SCons'를 선택한다.

Scons

  1. 하단의 All Contents로 변경 후 Navigator 하단의 Rte를 선택하고 우측 Input Files List의 Add 버튼을 클릭한다.

Scons/Rte

  1. 창의 왼쪽 상단 Value에 App_CANTest를 입력한 후 Add 버튼을 눌러 추가하고 OK 버튼을 누른다.

AddtoRte

  1. 다시 SWC_SeatSwitch로 돌아가 Runnables를 선택하고 Runnable을 생성한 후 Short Name을 'RE_SeatSwitch'로 Symbol 이름은 'SeatSwitch_func'로 설정한 후 Can Be Invoked Concurrently를 false로 설정한다.

Runnable

  1. 하단의 RTE Event 테이블을 확장한 후 'Add - Timming Event - Ok' 순서로 선택하여 추가하고, 추가된 Timming Event를 선택하여 Period를 100 mesc로 수정한 후 Ok를 클릭하여여 완료한다.

Addevent

sec

  1. 'Configuration - System - Composition - RootComposition.arxml - CSWC_RootComposition'을 선택, 하단의 Components and Ports를 선택한 후 Components의 + 버튼을 클릭하여 SWC_SeatSwitch를 추가해준다.

RootComp

AddComp

  1. 좌측 상단의 EcuExtract를 클릭한 후 'ECU Software Components Mapping - Ok - Apply'를 클릭하여 설정을 완료한다.

ECUMapping

Apply

  1. 이어서 하단에 Data Mappings를 선택하고 'SWC_SeatSwitch - Create Ports From Network'를 선택한다.

CreatePort

  1. 'Project - Ok'를 선택한 후 TxPort 부분에서 ECU1_Msg_OE2 왼쪽 박스를 체크한 후 'Ok - Ok'를 클릭한다.

Project

TxPort

  1. 우측에 'Add/Remove All - Ok' 클릭을 통해 Port Interface의 Data Elements(Signal)와 통신 Signal을 전부 mapping 해준다.

Add

DataMapping

  1. 11~12번과 같이 'Create Port From Network - Project - Ok'를 선택, 기존에 생성한 RE_SeatSwitch를 선택하고 DSP 박스도 클릭, 'Ok -Ok'를 클릭하여 완료한다.

RunnableSelect

  1. IO를 사용하기 위한 Port를 생성한다. 'SWC_SeatSwitch - Ports' 선택, 'RPort Prototype - + - Client Server Interface - Client'를 선택한다.

RPort

  1. 하단의 IoHwAb_If_DigDir를 선택, Ok를 클릭하여 추가 해준다.

IoHwAb

  1. Short Name을 R_IO로 변경한 후 아래의 Communication Spec 부분에 Operations에서 ReadDirect를 선택한 후 Enable Required Com Specs를 체크해준다.

ReadDirect

  1. 이어서 Runnables탭의 'Operation - Mode - TriggerAccess'에서 Add를 선택한 뒤 SynchronousServerCallPoint의 R_IO.ReadDirect선택하고 OK를 클릭한다.

SSCP

  1. 상단메뉴에서 Configure ECU & Generate Code 선택 Generate ECU Configuration 을 클릭한다.

ECUconfig

  1. Next를 클릭하고 Service 부분에 Rte를 선택후 Next 클릭, RTE : Generate SwcInstance Configuration 가 체크되어 있는지 확인 후 Finish를 선택한다.

selectRte

configfinish

  1. 이어서 아래 Overview fo Modules에서 Rte를 클릭한 후 Task Mapping을 선택한 후 'SW Component Instance - SwcInstance_SWC_SeatSwitch'를 선택해준다.

TaskMapping

SWCInstance

  1. 아래의 OsTask Mapping Table에서 OsTask_ASW_FG1_100ms를 선택, 위의 TE_RE_SeatSwitch를 선택 후 Add를 클릭한다.

TEMapping

  1. Configure ECU and Generate Code로 들어가 하단의 Service and I/O를 선택, Svc_IoHwAb를 클릭하여 Table을 열고 P_IoHwAbDigitalDirectLogical_S1을 선택한다.

SelectS1

  1. 이어서 상단의 Automatic Connection 우측의 + 버튼을 클릭, Respect Naming Rule의 체크를 해제한 후 생성되는 P_IoHwAbDigitalDirectLogical_S1↔R_IO를 선택한 후 Ok를 클릭한다.

IOMapping

  1. 다시 SWC_SeatSwitch로 돌아가 Overview를 선택한 후 Skeleton Code를 생성을 위해 하단의 Generate Code를 클릭한다.

GenerateCode

  1. 이어진 창에서 Source Folder 우측의 Browser를 클릭한 후 '현재 workspace 하위의 작업중인 프로잭트 - Static_Code - Reference_Code'를 선택 후 확인을 클릭하여 코드의 생성 위치를 지정해 준다. 이후 '확인 - Finish - No'를 클릭해 코드 생성을 완료한다.

Codelocate

  1. 'Static_Code - Reference_Code - SWC_SeatSwitch.c'를 선택 후 다음과 같이 코드를 작성하고 Build 버튼을 눌러 다음과 같이 결과가 나오는 것을 확인한다.

Code

Build

Step 4) ECU2 Configuration#

  1. Step 1) 과정과 동일하게 기존의 DBC를 삭제한다.

  2. ECU2는 이전과 다르게 Project.dbc file을 수정해주어야 한다. 'Reference - DB - Project.dbc' 파일을 오른쪽 창으로 드래그 앤 드롭하여 Text-editor로 연다.

DBCOpen

  1. TestClient(진단기)간의 메시지 정의를 ECU1->ECU2로 대체함으로 기존에 있는 Dcm 기능에 수정 또는 삭제 없이 빌드할 수 있도록 한다.

DBC수정

  1. 수정된 DBC 파일을 Step 1-4와 같이 선택한 후 Import DBC 쪽으로 드래그&드롭한다.

  2. Next를 선택한 후 Select ECU에서 ECU2를 선택한 이후 다음과 같이 Dcm. Nm에 관련된 Message들을 아래와 같이 설정해주고 'Next - Finish' 버튼을 클릭한다.

ECU2config

  1. Step2) ECU Harmonize과정과 동일하게 작업해준 후 build를 하였을 때 위와 같이 오류 메시지가 뜨면 오류 부분을 더블클릭 후 ',' 앞에 0을 입력하고 저장한 후 망치 아이콘에서 Compile을 선택하여 성공적으로 설정이 완료되었는지 확인한다. "ECU2 빌드 시 이 과정을 반복한다."

OsekNM_err

0추가

Compile

  1. Step3)의 1~6 과정과 동일하게 AUTOSAR file 생성, Component Instance, Port 생성 후 SCons에 AUTOSAR file을 추가해주고 설정을 마무리한다.

AUTOSARfile

filename

SWCname

SCons

SCons/Rte

AddtoRte

  1. 생성한 SWC를 RootCompostion에 넣는 작업도 동일하게 해준다.

RootCom

AddSWC

  1. 좌측 상단의 EcuExtract를 클릭한 후 ECU Software Components Mapping을 클릭하고 'Ok - Apply'를 클릭한다.

ECUMapping

Apply

  1. 다시 SWC_SeatHeatingControl로 돌아가 Sort Name은 RE_SeatHeatingControl, Symbol 이름은 SeatHeatingControl_func인 Runnable을 생성해준다.

Runnable

  1. 다시 EcuExtract를 클릭한 후 Data Mappings를 선택하고 'SWC_SeatSwitch - Create Ports From Network'를 선택한다.

CreatePort

  1. 'Project - Ok'를 선택한 후 RxPort 부분에서 ECU1_Msg_OE2 왼쪽 박스를 체크한후 'Ok - Ok'를 클릭한다.

Project

RxPort

  1. 우측에 'Add/Remove All - Ok' 클릭을 통해 Port Interface의 Data Elements(Signal)와 통신 Signal을 전부 mapping 해준다.

Add

DataMapping

  1. 11~12번과 같이 'Create Port From Network - Project - Ok'를 선택, Data Access Runnable, Start on DRE 모두 기존에 생성한 RE_SeatHeatingControl 선택하고 사이의 Data Receive Point도 DRPBA(Data Receive Point By Argument)를 선택한 후 , 'Ok - Ok'를 클릭하여 완료한다.

RunnableSelect

  1. IO를 사용하기 위한 Port를 생성한다. 'SWC_SeatHeatingControl- Ports'선택, 'RPort Prototype - + - Client Server Interface - Client'를 선택한다.

RPort

  1. 하단의 IoHwAb_If_DigDir를 선택, Ok를 클릭하여 추가 해준다.

IoHwAb

  1. Short Name을 R_HeatingElement로 변경한 후 아래의 Communication Spec 부분에 Operations에서 WriteDirect를 선택한 후 Enable Required Com Specs를 체크해준다.

ReadDirect

  1. 이어서 Runnables탭의 'Operation - Mode - TriggerAccess'에서 Add를 선택한 뒤 SynchronousServerCallPoint의 R_HeatingControl.WriteDirect선택하고 OK를 클릭한다.

SSCP

  1. Data Received Event에 사용할 Task 생성을 위해 기존 화면에서 하단의 Overview fo Modules에서서 'OS - Task'를 선택하고 우측 상단의 + 클릭 후 Task를 생성한다.

Os

Task

  1. 다음과 같이 Task가 생성되면 아래와 같이 설정해준다. Resourece Ref 부분은 'Browser - OsResource_FG1 선택 - Add' 순서로 설정한다.

NewTask

Taskconfig

  1. 계속해서 'Os - Application'으로 이동하여 OsApplication()을 선택한 후 App_Task_Ref 추가를 위해 Brower를 클릭한다.

OsApplication

  1. 방금 생성한 Task를 선택한 후 'Add - Ok'를 클릭하여 설정을 완료한다.

TaskAdd

  1. 상단메뉴에서 Configure ECU & Generate Code 선택 Generate ECU Configuration 을 클릭한다.

ECUconfig

  1. Next를 클릭하고 Service 부분에 Rte를 선택하여 Next 클릭, RTE : Generate SwcInstance Configuration 가 체크되어 있는지 확인 후 Finish를 선택한다.

selectRte

configfinish

  1. 이어서 Overview of Modules에 Rte를 선택한 후 Task Mapping에 들어가 'SW Component Instance - SWcInstance_SWC_SeatHeatingControl'을 선택해준다.

Rte

SWCInstance

  1. 아래의 OsTask Mapping Table에서 unMapped 선택, 이전 단계에서 생성한 OsTask_CANTest_DataReceivedEvent 선택, 상단의 Event 두개를 선택 후 Add를 클릭하여 설정을 완료한다.

DREMapping

TaskMapping

  1. Configure ECU and Generate Code로 들어가 하단의 Service and I/O를 선택, Svc_IoHwAb를 클릭하여 Table을 열고 P_IoHwAbDigitalDirectLogical_LED01을 선택한다.

SelectLED01

  1. 이어서 상단의 Automatic Connection 우측의 + 버튼을 클릭, Respect Naming Rule의 체크를 해제한 후 생성되는 P_IoHwAbDigitalDirectLogical_LED01↔R_HeatingElement를 선택한 후 Ok를 클릭한다.

IOMapping

  1. 현재 baseproject에서 LED에 해당하는 Port가 PIN_IN으로 설정되어 있기에 수정해주어야 한다.

  2. 다시 상단 메뉴에서 Configure ECU & Generate Code를 선택해주고 아래의 Overview of Modules에서 IoHwAb를 선택하여 준다.

IOHWAB

  1. 이어서 아래의 All Contents를 선택한 후 'IoHwAbDigitalDirect - Logical - IoHwAbDigitalDirectLogical_LED01'을 선택하여 어떤 Port가 LED01으로 설정되어 있는지 확인한다.(현재 그림에서는 PortE 16)

LEDPort

  1. 이전 Configure ECU & Generate Code로 돌아가 하단에 Overview of Modules에서 Port를 선택한다.

Port

  1. 이어서 아래의 Container를 선택한 후 'PortContainer_E - Pin - PortContainer_E_PortPin_16'을 선택하여 Initial Mode를 PORT_PIN_IN에서 PORT_PIN_OUT으로 변경하여 준다.

PortPinConfig

  1. 다시 SWC_SeatHeatingControl로 돌아가 Overview를 선택한 후 하단의 Generate Code를 클릭릭한다.

GenerateCode

  1. 이어진 창에서 Source Folder 우측의 Browser를 클릭한 후 '현재 workspace 하위의 작업중인 프로잭트 - Static_Code - Reference_Code'를 선택 후 확인을 클릭하여 코드의 생성 위치를 지정해 준다. 이후 '확인 - Finish - No'를 클릭해 코드 생성을 완료한다.

Codelocate

  1. Static_Code>Reference_Code>SWC_SeatHeatingControl.c를 선택 후 다음과 같이 코드를 작성하고 Build 버튼을 눌러 다음과 같이 결과가 나오는 것을 확인한다.

Code

Build

  1. 실행 결과는 다음과 같이 나오게 된다. ECU1의 SW를 누르지 않을 경우 Sig1의 write2 값이 0이 된다. 그러므로 ECU2에서 받은 Message의 payload에서 0을 읽어 LED에는 불이 들어오지 않게 된다. ECU1의 SW를 누를 경우 Sig의 write2 값이 1이되고 ECU2에서 read1으로 읽는 값이 1이 된다. 그러므로 LED에는 아래와 같이 불이 들어오는 것을 확인할 수 있다.

Sw&LEDoff

SW&LEDon