当前位置:   article > 正文

ucos ii移植到STM32 (HardFault_Handler)_ucos hardfault_handler

ucos hardfault_handler

 转载请注明原文地址:http://blog.csdn.net/oyhb_1992/article/details/72654582

Ucosii的移植到STM32其实非常简单,但有些时候就是会出现一些莫名其妙的错误!

        Ucosii的移植网上都说是修改os_cpu.h     os_cpu_c.c      os_cpu_a.asm三个文件,其实这样说是不全的!还需要修改startup_stm32f10x_hd.s启动文件一小部分代码和自己实现SysTick_Handler(void)时钟滴答中断函数。

        os_cpu.h os_cpu_c.c       os_cpu_a.asm这三部分很简单,网上到处都是直接复制粘贴

os_cpu.h

  1. /************************(C) COPYLEFT 2010 Leafgrass *************************
  2. * File Name : os_cpu_c.c
  3. * Author : Librae
  4. * Date : 06/10/2010
  5. * Description : μCOS-II在STM32上的移植代码C语言部分,
  6. * 包括任务堆栈初始化代码和钩子函数等
  7. ******************************************************************************/
  8. #ifndef __OS_CPU_H__
  9. #define __OS_CPU_H__
  10. #ifdef OS_CPU_GLOBALS
  11. #define OS_CPU_EXT
  12. #else
  13. #defineOS_CPU_EXT extern
  14. #endif
  15. /******************************************************************************
  16. * 定义与编译器无关的数据类型
  17. ******************************************************************************/
  18. typedef unsignedchar BOOLEAN;
  19. typedef unsignedchar INT8U; /* Unsigned 8 bit quantity */
  20. typedef signed char INT8S; /*Signed 8 bit quantity */
  21. typedef unsignedshort INT16U; /*Unsigned 16 bit quantity */
  22. typedef signed short INT16S; /* Signed 16 bit quantity */
  23. typedef unsignedint INT32U; /* Unsigned 32 bit quantity */
  24. typedef signed int INT32S; /*Signed 32 bit quantity */
  25. typedef float FP32; /*Single precision floating point*/
  26. typedef double FP64; /* Double precisionfloating point*/
  27. //STM32是32位位宽的,这里OS_STK和OS_CPU_SR都应该为32位数据类型
  28. typedef unsignedint OS_STK; /* Each stack entry is 32-bit wide*/
  29. typedef unsignedint OS_CPU_SR; /* Define size of CPU status register*/
  30. /*
  31. *******************************************************************************
  32. * Cortex M3
  33. * Critical SectionManagement
  34. *******************************************************************************
  35. */
  36. /*
  37. *******************************************************************************
  38. * ARM Miscellaneous
  39. *******************************************************************************
  40. */
  41. //定义栈的增长方向.
  42. //CM3中,栈是由高地址向低地址增长的,所以OS_STK_GROWTH设置为1
  43. #define OS_STK_GROWTH 1 /* Stack grows from HIGH to LOW memory on ARM */
  44. //任务切换宏,由汇编实现.
  45. #define OS_TASK_SW() OSCtxSw()
  46. /*
  47. *******************************************************************************
  48. * PROTOTYPES
  49. * (see OS_CPU_A.ASM)
  50. *******************************************************************************
  51. */
  52. //OS_CRITICAL_METHOD= 1 :直接使用处理器的开关中断指令来实现宏
  53. //OS_CRITICAL_METHOD= 2 :利用堆栈保存和恢复CPU的状态
  54. //OS_CRITICAL_METHOD= 3 :利用编译器扩展功能获得程序状态字,保存在局部变量cpu_sr
  55. #define OS_CRITICAL_METHOD 3 //进入临界段的方法
  56. #ifOS_CRITICAL_METHOD == 3
  57. #define OS_ENTER_CRITICAL() {cpu_sr = OS_CPU_SR_Save();}
  58. #define OS_EXIT_CRITICAL() {OS_CPU_SR_Restore(cpu_sr);}
  59. #endif
  60. void OSCtxSw(void);
  61. void OSIntCtxSw(void);
  62. void OSStartHighRdy(void);
  63. void OSPendSV(void);
  64. #ifOS_CRITICAL_METHOD == 3u /* See OS_CPU_A.ASM */
  65. OS_CPU_SR OS_CPU_SR_Save(void);
  66. void OS_CPU_SR_Restore(OS_CPU_SR cpu_sr);
  67. #endif
  68. OS_CPU_EXT INT32UOSInterrputSum;
  69. #endif
  70. /************************(C) COPYLEFT 2010 Leafgrass ************************/

