Flash 페이지는 2KB인데 CAN 프레임은 8바이트. 256개 프레임이 필요하다.
데이터 프레임 구조
Byte 0: 시퀀스 번호 (0~255)
Byte 1-7: 데이터 (7바이트)
시퀀스 번호로 프레임 순서를 구분한다. 2KB = 7바이트 × 293프레임 ≈ 294프레임 필요.
처리 함수
void Handle_DataFrame(uint8_t *data) {
uint8_t seq = data[0];
// 버퍼에 저장
memcpy(&g_page_buffer[seq * 7], &data[1], 7);
g_received_frames++;
// 페이지 완료?
if (g_received_frames >= 293) {
// Flash 쓰기
Flash_WritePage(g_current_page, g_page_buffer);
g_current_page++;
g_received_frames = 0;
// 응답
CAN_Send(0x5FE, 0x43, g_current_page);
}
}
Flash 쓰기
void Flash_WritePage(uint32_t page, uint8_t *data) {
uint32_t addr = BUFFER_START + page * 2048;
Flash_Unlock();
Flash_ErasePage(addr);
for (int i = 0; i < 2048; i += 2) {
uint16_t halfword = data[i] | (data[i+1] << 8);
Flash_WriteHalfWord(addr + i, halfword);
}
Flash_Lock();
}
버퍼 영역(0x08004000)에 먼저 쓴다. 검증 후에 앱 영역으로 복사.
CRC 검증
모든 페이지 전송 후:
void Handle_Verify(void) {
uint32_t crc = CalcCRC32(BUFFER_START, g_total_size);
if (crc == g_expected_crc) {
// 버퍼 → 앱 영역 복사
CopyBufferToApp();
CAN_Send(0x5FE, 0x45, 0); // OK
} else {
CAN_Send(0x5FE, 0x4F, 0); // FAIL
}
}
다음 글에서 Python 업로더 제작.