Esempio n. 1
0
File: kos.c Progetto: puchinya/kos
void kos_init_regs(void)
{
	uint32_t msp = __get_MSP();
	__set_PSP(msp);
	__set_MSP((uint32_t)g_kos_isr_stk + g_kos_isr_stksz);
	__set_CONTROL(2);
}
Esempio n. 2
0
/*******************************************************************************
 * 名    称: IAP_JumpTo()
 * 功    能: 跳转到应用程序段
 * 入口参数:
 * 出口参数: 无
 * 作   者: 无名沈
 * 创建日期: 2014-04-23
 * 修    改: 
 * 修改日期: 
 *******************************************************************************/
void IAP_JumpTo(u32 appAddr)
{    
    u32     JumpAddress = 0;
    u8      cpu_sr;
        
    /***********************************************
    * 描述: 保存程序地址
    */
    IAP_SetAppAddr(appAddr);
    /***********************************************
    * 描述: 关中断,防止值被中断修改
    */
    CPU_CRITICAL_ENTER();
    /***********************************************
    * 描述: 外设恢复默认,避免进入应用程序后影响程序正常运行
    */
    IAP_DevDeInit();  
    /***********************************************
    * 描述: 获取应用入口及初始化堆栈指针
    */
    JumpAddress   =*(volatile u32*) (appAddr + 4); // 地址+4为PC地址
    pApp          = (pFunction)JumpAddress;         // 函数指针指向APP
    __set_MSP       (*(volatile u32*) appAddr);    // 初始化主堆栈指针(MSP)
    __set_PSP       (*(volatile u32*) appAddr);    // 初始化进程堆栈指针(PSP)
    __set_CONTROL   (0);                            // 清零CONTROL
    /***********************************************
    * 描述: 跳转到APP程序
    */
    pApp();
    
    CPU_CRITICAL_EXIT();
}
Esempio n. 3
0
static void tt_use_PSP(unsigned int irq_stack_addr)
{
	__set_PSP(__get_MSP());
	__set_MSP(irq_stack_addr);
	__set_CONTROL(2);
	__ISB();
}
Esempio n. 4
0
static void isr_reset(void)
{
    // remove compiler warning
    (void)g_pfnVectors;

    /**
     * The hyperload bootloader sets the MSP/PSP upon a true reset, which is when the
     * LPC17xx (Cortex-M3) sets the values of the stack pointer.  But since we are
     * booting after a bootloader, we have to manually setup the stack pointers ourselves.
     */
    do {
        const uint32_t topOfStack = (uint32_t) &_vStackTop;
        __set_PSP(topOfStack);
        __set_MSP(topOfStack);
    } while(0);

    do {
        // Copy data from FLASH to RAM
        unsigned int LoadAddr, ExeAddr, SectionLen;
        unsigned int *SectionTableAddr;

        // Load base address of Global Section Table
        SectionTableAddr = &__data_section_table;

        // Copy the data sections from flash to SRAM.
        while (SectionTableAddr < &__data_section_table_end)
        {
            LoadAddr = *SectionTableAddr++;
            ExeAddr = *SectionTableAddr++;
            SectionLen = *SectionTableAddr++;
            data_init(LoadAddr, ExeAddr, SectionLen);
        }

        // At this point, SectionTableAddr = &__bss_section_table;
        // Zero fill the bss segment
        while (SectionTableAddr < &__bss_section_table_end)
        {
            ExeAddr = *SectionTableAddr++;
            SectionLen = *SectionTableAddr++;
            bss_init(ExeAddr, SectionLen);
        }
    } while (0) ;

    #if defined (__cplusplus)
        __libc_init_array();    // Call C++ library initialization
    #endif

    do {
        low_level_init();   // Initialize minimal system, such as Clock & UART
        high_level_init();  // Initialize high level board specific features
        main();             // Finally call main()
    } while(0);

    // In case main() exits:
    uart0_init(SYS_CFG_UART0_BPS);
    u0_dbg_put("main() should never exit on this system\n");
    while (1) {
        ;
    }
}
Esempio n. 5
0
void Init_Cpu(void)
{
    __set_PSP((uint32_t)msp_top);
    __set_PRIMASK(1);
    __set_FAULTMASK(1);
    __set_CONTROL(0);

    #if (CN_CPU_OPTIONAL_FPU == 1)
    startup_scb_reg->CPACR = (3UL << 20)|(3UL << 22);    //使能FPU
    startup_scb_reg->FPCCR = (1UL << 31);                //关闭lazy stacking
    #endif
    switch(startup_scb_reg->CPUID)
    {
    }

    extern void SysClockInit(void);
    SysClockInit();

#ifdef USE_HAL_DRIVER
    HAL_TickInit();
#endif

    extern void SRAM_Init(void);
    SRAM_Init();

    IAP_SelectLoadProgam();
}
Esempio n. 6
0
void execute_user_code(void)
{
  void (*user_code_entry)(void);

  unsigned *p;  // used for loading address of reset handler from user flash

  /* Change the Vector Table to the USER_FLASH_START
  in case the user application uses interrupts */
  SCB->VTOR = (USER_FLASH_START & 0x1FFFFF80);

  /* SP (stack pointer) register must be set correctly before jump to the
   *  user application: http://www.keil.com/forum/17342/
   */
  __set_PSP(USER_FLASH_START);

  // Load contents of second word of user flash - the reset handler address
  // in the applications vector table
  p = (unsigned *)(USER_FLASH_START +4);

  // Set user_code_entry to be the address contained in that second word
  // of user flash
  user_code_entry = (void *) *p;

  // Jump to user application
  user_code_entry();
}
//! @brief Exits bootloader and jumps to the user application.
static void jump_to_application(uint32_t applicationAddress, uint32_t stackPointer)
{
#if BL_FEATURE_OTFAD_MODULE
    quadspi_cache_clear();
    oftfad_resume_as_needed();
#endif

    shutdown_cleanup(kShutdownType_Shutdown);

    // Create the function call to the user application.
    // Static variables are needed since changed the stack pointer out from under the compiler
    // we need to ensure the values we are using are not stored on the previous stack
    static uint32_t s_stackPointer = 0;
    s_stackPointer = stackPointer;
    static void (*farewellBootloader)(void) = 0;
    farewellBootloader = (void (*)(void))applicationAddress;

    // Set the VTOR to the application vector table address.
    SCB->VTOR = (uint32_t)APP_VECTOR_TABLE;

    // Set stack pointers to the application stack pointer.
    __set_MSP(s_stackPointer);
    __set_PSP(s_stackPointer);

   // while (1); /* SGF REMOVE */
    // Jump to the application.
    farewellBootloader();
    // Dummy fcuntion call, should never go to this fcuntion call
    shutdown_cleanup(kShutdownType_Shutdown);
}
Esempio n. 8
0
void Init_Cpu(void)
{
    __set_PSP((uint32_t)msp_top);
    __set_PRIMASK(1);
    __set_FAULTMASK(1);
    __set_CONTROL(0);

    #if (CN_CPU_OPTIONAL_FPU == 1)
        pg_scb_reg->CPACR = (3UL << 20)|(3UL << 22);    //使能FPU
        pg_scb_reg->FPCCR = (1UL << 31);                //关闭lazy stacking
    #endif
    switch(pg_scb_reg->CPUID)
    {
//        case cn_revision_r0p1://todo
//            break;    //好像没什么要做的
    }

    extern void WDT_Disable(void);
    WDT_Disable();  //关狗

    extern void SysClockInit(void);
    SysClockInit();

    extern void SDRAM_Init(void);
    SDRAM_Init();

    extern void Cache_Init(void);
    Cache_Init();

    Load_Preload();
}
Esempio n. 9
0
int init_sys(void)
{
    SCB->CCR |= SCB_CCR_STKALIGN_Msk; // enable double word stack alignment
 
    PSP_array[0] = ((unsigned int)task0_stack) + (sizeof task0_stack) - 16*4; // top of stack
    HW32_REG((PSP_array[0] + (14<<2))) = (unsigned long)task0; // initial Program Counter
    HW32_REG((PSP_array[0] + (15<<2))) = 0x01000000;           // initial PSR
 
    PSP_array[1] = ((unsigned int)task1_stack) + (sizeof task1_stack) - 16*4;
    HW32_REG((PSP_array[1] + (14<<2))) = (unsigned long)task1;
    HW32_REG((PSP_array[1] + (15<<2))) = 0x01000000;
 
    curr_task = 0;
    __set_PSP((PSP_array[curr_task] + 16*4)); // set PSP to top of stack
    NVIC_SetPriority(PendSV_IRQn, 0xFF);
    SysTick_Config(168000);
 
    __set_CONTROL(0x3);
 
    __ISB();
 
    task0();
 
    /*while(1) {
        stop_cpu;
    }; */
}
Esempio n. 10
0
void _start()
{
	/* copy data segment from flash to ram */
	{
		const size_t datalen = (size_t) &_edata - (unsigned int) &_sdata;
		memcpy(&_sdata, &_sidata, datalen);
	}

	/* zero out bss segment */
	{
		const size_t bsslen = (size_t) &_ebss - (unsigned int) &_sbss;
		memset(&_sbss, 0x0, bsslen);
	}

	SystemInit();

	/* set process stack */
	__set_PSP((uint32_t) &_eusrstack);

	/* enable drivers */
	for (size_t i = 0; i < sizeof(drivers); i++)
	{
		const driver_t* drv_p = drivers[i];
		if (drv_p->driver_reset != NULL)
		  drv_p->driver_reset();
		enable_clocks(drv_p);

	}

	(void) _init_crt1();
	(void) main();
}
Esempio n. 11
0
/**
\brief Test case: TC_CoreFunc_PSP
\details
- Check if __get_PSP and __set_PSP intrinsic can be used to manipulate process stack pointer.
*/
void TC_CoreFunc_PSP (void) {
  // don't use stack for this variables
  static uint32_t orig;
  static uint32_t psp;
  static uint32_t result;

  orig = __get_PSP();

  psp = orig + 0x12345678U;
  __set_PSP(psp);

  result = __get_PSP();

  __set_PSP(orig);

  ASSERT_TRUE(result == psp);
}
Esempio n. 12
0
static inline void set_and_switch_to_psp(void)
{
	u32_t process_sp;

	process_sp = (u32_t)&_interrupt_stack + CONFIG_ISR_STACK_SIZE;
	__set_PSP(process_sp);
	switch_sp_to_psp();
}
Esempio n. 13
0
/** Switch the context back from the destination box to the source one.
 *
 * @internal
 *
 * In this function we keep the same naming convention of the switch-in. Hence,
 * here the destination box is the one we are leaving, the source box is the one
 * we are switching to. We do not need any input from the caller as we already
 * know where we are switching to from the stacked state.
 *
 * @warning With thread context switches there is no context switch-out, but
 * only a context switch-in (from the current thread to the next one), so this
 * function should not be used for that purpose. An error will be thrown if used
 * for thread switches. */