os_cpu.h

  1. /*
  2. *********************************************************************************************************
  3. * uC/OS-II
  4. * TheReal-Time Kernel
  5. *
  6. *
  7. * (c) Copyright2006, Micrium, Weston, FL
  8. * AllRights Reserved
  9. *
  10. * ARMCortex-M3 Port
  11. *
  12. * File : OS_CPU_C.C
  13. * Version : V2.86
  14. * By : Jean J. Labrosse
  15. *
  16. * For : ARMv7M Cortex-M3
  17. * Mode : Thumb2
  18. * Toolchain :RealView Development Suite
  19. * RealView MicrocontrollerDevelopment Kit (MDK)
  20. * ARM Developer Suite (ADS)
  21. * Keil uVision
  22. *********************************************************************************************************
  23. */
  24. #define OS_CPU_GLOBALS
  25. #include"includes.h"
  26. /*
  27. *********************************************************************************************************
  28. * LOCALVARIABLES
  29. *********************************************************************************************************
  30. */
  31. #if OS_TMR_EN >0
  32. static INT16U OSTmrCtr;
  33. #endif
  34. /*
  35. *********************************************************************************************************
  36. * OSINITIALIZATION HOOK
  37. * (BEGINNING)
  38. *
  39. * Description:This function is called by OSInit() at the beginning of OSInit().
  40. *
  41. * Arguments : none
  42. *
  43. * Note(s) : 1) Interrupts should be disabled duringthis call.
  44. *********************************************************************************************************
  45. */
  46. #ifOS_CPU_HOOKS_EN > 0 && OS_VERSION > 203
  47. void OSInitHookBegin (void)
  48. {
  49. #if OS_TMR_EN >0
  50. OSTmrCtr = 0;
  51. #endif
  52. }
  53. #endif
  54. /*
  55. *********************************************************************************************************
  56. * OSINITIALIZATION HOOK
  57. * (END)
  58. *
  59. * Description:This function is called by OSInit() at the end of OSInit().
  60. *
  61. * Arguments : none
  62. *
  63. * Note(s) : 1) Interrupts should be disabled duringthis call.
  64. *********************************************************************************************************
  65. */
  66. #ifOS_CPU_HOOKS_EN > 0 && OS_VERSION > 203
  67. void OSInitHookEnd (void)
  68. {
  69. }
  70. #endif
  71. /*
  72. *********************************************************************************************************
  73. * TASKCREATION HOOK
  74. *
  75. * Description:This function is called when a task is created.
  76. *
  77. * Arguments : ptcb is a pointer to the task control block of the task being created.
  78. *
  79. * Note(s) : 1) Interrupts are disabled during thiscall.
  80. *********************************************************************************************************
  81. */
  82. #ifOS_CPU_HOOKS_EN > 0
  83. void OSTaskCreateHook (OS_TCB *ptcb)
  84. {
  85. #ifOS_APP_HOOKS_EN > 0
  86. App_TaskCreateHook(ptcb);
  87. #else
  88. (void)ptcb; /* Preventcompiler warning */
  89. #endif
  90. }
  91. #endif
  92. /*
  93. *********************************************************************************************************
  94. * TASKDELETION HOOK
  95. *
  96. * Description:This function is called when a task is deleted.
  97. *
  98. * Arguments : ptcb is a pointer to the task control block of the task being deleted.
  99. *
  100. * Note(s) : 1) Interrupts are disabled during thiscall.
  101. *********************************************************************************************************
  102. */
  103. #ifOS_CPU_HOOKS_EN > 0
  104. void OSTaskDelHook (OS_TCB *ptcb)
  105. {
  106. #ifOS_APP_HOOKS_EN > 0
  107. App_TaskDelHook(ptcb);
  108. #else
  109. (void)ptcb; /* Preventcompiler warning */
  110. #endif
  111. }
  112. #endif
  113. /*
  114. *********************************************************************************************************
  115. * IDLE TASK HOOK
  116. *
  117. * Description:This function is called by the idle task. This hook has been added to allow you to do
  118. * such things as STOP the CPU toconserve power.
  119. *
  120. * Arguments : none
  121. *
  122. * Note(s) : 1) Interrupts are enabled during thiscall.
  123. *********************************************************************************************************
  124. */
  125. #ifOS_CPU_HOOKS_EN > 0 && OS_VERSION >= 251
  126. void OSTaskIdleHook (void)
  127. {
  128. #ifOS_APP_HOOKS_EN > 0
  129. App_TaskIdleHook();
  130. #endif
  131. }
  132. #endif
  133. /*
  134. *********************************************************************************************************
  135. * STATISTIC TASK HOOK
  136. *
  137. * Description:This function is called every second by uC/OS-II's statistics task. This allows your
  138. * application to add functionalityto the statistics task.
  139. *
  140. * Arguments : none
  141. *********************************************************************************************************
  142. */
  143. #ifOS_CPU_HOOKS_EN > 0
  144. void OSTaskStatHook (void)
  145. {
  146. #ifOS_APP_HOOKS_EN > 0
  147. App_TaskStatHook();
  148. #endif
  149. }
  150. #endif
  151. /*
  152. *********************************************************************************************************
  153. * INITIALIZE A TASK'S STACK
  154. *
  155. * Description:This function is called by either OSTaskCreate() or OSTaskCreateExt() to initializethe
  156. * stack frame of the task beingcreated. This function is highlyprocessor specific.
  157. *
  158. * Arguments : task is a pointer to the task code
  159. *
  160. * p_arg is a pointer to a user supplied dataarea that will be passed to the task
  161. * when the task firstexecutes.
  162. *
  163. * ptos is a pointer to the top ofstack. It is assumed that 'ptos' pointsto
  164. * a 'free' entry on the taskstack. If OS_STK_GROWTH is set to 1 then
  165. * 'ptos' will containthe HIGHEST valid address of the stack. Similarly, if
  166. * OS_STK_GROWTH isset to 0, the 'ptos' will contains the LOWEST valid address
  167. * of the stack.
  168. *
  169. * opt specifies options that can be usedto alter the behavior of OSTaskStkInit().
  170. * (see uCOS_II.H forOS_TASK_OPT_xxx).
  171. *
  172. * Returns : Always returns the location of the newtop-of-stack once the processor registers have
  173. * been placed on the stack in theproper order.
  174. *
  175. * Note(s) : 1) Interrupts are enabled when your taskstarts executing.
  176. * 2) All tasks run in Thread mode,using process stack.
  177. *********************************************************************************************************
  178. */
  179. OS_STK*OSTaskStkInit (void (*task)(void *p_arg), void *p_arg, OS_STK *ptos, INT16Uopt)
  180. {
  181. OS_STK *stk;
  182. (void)opt; /* 'opt' isnot used, prevent warning */
  183. stk = ptos; /* Load stack pointer */
  184. /* Registers stacked as if auto-saved on exception */
  185. *(stk) = (INT32U)0x01000000L; /* xPSR */
  186. *(--stk) = (INT32U)task; /* Entry Point */
  187. *(--stk) = (INT32U)0xFFFFFFFEL; /* R14 (LR) (init value will cause fault if ever used)*/
  188. *(--stk) = (INT32U)0x12121212L; /* R12 */
  189. *(--stk) = (INT32U)0x03030303L; /* R3 */
  190. *(--stk) = (INT32U)0x02020202L; /* R2 */
  191. *(--stk) = (INT32U)0x01010101L; /* R1 */
  192. *(--stk) = (INT32U)p_arg; /* R0 : argument */
  193. /* Remaining registers saved on process stack */
  194. *(--stk) = (INT32U)0x11111111L; /* R11 */
  195. *(--stk) = (INT32U)0x10101010L; /* R10 */
  196. *(--stk) = (INT32U)0x09090909L; /* R9 */
  197. *(--stk) = (INT32U)0x08080808L; /* R8 */
  198. *(--stk) = (INT32U)0x07070707L; /* R7 */
  199. *(--stk) = (INT32U)0x06060606L; /* R6 */
  200. *(--stk) = (INT32U)0x05050505L; /* R5 */
  201. *(--stk) = (INT32U)0x04040404L; /* R4 */
  202. return (stk);
  203. }
  204. /*
  205. *********************************************************************************************************
  206. * TASK SWITCHHOOK
  207. *
  208. * Description:This function is called when a task switch is performed. This allows you to perform other
  209. * operations during a contextswitch.
  210. *
  211. * Arguments : none
  212. *
  213. * Note(s) : 1) Interrupts are disabled during thiscall.
  214. * 2) It is assumed that the globalpointer 'OSTCBHighRdy' points to the TCB of the task that
  215. * will be 'switched in' (i.e.the highest priority task) and, 'OSTCBCur' points to the
  216. * task being switched out (i.e. thepreempted task).
  217. *********************************************************************************************************
  218. */
  219. #if(OS_CPU_HOOKS_EN > 0) && (OS_TASK_SW_HOOK_EN > 0)
  220. void OSTaskSwHook (void)
  221. {
  222. #ifOS_APP_HOOKS_EN > 0
  223. App_TaskSwHook();
  224. #endif
  225. }
  226. #endif
  227. /*
  228. *********************************************************************************************************
  229. * OS_TCBInit() HOOK
  230. *
  231. * Description:This function is called by OS_TCBInit() after setting up most of the TCB.
  232. *
  233. * Arguments : ptcb is a pointer to the TCB of the task being created.
  234. *
  235. * Note(s) : 1) Interrupts may or may not be ENABLEDduring this call.
  236. *********************************************************************************************************
  237. */
  238. #ifOS_CPU_HOOKS_EN > 0 && OS_VERSION > 203
  239. void OSTCBInitHook (OS_TCB *ptcb)
  240. {
  241. #ifOS_APP_HOOKS_EN > 0
  242. App_TCBInitHook(ptcb);
  243. #else
  244. (void)ptcb; /* Prevent compilerwarning */
  245. #endif
  246. }
  247. #endif
  248. /*
  249. *********************************************************************************************************
  250. * TICK HOOK
  251. *
  252. * Description:This function is called every tick.
  253. *
  254. * Arguments : none
  255. *
  256. * Note(s) : 1) Interrupts may or may not be ENABLEDduring this call.
  257. *********************************************************************************************************
  258. */
  259. #if(OS_CPU_HOOKS_EN > 0) && (OS_TIME_TICK_HOOK_EN > 0)
  260. void OSTimeTickHook (void)
  261. {
  262. #ifOS_APP_HOOKS_EN > 0
  263. App_TimeTickHook();
  264. #endif
  265. #if OS_TMR_EN >0
  266. OSTmrCtr++;
  267. if (OSTmrCtr >= (OS_TICKS_PER_SEC /OS_TMR_CFG_TICKS_PER_SEC)) {
  268. OSTmrCtr = 0;
  269. OSTmrSignal();
  270. }
  271. #endif
  272. }
  273. #endif
  274. #ifOS_CPU_HOOKS_EN > 0u && OS_VERSION > 290u
  275. voidOSTaskReturnHook(OS_TCB *ptcb)
  276. {
  277. (void)ptcb;
  278. }
  279. #endif
  280. /*-----------------------(C) COPYRIGHT @ 2012 liycobl ----------------- end of file -----------------*/

