Quantcast
Channel: Active questions tagged gcc - Stack Overflow
Viewing all articles
Browse latest Browse all 22070

Stack Frame not correct with GCC and STM32

$
0
0

I am trying to create simple SVC Handler in GNU GCC (Not ARM GCC). If SVC service is called, it enters SVC_Handler() correctly, but when I try to find the SVC number used to call SVC Handler (svc_number), I get value 248 instead of 1.

I'm using CubeMX IDE and Nucleo-F401RE board.

Code:

void SVC_Handler(void)
{
     asm volatile (
            "TST lr, #4\t\n""ITE EQ\t\n""MRSEQ r0, msp\t\n""MRSNE r0, psp\t\n""B %[SVC_Handler_Main]\t\n"
            :
            : [SVC_Handler_Main] "i" (SVC_Handler_Main)
            : "r0"
    );

}

void SVC_Handler_Main(unsigned int* svc_args) {
     uint8_t svc_number;

     svc_number = ((char* )svc_args[6])[-2];
     switch(svc_number) { // <- that's where I get 248 instead of 1
     case SVC_ADD:
         SVC_Add_Handler(svc_args[0], svc_args[1]);
         break;
     default:
         break;
     }
}

int __attribute__ ((noinline)) SVC_Service_Add(int x, int y) {
    svc(SVC_ADD);
}

#define SVC_ADD 1

#define svc(code) asm volatile ("SVC %[immediate]"::[immediate] "I" (code))

I used watch expression with breakpoint after svc_number and it's value is 248, instead of 1 that it should be.

Service Calls (SVC) are used mainly in RTOS design for software to enter privileged mode. ARM GCC has some nice support for SV calls, whereas in GNU GCC you have to do it all yourself. The theory goes like this: When a SV call (in my case SVC_Service_Add() ) is made, it invokes the SVC_Handler(). SVC_Handler() checks which stack is used (main msp or process psp), that information is found by reading bit 2 of Link Register (LR). Depending on that, either msp or psp is saved in r0. After that, compiler puts r0,r1,r2,r3,r12,r14, return address and xPSR in svc_args, so those parameters can be used in SVC_Handler_Main. svc_args[0]=r0, svc_args[1]=r1,...svc_args[6]=SP(the one we are interested in, the one where SVC number is kept). Since Cortex M4 stack is full descending, we need to do [-2] to get the byte of svc_args[6] we are interested in. Since the call to the SVC_Handler was done by the SVC_ADD macro (0x01), ((char *) svc_args[6])[-2] should equal to SVC_ADD, so a proper function can be called from SVC_Handler_Main(). I'm not getting 1, I'm getting 248 for some reason.

Question: why is svc_number equal to 248 whereas I was expecting 1


Viewing all articles
Browse latest Browse all 22070

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>