
DiagnosticSessionControl(0x10), SecurityAccess(0x27), RoutineControl(0x31)의 요청·응답과 중단 구간을 확인했습니다.
BOOTLOADER EVIDENCE
AURIX TC234LP에서 요구사항을 메모리 구획과 UDS 처리 흐름으로 구체화하고, MCAL·RTE를 활용해 Application 백업·복원과 SHA-256 비교 분기를 구현했습니다. CAN 응답 중단을 Trace32로 추적해 비정렬 word 접근을 특정한 과정부터 수정 코드·당시 재검증 기록까지 소개합니다.
01 / 프로젝트 역할
개인 프로젝트 · 요구사항 분석, Flash 메모리 구성, 백업·복원 기능 구현과 Trace32 디버깅을 담당했습니다.
02 / 트러블슈팅
TRACE32 · RESTORE
SID 0x31 RoutineControl 처리 중 발생한 CAN 응답 중단을 Trace32의 함수 Breakpoint, Register·Variable View와 DMI Trap 정보로 추적했습니다. copyBuf, A5, DEADD가 동일한 비정렬 주소 0x7000240D를 가리키는 것을 확인해 FlsLoader_Write() source buffer의 홀수 주소 접근을 원인으로 특정했습니다.
아래 수정·재검증은 교육 당시 기록입니다. 현재 ECU 재시험 결과와 구분하며, 이후 정적 리뷰에서 발견한 미해결 문제는 CODE REVIEW에서 확인할 수 있습니다.
SID 0x31 RoutineControl의 RCOR_EraseMemory_App 처리에서 EA_AppToBackup() 호출 이후 ECU의 CAN 응답이 중단됐습니다.Break.Set EA_AppToBackup 후 함수 진입과 FlsLoader_Write() 인수를 추적했습니다.copyBuf와 Register A5가 모두 0x7000240D를 가리키는 것을 확인했습니다.ALN Error와 DEADD = 0x7000240D를 확인해 오류 주소를 교차 검증했습니다.Break.Set 0x80027800++0xFF /Program /Onchip 적용 후 BTV = 0x80027800, PC = 0x80027840 상태를 확인했습니다.static uint8 copyBuf[]가 홀수 주소에 배치되어 word load에 필요한 정렬을 충족하지 못했습니다. Flash Loader 고유의 4바이트 계약은 별도 문서 확인이 필요합니다.uint32 backing array와 uint8* view로 정렬을 확보한 뒤 Application→Backup→Application 양방향 Write·Read와 SHA-256 판정을 다시 수행했습니다.P:0x701006CA ld16.w d15,[a5]는 source 주소를 읽는 word load입니다. A5 = 0x7000240D는 홀수 주소입니다. Trap 진입 시 PC = 0x80027840은 BTV = 0x80027800에서 0x40 떨어져 Class 2에 해당하고, D15 = 4는 TIN 4(ALN)입니다. DMI의 DEADD = 0x7000240D도 같은 주소를 가리킵니다.
TriCore의 비주변장치 메모리에서 데이터 레지스터 word load는 2바이트 정렬을 허용합니다. 이 사례는 그 조건부터 위반했습니다. uint32 저장 공간으로 4바이트 정렬을 확보한 수정과 CPU의 최소 접근 조건을 구분합니다. Infineon TC1.6 아키텍처 · Alignment / Trap
아래 화면은 실제 프로젝트 수행 중 CANoe와 Trace32에서 수집했습니다. UDS 요청·응답, 함수 인수, Register, Variable View와 DMI 상태를 함께 비교해 Memory Alignment Error의 발생 주소와 원인을 확인했습니다.

DiagnosticSessionControl(0x10), SecurityAccess(0x27), RoutineControl(0x31)의 요청·응답과 중단 구간을 확인했습니다.

copyBuf 시작 주소와 A5, Trace32 오류 표시가 0x7000240D로 일치했습니다.