os_cpu_a.asm

  1. ;/***********************(C) COPYRIGHT 2010 Libraworks *************************
  2. ;* File Name : os_cpu_a.asm
  3. ;* Author : Librae
  4. ;* Version : V1.0
  5. ;* Date : 06/10/2010
  6. ;* Description : μCOS-II asm port for STM32
  7. ;*******************************************************************************/
  8. IMPORT OSRunning ; External references
  9. IMPORT OSPrioCur
  10. IMPORT OSPrioHighRdy
  11. IMPORT OSTCBCur
  12. IMPORT OSTCBHighRdy
  13. IMPORT OSIntNesting
  14. IMPORT OSIntExit
  15. IMPORT OSTaskSwHook
  16. EXPORT OSStartHighRdy
  17. EXPORT OSCtxSw
  18. EXPORT OSIntCtxSw
  19. EXPORT OS_CPU_SR_Save ;Functions declared in this file
  20. EXPORT OS_CPU_SR_Restore
  21. EXPORT PendSV_Handler
  22. NVIC_INT_CTRL EQU 0xE000ED04 ;中断控制寄存器
  23. NVIC_SYSPRI2 EQU 0xE000ED20 ;系统优先级寄存器(2)
  24. NVIC_PENDSV_PRIEQU 0xFFFF0000 ; PendSV中断和系统节拍中断
  25. ; (都为最低,0xff).
  26. NVIC_PENDSVSET EQU 0x10000000 ;触发软件中断的值.
  27. PRESERVE8
  28. AREA |.text|, CODE, READONLY
  29. THUMB
  30. ;********************************************************************************************************
  31. ; CRITICALSECTION METHOD 3 FUNCTIONS
  32. ;
  33. ; Description:Disable/Enable interrupts by preserving the state of interrupts. Generally speaking you
  34. ; would store the state of theinterrupt disable flag in the local variable 'cpu_sr' and then
  35. ; disable interrupts. 'cpu_sr' is allocated in all of uC/OS-II'sfunctions that need to
  36. ; disable interrupts. You would restore the interrupt disable stateby copying back 'cpu_sr'
  37. ; into the CPU's status register.
  38. ;
  39. ; Prototypes: OS_CPU_SR OS_CPU_SR_Save(void);
  40. ; void OS_CPU_SR_Restore(OS_CPU_SR cpu_sr);
  41. ;
  42. ;
  43. ; Note(s) : 1) These functions are used in generallike this:
  44. ;
  45. ; void Task (void *p_arg)
  46. ; {
  47. ; #if OS_CRITICAL_METHOD ==3 /* Allocate storage for CPUstatus register */
  48. ; OS_CPU_SR cpu_sr;
  49. ; #endif
  50. ;
  51. ; :
  52. ; :
  53. ; OS_ENTER_CRITICAL(); /* cpu_sr = OS_CPU_SaveSR(); */
  54. ; :
  55. ; :
  56. ; OS_EXIT_CRITICAL(); /* OS_CPU_RestoreSR(cpu_sr); */
  57. ; :
  58. ; :
  59. ; }
  60. ;********************************************************************************************************
  61. OS_CPU_SR_Save
  62. MRS R0, PRIMASK ;读取PRIMASK到R0,R0为返回值
  63. CPSID I ;PRIMASK=1,关中断(NMI和硬件FAULT可以响应)
  64. BX LR ;返回
  65. OS_CPU_SR_Restore
  66. MSR PRIMASK, R0 ;读取R0到PRIMASK中,R0为参数
  67. BX LR ;返回
  68. ;/**************************************************************************************
  69. ;* 函数名称: OSStartHighRdy
  70. ;*
  71. ;* 功能描述:使用调度器运行第一个任务
  72. ;*
  73. ;* 参 数: None
  74. ;*
  75. ;* 返 回 值: None
  76. ;**************************************************************************************/
  77. OSStartHighRdy
  78. LDR R4, =NVIC_SYSPRI2 ; set thePendSV exception priority
  79. LDR R5, =NVIC_PENDSV_PRI
  80. STR R5, [R4]
  81. MOV R4, #0 ; set thePSP to 0 for initial context switch call
  82. MSR PSP, R4
  83. LDR R4, =OSRunning ; OSRunning= TRUE
  84. MOV R5, #1
  85. STRB R5, [R4]
  86. ;切换到最高优先级的任务
  87. LDR R4, =NVIC_INT_CTRL ;rigger thePendSV exception (causes context switch)
  88. LDR R5, =NVIC_PENDSVSET
  89. STR R5, [R4]
  90. CPSIE I ;enableinterrupts at processor level
  91. OSStartHang
  92. B OSStartHang ;shouldnever get here
  93. ;/**************************************************************************************
  94. ;* 函数名称: OSCtxSw
  95. ;*
  96. ;* 功能描述:任务级上下文切换
  97. ;*
  98. ;* 参 数: None
  99. ;*
  100. ;* 返 回 值: None
  101. ;***************************************************************************************/
  102. OSCtxSw
  103. PUSH {R4, R5}
  104. LDR R4, =NVIC_INT_CTRL ;触发PendSV异常 (causes context switch)
  105. LDR R5, =NVIC_PENDSVSET
  106. STR R5, [R4]
  107. POP {R4, R5}
  108. BX LR
  109. ;/**************************************************************************************
  110. ;* 函数名称: OSIntCtxSw
  111. ;*
  112. ;* 功能描述:中断级任务切换
  113. ;*
  114. ;* 参 数: None
  115. ;*
  116. ;* 返 回 值: None
  117. ;***************************************************************************************/
  118. OSIntCtxSw
  119. PUSH {R4, R5}
  120. LDR R4, =NVIC_INT_CTRL ;触发PendSV异常(causes context switch)
  121. LDR R5, =NVIC_PENDSVSET
  122. STR R5, [R4]
  123. POP {R4, R5}
  124. BX LR
  125. NOP
  126. ;/**************************************************************************************
  127. ;* 函数名称: OSPendSV
  128. ;*
  129. ;* 功能描述: OSPendSV is used to cause acontext switch.
  130. ;*
  131. ;* 参 数: None
  132. ;*
  133. ;* 返 回 值: None
  134. ;***************************************************************************************/
  135. PendSV_Handler
  136. CPSID I ; Prevent interruption during context switch
  137. MRS R0, PSP ; PSP is process stackpointer如果在用PSP堆栈,则可以忽略保存寄存器,参考CM3权威中的双堆栈-白菜注
  138. CBZ R0, PendSV_Handler_Nosave ; Skip register save thefirst time
  139. SUBS R0, R0, #0x20 ; Saveremaining regs r4-11 on process stack
  140. STM R0, {R4-R11}
  141. LDR R1, =OSTCBCur ;OSTCBCur->OSTCBStkPtr = SP;
  142. LDR R1, [R1]
  143. STR R0, [R1] ;R0 is SP of process being switched out
  144. ; At this point, entire context of process has been saved
  145. PendSV_Handler_Nosave
  146. PUSH {R14} ; Save LR exc_return value
  147. LDR R0, =OSTaskSwHook ;OSTaskSwHook();
  148. BLX R0
  149. POP {R14}
  150. LDR R0, =OSPrioCur ;OSPrioCur = OSPrioHighRdy;
  151. LDR R1, =OSPrioHighRdy
  152. LDRB R2, [R1]
  153. STRB R2, [R0]
  154. LDR R0, =OSTCBCur ;OSTCBCur = OSTCBHighRdy;
  155. LDR R1, =OSTCBHighRdy
  156. LDR R2, [R1]
  157. STR R2, [R0]
  158. LDR R0, [R2] ;R0 is new process SP; SP = OSTCBHighRdy->OSTCBStkPtr;
  159. LDM R0, {R4-R11} ;Restore r4-11 from new process stack
  160. ADDS R0, R0, #0x20
  161. MSR PSP, R0 ;Load PSP with new process SP
  162. ORR LR, LR, #0x04 ; Ensureexception return uses process stack
  163. CPSIE I
  164. BX LR ; Exception return willrestore remaining context
  165. end

