static void prvSVCHandler( unsigned long *pulParam ) { unsigned char ucSVCNumber; /* The stack contains: r0, r1, r2, r3, r12, r14, the return address and xPSR. The first argument (r0) is pulParam[ 0 ]. */ ucSVCNumber = ( ( unsigned char * ) pulParam[ portOFFSET_TO_PC ] )[ -2 ]; switch( ucSVCNumber ) { case portSVC_START_SCHEDULER : *(portNVIC_SYSPRI1) |= portNVIC_SVC_PRI; prvRestoreContextOfFirstTask(); break; case portSVC_YIELD : *(portNVIC_INT_CTRL) = portNVIC_PENDSVSET; break; case portSVC_RAISE_PRIVILEGE : __asm volatile ( " mrs r1, control \n" /* Obtain current control value. */ " bic r1, #1 \n" /* Set privilege bit. */ " msr control, r1 \n" /* Write back new control value. */ :::"r1" ); break; default : /* Unknown SVC call. */ break; } }
static void prvSVCHandler(uint32_t *pulParam ) { uint8_t ucSVCNumber; /* The stack contains: r0, r1, r2, r3, r12, r14, the return address and xPSR. The first argument (r0) is pulParam[ 0 ]. */ ucSVCNumber = ( ( uint8_t * ) pulParam[ portOFFSET_TO_PC ] )[ -2 ]; switch( ucSVCNumber ) { case portSVC_START_SCHEDULER : *(portNVIC_SYSPRI1) |= portNVIC_SVC_PRI; prvRestoreContextOfFirstTask(); break; case portSVC_YIELD : *(portNVIC_INT_CTRL) = portNVIC_PENDSVSET; /* Barriers are normally not required but do ensure the code is completely within the specified behaviour for the architecture. */ __asm volatile( "dsb" ); __asm volatile( "isb" ); break; case portSVC_SYSCALL : { /* Read the syscall index from the instruction that raised this syscall. */ uint16_t syscall_index = ((uint16_t*)pulParam[portOFFSET_TO_PC])[0]; pulParam[portOFFSET_TO_PC] = vApplicationStartSyscall(syscall_index); /* Modify the control register to raise the thread mode privilege level */ __asm volatile ( " mrs r1, control \n" /* Obtain current control value. */ " bic r1, #1 \n" /* Set privilege bit. */ " msr control, r1 \n" /* Write back new control value. */ :::"r1" ); /* Now we're going to return from this ISR. If everything goes right, we'll land in the address returned from vApplicationStartSyscall in privileged mode. */ } break; default : /* Unknown SVC call. */ break; } }
static void prvSVCHandler( uint32_t *pulParam ) { uint8_t ucSVCNumber; /* The stack contains: r0, r1, r2, r3, r12, r14, the return address and xPSR. The first argument (r0) is pulParam[ 0 ]. */ ucSVCNumber = ( ( uint8_t * ) pulParam[ portOFFSET_TO_PC ] )[ -2 ]; switch( ucSVCNumber ) { case portSVC_START_SCHEDULER : *(portNVIC_SYSPRI1) |= portNVIC_SVC_PRI; prvRestoreContextOfFirstTask(); break; case portSVC_YIELD : *(portNVIC_INT_CTRL) = portNVIC_PENDSVSET; /* Barriers are normally not required but do ensure the code is completely within the specified behaviour for the architecture. */ __asm volatile( "dsb" ); __asm volatile( "isb" ); break; case portSVC_RAISE_PRIVILEGE : __asm volatile ( " mrs r1, control \n" /* Obtain current control value. */ " bic r1, #1 \n" /* Set privilege bit. */ " msr control, r1 \n" /* Write back new control value. */ :::"r1" ); break; default : /* Unknown SVC call. */ break; } }