Przeglądaj źródła

上传文件至 'ports'

Yun_Lib_Share 1 rok temu
rodzic
commit
0b47d6667d
4 zmienionych plików z 411 dodań i 0 usunięć
  1. 197 0
      ports/zf_critical.c
  2. 103 0
      ports/zf_critical.h
  3. 66 0
      ports/zf_debug.h
  4. 45 0
      ports/zf_malloc.h

+ 197 - 0
ports/zf_critical.c

@@ -0,0 +1,197 @@
+/**
+  *****************************************************************************
+  * @file    zf_critical.c
+  * @author  Zorb
+  * @version V1.0.0
+  * @date    2018-06-28
+  * @brief   硬件相关操作(临界状态、现场保护与恢复、PendSV异常)的实现
+  *****************************************************************************
+  * @history
+  *
+  * 1. Date:2018-06-28
+  *    Author:Zorb
+  *    Modification:建立文件
+  *
+  *****************************************************************************
+  */
+
+#include "zf_critical.h"
+#include "zf_assert.h"
+
+/******************************************************************************
+ * 描述  :保存中断寄存器的值,然后关中断
+ * 参数  :无
+ * 返回  :中断寄存器的值
+******************************************************************************/
+__asm uint32_t ZF_SR_Save(void)
+{
+    MRS     R0, PRIMASK
+    CPSID   I
+    BX      LR
+}
+
+/******************************************************************************
+ * 描述  :恢复中断寄存器的值
+ * 参数  :(in)-sr 中断寄存器的值
+ * 返回  :无
+******************************************************************************/
+__asm void ZF_SR_Restore(uint32_t sr)
+{
+    MSR     PRIMASK, R0
+    BX      LR
+}
+
+/******************************************************************************
+ * 描述  :关闭所有中断(但是不包括fault和NMI中断)
+ * 参数  :无
+ * 返回  :无
+******************************************************************************/
+__asm void INTERRUPT_DISABLE(void)
+{
+    CPSID   I
+    BX      LR
+}
+
+/******************************************************************************
+ * 描述  :开启中断总开关
+ * 参数  :无
+ * 返回  :无
+******************************************************************************/
+__asm void INTERRUPT_ENABLE(void)
+{
+    CPSIE   I
+    BX      LR
+}
+
+/******************************************************************************
+ * 描述  :初始化任务堆栈
+ * 参数  :(in)-pTask       任务指针
+ *         (in)-taskProcess 任务程序指针
+ *         (in)-parg        任务程序参数列表指针
+ * 返回  :无
+******************************************************************************/
+void ZF_initTaskStack(Task *pTask, ITaskProcess taskProcess, void *parg)
+{
+    ZF_STK_TYPE *pStkPtr;
+    
+    ZF_ASSERT(pTask != (Task *)0)
+    ZF_ASSERT(taskProcess != (ITaskProcess)0)
+    
+    pStkPtr = (ZF_STK_TYPE *)((ZF_STK_TYPE)pTask->pStkBase
+        + (ZF_STK_TYPE)pTask->StkSize);
+    
+    /* 异常发生时自动保存的寄存器 */
+    *--pStkPtr = (ZF_STK_TYPE)0x01000000u;          /* xPSR的bit24必须置1 */
+    *--pStkPtr = (ZF_STK_TYPE)taskProcess;          /* 任务的入口地址 */
+    *--pStkPtr = (ZF_STK_TYPE)0x00000000u;          /* R14 (LR) */
+    *--pStkPtr = (ZF_STK_TYPE)0x00000000u;          /* R12 */
+    *--pStkPtr = (ZF_STK_TYPE)0x00000000u;          /* R3 */
+    *--pStkPtr = (ZF_STK_TYPE)0x00000000u;          /* R2 */
+    *--pStkPtr = (ZF_STK_TYPE)0x00000000u;          /* R1 */
+    *--pStkPtr = (ZF_STK_TYPE)parg;                 /* R0 : 任务形参 */
+    
+    /* 异常发生时需手动保存的寄存器 */
+    *--pStkPtr = (ZF_STK_TYPE)0x00000000u;          /* R11 */
+    *--pStkPtr = (ZF_STK_TYPE)0x00000000u;          /* R10 */
+    *--pStkPtr = (ZF_STK_TYPE)0x00000000u;          /* R9 */
+    *--pStkPtr = (ZF_STK_TYPE)0x00000000u;          /* R8 */
+    *--pStkPtr = (ZF_STK_TYPE)0x00000000u;          /* R7 */
+    *--pStkPtr = (ZF_STK_TYPE)0x00000000u;          /* R6 */
+    *--pStkPtr = (ZF_STK_TYPE)0x00000000u;          /* R5 */
+    *--pStkPtr = (ZF_STK_TYPE)0x00000000u;          /* R4 */
+    
+    pTask->pStkPtr = pStkPtr;
+}
+
+/******************************************************************************
+ * 描述  :开启中断,并触发PendSV异常(用于系统第一次任务调度)
+ * 参数  :无
+ * 返回  :无
+******************************************************************************/
+__asm void SF_readyGo(void)
+{
+    /* 设置PendSV异常优先级为最低 */
+    LDR     R0, = NVIC_SYSPRI14
+    LDR     R1, = NVIC_PENDSV_PRI
+    STRB    R1, [R0]
+    NOP
+    
+    /* 设置psp的值为0,开始第一次上下文切换 */
+    MOVS    R0, #0
+    MSR     PSP, R0
+    
+    /* 触发PendSV异常 */
+    LDR     R0, =NVIC_INT_CTRL
+    LDR     R1, =NVIC_PENDSVSET
+    STR     R1, [R0]
+    
+    /* 开中断 */
+    CPSIE   I
+    
+/* 一个死循环,程序正常运作不会来到这里 */
+OSStartHang
+    B       OSStartHang
+    NOP
+}
+
+/******************************************************************************
+ * 描述  :PendSV异常处理
+ * 参数  :无
+ * 返回  :无
+******************************************************************************/
+__asm void PendSV_Handler(void)
+{
+    IMPORT  pCurrentTask
+    IMPORT  pTopPriorityTask
+    
+    /* 任务的保存,即把CPU寄存器的值存储到任务的堆栈中 */
+    /* 关中断,NMI和HardFault除外 */
+    CPSID   I
+    
+    /* 判断是否第一次运行 */
+    MRS     R0, PSP
+    CBZ     R0, PendSVHandler_NotSave
+    
+    /**
+        在进入PendSV异常的时候,当前CPU的xPSR,PC(任务入口地址),
+        R14,R12,R3,R2,R1,R0会自动存储到当前任务堆栈,同时递减PSP的值
+    **/
+    /* 手动存储CPU寄存器R4-R11的值到当前任务的堆栈 */
+    STMDB   R0!, {R4-R11}
+    
+    /* R0指向pCurrentTask的堆栈指针(指向空闲位置的顶部) */
+    LDR     R1, = pCurrentTask
+    LDR     R1, [R1]
+    STR     R0, [R1]
+    NOP
+    
+/* 任务的切换,即把下一个要运行的任务的堆栈内容加载到CPU寄存器中 */
+PendSVHandler_NotSave
+
+    /* 等效操作pCurrentTask = pTopPriorityTask; */
+    LDR     R0, = pCurrentTask
+    LDR     R1, = pTopPriorityTask
+    LDR     R2, [R1]
+    STR     R2, [R0]
+    
+    /* pTopPriorityTask的信息出栈 */
+    LDR     R0, [R2]
+    LDMIA   R0!, {R4-R11}
+    
+    /* 设置PSP指向下一个要执行的任务的堆栈的栈底(已弹出了寄存器信息) */
+    MSR     PSP, R0
+    /* 确保异常返回使用的堆栈指针是PSP */
+    ORR     LR, LR, #0x04 /* 设置LR寄存器的位2为1 */
+    CPSIE   I /* 开中断 */
+    
+    /**
+        函数返回,这个时候任务堆栈中的剩下内容将会自动加载到
+        xPSR,PC(任务入口地址),R14,R12,R3,R2,R1,R0(任务的形参)
+        同时PSP的值也将更新,即指向任务堆栈的栈顶。
+        在STM32中,堆栈是由高地址向低地址生长的
+    **/
+    BX      LR
+    NOP
+}
+
+/******************************** END OF FILE ********************************/