关键是:

        关键点1

        官方移植好的版本里自带STM32启动文件vectors.s,当然我们一般用STM32库自带的startup_stm32f10x_hd.s启动文件。这里就有要注意的地方。按照官方移植好的版本要求PendSV的中断函数名字是OS_CPU_OSPendSV,而startup_stm32f10x_hd.s里面已经定义好的名字是PendSV_Handler 

  1. PendSV_Handler PROC
  2. EXPORT PendSV_Handler [WEAK]
  3. B .
  4. ENDP

所以我们要统一一下,我的办法是把Ucosii中所有出现的OS_CPU_OSPendSV改成PendSV_Handler。为什么不改startup_stm32f10x_hd.s,是因为这样移植的兼容性更好,下次一直到另一个STM32工程里时候,直接把Ucos ii的文件全部拷贝过去,不用修改另一个STM32工程里的startup_stm32f10x_hd.s

        关键点2

        编写SysTick_Handler(void)时钟滴答中断函数。

随便在某一个源文件里实现就可以,我在stm32f10x_it.c里实现了这个函数

  1. /**
  2. * @brief This function handles SysTick Handler.
  3. * @param None
  4. * @retval None
  5. */
  6. //2017-5-21欧阳海宾注释掉。
  7. voidSysTick_Handler(void)
  8. {
  9. OSIntEnter(); //进入中断
  10. OSTimeTick(); //调用ucos的时钟服务程序
  11. OSIntExit(); //触发任务切换软中断
  12. }