TContextPreviousState * context_switch_out(TContextSwitchType context_type)
{
    uint8_t src_id, dst_id;
    uint32_t src_sp;
    TContextPreviousState * previous_state;

    /* This function is not needed for unbound context switches.
     * In those cases there is only a switch from a source box to a destination
     * box, and it can be done without state keeping. It is the host OS that
     * takes care of switching the stacks. */
    if (context_type == CONTEXT_SWITCH_UNBOUND_THREAD) {
        HALT_ERROR(NOT_ALLOWED, "Unbound context switching (e.g. for thread context switching) does not need to switch "
                                "out. Just call the context_switch_in(...) function repeatedly to switch from one task "
                                "to another.");
    }

    /* Destination box: Gather information from the current state. */
    dst_id = g_active_box;

    /* Source box: Gather information from the previous state. */
    /* This function halts if it finds an error. */
    previous_state = context_state_pop();
    src_id = previous_state->src_id;
    src_sp = previous_state->src_sp;

    /* The source/destination box IDs can be the same (for example, in IRQs). */
    if (src_id != dst_id) {
        /* Store outgoing newlib reent pointer. */
        UvisorBoxIndex * index = (UvisorBoxIndex *) g_context_current_states[dst_id].bss;
        index->bss.address_of.newlib_reent = (uint32_t) *(__uvisor_config.newlib_impure_ptr);

        /* Update the ID of the currently active box. */
        g_active_box = src_id;
        /* Update the context pointer to the one of the source box. */
        index = (UvisorBoxIndex *) g_context_current_states[src_id].bss;
        *(__uvisor_config.uvisor_box_context) = (uint32_t *) index;

        /* Switch MPU configurations. */
        /* This function halts if it finds an error. */
        vmpu_switch(dst_id, src_id);

        /* Restore incoming newlib reent pointer. */
        *(__uvisor_config.newlib_impure_ptr) = (uint32_t *) index->bss.address_of.newlib_reent;
    }

    /* Set the stack pointer for the source box. This is only needed if the
     * context switch is tied to a function.
     * Unbound context switches require the host OS to set the correct stack
     * pointer before handling execution to the unprivileged code. */
    if (context_type == CONTEXT_SWITCH_FUNCTION_GATEWAY ||
        context_type == CONTEXT_SWITCH_FUNCTION_ISR     ||
        context_type == CONTEXT_SWITCH_FUNCTION_DEBUG) {
        __set_PSP(src_sp);
    }

    return previous_state;
}
/*! 
    \brief C part of the SVC exception handler

     SVC 0 is initializing the OS and starting the scheduler.
     Each thread stack frame is initialized.
     
    \param svc_args Used to extract the SVC number 
*/
void SVC_Handler_C(unsigned int * svc_args)
{
  uint8_t svc_number;
  svc_number = ((char *) svc_args[6])[-2]; // Memory[(Stacked PC)-2]
	// marking kernel as busy
	kernel_busy = 1;
  switch(svc_number) {
		
		//************* SVC( 0 )   OS Start	
    case (0): // OS start		  
 	    // Starting the task scheduler
		  //TWP  playing a trick here!? by making curr = next, will make next's stack and current's stack the same stack!
		  //   will save (garbage) current register values, and then immediately restore them as next's initial values :-)
		curr_task = rtr_q_h; // Switch to head ready-to-run task (Current task)		
		//     when current task was put in RTRQ its state was set to RUNNING 
		  
		svc_exc_return = HW32_REG(( curr_task->stack_p )); // Return to thread with PSP
		__set_PSP(( (uint32_t) curr_task->stack_p + 10*4));  // Set PSP to @R0 of task 0 exception stack frame

		NVIC_SetPriority(PendSV_IRQn, 0xFF);       // Set PendSV to lowest possible priority
		if (SysTick_Config(os_sysTickTicks) != 0)  // 1000 Hz SysTick interrupt on 16MHz core clock
			{
				stop_cpu2;
				// Impossible SysTick_Config number of ticks
			}
		__set_CONTROL(0x3);                  // Switch to use Process Stack, unprivileged state
		__ISB();       // Execute ISB after changing CONTROL (architectural recommendation)			
		break;
		
		//************* SVC( 1 )	Thread Yield
    case (1): // Thread Yield
		if (curr_task != rtr_q_h)
			{ 
				// Context switching needed
				ScheduleContextSwitch();
			}		
		__ISB();       					
		break;
    
		//************* SVC( 2 )    Stack Frame Allocation for First Launch
		//TWPV6: no longer used!  Functionality moved to osThreadCreate ... case left here (for now) 
    case (2): // Stack Allocation
		__ISB();       			
		break;			
    default:
#if ((ENABLE_KERNEL_PRINTF) && (ENABLE_KERNEL_PRINTF == 1))
		printf("ERROR: Unknown SVC service number\n\r");
		printf("- SVC number 0x%x\n\r", svc_number);
#endif
		stop_cpu2;
		break;
  } // end switch
	
	// marking kernel as normal
	kernel_busy = 0;
}	
Esempio n. 15
0
/**
 * @brief   Exception exit redirection to _port_switch_from_isr().
 */
