Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
0eed279
Implement stdin
southernbear Jul 4, 2013
7e1c6d2
fix: thread exiting does not call sched_task_exit
southernbear Jul 6, 2013
98c9c93
Implement hwtimer with SysTick [init, set, now, callback]
southernbear Jul 9, 2013
8a5e0d7
Implement hwtimer with SysTick [enable/disable interrupt, unset]
southernbear Jul 9, 2013
34d738f
Cleanup: stm32f407vgt6/stm32f4-hwtimer_arch.c
southernbear Jul 9, 2013
b81ee81
Move irq functions to irq.c
southernbear Jul 10, 2013
4d39be4
Add dependency to 'irq.h' in 'syscalls.c'
southernbear Jul 10, 2013
59d0db7
Add PendSV function
southernbear Jul 10, 2013
099f513
Move context switch codes to 'cpu.c'
southernbear Jul 10, 2013
d2ea712
Add PendSV handler
southernbear Jul 10, 2013
e853a17
Can wakeup from hwtimer isr
southernbear Jul 10, 2013
bdea7ce
Change hwtimer implementation to timer 2
southernbear Jul 11, 2013
634430c
Implement sleep mode
southernbear Jul 12, 2013
1d9ad90
Cleanup stm32f407vgt6-lpm.c
southernbear Jul 12, 2013
d8ededd
Fix that can not set hwtimer again in callback
southernbear Jul 13, 2013
af358cd
Fix: thread can not be activated when a thread exit
southernbear Jul 13, 2013
2f3b552
Use PendSV instead of SVC to handle context switch
southernbear Jul 13, 2013
6cb2313
Move save and restore context from header to c file
southernbear Jul 13, 2013
8e97615
Cleanup include/cpu.h
southernbear Jul 13, 2013
e5c2736
Cleanup: cpu.c
southernbear Jul 13, 2013
29d9abe
Fix coding style
southernbear Jul 13, 2013
d030671
fix coding style
southernbear Jul 19, 2013
8af6728
added Makefile to define dependencies
OlegHahm Jul 29, 2013
d0becc6
Implement long term sleep with RTC Wakeup
southernbear Aug 6, 2013
40f09b3
Implement RTC auto calibration
southernbear Aug 12, 2013
4c6818c
Add RTC auto calibration option and enable by default
southernbear Aug 18, 2013
8db582c
Add comment
southernbear Aug 18, 2013
3cc2813
Coding convention fix
southernbear Aug 19, 2013
74ccef3
Merge remote-tracking branch 'OlegHahm/master' into longterm-sleep
southernbear Aug 19, 2013
b078ded
Add printf stack size
southernbear Aug 19, 2013
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions Makefile.include
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
ifeq ($(CPU),stm32f407vgt6)
export USEMODULE += stm32f4xxstdperi
export UNDEF += $(BINDIR)syscalls.o
endif
154 changes: 9 additions & 145 deletions stm32f407vgt6/atom.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,152 +4,16 @@
* Created on: 10.08.2012
* Author: pfeiffer
*/
#include "sched.h"
#include "atomic.h"
#include "cpu.h"

extern void sched_task_exit(void);
void sched_task_return(void);

unsigned int atomic_set_return(unsigned int* p, unsigned int uiVal) {
//unsigned int cspr = disableIRQ(); //crashes
dINT();
unsigned int uiOldVal = *p;
*p = uiVal;
//restoreIRQ(cspr); //crashes
eINT();
return uiOldVal;
}

void cpu_switch_context_exit(void){
sched_run();
sched_task_return();
}


void thread_yield(void) {
asm("svc 0x01\n");
}


__attribute__((naked))
void SVC_Handler(void)
unsigned int atomic_set_return(unsigned int *p, unsigned int uiVal)
{
save_context();
asm("bl sched_run");
/* call scheduler update active_thread variable with pdc of next thread
* the thread that has higest priority and is in PENDING state */
restore_context();
}