关键点3:编写延时函数,正点原子或刘洋都有,直接粘贴出来就是

Pbdata.h

  1. #ifndef _pbdata_H
  2. #define _pbdata_H
  3. #include"stm32f10x.h"
  4. #include"includes.h"
  5. #include"misc.h"
  6. //ucosII任务堆栈设置
  7. //设置任务优先级
  8. #defineSTART_TASK_PRIO 8
  9. #defineSTART_TASK2_PRIO 9
  10. #defineSTART_TASK3_PRIO 10
  11. //设置任务堆栈大小
  12. #defineSTART_STK_SIZE 64 //空间大小=64*4(字节)
  13. #defineSTART_STK_SIZE2 64 // 空间大小=64*4(字节)
  14. #defineSTART_STK_SIZE3 64 // 空间大小=64*4(字节)
  15. //创建任务堆栈空间
  16. static OS_STKSTART_TASK_STK[START_STK_SIZE];
  17. static OS_STKSTART_TASK_STK2[START_STK_SIZE2];
  18. static OS_STKSTART_TASK_STK3[START_STK_SIZE3];
  19. extern OS_EVENT*led1_MsgQueue;
  20. extern void*MsgQueuetb[20];
  21. //定义函数
  22. void delay(uint32_t nCount);
  23. void Delay_Init(void);
  24. void delay_us(uint32_t nus);
  25. void delay_ms(uint16_t nms);
  26. void LED_GPIO_Config(void);
  27. /* the macrodefinition to trigger the led on or off
  28. * 1 - on
  29. - 0 - off
  30. */
  31. #define ON 1
  32. #define OFF 0
  33. //带参宏,可以像内联函数一样使用
  34. #define LED1(a) if (a) \
  35. GPIO_ResetBits(GPIOB,GPIO_Pin_8);\
  36. else \
  37. GPIO_SetBits(GPIOB,GPIO_Pin_8)
  38. #endif