void _port_irq_epilogue(void) {

  port_lock_from_isr();
  if ((SCB->ICSR & SCB_ICSR_RETTOBASE_Msk) != 0) {

    /* The port_extctx structure is pointed by the PSP register.*/
    struct port_extctx *ctxp = (struct port_extctx *)__get_PSP();

    /* Adding an artificial exception return context, there is no need to
       populate it fully.*/
    ctxp--;

    /* Writing back the modified PSP value.*/
    __set_PSP((uint32_t)ctxp);

    /* Setting up a fake XPSR register value.*/
    ctxp->xpsr = (regarm_t)0x01000000;

    /* The exit sequence is different depending on if a preemption is
       required or not.*/
    if (chSchIsRescRequiredI()) {
      /* Preemption is required we need to enforce a context switch.*/
      ctxp->pc = (regarm_t)_port_switch_from_isr;
#if CORTEX_USE_FPU
      /* Enforcing a lazy FPU state save by accessing the FPCSR register.*/
      (void) __get_FPSCR();
#endif
    }
    else {
      /* Preemption not required, we just need to exit the exception
         atomically.*/
      ctxp->pc = (regarm_t)_port_exit_from_isr;
    }

#if CORTEX_USE_FPU
    {
      uint32_t fpccr;

      /* Saving the special register SCB_FPCCR into the reserved offset of
         the Cortex-M4 exception frame.*/
      (ctxp + 1)->fpccr = (regarm_t)(fpccr = FPU->FPCCR);

      /* Now the FPCCR is modified in order to not restore the FPU status
         from the artificial return context.*/
      FPU->FPCCR = fpccr | FPU_FPCCR_LSPACT_Msk;
    }
#endif

    /* Note, returning without unlocking is intentional, this is done in
       order to keep the rest of the context switch atomic.*/
    return;
  }
  port_unlock_from_isr();
}
Esempio n. 16
0
/**
 * @brief   PendSV vector.
 * @details The PendSV vector is used for exception mode re-entering after a
 *          context switch.
 */
