【嵌入式】uCOS-II在STM32上的移植
2016-12-06 23:43
399 查看
本文主要提供uCOS在STM32上的移植的一些步骤和个人见解,只涉及具体实操加一点解释,不讲原理,如有不当之处敬请指出。
文中使用的STM32型号为STM32F103C8T6,使用的uCOS版本为V2.91
零、
关于使用MDK创建STM32工程的步骤,在本人的另一篇文章,有兴趣的可以参考一下。
http://blog.csdn.net/d521000121/article/details/53107579
一、
先从网上下载下来uCOS-II的源码(官网可能在国内下不了,随便百度一搜多的是了),反正STM32是满足移植条件的了,我们直接就进行移植吧。
为了便于使用,我把源码分成三个目录,建好了工程后如下图:
![](https://img-blog.csdn.net/20161206231936607?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvZDUyMTAwMDEyMQ==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
这里解释一下,
UCOSII-PORT将是我们要自己写的一些文件,它和我们使用的芯片有关。
UCOSII-CONFIG是uCOS-II的一些相关设置文件,我们分别把两个头文件放在里面。
UCOSII-CORE是uCOS-II内核功能实现的代码,这一部分我们是不用理会的。
剩下的目录意思可以参考前面我提到的另一篇博文。
二、
工程建好了之后,我们就可以开始写一些与硬件相关的部分,使uCOS能泡在我们的STM32上。
这里分三个文件,就是在UCOSII-PORT里面的三个文件
1.OS_CPU.H
1).定义与编译器相关的数据类型,因为为了保证移植性,源码中是没有直接使用C语言的数据另行的,所以我们需要定义一下。
2).定义允许和禁止终端的宏,uCOS-II在访问临界区代码时,需要先关闭终端,后再打开中断,实现这两个功能的宏,也需要我们写。
就是定义OS_ENTER_CRITICAL() 和 OS_EXIT_CRITICAL()这两个宏。
3).定义栈的增长方向,其实对于ARM的处理器都是支持的,但是C语言编译器GCC只支持从上往下生长,所以要这样定义
#define OS_STK_GROWTH 1
4).定义OS_TASK_SW()宏
这个宏是任务从低优先级切换到高优先级时候用的,可以使用软中断将中断向量指向OSCtxSW()函数,或者直接调用OSCtxSW()函数就好了。
2.OS_CPU_A.ASM
1).编写在OS_CPU.H中提到的一些需要用汇编语言实现的函数代码。
2).编写OSSTartHighRdy()函数,这时一个运行优先级最高的就绪任务。
它会在OSStart()启动后就执行,负责从最高优先级任务的TCB控制块中获得该任务的堆栈指针SP,然后进行CPU的现场恢复。这时系统会将控制权交给用户创建的任务。要写这个函数主要是因为SP操作会因CPU而异。
3).编写OSCtxSw()函数,这是任务优先级切换函数,其工作也是换的最高优先级任务的堆栈指针,然后进行切换。
4).编写OSInitCtSw()函数,这时中断级的任务切换函数,这个跟OSCtxSw()类似,但是它不需要保存被中断任务。
3.OS_CPU_C.C
这是移植C语言编写的6个与操作系统相关的函数。
这里唯一必须移植的是任务堆栈初始化函数OSTaskStkInit()。这个函数会在任务被创建的时候调用,负责初始化任务的堆栈结构并返回新堆栈指针stk,初始化工作结束后,返回新的堆栈栈顶指针。
其余的均为Hook函数,又叫钩子函数,主要用来控制uCOS-II功能,必须被声明但并不一定要含有代码。
4.要写的基本就写完了,然后我们就可以开始写我们想写的部分了
还记得我们在前面进入临界段的方法函数里面,有用到一个cpu_sr,所以我们在使用开关中断的方法之前,必须先定义一个局部变量cpu_sr,并设为0。
main函数里面,分为几步:
1).硬件初始化,比如gpio口,AD,DA什么的。
2).OSInit()
3).创建任务
创建任务前,需要先申请任务堆栈空间以及任务的优先级
4).OSStart()
这里我就写了一个LED灯点亮然后熄灭的小程序,大家可以参考参考。
最后应该还有挺多没讲清楚的地方,本人也只是在自己摸索阶段,有问题的地方谢谢大家指出。
文中使用的STM32型号为STM32F103C8T6,使用的uCOS版本为V2.91
零、
关于使用MDK创建STM32工程的步骤,在本人的另一篇文章,有兴趣的可以参考一下。
http://blog.csdn.net/d521000121/article/details/53107579
一、
先从网上下载下来uCOS-II的源码(官网可能在国内下不了,随便百度一搜多的是了),反正STM32是满足移植条件的了,我们直接就进行移植吧。
为了便于使用,我把源码分成三个目录,建好了工程后如下图:
这里解释一下,
UCOSII-PORT将是我们要自己写的一些文件,它和我们使用的芯片有关。
UCOSII-CONFIG是uCOS-II的一些相关设置文件,我们分别把两个头文件放在里面。
UCOSII-CORE是uCOS-II内核功能实现的代码,这一部分我们是不用理会的。
剩下的目录意思可以参考前面我提到的另一篇博文。
二、
工程建好了之后,我们就可以开始写一些与硬件相关的部分,使uCOS能泡在我们的STM32上。
这里分三个文件,就是在UCOSII-PORT里面的三个文件
1.OS_CPU.H
1).定义与编译器相关的数据类型,因为为了保证移植性,源码中是没有直接使用C语言的数据另行的,所以我们需要定义一下。
2).定义允许和禁止终端的宏,uCOS-II在访问临界区代码时,需要先关闭终端,后再打开中断,实现这两个功能的宏,也需要我们写。
就是定义OS_ENTER_CRITICAL() 和 OS_EXIT_CRITICAL()这两个宏。
3).定义栈的增长方向,其实对于ARM的处理器都是支持的,但是C语言编译器GCC只支持从上往下生长,所以要这样定义
#define OS_STK_GROWTH 1
4).定义OS_TASK_SW()宏
这个宏是任务从低优先级切换到高优先级时候用的,可以使用软中断将中断向量指向OSCtxSW()函数,或者直接调用OSCtxSW()函数就好了。
/************************ (C) COPYLEFT 2010 Leafgrass ************************* * File Name : os_cpu_c.c * Author : Librae * Date : 06/10/2010 * Description : μCOS-II在STM32上的移植代码C语言部分, * 包括任务堆栈初始化代码和钩子函数等 ******************************************************************************/ #ifndef __OS_CPU_H__ #define __OS_CPU_H__ #ifdef OS_CPU_GLOBALS #define OS_CPU_EXT #else #define OS_CPU_EXT extern #endif /****************************************************************************** * 定义与编译器无关的数据类型 ******************************************************************************/ typedef unsigned char BOOLEAN; typedef unsigned char INT8U; /* Unsigned 8 bit quantity */ typedef signed char INT8S; /* Signed 8 bit quantity */ typedef unsigned short INT16U; /* Unsigned 16 bit quantity */ typedef signed short INT16S; /* Signed 16 bit quantity */ typedef unsigned int INT32U; /* Unsigned 32 bit quantity */ typedef signed int INT32S; /* Signed 32 bit quantity */ typedef float FP32; /* Single precision floating point*/ typedef double FP64; /* Double precision floating point*/ //STM32是32位位宽的,这里OS_STK和OS_CPU_SR都应该为32位数据类型 typedef unsigned int OS_STK; /* Each stack entry is 32-bit wide*/ typedef unsigned int OS_CPU_SR; /* Define size of CPU status register*/ /* ******************************************************************************* * Cortex M3 * Criti 11400 cal Section Management ******************************************************************************* */ /* ******************************************************************************* * PROTOTYPES * (see OS_CPU_A.ASM) ******************************************************************************* */ //OS_CRITICAL_METHOD = 1 :直接使用处理器的开关中断指令来实现宏 //OS_CRITICAL_METHOD = 2 :利用堆栈保存和恢复CPU的状态 //OS_CRITICAL_METHOD = 3 :利用编译器扩展功能获得程序状态字,保存在局部变量cpu_sr #define OS_CRITICAL_METHOD 3 //进入临界段的方法 #if OS_CRITICAL_METHOD == 3 #define OS_ENTER_CRITICAL() {cpu_sr = OS_CPU_SR_Save();} #define OS_EXIT_CRITICAL() {OS_CPU_SR_Restore(cpu_sr);} #endif #if OS_CRITICAL_METHOD == 3u /* See OS_CPU_A.ASM */ OS_CPU_SR OS_CPU_SR_Save(void); void OS_CPU_SR_Restore(OS_CPU_SR cpu_sr); #endif /* ******************************************************************************* * ARM Miscellaneous ******************************************************************************* */ //定义栈的增长方向. //CM3中,栈是由高地址向低地址增长的,所以OS_STK_GROWTH设置为1 #define OS_STK_GROWTH 1 /* Stack grows from HIGH to LOW memory on ARM */ //任务切换宏,由汇编实现. #define OS_TASK_SW() OSCtxSw() void OSCtxSw(void); void OSIntCtxSw(void); void OSStartHighRdy(void); void OSPendSV(void); OS_CPU_EXT INT32U OSInterrputSum; #endif /************************ (C) COPYLEFT 2010 Leafgrass ************************/
2.OS_CPU_A.ASM
1).编写在OS_CPU.H中提到的一些需要用汇编语言实现的函数代码。
2).编写OSSTartHighRdy()函数,这时一个运行优先级最高的就绪任务。
它会在OSStart()启动后就执行,负责从最高优先级任务的TCB控制块中获得该任务的堆栈指针SP,然后进行CPU的现场恢复。这时系统会将控制权交给用户创建的任务。要写这个函数主要是因为SP操作会因CPU而异。
3).编写OSCtxSw()函数,这是任务优先级切换函数,其工作也是换的最高优先级任务的堆栈指针,然后进行切换。
4).编写OSInitCtSw()函数,这时中断级的任务切换函数,这个跟OSCtxSw()类似,但是它不需要保存被中断任务。
;/*********************** (C) COPYRIGHT 2010 Libraworks ************************* ;* File Name : os_cpu_a.asm ;* Author : Librae ;* Version : V1.0 ;* Date : 06/10/2010 ;* Description : μCOS-II asm port for STM32 ;*******************************************************************************/ IMPORT OSRunning ; External references IMPORT OSPrioCur IMPORT OSPrioHighRdy IMPORT OSTCBCur IMPORT OSTCBHighRdy IMPORT OSIntNesting IMPORT OSIntExit IMPORT OSTaskSwHook EXPORT OSStartHighRdy EXPORT OSCtxSw EXPORT OSIntCtxSw EXPORT OS_CPU_SR_Save ; Functions declared in this file EXPORT OS_CPU_SR_Restore EXPORT PendSV_Handler NVIC_INT_CTRL EQU 0xE000ED04 ; 中断控制寄存器 NVIC_SYSPRI2 EQU 0xE000ED20 ; 系统优先级寄存器(2) NVIC_PENDSV_PRI EQU 0xFFFF0000 ; PendSV中断和系统节拍中断 ; (都为最低,0xff). NVIC_PENDSVSET EQU 0x10000000 ; 触发软件中断的值. PRESERVE8 AREA |.text|, CODE, READONLY THUMB ;******************************************************************************************************** ; CRITICAL SECTION METHOD 3 FUNCTIONS ; ; Description: Disable/Enable interrupts by preserving the state of interrupts. Generally speaking you ; would store the state of the interrupt disable flag in the local variable 'cpu_sr' and then ; disable interrupts. 'cpu_sr' is allocated in all of uC/OS-II's functions that need to ; disable interrupts. You would restore the interrupt disable state by copying back 'cpu_sr' ; into the CPU's status register. ; ; Prototypes : OS_CPU_SR OS_CPU_SR_Save(void); ; void OS_CPU_SR_Restore(OS_CPU_SR cpu_sr); ; ; ; Note(s) : 1) These functions are used in general like this: ; ; void Task (void *p_arg) ; { ; #if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */ ; OS_CPU_SR cpu_sr; ; #endif ; ; : ; : ; OS_ENTER_CRITICAL(); /* cpu_sr = OS_CPU_SaveSR(); */ ; : ; : ; OS_EXIT_CRITICAL(); /* OS_CPU_RestoreSR(cpu_sr); */ ; : ; : ; } ;******************************************************************************************************** OS_CPU_SR_Save MRS R0, PRIMASK ;读取PRIMASK到R0,R0为返回值 CPSID I ;PRIMASK=1,关中断(NMI和硬件FAULT可以响应) BX LR ;返回 OS_CPU_SR_Restore MSR PRIMASK, R0 ;读取R0到PRIMASK中,R0为参数 BX LR ;返回 ;/************************************************************************************** ;* 函数名称: OSStartHighRdy ;* ;* 功能描述: 使用调度器运行第一个任务 ;* ;* 参 数: None ;* ;* 返 回 值: None ;**************************************************************************************/ OSStartHighRdy LDR R4, =NVIC_SYSPRI2 ; set the PendSV exception priority LDR R5, =NVIC_PENDSV_PRI STR R5, [R4] MOV R4, #0 ; set the PSP to 0 for initial context switch call MSR PSP, R4 LDR R4, =OSRunning ; OSRunning = TRUE MOV R5, #1 STRB R5, [R4] ;切换到最高优先级的任务 LDR R4, =NVIC_INT_CTRL ;rigger the PendSV exception (causes context switch) LDR R5, =NVIC_PENDSVSET STR R5, [R4] CPSIE I ;enable interrupts at processor level OSStartHang B OSStartHang ;should never get here ;/************************************************************************************** ;* 函数名称: OSCtxSw ;* ;* 功能描述: 任务级上下文切换 ;* ;* 参 数: None ;* ;* 返 回 值: None ;***************************************************************************************/ OSCtxSw PUSH {R4, R5} LDR R4, =NVIC_INT_CTRL ;触发PendSV异常 (causes context switch) LDR R5, =NVIC_PENDSVSET STR R5, [R4] POP {R4, R5} BX LR ;/************************************************************************************** ;* 函数名称: OSIntCtxSw ;* ;* 功能描述: 中断级任务切换 ;* ;* 参 数: None ;* ;* 返 回 值: None ;***************************************************************************************/ OSIntCtxSw PUSH {R4, R5} LDR R4, =NVIC_INT_CTRL ;触发PendSV异常 (causes context switch) LDR R5, =NVIC_PENDSVSET STR R5, [R4] POP {R4, R5} BX LR NOP ;/************************************************************************************** ;* 函数名称: OSPendSV ;* ;* 功能描述: OSPendSV is used to cause a context switch. ;* ;* 参 数: None ;* ;* 返 回 值: None ;***************************************************************************************/ PendSV_Handler CPSID I ; Prevent interruption during context switch MRS R0, PSP ; PSP is process stack pointer 如果在用PSP堆栈,则可以忽略保存寄存器,参考CM3权威中的双堆栈-白菜注 CBZ R0, PendSV_Handler_Nosave ; Skip register save the first time SUBS R0, R0, #0x20 ; Save remaining regs r4-11 on process stack STM R0, {R4-R11} LDR R1, =OSTCBCur ; OSTCBCur->OSTCBStkPtr = SP; LDR R1, [R1] STR R0, [R1] ; R0 is SP of process being switched out ; At this point, entire context of process has been saved PendSV_Handler_Nosave PUSH {R14} ; Save LR exc_return value LDR R0, =OSTaskSwHook ; OSTaskSwHook(); BLX R0 POP {R14} LDR R0, =OSPrioCur ; OSPrioCur = OSPrioHighRdy; LDR R1, =OSPrioHighRdy LDRB R2, [R1] STRB R2, [R0] LDR R0, =OSTCBCur ; OSTCBCur = OSTCBHighRdy; LDR R1, =OSTCBHighRdy LDR R2, [R1] STR R2, [R0] LDR R0, [R2] ; R0 is new process SP; SP = OSTCBHighRdy->OSTCBStkPtr; LDM R0, {R4-R11} ; Restore r4-11 from new process stack ADDS R0, R0, #0x20 MSR PSP, R0 ; Load PSP with new process SP ORR LR, LR, #0x04 ; Ensure exception return uses process stack CPSIE I BX LR ; Exception return will restore remaining context end
3.OS_CPU_C.C
这是移植C语言编写的6个与操作系统相关的函数。
这里唯一必须移植的是任务堆栈初始化函数OSTaskStkInit()。这个函数会在任务被创建的时候调用,负责初始化任务的堆栈结构并返回新堆栈指针stk,初始化工作结束后,返回新的堆栈栈顶指针。
其余的均为Hook函数,又叫钩子函数,主要用来控制uCOS-II功能,必须被声明但并不一定要含有代码。
/* ********************************************************************************************************* * uC/OS-II * The Real-Time Kernel * * * (c) Copyright 2006, Micrium, Weston, FL * All Rights Reserved * * ARM Cortex-M3 Port * * File : OS_CPU_C.C * Version : V2.86 * By : Jean J. Labrosse * * For : ARMv7M Cortex-M3 * Mode : Thumb2 * Toolchain : RealView Development Suite * RealView Microcontroller Development Kit (MDK) * ARM Developer Suite (ADS) * Keil uVision ********************************************************************************************************* */ #define OS_CPU_GLOBALS #include "includes.h" /* ********************************************************************************************************* * LOCAL VARIABLES ********************************************************************************************************* */ #if OS_TMR_EN > 0 static INT16U OSTmrCtr; #endif /* ********************************************************************************************************* * OS INITIALIZATION HOOK * (BEGINNING) * * Description: This function is called by OSInit() at the beginning of OSInit(). * * Arguments : none * * Note(s) : 1) Interrupts should be disabled during this call. ********************************************************************************************************* */ #if OS_CPU_HOOKS_EN > 0 && OS_VERSION > 203 void OSInitHookBegin (void) { #if OS_TMR_EN > 0 OSTmrCtr = 0; #endif } #endif /* ********************************************************************************************************* * OS INITIALIZATION HOOK * (END) * * Description: This function is called by OSInit() at the end of OSInit(). * * Arguments : none * * Note(s) : 1) Interrupts should be disabled during this call. ********************************************************************************************************* */ #if OS_CPU_HOOKS_EN > 0 && OS_VERSION > 203 void OSInitHookEnd (void) { } #endif /* ********************************************************************************************************* * TASK CREATION HOOK * * Description: This function is called when a task is created. * * Arguments : ptcb is a pointer to the task control block of the task being created. * * Note(s) : 1) Interrupts are disabled during this call. ********************************************************************************************************* */ #if OS_CPU_HOOKS_EN > 0 void OSTaskCreateHook (OS_TCB *ptcb) { #if OS_APP_HOOKS_EN > 0 App_TaskCreateHook(ptcb); #else (void)ptcb; /* Prevent compiler warning */ #endif } #endif /* ********************************************************************************************************* * TASK DELETION HOOK * * Description: This function is called when a task is deleted. * * Arguments : ptcb is a pointer to the task control block of the task being deleted. * * Note(s) : 1) Interrupts are disabled during this call. ********************************************************************************************************* */ #if OS_CPU_HOOKS_EN > 0 void OSTaskDelHook (OS_TCB *ptcb) { #if OS_APP_HOOKS_EN > 0 App_TaskDelHook(ptcb); #else (void)ptcb; /* Prevent compiler warning */ #endif } #endif /* ********************************************************************************************************* * IDLE TASK HOOK * * Description: This function is called by the idle task. This hook has been added to allow you to do * such things as STOP the CPU to conserve power. * * Arguments : none * * Note(s) : 1) Interrupts are enabled during this call. ********************************************************************************************************* */ #if OS_CPU_HOOKS_EN > 0 && OS_VERSION >= 251 void OSTaskIdleHook (void) { #if OS_APP_HOOKS_EN > 0 App_TaskIdleHook(); #endif } #endif /* ********************************************************************************************************* * STATISTIC TASK HOOK * * Description: This function is called every second by uC/OS-II's statistics task. This allows your * application to add functionality to the statistics task. * * Arguments : none ********************************************************************************************************* */ #if OS_CPU_HOOKS_EN > 0 void OSTaskStatHook (void) { #if OS_APP_HOOKS_EN > 0 App_TaskStatHook(); #endif } #endif /* ********************************************************************************************************* * INITIALIZE A TASK'S STACK * * Description: This function is called by either OSTaskCreate() or OSTaskCreateExt() to initialize the * stack frame of the task being created. This function is highly processor specific. * * Arguments : task is a pointer to the task code * * p_arg is a pointer to a user supplied data area that will be passed to the task * when the task first executes. * * ptos is a pointer to the top of stack. It is assumed that 'ptos' points to * a 'free' entry on the task stack. If OS_STK_GROWTH is set to 1 then * 'ptos' will contain the HIGHEST valid address of the stack. Similarly, if * OS_STK_GROWTH is set to 0, the 'ptos' will contains the LOWEST valid address * of the stack. * * opt specifies options that can be used to alter the behavior of OSTaskStkInit(). * (see uCOS_II.H for OS_TASK_OPT_xxx). * * Returns : Always returns the location of the new top-of-stack once the processor registers have * been placed on the stack in the proper order. * * Note(s) : 1) Interrupts are enabled when your task starts executing. * 2) All tasks run in Thread mode, using process stack. ********************************************************************************************************* */ OS_STK *OSTaskStkInit (void (*task)(void *p_arg), void *p_arg, OS_STK *ptos, INT16U opt) { OS_STK *stk; (void)opt; /* 'opt' is not used, prevent warning */ stk = ptos; /* Load stack pointer */ /* Registers stacked as if auto-saved on exception */ *(stk) = (INT32U)0x01000000L; /* xPSR */ *(--stk) = (INT32U)task; /* Entry Point */ *(--stk) = (INT32U)0xFFFFFFFEL; /* R14 (LR) (init value will cause fault if ever used)*/ *(--stk) = (INT32U)0x12121212L; /* R12 */ *(--stk) = (INT32U)0x03030303L; /* R3 */ *(--stk) = (INT32U)0x02020202L; /* R2 */ *(--stk) = (INT32U)0x01010101L; /* R1 */ *(--stk) = (INT32U)p_arg; /* R0 : argument */ /* Remaining registers saved on process stack */ *(--stk) = (INT32U)0x11111111L; /* R11 */ *(--stk) = (INT32U)0x10101010L; /* R10 */ *(--stk) = (INT32U)0x09090909L; /* R9 */ *(--stk) = (INT32U)0x08080808L; /* R8 */ *(--stk) = (INT32U)0x07070707L; /* R7 */ *(--stk) = (INT32U)0x06060606L; /* R6 */ *(--stk) = (INT32U)0x05050505L; /* R5 */ *(--stk) = (INT32U)0x04040404L; /* R4 */ return (stk); } /* ********************************************************************************************************* * TASK SWITCH HOOK * * Description: This function is called when a task switch is performed. This allows you to perform other * operations during a context switch. * * Arguments : none * * Note(s) : 1) Interrupts are disabled during this call. * 2) It is assumed that the global pointer 'OSTCBHighRdy' points to the TCB of the task that * will be 'switched in' (i.e. the highest priority task) and, 'OSTCBCur' points to the * task being switched out (i.e. the preempted task). ********************************************************************************************************* */ #if (OS_CPU_HOOKS_EN > 0) && (OS_TASK_SW_HOOK_EN > 0) void OSTaskSwHook (void) { #if OS_APP_HOOKS_EN > 0 App_TaskSwHook(); #endif } #endif /* ********************************************************************************************************* * OS_TCBInit() HOOK * * Description: This function is called by OS_TCBInit() after setting up most of the TCB. * * Arguments : ptcb is a pointer to the TCB of the task being created. * * Note(s) : 1) Interrupts may or may not be ENABLED during this call. ********************************************************************************************************* */ #if OS_CPU_HOOKS_EN > 0 && OS_VERSION > 203 void OSTCBInitHook (OS_TCB *ptcb) { #if OS_APP_HOOKS_EN > 0 App_TCBInitHook(ptcb); #else (void)ptcb; /* Prevent compiler warning */ #endif } #endif /* ********************************************************************************************************* * TICK HOOK * * Description: This function is called every tick. * * Arguments : none * * Note(s) : 1) Interrupts may or may not be ENABLED during this call. ********************************************************************************************************* */ #if (OS_CPU_HOOKS_EN > 0) && (OS_TIME_TICK_HOOK_EN > 0) void OSTimeTickHook (void) { #if OS_APP_HOOKS_EN > 0 App_TimeTickHook(); #endif #if OS_TMR_EN > 0 OSTmrCtr++; if (OSTmrCtr >= (OS_TICKS_PER_SEC / OS_TMR_CFG_TICKS_PER_SEC)) { OSTmrCtr = 0; OSTmrSignal(); } #endif } #endif #if OS_CPU_HOOKS_EN > 0u && OS_VERSION > 290u void OSTaskReturnHook(OS_TCB *ptcb) { (void)ptcb; } #endif /*----------------------- (C) COPYRIGHT @ 2012 liycobl ----------------- end of file -----------------*/
4.要写的基本就写完了,然后我们就可以开始写我们想写的部分了
还记得我们在前面进入临界段的方法函数里面,有用到一个cpu_sr,所以我们在使用开关中断的方法之前,必须先定义一个局部变量cpu_sr,并设为0。
main函数里面,分为几步:
1).硬件初始化,比如gpio口,AD,DA什么的。
2).OSInit()
3).创建任务
创建任务前,需要先申请任务堆栈空间以及任务的优先级
4).OSStart()
这里我就写了一个LED灯点亮然后熄灭的小程序,大家可以参考参考。
/*********************************Includes*********************************/ #include "stm32f10x.h" #include "includes.h" /**************************************************************************/ /********************************task config*******************************/ //start task #define START_TASK_PRIO 10 #define START_STK_SIZE 64 OS_STK START_TASK_STK[START_STK_SIZE]; void start_task (void *pdata); //led task #define LED_TASK_PRIO 11 #define LED_STK_SIZE 64 OS_STK LED_TASK_STK[LED_STK_SIZE]; void led_task (void *pdata); void led_init (void); /**************************************************************************/ int main(void) { delay_init(); NVIC_Configuration(); led_init(); OSInit(); OSTaskCreate(start_task, NULL, (OS_STK *) &START_TASK_STK[START_STK_SIZE-1], START_TASK_PRIO); OSStart(); return 0; } void led_init () { GPIO_InitTypeDef GPIO_InitStructure; delay_init(); RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); //使能PB端口时钟 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8; //LED0-->PB.8 端口配置 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //IO口速度为50MHz GPIO_Init(GPIOB, &GPIO_InitStructure); //根据设定参数初始化GPIOB.8 GPIO_SetBits(GPIOB,GPIO_Pin_8); //PB.8 输出高 } void led_task (void *pdata) { while (1) { GPIO_SetBits(GPIOB,GPIO_Pin_8); //PB.8 输出高 OSTimeDly(200); GPIO_ResetBits(GPIOB,GPIO_Pin_8); //PB.8 输出低 OSTimeDly(200); } } void start_task (void *pdata) { OS_CPU_SR cpu_sr = 0; //用于开关中断进入临界段 pdata = pdata; OS_ENTER_CRITICAL(); OSTaskCreate(led_task, NULL, (OS_STK *) &LED_TASK_STK[LED_STK_SIZE-1], LED_TASK_PRIO); OS_EXIT_CRITICAL(); OSTaskSuspend(START_TASK_PRIO); }
最后应该还有挺多没讲清楚的地方,本人也只是在自己摸索阶段,有问题的地方谢谢大家指出。
相关文章推荐
- 如何把UCos-ii_在STM32上的移植
- 如何把UCos-ii_在STM32上的移植
- uCOS-II移植到STM32的详细步骤
- ucos-II移植到stm32上关于systick部分的修改
- CoIDE下UCos-II在STM32下的移植
- STM32平台移植uCOS-II详细说明
- STM32移植uCOS-II
- 如何把UCos-ii_在STM32上的移植
- STM32移植uCOS-II系统(1)
- 怎样把UCos-ii_在STM32上的移植
- STM32移植uCOS-II系统(2)
- ucOS_II移植:Stm32启动代码分析
- STM32移植uCOS-II的详细注释
- STM32+uCOS-II+uc/GUI移植 (uC/GUI API函数学习一)
- uCOS-II移植到STM32上的详细步骤
- 基于STM32的uCOS-II移植详解
- ucos-ii和ucgui在stm32上的移植及工程
- STM32W108无线传感器网络嵌入式uCOS-II的移植及实时环境监测
- STM32W108无线传感器网络嵌入式uCOS-II的移植及实时环境监測
- STM32移植uCOS-ii笔记