Pbdata.c

  1. #include"pbdata.h"
  2. OS_EVENT*led1_MsgQueue;
  3. void* MsgQueuetb[20];
  4. static uint8_t fac_us=0;//us延时倍乘数
  5. static uint16_tfac_ms=0;//ms延时倍乘数
  6. //初始化延迟函数
  7. //当使用ucos的时候,此函数会初始化ucos的时钟节拍
  8. //SYSTICK的时钟固定为HCLK时钟的1/8
  9. //SYSCLK:系统时钟
  10. void Delay_Init(void)
  11. {
  12. uint32_t reload;
  13. SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8); //选择外部时钟 HCLK/8
  14. fac_us=SystemCoreClock/8000000; //为系统时钟的1/8
  15. reload=SystemCoreClock/8000000; //每秒钟的计数次数 单位为K
  16. reload*=1000000/OS_TICKS_PER_SEC;//根据OS_TICKS_PER_SEC设定溢出时间
  17. //reload为24位寄存器,最大值:16777216,在72M下,约合1.86s左右
  18. fac_ms=1000/OS_TICKS_PER_SEC;//代表ucos可以延时的最少单位
  19. SysTick->CTRL|=SysTick_CTRL_TICKINT_Msk; //开启SYSTICK中断
  20. SysTick->LOAD=reload; //每1/OS_TICKS_PER_SEC秒中断一次
  21. SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk; //开启SYSTICK
  22. }
  23. //延时nus
  24. //nus为要延时的us数.
  25. void delay_us(uint32_t nus)
  26. {
  27. uint32_t ticks;
  28. uint32_t told,tnow,tcnt=0;
  29. uint32_t reload=SysTick->LOAD; //LOAD的值
  30. ticks=nus*fac_us; //需要的节拍数
  31. tcnt=0;
  32. told=SysTick->VAL; //刚进入时的计数器值
  33. while(1)
  34. {
  35. tnow=SysTick->VAL;
  36. if(tnow!=told)
  37. {
  38. if(tnow<told)tcnt+=told-tnow;//这里注意一下SYSTICK是一个递减的计数器就可以了.
  39. elsetcnt+=reload-tnow+told;
  40. told=tnow;
  41. if(tcnt>=ticks)break;//时间超过/等于要延迟的时间,则退出.
  42. }
  43. };
  44. }
  45. //延时nms
  46. //nms:要延时的ms数
  47. void delay_ms(uint16_tnms)
  48. {
  49. if(OSRunning==TRUE)//如果os已经在跑了
  50. {
  51. if(nms>=fac_ms)//延时的时间大于ucos的最少时间周期
  52. {
  53. OSTimeDly(nms/fac_ms);//ucos延时
  54. }
  55. nms%=fac_ms; //ucos已经无法提供这么小的延时了,采用普通方式延时
  56. }
  57. delay_us((uint32_t)(nms*1000)); //普通方式延时,此时ucos无法启动调度.
  58. }
  59. void delay(uint32_t nCount)
  60. {
  61. for(;nCount!=0;nCount--);
  62. }
  63. /*
  64. *函数名:LED_GPIO_Config
  65. *描述 :配置LED用到的I/O口
  66. *输入 :无
  67. *输出 :无
  68. */
  69. void LED_GPIO_Config(void)
  70. {
  71. /*定义一个GPIO_InitTypeDef类型的结构体*/
  72. GPIO_InitTypeDef GPIO_InitStructure;
  73. /*开启GPIOF的外设时钟*/
  74. RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
  75. /*选择要控制的GPIOC引脚*/
  76. GPIO_InitStructure.GPIO_Pin= GPIO_Pin_8|GPIO_Pin_7|GPIO_Pin_5;
  77. /*设置引脚模式为通用推挽输出*/
  78. GPIO_InitStructure.GPIO_Mode= GPIO_Mode_Out_PP;
  79. /*设置引脚速率为50MHz */
  80. GPIO_InitStructure.GPIO_Speed= GPIO_Speed_50MHz;
  81. /*调用库函数,初始化GPIOC*/
  82. GPIO_Init(GPIOB,&GPIO_InitStructure);
  83. /* 关闭所有led灯*/
  84. GPIO_SetBits(GPIOB, GPIO_Pin_8);
  85. // GPIO_SetBits(GPIOB, GPIO_Pin_7);
  86. GPIO_ResetBits(GPIOB,GPIO_Pin_7);
  87. GPIO_ResetBits(GPIOB,GPIO_Pin_5);
  88. }