void PendSV_Handler(void) {

  /* The port_extctx structure is pointed by the PSP register.*/
  struct port_extctx *ctxp = (struct port_extctx *)__get_PSP();

  /* Discarding the current exception context and positioning the stack to
     point to the real one.*/
  ctxp++;

  /* Writing back the modified PSP value.*/
  __set_PSP((uint32_t)ctxp);
}
Esempio n. 17
0
void Init_Cpu(void)
{
    __set_PSP((uint32_t)msp_top);
    __set_PRIMASK(1);
    __set_FAULTMASK(1);
    __set_CONTROL(0);
    switch(pg_scb_reg->CPUID)
    {
        case cn_revision_r0p0:
            break;    //市场没有版本0的芯片
        case cn_revision_r1p0:
            pg_scb_reg->CCR |= 1<<bo_scb_ccr_stkalign;
            break;
        case cn_revision_r1p1:
            pg_scb_reg->CCR |= 1<<bo_scb_ccr_stkalign;
            break;
        case cn_revision_r2p0:break;    //好像没什么要做的
    }

    pg_inflash_fpec_reg->ACR &= ~(u32)0x1f;
    pg_inflash_fpec_reg->ACR |= (CN_CFG_MCLK-1)/24000000;   //设置等待周期。
    pg_inflash_fpec_reg->ACR |= 0x10;       //开启预取


    if(((pg_rcc_reg->CR & cn_cr_check_mask) != cn_cr_check)
                || ((pg_rcc_reg->CFGR & cn_cfgr_check_mask) != cn_cfgr_check))
    {
        //开始初始化时钟
        //step1:复位时钟控制寄存器
        pg_rcc_reg->CR |= (uint32_t)0x00000001;
        // 复位 SW[1:0], HPRE[3:0], PPRE1[2:0], PPRE2[2:0], ADCPRE[1:0] MCO[2:0] 位
        pg_rcc_reg->CFGR &= (uint32_t)0xF8FF0000;
        // 复位 HSEON, CSSON and PLLON 位
        pg_rcc_reg->CR &= (uint32_t)0xFEF6FFFF;
        // 复位 HSEBYP 位
        pg_rcc_reg->CR &= (uint32_t)0xFFFBFFFF;
        // 复位 PLLSRC, PLLXTPRE, PLLMUL[3:0] and USBPRE 位
        pg_rcc_reg->CFGR &= (uint32_t)0xFF80FFFF;
        // 禁止所有中断
        pg_rcc_reg->CIR = 0x00000000;

        //step2:设置各时钟控制位以及倍频、分频值
        pg_rcc_reg->CFGR = cn_cfgr_set+(7<<24);   // set clock configuration register
        pg_rcc_reg->CR   = cn_cr_set;     // set clock control register

        while(bb_rcc_cr_hserdy ==0);
        while(bb_rcc_cr_pllrdy ==0);
    }
    SRAM_Init();

    Load_Preload();
}
Esempio n. 18
0
/**
 * @brief   Exception exit redirection to _port_switch_from_isr().
 */