ALN Error와 DEADD = 0x7000240D를 확인해 정렬 위반 주소를 교차 검증했습니다.

BTV = 0x80027800, PC = 0x80027840을 확인해 Trap Vector 범위 진입을 직접 포착했습니다.
수정 전
static uint8 copyBuf[MEMORY_COPY_CHUNK_SIZE];
memcpy(copyBuf,
(const void *)(MEMORY_ADDRESS_APPLICATION + offset),
copySize);
*errorResult = (uint8)FlsLoader_Write(
MEMORY_ADDRESS_BACKUP + offset,
copySize,
copyBuf);
수정 후 핵심
uint32 i;
static uint32 copyBuf[8];
uint8* copyBufByte = (uint8*)copyBuf;
for (i = 0u; i < copySize; i++)
{
copyBufByte[i] = *((const uint8*)(MEMORY_ADDRESS_APPLICATION + offset + i));
}
보관된 수정 후 소스의 발췌입니다. 32바이트 backing buffer를 두고 바이트 단위로 복사합니다. uint8이 unsigned char인 타입 정의에서는 MISRA C:2012 Rule 11.3의 문자형 포인터 예외와 연결할 수 있습니다. 전체 MISRA 준수 판정은 아닙니다.
| 방향 | Erase | Source | Destination | 검증 |
|---|---|---|---|---|
| Application Primary → Backup | PFLASH_AREA_APPICATION_SECONDARY | MEMORY_ADDRESS_APPLICATION + offset | MEMORY_ADDRESS_BACKUP + offset | Write return, read-back, SHA-256 |
| Backup → Application Primary | PFLASH_AREA_APPICATION_PRIMARY | MEMORY_ADDRESS_BACKUP + offset | MEMORY_ADDRESS_APPLICATION + offset | Write return, read-back, SHA-256 |
정렬 수정 후 Application Primary→Backup(EA_AppToBackup())과 Backup→Application Primary(EA_AppRestore()) 양방향 Flash Write·Read, UDS 응답 흐름과 SHA-256 판정을 다시 확인했습니다.
교육용 프레임워크: Tester → CAN·ISO-TP → BswCom → BswDcm → RTE 호출 → EcuAbsFls → FlsLoader → Flash
Programming Session · DiagnosticSessionControl(0x10) → SecurityAccess(0x27) → Backup·Erase · RoutineControl(0x31) → RequestDownload(0x34) → TransferData(0x36) → RequestTransferExit(0x37) → RoutineControl(0x31)에서 SHA-256 확인 → ECUReset(0x11)
위 경로는 교육 프로젝트의 모듈명입니다. AUTOSAR Classic의 표준 진단 경로(CanTp → PduR → Dcm)와 구분합니다.
valid pattern 확인과 SHA-256 비교 분기 구현 — 기록 순서 결함은 이후 정적 리뷰에서 발견아래는 교육 당시 구현과 기록의 정리입니다. 이후 발견한 길이 상한·권한 검사 누락과 valid pattern 기록 순서 문제는 CODE REVIEW에 구분했습니다. 개선안은 적용·빌드·ECU 검증하지 않았으며, 정상 경로의 동작 기록이 모든 실패 조건에서의 안전성을 뜻하지 않습니다.
요구사항 PDF, Notion 수행 기록, 보관 소스를 대조해 프로젝트 1–4의 구현 범위를 정리했습니다. 아래 내용은 소스와 당시 기록의 비교이며 새 ECU 시험 결과가 아닙니다.
| 요구사항 | 구현 내용 | 확인 근거 |
|---|---|---|
| UDS 리프로그래밍 | 세션 진입·보안 접근·삭제·다운로드·무결성 검사·리셋 연결 | BswDcm의 대표 경로에 사용하는 고유 SID 7개. RoutineControl의 Erase·Check는 같은 서비스의 두 루틴 |
| Flash App 영역 백업·복원 | Primary → Backup 보존, 실패 시 Backup → Primary 복원 | EA_AppToBackup()·EA_AppRestore(), Notion 프로젝트 1의 중단 후 복원 수행 기록 |
| 메모리 구획 | 링커 스크립트로 Primary·Backup·해시·valid pattern 영역 지정 | PDF 117쪽 링크 설정과 소스 주소 정의 대조. Primary 0x80100000, Backup 0x80180000 |
| AUTOSAR 기반 MCAL·RTE 활용 | BswDcm → RTE → EcuAbsFls → Flash Loader 호출 연결 | 진단 처리·ECU 추상화·드라이버 인터페이스 활용 범위. 전체 AUTOSAR 표준 스택 자체 구현이나 적합성 검증을 뜻하지 않음 |
| SW Binary 변경 검출 | SHA-256 계산·저장 해시 비교, 불일치 시 NRC 0x72와 Restore 요청 | 프로젝트 2·3 소스와 Notion의 정상·변조 Binary 수행 기록. 고정 키 접두어 해시는 HMAC·전자서명이 아님 |
| SW Binary 바이트 변환 | TransferData에서 데이터에 -0x05 적용 후 기록, 해시 바이트 제외 | 프로젝트 4 소스와 +0x05/-0x05 변환 관계. 암호학적 기밀성을 보장하는 방식은 아님 |
메모리 운용 차이: PDF의 구현 예시는 신규 Binary를 Secondary에서 검사한 뒤 Primary로 복사합니다. 본 프로젝트의 Notion 기록과 보관 소스는 기존 Primary를 Backup에 보존하고 신규 Binary를 Primary에 기록한 뒤, 검사 실패 시 복원하는 흐름입니다.
최종 소스에 포함되지 않은 항목: Notion 프로젝트 5의 다운로드 중 SHA-256 누적 계산 예시는 최종 소스에 반영되어 있지 않습니다. 프로젝트 6의 시도·성공 횟수 제한도 구현 성과에 포함하지 않았습니다. 최종 소스의 해시 계산은 RoutineControl에서 Primary를 다시 읽는 방식입니다.
AURIX TC234LP Bootloader의 PFlash·DFlash 구획과 Backup·Restore 방향을 실제 링커 주소로 정리했습니다.
| 영역 | 주소 범위 | 크기 | 용도 | 관련 함수·심볼 |
|---|---|---|---|---|
| Bootloader User | 0x80000000–0x80025FFF | 152 KiB | Bootloader 코드와 BMHD 인접 영역, 실행 시작점 0x80000020 | RESET |
| Bootloader INTTAB·Trap | 0x80026000–0x80027FFF | 8 KiB | 인터럽트 벡터 및 Trap Table | INTTAB 0x80026000, BTV 0x80027800 |
| Application Primary | 0x80100000–0x8017DFFF | 504 KiB | 현재 실행 대상 Application Binary | MEMORY_ADDRESS_APPLICATION, EA_AppToBackup() |
| Application INTTAB | 0x8017E000–0x8017FFBF | 8 KiB - 64 B | Application 벡터 영역 | pflash_app_inttab |
| SHA-256 저장 영역 | 0x8017FFC0–0x8017FFDF | 32 B | 계산값과 비교하는 저장 해시 (전자서명 아님) | MEMORY_ADDRESS_SIGNATURE |
| Valid Pattern | 0x8017FFE0–0x8017FFFF | 32 B | 리프로그래밍 완료·실행 가능 상태 표시 | pflash_app_valid |
| Application Backup | 0x80180000–0x801FFFFF | 512 KiB | 업데이트 전 Application 보존 및 실패 복구 | EA_AppToBackup(), EA_AppRestore() |
| DFlash Bank 0 | 0xAF000000–0xAF01FFFF | 128 KiB | 비휘발성 상태·로그 저장 후보 영역 | dflash0 |
| DFlash Bank 1 | 0xAF100000–0xAF103FFF | 16 KiB | 비휘발성 보조 영역 | Bank 1 (심볼 원본 재확인 필요) |
#define INTTAB 0x80026000
#define RESET 0x80000020
#define IFXTRAPTAB (INTTAB + 0x1800)
memory pflash_app_valid {
size = 32;
map cached(dest_offset=0x8017FFE0, size=32);
}
memory pflash_app_backup {
size = 512k;
map cached(dest_offset=0x80180000, size=512k);
}
Bootloader 링크 설정에서 Application과 Backup은 reserved rom으로 선언되어 Bootloader 코드가 해당 영역에 배치되지 않습니다. SHA-256은 이 프로젝트에서 Binary 변경 여부를 판단하는 무결성 검사로 사용했습니다.
UDS 7개 서비스의 대표 호출 흐름과 Backup·Restore 분기를 요약했습니다. 전체 오류 처리의 완전성이나 안전성을 입증하는 시퀀스는 아닙니다.
| 순서 | 서비스 | 당시 구현 흐름 | 확인 범위·미해결 문제 |
|---|---|---|---|
| 1 | 0x10 DiagnosticSessionControl | Programming Session 진입 | 정상 절차의 진입 흐름. 모든 서비스의 세션 검사를 보장하지 않음 |
| 2 | 0x27 SecurityAccess | Seed/Key 교환 분기 | 고정 Seed/Key 사용. EraseMemory 권한 검사 누락은 별도 미해결 |
| 3 | 0x31 RoutineControl | EA_AppToBackup() 후 RID_EraseMemory 실행 | 요청 길이·세션·권한·physical request 검사 누락. Backup 실패 시 Erase 차단은 공개 근거로 입증하지 못함 |
| 4 | 0x34 RequestDownload | 주소·길이와 전송 상태 초기화 | 광고한 블록 길이와 실제 TransferData 길이 상한 검사는 별개이며, 후자는 누락 |
| 5 | 0x36 TransferData | Block Sequence 처리, 바이트 변환 후 Primary에 Binary 기록 | 길이 상한·ISO-TP 재조립 경계 검사 누락. 순서 오류 시험은 근거 부족 |
| 6 | 0x37 RequestTransferExit | 전송 길이 확인 후 valid pattern 기록 | 이 단계에서는 해시를 비교하지 않음. SHA-256 검증 전에 valid pattern을 기록하는 순서 결함. 수정안 미적용 |
| 7 | 0x31 RID_CheckProgrammingDependencies | Primary를 읽어 키 접두어 SHA-256 계산·비교, 불일치 시 Backup 복구 | 교재의 Secondary 검증 후 Primary 복사 방식과 다름. 완전한 의존성·안전 조건 검사를 입증한 것은 아님 |
| 8 | 0x11 ECUReset | Reset 및 Application 실행 경로 | Restore 후 Application 정상 진입은 별도 실행 근거 부족 |
SessionControl 응답 50 02 00 32 01 F4는 P2=50ms, P2*=5000ms를 광고합니다. P2*는 ResponsePending 이후의 대기시간이며 처음부터 5초 무응답을 허용하는 뜻이 아닙니다.
보관된 복사 루프는 32바이트 단위로 EA_wdgTriggerUpdateSlow()를 호출한 다음 인터럽트를 비활성화하고 Flash write를 수행합니다. 호출 존재는 확인했지만 watchdog 드라이버의 동작, erase 최장 지연과 진단 응답 기한 준수는 실행 검증하지 않았습니다. 공개 소스 범위에서는 이 장시간 처리에 대한 NRC 0x78 송신을 확인하지 못했습니다.
코드 영역은 504KiB이지만 복사 루프의 MEMORY_SIZE_APPLICATION은 512KiB−32B = 524256B입니다. Flash 처리 시간이나 다운로드 처리량의 측정값으로 혼동하지 않습니다.
아래 RID는 교육 프로젝트 정의입니다. 표준 eraseMemory 0xFF00, checkProgrammingDependencies 0xFF01과 다르며 표준값으로 제시하지 않습니다.
#define RID_CheckProgrammingDependencies 0x0001u
#define RID_EraseMemory 0x0002u
#define RCOR_EraseMemory_App 0xF001u
31 01 00 02 F0 01
| | |-----| |---|
SID RID RCOR
BswDcm
→ Rte_Call_BswDcm_rEcuAbsFls_erasePflashBlock()
→ REoiEcuAbs_pEcuAbsFls_erasePflashBlock()
→ EA_erasePflashBlock()
설계 의도와 당시 구현의 차이: SHA-256 불일치 시 EA_AppRestore()를 호출하는 복구 분기는 구현했지만, RequestTransferExit에서 해시 검증 전에 valid pattern을 기록했습니다. 검증 성공 후에만 valid pattern을 기록하도록 바꾸는 것은 미적용 개선안입니다. 이 자료는 불일치·전원 중단 상황에서 신규 Application 부팅이 항상 차단된다고 주장하지 않습니다.
직접 보여줄 수 있는 캡처·소스와 수행 서술을 구분했습니다. 아래 자료는 보관 기록이며 현재 환경에서 새 빌드나 ECU 재시험을 수행한 결과가 아닙니다.
| 연결 ID | 확인 내용 | 근거 유형 | 확인 범위 |
|---|---|---|---|
| BL-TC-09 | CAN 응답 중단과 Alignment Trap | CANoe·Trace32 캡처 | 오류 명령·주소·Trap 원인의 연결 |
| BL-TC-10 | 정렬 버퍼 수정 | 수정 전후 소스 | uint32 저장 공간과 바이트 복사 변경 확인; 수정 후 ECU 실행 로그는 공개 자료에 없음 |
| BL-TC-01·05·06·07 | 다운로드·해시 불일치·Backup·Restore | 구현 흐름과 수행 기록 요약 | 기능 분기와 재검증 서술; 독립적으로 실행 PASS를 확인할 원본 로그는 비공개 |
| BL-TC-04 | valid pattern 기록 순서 | 정적 코드 리뷰 | 검증 전 valid 기록 문제 확인; 중단 시 안전 부팅 성공으로 판정하지 않음 |
길이·권한 검사와 valid pattern 순서 개선안은 미적용·미검증입니다. 호스트 단위 테스트를 추가하더라도 Flash 하드웨어·전원 중단·실제 부팅 시험을 대신하지 않습니다.
기능 동작으로 끝내지 않고 완성된 C/H를 다시 읽어 입력 경계와 검증 순서를 점검했습니다. 아래는 스스로 찾아 문서화한 결함입니다.
TransferData 길이 상한 미강제 — RequestDownload가 광고한 블록 길이는 514바이트지만 transferData()는 diagDataLengthRx < 3만 거부합니다. ISO-TP First Frame은 12bit 길이 필드로 최대 4,095바이트를 선언할 수 있어, 재조립 경로가 이를 그대로 넘기면 514바이트 버퍼에 최대 3,579바이트를 넘겨 쓸 수 있습니다.valid pattern 기록 순서 — RequestTransferExit에서 SHA-256 검증 전에 valid pattern을 기록합니다. 검증에 성공한 뒤에 기록하도록 순서를 바꿔야 합니다.EraseMemory — 정확한 요청 길이, Programming Session, SecurityAccess, physical request를 확인하지 않고 Primary를 삭제합니다.이 항목들은 게시된 소스를 정적으로 검토해 확인한 것이며, 개선안을 실제로 구현·빌드·ECU에서 검증한 결과가 아닙니다. 교육 당시 snapshot은 무결성 비교를 위해 수정하지 않고 보존했습니다.