到这里就移植完成,但是用的时候经常会有问题!这里就针对网上最流行的一种问题进行解决

经常会有人,运行的时候卡在空闲任务或单步调试进入硬件错误的中断函数里或者卡在延时函数。

  1. /**
  2. * @brief This function handles NMI exception.
  3. * @param None
  4. * @retval None
  5. */
  6. void NMI_Handler(void)
  7. {
  8. }
  9. /**
  10. * @brief This function handles Hard Fault exception.
  11. * @param None
  12. * @retval None
  13. */
  14. void HardFault_Handler(void)
  15. {
  16. if (CoreDebug->DHCSR & 1) { //check C_DEBUGEN == 1 -> DebuggerConnected
  17. __breakpoint(0); // halt program execution here
  18. }
  19. /* Go to infinite loop when Hard Faultexception occurs */
  20. while (1)
  21. {
  22. }
  23. }
  24. 其实都是一个原因,就是空闲任务不能少且不能放错位置,初始化统计任务不能放在OSInit();和OSStart();之间,必须用在另一个任务的初始化代码里来,否则会出现运行的时候卡在空闲任务或单步调试进入硬件错误的中断函数里,我就是在这里卡了一天才移植成功,网上百度居然没有一种方法说明白了问题的所在和解决办法。
  25. 下面贴出我的主函数
  26. main.c
  27. #include"includes.h" //里面是ucos ii的头文件
  28. #define ON 1
  29. #define OFF 0
  30. #define LED2(a) if (a) \
  31. GPIO_ResetBits(GPIOB,GPIO_Pin_8);\
  32. else \
  33. GPIO_SetBits(GPIOB,GPIO_Pin_8)
  34. //设置任务堆栈大小
  35. void start_task(void *pdata);
  36. void start_task2(void *pdata);
  37. void start_task3(void *pdata);
  38. OS_EVENT *sem;
  39. int main(void)
  40. {
  41. RCC_ClocksTypeDefRCC_Clocks;
  42. sem=OSSemCreate(0);
  43. Delay_Init(); //初始化延时函数
  44. SystemInit();
  45. LED_GPIO_Config();
  46. RCC_GetClocksFreq(&RCC_Clocks);
  47. OSInit();//初始化UCOS操作系统
  48. // OSStatInit();//初始化统计任务放在此处会导致硬件错误,必须放在下面就Ok了 欧阳海宾2017-5-22
  49. OSTaskCreate(start_task,//指向任务代码的指针
  50. (void *)0,//任务开始执行时,传递给任务参数的指针
  51. (OS_STK*)&START_TASK_STK[START_STK_SIZE-1],//分配给任务堆栈的栈顶指针
  52. START_TASK_PRIO);//分配给任务的优先级
  53. OSTaskCreate(start_task2,//指向任务代码的指针
  54. (void *)0,//任务开始执行时,传递给任务参数的指针
  55. (OS_STK*)&START_TASK_STK2[START_STK_SIZE2-1],//分配给任务堆栈的栈顶指针
  56. START_TASK2_PRIO);//分配给任务的优先级
  57. OSTaskCreate(start_task3,//指向任务代码的指针
  58. (void *)0,//任务开始执行时,传递给任务参数的指针
  59. (OS_STK*)&START_TASK_STK3[START_STK_SIZE3-1],//分配给任务堆栈的栈顶指针
  60. START_TASK3_PRIO);//分配给任务的优先级
  61. OSStart();//启动ucos操作系统
  62. }
  63. void start_task(void *pdata)
  64. {
  65. INT8U error;
  66. OS_CPU_SR cpu_sr=0;
  67. pdata=pdata;
  68. // OSStatInit();//初始化统计任务,不能放在上面!
  69. while(1)
  70. {
  71. OSSemPend(sem,0,&error);
  72. LED2(OFF);
  73. delay_ms(500);
  74. // OSSemPost(sem);
  75. // delay_ms(500);
  76. }
  77. }
  78. void start_task2(void *pdata)
  79. {
  80. INT8U error;
  81. OS_CPU_SR cpu_sr=0;
  82. pdata=pdata;
  83. // OSStatInit();//初始化统计任务
  84. OSStatInit();//???????
  85. while(1)
  86. {
  87. LED2(ON);
  88. delay_ms(500);
  89. OSSemPost(sem);
  90. // delay_ms(500);
  91. // OSSemPend(sem,0,&error);
  92. }
  93. }
  94. void start_task3(void *pdata)
  95. {
  96. uint16_t i=0;
  97. pdata = pdata;
  98. while(1)
  99. {
  100. // OS_ENTER_CRITICAL();
  101. OSIdleCtr++;
  102. // OS_EXIT_CRITICAL();
  103. }
  104. }

这个代码是我在硬件STM32f103上实现了的,可以实现led闪烁!



声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/article/detail/50553?site
推荐阅读
相关标签
  

闽ICP备14008679号