void _port_irq_epilogue(void) {

    port_lock_from_isr();
    if ((SCB_ICSR & ICSR_RETTOBASE) != 0) {
        struct extctx *ctxp;

        /* Current PSP value.*/
        ctxp = (struct extctx *)__get_PSP();

        /* Adding an artificial exception return context, there is no need to
           populate it fully.*/
        ctxp--;
        __set_PSP((unsigned long)ctxp);
        ctxp->xpsr = (regarm_t)0x01000000;

        /* The exit sequence is different depending on if a preemption is
           required or not.*/
        if (chSchIsPreemptionRequired()) {
            /* Preemption is required we need to enforce a context switch.*/
            ctxp->pc = (regarm_t)_port_switch_from_isr;
#if CORTEX_USE_FPU
            /* Triggering a lazy FPU state save.*/
            (void)__get_FPSCR();
#endif
        }
        else {
            /* Preemption not required, we just need to exit the exception
               atomically.*/
            ctxp->pc = (regarm_t)_port_exit_from_isr;
        }

#if CORTEX_USE_FPU
        {
            uint32_t fpccr;

            /* Saving the special register SCB_FPCCR into the reserved offset of
               the Cortex-M4 exception frame.*/
            (ctxp + 1)->fpccr = (regarm_t)(fpccr = SCB_FPCCR);

            /* Now the FPCCR is modified in order to not restore the FPU status
               from the artificial return context.*/
            SCB_FPCCR = fpccr | FPCCR_LSPACT;
        }
#endif

        /* Note, returning without unlocking is intentional, this is done in
           order to keep the rest of the context switch atomic.*/
        return;
    }
    port_unlock_from_isr();
}
Esempio n. 19
0
void cmd_reset(void)
{
    rt_uint32_t usrAddr = 0x08000000;
    typedef void (*funcPtr)(void);
    typedef volatile uint32_t vu32;
    __set_PRIMASK(0); //关闭所有中断,可以没有
    if(((*(vu32*)usrAddr)&0x2FFE0000)==0x20000000) //判断地址是不是在RAM之内
    {
        rt_uint32_t jumpAddr = *(vu32*) (usrAddr+0x04); /* reset ptr in vector table */
        funcPtr usrMain1 = (funcPtr)jumpAddr;
        __set_PSP(*(vu32*)usrAddr);  //设置堆栈指针
        usrMain1();                                /* go! */
    }
}
Esempio n. 20
0
/**
 * @brief   NMI vector.
 * @details The NMI vector is used for exception mode re-entering after a
 *          context switch.
 */
