[문의] Exception Handler 관련
418
안녕하세요. 금일 free-rtos 강좌를 완강했습니다. 강의 및 질의/응답을 통해서 부족한 부분을 많이 채웠습니다.
강의와 연관성이 없는 질문하나 드립니다. 개인적으로, 강사님이 알려주신 환경 (cubeide) 에 exception handler를 적용해보고 있는데, 쉽지 않네요.
exception handler는 cortex-m3 계열의 core와 IAR 컴파일러 환경에서 작성된 source같은데....cortex-m4f 및 gcc 기반으로 변경하려니 exception 발생 시 자동으로 stacking되는 register도 floating point 연산이 없는 core와 달리 늘어난 것 같고, assembler도 잘 모르겠고 .... 난항입니다.
혹시, cubeide, cortex-m4f 환경에서, exception handler가 적용된 참조할만한 예제가 있으면 도움 부탁드립니다.
답변 3
0
안녕하세요. chucky2님!
완강을 축하드립니다. 질문도 많이하시고 ^^ 저도 즐거웠습니다.
이 강좌 마지막 챕터(포팅 사례와 소스코드)를 보시면 다양한 STM32-M4F 포팅 소스들이 있습니다.
혹시 원하시는 것이 다른 것이었다면 다시 글 남겨주세요.
마지막으로 감사드리며, 괜찮으시다면 수강평 부탁드려요. ㅎ~
0
수강평은 남기도록 하죠~
궁금한 내용은 아래와 같습니다. 목적은 exception handler를 적용하여 hard/bus/memory management/usage fault 등 발생 시, stack 및 system control register를 정보를 활용하여 문제점을 확인하는 겁니다.
IAR 컴파일러 및 cortex-m3에서 작성된 내용을 cubeide 및 cortex-m4f 환경으로 변경해보고자 하는데, IAR vs GCC, floating point 유/무에 따라서 적용하는게 좀 다른가봅니다.
관련해서 참조할만한 자료가 있을까요? 컴파일러가 다르다는게 ....정말 간단하게 적용이 쉽지 않네요.
/* Call the clock system initialization function.*/
bl SystemInit
/* Call static constructors */
bl __libc_init_array
/* Call the application's entry point.*/
bl main
bx lr
.size Reset_Handler, .-Reset_Handler
.section .text._HardFault_Handler,"ax",%progbits
.weak _HardFault_Handler
.type _HardFault_Handler, %function
_HardFault_Handler:
PUSH {r0, lr}
ADD r0, sp, #8
LDR r1, [sp, #4]
MRS r2, psp
BL HardFault_Handler
POP {r0, pc}
.size _HardFault_Handler, .-_HardFault_Handler
.section .text._UsageFault_Handler,"ax",%progbits
.weak _UsageFault_Handler
.type _UsageFault_Handler, %function
_UsageFault_Handler:
PUSH {r0, lr}
/*BL _Print_Reg*/
ADD r0, sp, #8
LDR r1, [sp, #4]
MRS r2, psp
BL UsageFault_Handler
POP {r0, pc}
.size _UsageFault_Handler, .-_UsageFault_Handler
.section .text._BusFault_Handler,"ax",%progbits
.weak _BusFault_Handler
.type _BusFault_Handler, %function
_BusFault_Handler:
PUSH {r0, lr}
/*BL _Print_Reg*/
ADD r0, sp, #8
LDR r1, [sp, #4]
MRS r2, psp
BL BusFault_Handler
POP {r0, pc}
.size _BusFault_Handler, .-_BusFault_Handler
g_pfnVectors:
.word _estack
.word Reset_Handler
.word NMI_Handler
.word _HardFault_Handler /*.word HardFault_Handler*/
.word _MemManage_Handler
.word _BusFault_Handler
.word _UsageFault_Handler
.word 0
.word 0
.word 0
.word 0
void HardFault_Handler(unsigned int * sp, unsigned int lr, unsigned int * psp);
void HardFault_Handler(unsigned int * sp, unsigned int lr, unsigned int * psp)
{
int i;
printf("Hard Fault!\n");
printf("LR(EXC_RETURN)=0x%x\n", lr);
printf("MSP=0x%p\n", sp);
printf("PSP=0x%p\n", psp);
if((lr & 0xF) == 0x1)
{
printf("Exception occurs from handler mode\n");
for(i=0; i<(sizeof(Stack_reg)/sizeof(Stack_reg[0])); i++)
{
printf("MSP[%d],%s=0x%x\n", i, Stack_reg[i], sp[i]);
}
}
else
{
printf("Exception occurs from thread mode\n");
for(i=0; i<(sizeof(Stack_reg)/sizeof(Stack_reg[0])); i++)
{
if((lr & 0xF) == 0x9) printf("MSP[%d],%s=0x%x\n", i, Stack_reg[i], sp[i]);
else printf("PSP[%d],%s=0x%x\n", i, Stack_reg[i], psp[i]);
}
}
printf("HFSR(Hard Fault Reason) => 0x%lx\n", SCB->HFSR);
printf("SHCSR => 0x%lx\n", SCB->SHCSR);
printf("CFSR(Fault Reason) => 0x%lx\n", SCB->CFSR);
printf("MMFAR => 0x%lx\n", SCB->MMFAR);
printf("BFAR => 0x%lx\n", SCB->BFAR);
SCB->HFSR = (1u << 31)|(30 << 1)|(1 << 1);
SCB->CFSR = 0xffff << 0;
for(;;);
}이런 식으로 진행 중입니다....
0
안녕하세요. chucky2님!
질문하신 내용이 FreeRTOS 와 직접적인 관계는 없는것이었군요. ㅎ
폴트와 같은 익셉션 발생시 문제 해결에 도움이 될만한 일종의 helper 를 만들고 싶어하시는 것으로 이해하였습니다.
IAR, KEIL, CUBEIDE(GCC) 모두 어셈블러 문법이 조금씩 다릅니다. 인스트럭션이야 동일하지만, 컴파일러마다 지시어(directives) 가 다른 것이지요.
이는 컴파일러 툴마다의 문법 차이를 확인하면서 일일이 수정하시는 수밖에 없습니다. 특별한 방법이란 있을 수 없죠. 이것도 분명히 일종의 포팅(PORTING)으로 보며, 컴파일러 이식 행위입니다.
CM3 과 달리 CM4 에는 FPU가 있습니다. 하지만, 이것을 사용하지 않는다면 디버깅시 fp 컨텍스트(e.g. d0, d1, d2 ... ) 는 고려하지 않으셔도 되요.
위에 샘플로 보여주신 것처럼 진행하시면 되겠네요. ^^ 적어주신 내용을 보면 어셈블리어도 직접 다루실 수 있는 것으로 보입니다. 혹시 어셈블리 언어에 대한 정리된 내용이 필요하시면 지난 6월에 론칭한 제 강좌('ARM CORTEX 프로세서 프로그래밍') 가 좋습니다. 참고해주세요 ㅎㅎ