+ 103 - 0
ports/zf_critical.h

@@ -0,0 +1,103 @@
+/**
+  *****************************************************************************
+  * @file    zf_critical.h
+  * @author  Zorb
+  * @version V1.0.0
+  * @date    2018-06-28
+  * @brief   硬件相关操作(临界状态、现场保护与恢复、PendSV异常)的头文件
+  *****************************************************************************
+  * @history
+  *
+  * 1. Date:2018-06-28
+  *    Author:Zorb
+  *    Modification:建立文件
+  *
+  *****************************************************************************
+  */
+
+#ifndef __ZF_CRITICAL_H__
+#define __ZF_CRITICAL_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "stdint.h"
+#include "zf_task.h"
+
+extern Task *pTopPriorityTask; /* 最高优先级任务 */
+extern Task *pCurrentTask;     /* 当前任务 */
+
+/* 中断控制及状态寄存器 SCB_ICSR */
+#define NVIC_INT_CTRL 0xE000ED04
+
+/* 系统优先级寄存器 SCB_SHPR3:bit16~23 */
+#define NVIC_SYSPRI14 0xE000ED22
+
+/* 触发PendSV异常的值 Bit28:PENDSVSET */
+#define NVIC_PENDSVSET 0x10000000
+
+/* PendSV 优先级的值(最低) */
+#define NVIC_PENDSV_PRI 0xFF
+
+/* 触发PendSV异常,用于任务切换 */
+#define TASK_SWITCH() *((volatile uint32_t *)NVIC_INT_CTRL) = NVIC_PENDSVSET
+
+/* 任务堆栈数据类型 */
+typedef uint32_t ZF_STK_TYPE;
+
+/* 中断寄存器的值 */
+#define ZF_SR_VAL() uint32_t ZF_SR
+
+/* 保存中断寄存器的值,然后关中断 */
+#define ZF_INT_DIS() do                 \
+{                                       \
+    ZF_SR = ZF_SR_Save();               \
+} while (0)
+
+/* 恢复中断寄存器的值 */
+#define ZF_INT_EN() do                  \
+{                                       \
+    ZF_SR_Restore(ZF_SR);               \
+} while (0)
+
+/* 进入临界区 */
+#define ZF_CRITICAL_ENTER() do          \
+{                                       \
+    ZF_INT_DIS();                       \
+} while (0)
+
+/* 退出临界区 */
+#define ZF_CRITICAL_EXIT() do           \
+{                                       \
+    ZF_INT_EN();                        \
+} while (0)
+
+/* 中断寄存器的值 */
+extern uint32_t ZF_SR;
+
+/* 保存中断寄存器的值,然后关中断 */
+__asm uint32_t ZF_SR_Save(void);
+
+/* 恢复中断寄存器的值 */
+__asm void ZF_SR_Restore(uint32_t sr);
+
+/* 关闭所有中断(但是不包括fault和NMI中断) */
+__asm void INTERRUPT_DISABLE(void);
+
+/* 开启中断总开关 */
+__asm void INTERRUPT_ENABLE(void);
+
+/* 初始化任务堆栈 */
+void ZF_initTaskStack(Task *pTask, ITaskProcess taskProcess, void *parg);
+
+/* 开启中断,并触发PendSV异常(用于系统第一次任务调度) */
+__asm void SF_readyGo(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __ZF_CRITICAL_H__ */
+
+/******************************** END OF FILE ********************************/

+ 66 - 0
ports/zf_debug.h

@@ -0,0 +1,66 @@
+/**
+  *****************************************************************************
+  * @file    zf_debug.h
+  * @author  Zorb
+  * @version V1.0.0
+  * @date    2018-06-28
+  * @brief   调试输出的头文件
+  *****************************************************************************
+  * @history
+  *
+  * 1. Date:2018-06-28
+  *    Author:Zorb
+  *    Modification:建立文件
+  *
+  *****************************************************************************
+  */
+
+#ifndef __ZF_DEBUG_H__
+#define __ZF_DEBUG_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "stdio.h"
+#include "stdbool.h"
+
+#define LOG_D 0; /* 信息等级:正常 */
+#define LOG_W 1; /* 信息等级:告警 */
+#define LOG_E 2; /* 信息等级:错误 */
+
+#define _ZF_DEBUG             /* 定义调试功能 */
+#define ZF_DEBUG_ON true      /* 启用调试功能 */
+
+#ifdef _ZF_DEBUG
+    #if ZF_DEBUG_ON
+        #define ZF_DEBUG(rank, x...) do     \
+        {                                   \
+            char code[10] = "[rank=0]";     \
+            code[6] = '0' + (char)rank;     \
+            if (code[6] != '0')             \
+            {                               \
+                printf("\r\n\r\n%s", code); \
+            }                               \
+            printf(x);                      \
+            if (code[6] != '0')             \
+            {                               \
+                printf("%s\r\n\r\n", code); \
+            }                               \
+        } while(0)
+    #else
+        #define ZF_DEBUG(rank, x...)
+    #endif /* ZF_DEBUG_ON */
+#endif /* _ZF_DEBUG */
+
+#define ZF_DEBUG_D(x...) ZF_DEBUG(LOG_D, x)
+#define ZF_DEBUG_W(x...) ZF_DEBUG(LOG_W, x)
+#define ZF_DEBUG_E(x...) ZF_DEBUG(LOG_E, x)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __ZF_DEBUG_H__ */
+
+/******************************** END OF FILE ********************************/

+ 45 - 0
ports/zf_malloc.h

@@ -0,0 +1,45 @@
+/**
+  *****************************************************************************
+  * @file    zf_malloc.h
+  * @author  Zorb
+  * @version V1.0.0
+  * @date    2018-06-28
+  * @brief   内存管理的头文件
+  *****************************************************************************
+  * @history
+  *
+  * 1. Date:2018-06-28
+  *    Author:Zorb
+  *    Modification:建立文件
+  *
+  *****************************************************************************
+  */
+
+#ifndef __ZF_MALLOC_H__
+#define __ZF_MALLOC_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "stdlib.h"
+#include "string.h"
+
+#define _ZF_MALLOC             /* 定义内存管理功能 */
+
+#ifdef _ZF_MALLOC
+    /* 分配函数 */
+    #define ZF_MALLOC(size_) malloc(size_)
+    /* 释放函数 */
+    #define ZF_FREE(ptr_) free(ptr_)
+    /* 拷贝函数 */
+    #define ZF_MEMCPY(des_, src_, len_) memcpy(des_, src_, len_)
+#endif /* _ZF_MALLOC */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __ZF_MALLOC_H__ */
+
+/******************************** END OF FILE ********************************/