void NMI_Handler(void) {

  /* The port_extctx structure is pointed by the PSP register.*/
  struct port_extctx *ctxp = (struct port_extctx *)__get_PSP();

  /* Discarding the current exception context and positioning the stack to
     point to the real one.*/
  ctxp++;

  /* Writing back the modified PSP value.*/
  __set_PSP((uint32_t)ctxp);

  /* Restoring the normal interrupts status.*/
  port_unlock_from_isr();
}
Esempio n. 21
0
/**
 * @brief   PendSV vector.
 * @details The PendSV vector is used for exception mode re-entering after a
 *          context switch.
 * @note    The PendSV vector is only used in compact kernel mode.
 */
void PendSVVector(void) {
    struct extctx *ctxp;

    /* Current PSP value.*/
    ctxp = (struct extctx *)__get_PSP();

    /* Discarding the current exception context and positioning the stack to
       point to the real one.*/
    ctxp++;

#if CORTEX_USE_FPU
    /* Restoring the special register SCB_FPCCR.*/
    SCB_FPCCR = (uint32_t)ctxp->fpccr;
    SCB_FPCAR = SCB_FPCAR + sizeof (struct extctx);
#endif
    __set_PSP((unsigned long)ctxp);
}
Esempio n. 22
0
/**
 * @brief   Exception exit redirection to _port_switch_from_isr().
 */