/* kernel functions */
void ctx_switch(void)
{
/* Save return address on stack */
/* stmfd sp!, {lr} */

/* disable interrupts */
/* mov lr, #NOINT|SVCMODE */
/* msr CPSR_c, lr */
/* cpsid i */

/* save other register */
asm("nop");

asm("mov r12, sp");
asm("stmfd r12!, {r4-r11}");

/* save user mode stack pointer in *active_thread */
asm("ldr r1, =active_thread"); /* r1 = &active_thread */
asm("ldr r1, [r1]"); /* r1 = *r1 = active_thread */
asm("str r12, [r1]"); /* store stack pointer in tasks pdc*/

sched_task_return();
}
/* call scheduler so active_thread points to the next task */
void sched_task_return(void)
{
/* load pdc->stackpointer in r0 */
asm("ldr r0, =active_thread"); /* r0 = &active_thread */
asm("ldr r0, [r0]"); /* r0 = *r0 = active_thread */
asm("ldr sp, [r0]"); /* sp = r0 restore stack pointer*/
asm("pop {r4}"); /* skip exception return */
asm(" pop {r4-r11}");
asm(" pop {r0-r3,r12,lr}"); /* simulate register restor from stack */
// asm("pop {r4}"); /*foo*/
asm("pop {pc}");
}
/*
* cortex m4 knows stacks and handles register backups
*
* so use different stack frame layout
*
*
* with float storage
* ------------------------------------------------------------------------------------------------------------------------------------
* | R0 | R1 | R2 | R3 | LR | PC | xPSR | S0 | S1 | S2 | S3 | S4 | S5 | S6 | S7 | S8 | S9 | S10 | S11 | S12 | S13 | S14 | S15 | FPSCR |
* ------------------------------------------------------------------------------------------------------------------------------------
*
* without
*
* --------------------------------------
* | R0 | R1 | R2 | R3 | LR | PC | xPSR |
* --------------------------------------
*
*
*/
char * thread_stack_init(void * task_func, void * stack_start, int stack_size ) {
unsigned int * stk;
stk = (unsigned int *) (stack_start + stack_size);

/* marker */
stk--;
*stk = 0x77777777;

//FIXME FPSCR
stk--;
*stk = (unsigned int) 0;

//S0 - S15
for (int i = 15; i >= 0; i--) {
stk--;
*stk = i;
}

//FIXME xPSR
stk--;
*stk = (unsigned int) 0x01000200;

//program counter
stk--;
*stk = (unsigned int) task_func;

/* link register */
stk--;
*stk = (unsigned int) 0x0;

/* r12 */
stk--;
*stk = (unsigned int) 0;

/* r0 - r3 */
for (int i = 3; i >= 0; i--) {
stk--;
*stk = i;
}

/* r11 - r4 */
for (int i = 11; i >= 4; i--) {
stk--;
*stk = i;
}

/* foo */
/*stk--;
*stk = (unsigned int) 0xDEADBEEF;*/

/* lr means exception return code */
stk--;
*stk = (unsigned int) 0xfffffff9; // return to taskmode main stack pointer

return (char*) stk;
//unsigned int cspr = disableIRQ(); //crashes
dINT();
unsigned int uiOldVal = *p;
*p = uiVal;
//restoreIRQ(cspr); //crashes
eINT();
return uiOldVal;
}
167 changes: 141 additions & 26 deletions stm32f407vgt6/cpu.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,37 +5,152 @@
* Author: pfeiffer
*/

#include "stdint.h"
#include "stm32f4xx_tim.h"
#include <stdint.h>

void stm32f4_pclk_scale(uint32_t source, uint32_t target, uint32_t* pclksel, uint32_t* prescale)
#include "stm32f4xx.h"

#include "cpu.h"
#include "sched.h"

extern void sched_task_exit(void);

static inline void save_context(void);
static inline void restore_context(void);

__attribute__((always_inline))
static inline void save_context(void)
{
/* {r0-r3,r12,LR,PC,xPSR} are saved automatically on exception entry */

asm("ldr r1, =active_thread");
/* load address of currend pdc */
asm("ldr r1, [r1]");
/* deref pdc */
asm("cmp r1, #0");
/* active_thread exists */
asm("ittt ne");
/*if active_thread != NULL */
asm("pushne {r4-r11}");
/* save unsaved registers */
/*vstmdb sp!, {s16-s31} */ //FIXME save fpu registers if needed
asm("pushne {LR}");
/* save exception return value */
asm("strne sp, [r1]");
/* write sp to pdc->sp means current threads stack pointer */
}

