STM32F103移植例子
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
#include <cpu.h>
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,170 @@
|
||||
#ifndef INCLUDED_CPU_H
|
||||
#define INCLUDED_CPU_H
|
||||
|
||||
#ifndef INCLUDED_CMSIS_H
|
||||
#include <cmsis.h>
|
||||
#endif /*INCLUDED_CMSIS_H*/
|
||||
|
||||
#ifndef INCLUDED_OS_TYPES_H
|
||||
#include <os_types.h>
|
||||
#endif /*INCLUDED_OS_TYPES_H*/
|
||||
|
||||
#ifndef INCLUDED_OS_COMPILER_H
|
||||
#include <os_compiler.h>
|
||||
#endif /*INCLUDED_OS_COMPILER_H*/
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------------------------ */
|
||||
/* */
|
||||
|
||||
|
||||
#define os_port_disable_irq CMSIS_disable_irq
|
||||
#define os_port_enable_irq CMSIS_enable_irq
|
||||
#define os_port_save_disable_irq cpu_save_disable_irq
|
||||
#define os_port_restore_irq cpu_restore_irq
|
||||
#define os_port_save_disable_irq_in_isr cpu_save_disable_irq_in_isr
|
||||
#define os_port_restore_irq_in_isr cpu_restore_irq_in_isr
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------------------------ */
|
||||
/* */
|
||||
|
||||
#define CPU_SYSCALL_ID 0x00
|
||||
#define CPU_SYSCALL_OP_SAVE_DISABLE_IRQ 0x00
|
||||
#define CPU_SYSCALL_OP_RESTORE_IRQ 0x01
|
||||
#define CPU_SYSCALL_OP_SCHED 0x02
|
||||
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------------------------ */
|
||||
/* */
|
||||
|
||||
|
||||
#if defined(__CC_ARM) /* armcc (AC5) */
|
||||
|
||||
#define SVC_CALL_ARGS0(num, type, name) \
|
||||
__svc(num) type name(void);
|
||||
|
||||
#define SVC_CALL_ARGS1(num, type, name, a0) \
|
||||
__svc(num) type name(os_uintptr_t a0);
|
||||
|
||||
#define SVC_CALL_ARGS2(num, type, name, a0, a1) \
|
||||
__svc(num) type name(os_uintptr_t a0, os_uintptr_t a1);
|
||||
|
||||
#define SVC_CALL_ARGS3(num, type, name, a0, a1, a2) \
|
||||
__svc(num) type name(os_uintptr_t a0, os_uintptr_t a1, os_uintptr_t a2);
|
||||
|
||||
#define SVC_CALL_ARGS4(num, type, name, a0, a1, a2, a3) \
|
||||
__svc(num) type name(os_uintptr_t a0, os_uintptr_t a1, os_uintptr_t a2, os_uintptr_t a3);
|
||||
|
||||
|
||||
#elif defined(__GNUC__) /* gcc */
|
||||
|
||||
#define SVC_CALL_ARGS0(num, type, name) \
|
||||
static type name(void) { \
|
||||
register os_uintptr_t r0 __asm__("r0")=0; \
|
||||
__asm__ volatile ("svc " #num : : : "memory"); \
|
||||
return (type)r0; \
|
||||
}
|
||||
|
||||
#define SVC_CALL_ARGS1(num, type, name, a1) \
|
||||
OS_STATIC_FORCE_INLINE type name(os_uintptr_t a1) { \
|
||||
register os_uintptr_t r0 __asm__("r0") = a1; \
|
||||
__asm__ volatile ("svc " #num :"=r"(r0):"r"(r0) : "memory"); \
|
||||
return (type)r0; \
|
||||
}
|
||||
|
||||
#define SVC_CALL_ARGS2(num, type, name, a1, a2) \
|
||||
OS_STATIC_FORCE_INLINE type name(os_uintptr_t a1, os_uintptr_t a2) { \
|
||||
register os_uintptr_t r0 __asm__("r0") = a1;\
|
||||
register os_uintptr_t r1 __asm__("r1") = a2;\
|
||||
__asm__ volatile ("svc " #num :"=r"(r0) :"r"(r0), "r"(r1) : "memory"); \
|
||||
return (type)r0; \
|
||||
}
|
||||
|
||||
#define SVC_CALL_ARGS3(num, type, name, a1, a2, a3) \
|
||||
OS_STATIC_FORCE_INLINE type name(os_uintptr_t a1, os_uintptr_t a2, os_uintptr_t a3) { \
|
||||
register os_uintptr_t r0 __asm__("r0") = a1; \
|
||||
register os_uintptr_t r1 __asm__("r1") = a2; \
|
||||
register os_uintptr_t r2 __asm__("r2") = a3; \
|
||||
__asm__ volatile ("svc " #num :"=r"(r0) :"r"(r0), "r"(r1), "r"(r2) : "memory"); \
|
||||
return (type)r0; \
|
||||
}
|
||||
|
||||
#define SVC_CALL_ARGS4(num, type, name, a1, a2, a3, a4) \
|
||||
OS_STATIC_FORCE_INLINE type name(os_uintptr_t a1, os_uintptr_t a2, os_uintptr_t a3, os_uintptr_t a4) { \
|
||||
register os_uintptr_t r0 __asm__("r0") = a1; \
|
||||
register os_uintptr_t r1 __asm__("r1") = a2; \
|
||||
register os_uintptr_t r2 __asm__("r2") = a3; \
|
||||
register os_uintptr_t r3 __asm__("r3") = a4; \
|
||||
__asm__ volatile ("svc " #num :"=r"(r0) :"r"(r0), "r"(r1), "r"(r2), "r"(r3) : "memory"); \
|
||||
return (type)r0; \
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
SVC_CALL_ARGS1(0, os_uint_t, cpu_svc0_args1, a1)
|
||||
SVC_CALL_ARGS2(0, void, cpu_svc0_args2, a1, a2)
|
||||
|
||||
|
||||
OS_STATIC_FORCE_INLINE
|
||||
os_uint_t cpu_save_disable_irq_in_svc(void){
|
||||
return cpu_svc0_args1(CPU_SYSCALL_OP_SAVE_DISABLE_IRQ);
|
||||
}
|
||||
|
||||
OS_STATIC_FORCE_INLINE
|
||||
void cpu_restore_irq_in_svc(os_uint_t level){
|
||||
cpu_svc0_args2(CPU_SYSCALL_OP_RESTORE_IRQ, level);
|
||||
}
|
||||
|
||||
OS_STATIC_FORCE_INLINE
|
||||
void cpu_sched_in_svc(void){
|
||||
cpu_svc0_args1(CPU_SYSCALL_OP_SCHED);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------------------------ */
|
||||
/* */
|
||||
|
||||
|
||||
OS_STATIC_FORCE_INLINE
|
||||
int is_cpu_in_privilege(void){
|
||||
// 1. 检查是否在中断/异常中 (IPSR != 0 表示 Handler 模式)
|
||||
if ( CMSIS_get_IPSR() != 0) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
// 2. 如果在 Thread 模式,检查 CONTROL 寄存器
|
||||
return ((CMSIS_get_CONTROL() & 0x01) == 0)?1:0;
|
||||
}
|
||||
|
||||
|
||||
OS_STATIC_FORCE_INLINE
|
||||
os_uint_t cpu_save_disable_irq_in_isr(void){
|
||||
os_uint_t level = CMSIS_get_BASEPRI();
|
||||
CMSIS_set_BASEPRI((OS_CFG_SYSCALL_PRIORITY+1) << 4);
|
||||
return level;
|
||||
}
|
||||
|
||||
OS_STATIC_FORCE_INLINE
|
||||
void cpu_restore_irq_in_isr(os_uint_t value){
|
||||
CMSIS_set_BASEPRI(value);
|
||||
}
|
||||
|
||||
|
||||
OS_STATIC_FORCE_INLINE
|
||||
os_uint_t cpu_save_disable_irq(void){
|
||||
if(is_cpu_in_privilege()){
|
||||
return cpu_save_disable_irq_in_isr();
|
||||
}else{
|
||||
return cpu_save_disable_irq_in_svc();
|
||||
}
|
||||
}
|
||||
|
||||
OS_STATIC_FORCE_INLINE
|
||||
void cpu_restore_irq(os_uint_t value){
|
||||
if(is_cpu_in_privilege()){
|
||||
cpu_restore_irq_in_isr(value);
|
||||
}else{
|
||||
cpu_restore_irq_in_svc(value);
|
||||
}
|
||||
}
|
||||
|
||||
#endif /*INCLUDED_CPU_H*/
|
||||
+5
-143
@@ -6,116 +6,13 @@
|
||||
#include "os_compiler.h"
|
||||
#include "os_systick.h"
|
||||
#include "os_sched.h"
|
||||
/* ------------------------------------------------------------------------------------------------------------------ */
|
||||
/* */
|
||||
|
||||
#define OS_PORT_SYSCALL_ID 0x00
|
||||
#define OS_PORT_SYSCALL_OP_SAVE_DISABLE_IRQ 0x00
|
||||
#define OS_PORT_SYSCALL_OP_RESTORE_IRQ 0x01
|
||||
#define OS_PORT_SYSCALL_OP_SCHED 0x02
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------------------------ */
|
||||
/* */
|
||||
|
||||
volatile os_uint_t svc_exc_return;
|
||||
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------------------------ */
|
||||
/* */
|
||||
|
||||
OS_STATIC_FORCE_INLINE
|
||||
int is_cpu_in_privilege(void){
|
||||
// 1. 检查是否在中断/异常中 (IPSR != 0 表示 Handler 模式)
|
||||
if ( CMSIS_get_IPSR() != 0) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
// 2. 如果在 Thread 模式,检查 CONTROL 寄存器
|
||||
return ((CMSIS_get_CONTROL() & 0x01) == 0)?1:0;
|
||||
}
|
||||
|
||||
#if defined(__CC_ARM) /* armcc (AC5) */
|
||||
|
||||
#define SVC_CALL_ARGS0(num, type, name) \
|
||||
__svc(num) type name(void);
|
||||
|
||||
#define SVC_CALL_ARGS1(num, type, name, a0) \
|
||||
__svc(num) type name(os_uintptr_t a0);
|
||||
|
||||
#define SVC_CALL_ARGS2(num, type, name, a0, a1) \
|
||||
__svc(num) type name(os_uintptr_t a0, os_uintptr_t a1);
|
||||
|
||||
#define SVC_CALL_ARGS3(num, type, name, a0, a1, a2) \
|
||||
__svc(num) type name(os_uintptr_t a0, os_uintptr_t a1, os_uintptr_t a2);
|
||||
|
||||
#define SVC_CALL_ARGS4(num, type, name, a0, a1, a2, a3) \
|
||||
__svc(num) type name(os_uintptr_t a0, os_uintptr_t a1, os_uintptr_t a2, os_uintptr_t a3);
|
||||
|
||||
|
||||
#elif defined(__GNUC__) /* gcc */
|
||||
|
||||
#define SVC_CALL_ARGS0(num, type, name) \
|
||||
static type name(void) { \
|
||||
register os_uintptr_t r0 __asm__("r0")=0; \
|
||||
__asm__ volatile ("svc " #num : : : "memory"); \
|
||||
return (type)r0; \
|
||||
}
|
||||
|
||||
#define SVC_CALL_ARGS1(num, type, name, a1) \
|
||||
OS_STATIC_FORCE_INLINE type name(os_uintptr_t a1) { \
|
||||
register os_uintptr_t r0 __asm__("r0") = a1; \
|
||||
__asm__ volatile ("svc " #num :"=r"(r0):"r"(r0) : "memory"); \
|
||||
return (type)r0; \
|
||||
}
|
||||
|
||||
#define SVC_CALL_ARGS2(num, type, name, a1, a2) \
|
||||
OS_STATIC_FORCE_INLINE type name(os_uintptr_t a1, os_uintptr_t a2) { \
|
||||
register os_uintptr_t r0 __asm__("r0") = a1;\
|
||||
register os_uintptr_t r1 __asm__("r1") = a2;\
|
||||
__asm__ volatile ("svc " #num :"=r"(r0) :"r"(r0), "r"(r1) : "memory"); \
|
||||
return (type)r0; \
|
||||
}
|
||||
|
||||
#define SVC_CALL_ARGS3(num, type, name, a1, a2, a3) \
|
||||
OS_STATIC_FORCE_INLINE type name(os_uintptr_t a1, os_uintptr_t a2, os_uintptr_t a3) { \
|
||||
register os_uintptr_t r0 __asm__("r0") = a1; \
|
||||
register os_uintptr_t r1 __asm__("r1") = a2; \
|
||||
register os_uintptr_t r2 __asm__("r2") = a3; \
|
||||
__asm__ volatile ("svc " #num :"=r"(r0) :"r"(r0), "r"(r1), "r"(r2) : "memory"); \
|
||||
return (type)r0; \
|
||||
}
|
||||
|
||||
#define SVC_CALL_ARGS4(num, type, name, a1, a2, a3, a4) \
|
||||
OS_STATIC_FORCE_INLINE type name(os_uintptr_t a1, os_uintptr_t a2, os_uintptr_t a3, os_uintptr_t a4) { \
|
||||
register os_uintptr_t r0 __asm__("r0") = a1; \
|
||||
register os_uintptr_t r1 __asm__("r1") = a2; \
|
||||
register os_uintptr_t r2 __asm__("r2") = a3; \
|
||||
register os_uintptr_t r3 __asm__("r3") = a4; \
|
||||
__asm__ volatile ("svc " #num :"=r"(r0) :"r"(r0), "r"(r1), "r"(r2), "r"(r3) : "memory"); \
|
||||
return (type)r0; \
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
SVC_CALL_ARGS1(0, os_uint_t, os_port_svc0_args1, a1)
|
||||
SVC_CALL_ARGS2(0, void, os_port_svc0_args2, a1, a2)
|
||||
|
||||
OS_STATIC_FORCE_INLINE
|
||||
os_uint_t os_port_save_disable_irq_in_svc(void){
|
||||
return os_port_svc0_args1(OS_PORT_SYSCALL_OP_SAVE_DISABLE_IRQ);
|
||||
}
|
||||
|
||||
OS_STATIC_FORCE_INLINE
|
||||
void os_port_restore_irq_in_svc(os_uint_t level){
|
||||
os_port_svc0_args2(OS_PORT_SYSCALL_OP_RESTORE_IRQ, level);
|
||||
}
|
||||
|
||||
OS_STATIC_FORCE_INLINE
|
||||
void os_port_sched_in_svc(void){
|
||||
os_port_svc0_args1(OS_PORT_SYSCALL_OP_SCHED);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------------------------ */
|
||||
/* */
|
||||
|
||||
@@ -171,45 +68,12 @@ os_stack_t os_port_cpu_stack_init(os_task_entry_t entry, void* param
|
||||
return stack;
|
||||
}
|
||||
|
||||
void os_port_disable_irq(void){
|
||||
CMSIS_disable_irq();
|
||||
}
|
||||
|
||||
void os_port_enable_irq(void){
|
||||
CMSIS_enable_irq();
|
||||
}
|
||||
|
||||
os_uint_t os_port_save_disable_irq(void){
|
||||
if(is_cpu_in_privilege()){
|
||||
return os_port_save_disable_irq_in_isr();
|
||||
}else{
|
||||
return os_port_save_disable_irq_in_svc();
|
||||
}
|
||||
}
|
||||
|
||||
void os_port_restore_irq(os_uint_t level){
|
||||
if(is_cpu_in_privilege()){
|
||||
os_port_restore_irq_in_isr(level);
|
||||
}else{
|
||||
os_port_restore_irq_in_svc(level);
|
||||
}
|
||||
}
|
||||
|
||||
os_uint_t os_port_save_disable_irq_in_isr(void){
|
||||
os_uint_t level = CMSIS_get_BASEPRI();
|
||||
CMSIS_set_BASEPRI((OS_CFG_SYSCALL_PRIORITY+1) << 4);
|
||||
return level;
|
||||
}
|
||||
|
||||
void os_port_restore_irq_in_isr(os_uint_t level){
|
||||
CMSIS_set_BASEPRI(level);
|
||||
}
|
||||
|
||||
void os_sched(void){
|
||||
if(is_cpu_in_privilege()){
|
||||
os_sched_in_isr();
|
||||
}else{
|
||||
os_port_sched_in_svc();
|
||||
cpu_sched_in_svc();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -217,23 +81,22 @@ void SysTick_Handler(void){
|
||||
os_systick_tick();
|
||||
}
|
||||
|
||||
|
||||
void SVC_Handler_C(os_uintptr_t* svc_args){
|
||||
// 读取系统调用号:它存储在原本的 PC 指令前两个字节
|
||||
uint8_t svc_number = ((uint8_t *)svc_args[6])[-2];
|
||||
switch (svc_number) {
|
||||
case OS_PORT_SYSCALL_ID:{
|
||||
case CPU_SYSCALL_ID:{
|
||||
os_uint_t op = svc_args[0];
|
||||
switch (op) {
|
||||
case OS_PORT_SYSCALL_OP_SAVE_DISABLE_IRQ:{
|
||||
case CPU_SYSCALL_OP_SAVE_DISABLE_IRQ:{
|
||||
svc_args[0] = os_port_save_disable_irq_in_isr();
|
||||
break;
|
||||
}
|
||||
case OS_PORT_SYSCALL_OP_RESTORE_IRQ:{
|
||||
case CPU_SYSCALL_OP_RESTORE_IRQ:{
|
||||
os_port_restore_irq_in_isr(svc_args[1]);
|
||||
break;
|
||||
}
|
||||
case OS_PORT_SYSCALL_OP_SCHED:{
|
||||
case CPU_SYSCALL_OP_SCHED:{
|
||||
os_sched_in_isr();
|
||||
break;
|
||||
}
|
||||
@@ -246,4 +109,3 @@ void SVC_Handler_C(os_uintptr_t* svc_args){
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user