void _port_irq_epilogue(void) {

  port_lock_from_isr();
  if ((SCB->ICSR & SCB_ICSR_RETTOBASE_Msk) != 0) {
    struct port_extctx *ctxp;

#if CORTEX_USE_FPU
      /* Enforcing a lazy FPU state save by accessing the FPCSR register.*/
      (void) __get_FPSCR();
#endif

    /* The port_extctx structure is pointed by the PSP register.*/
    ctxp = (struct port_extctx *)__get_PSP();

    /* Adding an artificial exception return context, there is no need to
       populate it fully.*/
    ctxp--;

    /* Setting up a fake XPSR register value.*/
    ctxp->xpsr = (regarm_t)0x01000000;
#if CORTEX_USE_FPU
    ctxp->fpscr = (regarm_t)FPU->FPDSCR;
#endif

    /* Writing back the modified PSP value.*/
    __set_PSP((uint32_t)ctxp);

    /* The exit sequence is different depending on if a preemption is
       required or not.*/
    if (chSchIsPreemptionRequired()) {
      /* Preemption is required we need to enforce a context switch.*/
      ctxp->pc = (regarm_t)_port_switch_from_isr;
    }
    else {
      /* Preemption not required, we just need to exit the exception
         atomically.*/
      ctxp->pc = (regarm_t)_port_exit_from_isr;
    }

    /* Note, returning without unlocking is intentional, this is done in
       order to keep the rest of the context switch atomic.*/
    return;
  }
  port_unlock_from_isr();
}
Esempio n. 23
0
void Reset_Handler( void )
{
#if main_stack_size + proc_stack_size > 0
	/* Initialize the process stack pointer */
	__set_PSP((unsigned)__initial_sp);
	__set_CONTROL(CONTROL_SPSEL_Msk);
#endif
#if __FPU_USED
	/* Set CP10 and CP11 Full Access */
	SCB->CPACR = 0x00F00000U;
#endif
#ifndef __NO_SYSTEM_INIT
	/* Call the system clock intitialization function */
	SystemInit();
#endif
	/* Call the application's entry point */
	__main();
}
Esempio n. 24
0
/**
 * @brief   PendSV vector.
 * @details The PendSV vector is used for exception mode re-entering after a
 *          context switch.
 * @note    The PendSV vector is only used in compact kernel mode.
 */
void PendSV_Handler(void) {
  struct port_extctx *ctxp;

#if CORTEX_USE_FPU
  /* Enforcing unstacking of the FP part of the context.*/
  FPU->FPCCR &= ~FPU_FPCCR_LSPACT_Msk;
#endif

  /* The port_extctx structure is pointed by the PSP register.*/
  ctxp = (struct port_extctx *)__get_PSP();

  /* Discarding the current exception context and positioning the stack to
     point to the real one.*/
  ctxp++;

  /* Writing back the modified PSP value.*/
  __set_PSP((uint32_t)ctxp);
}
Esempio n. 25
0
/**
 * @brief   PendSV vector.
 * @details The PendSV vector is used for exception mode re-entering after a
 *          context switch.
 * @note    The PendSV vector is only used in compact kernel mode.
 */
void PendSVVector(void) {
  struct extctx *ctxp;

#if CORTEX_USE_FPU
  /* Enforcing unstacking of the FP part of the context.*/
  SCB_FPCCR &= ~FPCCR_LSPACT;
#endif

  /* Current PSP value.*/
  ctxp = (struct extctx *)__get_PSP();

  /* Discarding the current exception context and positioning the stack to
     point to the real one.*/
  ctxp++;

  /* Restoring real position of the original stack frame.*/
  __set_PSP((unsigned long)ctxp);
}
Esempio n. 26
0
/**
 * @brief   PendSV vector.
 * @details The PendSV vector is used for exception mode re-entering after a
 *          context switch.
 * @note    The PendSV vector is only used in compact kernel mode.
 */