__attribute__((always_inline))
static inline void restore_context(void)
{
uint32_t pclkdiv;
*prescale = source / target;

if( (*prescale % 4) == 0 ) {
*pclksel = TIM_CKD_DIV4;
pclkdiv = 4;
} else if( (*prescale % 2) == 0 ) {
*pclksel = TIM_CKD_DIV2;
pclkdiv = 2;
} else {
*pclksel = TIM_CKD_DIV1;
pclkdiv = 1;
}
*prescale /= pclkdiv;

if( *prescale % 2 )
(*prescale)++;
asm("ldr r0, =active_thread");
/* load address of currend pdc */
asm("ldr r0, [r0]");
/* deref pdc */
asm("ldr sp, [r0]");
/* load pdc->sp to sp register */

asm("pop {r0}");
/* restore exception retrun value from stack */
/*pop {s16-s31} */ //FIXME load fpu register if needed depends on r0 exret
asm("pop {r4-r11}");
/* load unloaded register */
// asm("pop {r4}"); /*foo*/
asm("bx r0"); /* load exception return value to pc causes end of exception*/
/* {r0-r3,r12,LR,PC,xPSR} are restored automatically on exception return */
}

void cpu_switch_context_exit(void)
{
__pendSV();
__enable_irq();
}

void thread_yield(void)
{
__pendSV();
}

__attribute__((naked))
void PendSV_Handler(void)
{
save_context();
sched_run();
restore_context();
}

/*
* cortex m4 knows stacks and handles register backups
*
* so use different stack frame layout
*
*
* with float storage
* ------------------------------------------------------------------------------------------------------------------------------------
* | R0 | R1 | R2 | R3 | LR | PC | xPSR | S0 | S1 | S2 | S3 | S4 | S5 | S6 | S7 | S8 | S9 | S10 | S11 | S12 | S13 | S14 | S15 | FPSCR |
* ------------------------------------------------------------------------------------------------------------------------------------
*
* without
*
* --------------------------------------
* | R0 | R1 | R2 | R3 | LR | PC | xPSR |
* --------------------------------------
*
*
*/
char *thread_stack_init(void *task_func, void *stack_start, uint32_t stack_size)
{
uint32_t *stk;
stk = (uint32_t *)(stack_start + stack_size);

/* marker */
stk--;
*stk = 0x77777777;

//FIXME FPSCR
stk--;
*stk = (uint32_t) 0;

//S0 - S15
for (int i = 15; i >= 0; i--) {
stk--;
*stk = i;
}

//FIXME xPSR
stk--;
*stk = (uint32_t) 0x01000200;

//program counter
stk--;
*stk = (uint32_t) task_func;

/* link register */
stk--;
*stk = (uint32_t) sched_task_exit;

/* r12 */
stk--;
*stk = (uint32_t) 0;

/* r0 - r3 */
for (int i = 3; i >= 0; i--) {
stk--;
*stk = i;
}

/* r11 - r4 */
for (int i = 11; i >= 4; i--) {
stk--;
*stk = i;
}

void cpu_clock_scale(uint32_t source, uint32_t target, uint32_t* prescale) {
uint32_t pclksel;
/* foo */
/*stk--;
*stk = (uint32_t) 0xDEADBEEF;*/

stm32f4_pclk_scale(source, target, &pclksel, prescale);
/* lr means exception return code */
stk--;
*stk = (uint32_t) 0xfffffff9; // return to taskmode main stack pointer

//PCLKSEL0 = (PCLKSEL0 & ~(BIT2|BIT3)) | (pclksel << 2); // timer 0
//PCLKSEL0 = (PCLKSEL0 & ~(BIT4|BIT5)) | (pclksel << 4); // timer 1
//PCLKSEL1 = (PCLKSEL1 & ~(BIT12|BIT13)) | (pclksel << 12); // timer 2
return (char *) stk;
}
2 changes: 2 additions & 0 deletions stm32f407vgt6/include/cpu-conf.h
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,8 @@ and the mailinglist (subscription via web site)
#define KERNEL_CONF_STACKSIZE_DEFAULT 2500
#endif

#define KERNEL_CONF_STACKSIZE_PRINTF 4096

#define KERNEL_CONF_STACKSIZE_IDLE 500
/** @} */

Expand Down
Loading