CAN 드라이버 및 소프트웨어 스택 개요
1. CAN 드라이버와 소프트웨어 스택 개념
1.1 CAN 드라이버란?
CAN(Controller Area Network) 드라이버는 MCU(Microcontroller Unit) 또는 임베디드 시스템에서 CAN 통신을 가능하게 하는 저수준(low-level) 소프트웨어 계층입니다. 이 드라이버는 하드웨어와 상위 애플리케이션 간의 인터페이스 역할을 수행하며, CAN 컨트롤러의 초기화, 데이터 송수신, 인터럽트 처리 등의 기능을 포함합니다.
1.2 CAN 소프트웨어 스택이란?
CAN 소프트웨어 스택은 CAN 드라이버를 포함하여 CAN 통신을 위한 전체적인 소프트웨어 아키텍처를 의미합니다. 일반적으로 CAN 소프트웨어 스택은 다음과 같은 계층으로 구성됩니다.
- 하드웨어 계층: 실제 CAN 컨트롤러 및 PHY(Physical Layer)로 구성됨
- 드라이버 계층: 하드웨어를 제어하는 펌웨어 및 HAL(Hardware Abstraction Layer)
- 프로토콜 계층: CAN 표준(예: CAN 2.0A, CAN 2.0B, CAN FD, ISO 11898 등)에 따른 메시지 처리
- 애플리케이션 계층: 사용자 애플리케이션과 통신하는 최상위 계층
이러한 계층화된 구조를 통해 CAN 통신을 보다 효율적이고 모듈화하여 구현할 수 있습니다.
2. MCU에서 CAN 통신을 위한 소프트웨어 아키텍처
2.1 기본적인 MCU 기반 CAN 아키텍처
MCU에서 CAN 통신을 구현할 때, 보통 다음과 같은 구조를 따릅니다.
+------------------------------+
| 애플리케이션 레이어 |
+------------------------------+
| 프로토콜 스택 (CANopen 등) |
+------------------------------+
| CAN 드라이버 및 HAL |
+------------------------------+
| 하드웨어 (CAN 컨트롤러) |
+------------------------------+
2.2 CAN 드라이버 주요 기능
MCU에서 CAN 드라이버는 다음과 같은 기능을 수행합니다.
- CAN 컨트롤러 초기화
- CAN 통신 속도 설정(예: 500kbps, 1Mbps)
- 필터 및 마스크 설정 (수신할 메시지 ID 필터링)
- 인터럽트 활성화
- 데이터 송수신
- 송신 버퍼 관리 및 메시지 송신
- 수신 버퍼 관리 및 메시지 수신
- 송수신 완료 인터럽트 처리
- 에러 처리
- 버스 충돌 감지 및 복구
- 에러 카운터 확인 및 CAN 버스 복귀
- 저전력 모드 지원
- 슬립 모드 및 웨이크업 처리
2.3 HAL을 이용한 CAN 드라이버 구현 (예제 코드)
대부분의 MCU 제조사는 HAL(Hardware Abstraction Layer)을 제공하여 CAN 드라이버를 쉽게 사용할 수 있도록 합니다. 여기서는 ESP32 IDF(ESP-IDF)를 활용한 CAN 초기화 및 메시지 송수신 예제를 살펴보겠습니다.
ESP32 IDF를 이용한 CAN 초기화 및 송수신 예제
ESP32는 twai
드라이버를 사용하여 CAN을 지원합니다. 다음은 ESP-IDF를 이용하여 CAN을 설정하는 예제입니다.
#include "driver/twai.h"
void CAN_Init(void) {
twai_general_config_t g_config = TWAI_GENERAL_CONFIG_DEFAULT(GPIO_NUM_21, GPIO_NUM_22, TWAI_MODE_NORMAL);
twai_timing_config_t t_config = TWAI_TIMING_CONFIG_500KBITS();
twai_filter_config_t f_config = TWAI_FILTER_CONFIG_ACCEPT_ALL();
if (twai_driver_install(&g_config, &t_config, &f_config) != ESP_OK) {
printf("Failed to install CAN driver\n");
return;
}
if (twai_start() != ESP_OK) {
printf("Failed to start CAN driver\n");
return;
}
printf("CAN driver initialized and started successfully\n");
}
ESP32 IDF를 이용한 CAN 메시지 송신
void CAN_SendMessage(void) {
twai_message_t message;
message.identifier = 0x123;
message.extd = 0;
message.rtr = 0;
message.data_length_code = 8;
memcpy(message.data, "ESP32CAN", 8);
if (twai_transmit(&message, pdMS_TO_TICKS(1000)) != ESP_OK) {
printf("Failed to send CAN message\n");
} else {
printf("CAN message sent successfully\n");
}
}
ESP32 IDF를 이용한 CAN 메시지 수신
void CAN_ReceiveMessage(void) {
twai_message_t message;
if (twai_receive(&message, pdMS_TO_TICKS(1000)) == ESP_OK) {
printf("Received message with ID: 0x%X, Data: ", message.identifier);
for (int i = 0; i < message.data_length_code; i++) {
printf("%02X ", message.data[i]);
}
printf("\n");
} else {
printf("Failed to receive CAN message\n");
}
}
ESP32 IDF를 사용하면 위와 같은 방식으로 CAN을 쉽게 초기화하고 송수신할 수 있습니다.
3. 주요 OS에서의 CAN 스택 지원
3.1 FreeRTOS에서의 CAN 지원
FreeRTOS는 기본적으로 CAN 스택을 제공하지 않지만, 하드웨어 드라이버를 활용하여 사용자 레벨에서 구현할 수 있습니다. 일반적으로 FreeRTOS의 큐(Queue) 또는 이벤트 그룹을 사용하여 CAN 메시지를 관리합니다.
FreeRTOS 기반 CAN 송수신 예제
void CAN_ReceiveTask(void *argument) {
CAN_RxHeaderTypeDef rxHeader;
uint8_t rxData[8];
while (1) {
if (HAL_CAN_GetRxMessage(&hcan, CAN_RX_FIFO0, &rxHeader, rxData) == HAL_OK) {
// 수신된 데이터 처리
}
vTaskDelay(pdMS_TO_TICKS(10));
}
}
3.2 Zephyr에서의 CAN 지원
Zephyr RTOS는 표준 CAN 스택을 제공하며, devicetree
및 kconfig
설정을 통해 CAN 인터페이스를 설정할 수 있습니다.
Zephyr에서 CAN을 설정하는 방법은 다음과 같습니다.
prj.conf
파일에서 CAN 활성화CONFIG_CAN=y CONFIG_CAN_LOOPBACK=y
devicetree
에서 CAN 인터페이스 정의&can0 { status = "okay"; };
- Zephyr에서 CAN 송신 코드 예제
struct can_frame frame; frame.id = 0x123; frame.dlc = 8; memcpy(frame.data, "ZephyrCAN", 8); can_send(can_dev, &frame, K_MSEC(100), NULL, NULL);
3.3 Linux에서의 CAN 지원
Linux에서는 SocketCAN
을 통해 CAN 인터페이스를 관리합니다. ip
및 candump
명령어를 이용하여 쉽게 CAN 메시지를 송수신할 수 있습니다.
- CAN 인터페이스 활성화
sudo ip link set can0 up type can bitrate 500000
- CAN 메시지 모니터링
candump can0
- CAN 메시지 송신
cansend can0 123#1122334455667788
4. 결론
CAN 드라이버 및 소프트웨어 스택은 MCU에서 CAN을 구현하는 데 필수적인 요소입니다. 주요 임베디드 OS(FreeRTOS, Zephyr, Linux)는 각기 다른 방식으로 CAN을 지원하며, 적절한 소프트웨어 아키텍처를 구성하는 것이 중요합니다. 본 글에서는 CAN 드라이버의 개념과 주요 기능을 설명하고, OS별 CAN 스택 지원 방식에 대해 소개했습니다. 향후 프로젝트에서 CAN을 활용할 때, 이러한 개념을 참고하여 적절한 구조를 설계하시길 바랍니다.
'CAN 통신' 카테고리의 다른 글
CAN 데이터 송수신 (ESP32 IDF 예제) (0) | 2025.02.25 |
---|---|
MCU에서 CAN 초기화 및 설정 (ESP32 기준) (0) | 2025.02.24 |
CAN 인터페이스 및 주요 하드웨어 (0) | 2025.02.22 |
CAN 통신의 전기적 특성 및 물리 계층 분석 (0) | 2025.02.21 |
CAN 하드웨어 구성 및 주요 요소 (0) | 2025.02.20 |