void PendSV_Handler(void) {

  /* The port_extctx structure is pointed by the PSP register.*/
  struct port_extctx *ctxp = (struct port_extctx *)__get_PSP();

  /* Discarding the current exception context and positioning the stack to
     point to the real one.*/
  ctxp++;

#if CORTEX_USE_FPU
  /* Restoring the special register FPCCR.*/
  FPU->FPCCR = (uint32_t)ctxp->fpccr;
  FPU->FPCAR = FPU->FPCAR + sizeof (struct port_extctx);
#endif

  /* Writing back the modified PSP value.*/
  __set_PSP((uint32_t)ctxp);
}
Esempio n. 27
0
void nOS_InitSpecific(void)
{
#if (NOS_CONFIG_DEBUG > 0)
    size_t i;

    for (i = 0; i < NOS_CONFIG_ISR_STACK_SIZE; i++) {
        _isrStack[i] = 0xFFFFFFFFUL;
    }
#endif

    /* Copy MSP to PSP */
    __set_PSP(__get_MSP());
    /* Set MSP to local ISR stack */
    __set_MSP((uint32_t)&_isrStack[NOS_CONFIG_ISR_STACK_SIZE] & 0xFFFFFFF8UL);
    /* Set current stack to PSP and privileged mode */
    __set_CONTROL(__get_CONTROL() | 0x00000002UL);
    /* Set PendSV exception to lowest priority */
    *(volatile uint32_t *)0xE000ED20UL |= 0x00FF0000UL;
}
Esempio n. 28
0
/**
 * @brief   Exception exit redirection to _port_switch_from_isr().
 */
void _port_irq_epilogue(void) {

  port_lock_from_isr();
  if ((SCB_ICSR & ICSR_RETTOBASE) != 0) {
    struct extctx *ctxp;

#if CORTEX_USE_FPU
    /* Enforcing a lazy FPU state save. Note, it goes in the original
       context because the FPCAR register has not been modified.*/
    (void)__get_FPSCR();
#endif

    /* Current PSP value.*/
    ctxp = (struct extctx *)__get_PSP();

    /* Adding an artificial exception return context, there is no need to
       populate it fully.*/
    ctxp--;
    ctxp->xpsr = (regarm_t)0x01000000;
#if CORTEX_USE_FPU
    ctxp->fpscr = (regarm_t)SCB_FPDSCR;
#endif
    __set_PSP((unsigned long)ctxp);

    /* The exit sequence is different depending on if a preemption is
       required or not.*/
    if (chSchIsPreemptionRequired()) {
      /* Preemption is required we need to enforce a context switch.*/
      ctxp->pc = (regarm_t)_port_switch_from_isr;
    }
    else {
      /* Preemption not required, we just need to exit the exception
         atomically.*/
      ctxp->pc = (regarm_t)_port_exit_from_isr;
    }

    /* Note, returning without unlocking is intentional, this is done in
       order to keep the rest of the context switch atomic.*/
    return;
  }
  port_unlock_from_isr();
}
/**
 * Boots the image described by the supplied image header.
 *
 * @param hdr                   The header for the image to boot.
 */
void
hal_system_start(void *img_start)
{
    typedef void jump_fn(void);

    uint32_t base0entry;
    uint32_t jump_addr;
    jump_fn *fn;

    /* First word contains initial MSP value. */
    __set_MSP(*(uint32_t *)img_start);
    __set_PSP(*(uint32_t *)img_start);

    /* Second word contains address of entry point (Reset_Handler). */
    base0entry = *(uint32_t *)(img_start + 4);
    jump_addr = base0entry;
    fn = (jump_fn *)jump_addr;

    /* Jump to image. */
    fn();
}
Esempio n. 30
0
/**
 * @brief   SVC vector.
 * @details The SVC vector is used for exception mode re-entering after a
 *          context switch.
 * @note    The PendSV vector is only used in advanced kernel mode.
 */
void SVC_Handler(void) {
  struct port_extctx *ctxp;

#if CORTEX_USE_FPU
  /* Enforcing unstacking of the FP part of the context.*/
  FPU->FPCCR &= ~FPU_FPCCR_LSPACT_Msk;
#endif

  /* The port_extctx structure is pointed by the PSP register.*/
  ctxp = (struct port_extctx *)__get_PSP();

  /* Discarding the current exception context and positioning the stack to
     point to the real one.*/
  ctxp++;

  /* Restoring real position of the original stack frame.*/
  __set_PSP((uint32_t)ctxp);

  /* Restoring the normal interrupts status.*/
  port_unlock_from_isr();
}