Переглянути джерело

完善分时调度系统内容,增加两种FIFO缓冲区示例

woshiashuai 2 роки тому
батько
коміт
ac1ebb2b05

+ 1 - 0
module_Template/FIFO缓冲区1/readme.txt

@@ -0,0 +1 @@
+简单的缓冲区示例1,可用作数据接收和发送

+ 42 - 0
module_Template/FIFO缓冲区1/txFIFO.c

@@ -0,0 +1,42 @@
+#include "txFIFO.h"
+
+can_message_t canTxBuffer[CAN_TXBUFFER_SIZE];
+TxFIFOCtrl_t TxFIFOCtrl = {
+    .totalSize = CAN_TXBUFFER_SIZE,
+    .totalRepeat = 1,
+    .pBuffer = canTxBuffer
+};
+
+uint8_t pushTxFIFO(TxFIFOCtrl_t *ctrl, can_message_t msg)
+{
+    uint8_t ret = 0;
+    if(ctrl->usedSize <= ctrl->totalSize) {
+        uint8_t index = (ctrl->index + ctrl->usedSize) % ctrl->totalSize;
+        memcpy(&ctrl->pBuffer[index], &msg, sizeof(can_message_t));
+        ctrl->usedSize++;
+    } else {
+        ret = 1;
+    }
+
+    return ret;
+}
+
+void txFIFOTask(TxFIFOCtrl_t *ctrl)
+{
+    if(ctrl->usedSize > 0) {
+        if(ctrl->usedRepeat != ctrl->totalRepeat) {
+        	// user handle begin
+            // if(CAN0_TxBufferIsBusy(0)) return ;
+        	// can_send(ctrl->pBuffer[ctrl->index].id, ctrl->pBuffer[ctrl->index].data, ctrl->pBuffer[ctrl->index].dlc);
+            // user handle end
+            ctrl->usedRepeat++;
+            if(ctrl->usedRepeat >= ctrl->totalRepeat) {
+                ctrl->usedRepeat = 0;
+                ctrl->index++;
+                ctrl->usedSize--;
+                if(ctrl->index >= ctrl->totalSize) ctrl->index = 0;
+            }
+        }
+    }
+}
+

+ 26 - 0
module_Template/FIFO缓冲区1/txFIFO.h

@@ -0,0 +1,26 @@
+#ifndef _TXFIFO_H
+#define _TXFIFO_H
+
+#define CAN_TXBUFFER_SIZE           (128U)
+#define CAN_TXREPEAT_NUM            (1U)
+    
+typedef struct {
+    uint32_t id;
+    uint8_t  dlc;
+    uint8_t  data[8];
+}can_message_t;
+
+typedef struct {
+    uint16_t index;
+    uint16_t usedSize;
+    uint16_t totalSize;
+    uint16_t usedRepeat;
+    uint16_t totalRepeat;
+    can_message_t *pBuffer;
+} TxFIFOCtrl_t;
+
+uint8_t pushTxFIFO(TxFIFOCtrl_t *ctrl, can_message_t msg);
+void txFIFOTask(TxFIFOCtrl_t *ctrl);
+    
+
+#endif /* _TXFIFO_H */

+ 76 - 0
module_Template/FIFO缓冲区2/RxFIFO.c

@@ -0,0 +1,76 @@
+#include "RxFIFO.h"
+
+can_message_t canRxBuffer[CAN_RXBUFFER_SIZE];
+RxFIFOCtrl_t RxFIFOCtrl = {
+    .BufferSize = CAN_RXBUFFER_SIZE,
+    .pBuffer = canRxBuffer
+};
+
+void CAN_RxInterrupt(void)
+{
+    can_message_t can_message_rx;
+    // can_message_rx.id = ;
+    // can_message_rx.dlc = l
+    // can_message_rx.data = ;
+    pushRxFIFO(can_message_rx);
+}
+
+/**
+  * @brief  Add a message to the FIFO to the data buffer
+  * @param  can_message_t message
+  * @retval None
+  * @note   None
+*/
+void pushRxFIFO(can_message_t can_message)
+{
+    NVIC_INTERRPUT_DISABLE;
+
+    memcpy(&RxFIFOCtrl.pBuffer[RxFIFOCtrl.WriteIndex], &can_message, sizeof(can_message_t));
+
+    RxFIFOCtrl.WriteIndex += 1;
+    
+    RxFIFOCtrl.WriteIndex = RxFIFOCtrl.WriteIndex & (RxFIFOCtrl.BufferSize - 1);
+
+    if(RxFIFOCtrl.WriteIndex == RxFIFOCtrl.ReadIndex){
+        RxFIFOCtrl.ReadIndex += 1;
+        RxFIFOCtrl.ReadIndex = RxFIFOCtrl.ReadIndex & (RxFIFOCtrl.BufferSize - 1);
+    }else{
+        RxFIFOCtrl.GotMsgNum++;
+    }
+
+    NVIC_INTERRPUT_ENABLE;
+}
+
+/**
+  * @brief  Read a message from the FIFO to the data buffer
+  * @param  can_message_t** Message pointer
+  * @param  msglen Gets the number of message frames
+  * @retval The number of actually obtained CAN message frames
+  * @note   None
+*/
+int32_t popRxFIFO(can_message_t **can_message, uint8_t msglen)
+{
+    NVIC_INTERRPUT_DISABLE;
+
+    int32_t msg_num = ((RxFIFOCtrl.WriteIndex >= RxFIFOCtrl.ReadIndex) ? RxFIFOCtrl.GotMsgNum : (RxFIFOCtrl.BufferSize - RxFIFOCtrl.ReadIndex));
+
+    *can_message = &RxFIFOCtrl.pBuffer[RxFIFOCtrl.ReadIndex];
+
+    msg_num = (msg_num < msglen) ? msg_num : msglen;
+    RxFIFOCtrl.GotMsgNum -= msg_num;
+    RxFIFOCtrl.ReadIndex = (RxFIFOCtrl.ReadIndex+msg_num) & (RxFIFOCtrl.BufferSize - 1);
+
+    NVIC_INTERRPUT_ENABLE;
+    return msg_num;
+}
+
+/* use example
+while(1) {
+    can_message_t *can_message;
+    if(popRxFIFO(&can_message, 1)) {
+        // user handle begin
+        // can_send(can_message);
+        // user handle begin
+    }
+}
+*/

+ 28 - 0
module_Template/FIFO缓冲区2/RxFIFO.h

@@ -0,0 +1,28 @@
+#ifndef _RXFIFO_H
+#define _RXFIFO_H
+
+#define CAN_RXBUFFER_SIZE           (128U)
+#define NVIC_INTERRPUT_DISABLE      // 自行定义
+#define NVIC_INTERRPUT_ENABLE       // 自行定义
+    
+typedef struct {
+    uint32_t id;
+    uint8_t  dlc;
+    uint8_t  data[8];
+}can_message_t;
+
+typedef struct {
+    uint16_t WriteIndex;        /*The index of the frame that is currently receiving data*/
+    uint16_t ReadIndex;         /*Complete frame, read data start index*/
+    uint16_t GotMsgNum;         /*The number of complete frames received*/
+    uint16_t BufferSize;        /*The maximum number of frames the buffer can hold*/
+    can_message_t *pBuffer;     /*Buffer first address*/
+}RxFIFOCtrl_t;
+
+extern RxFIFOCtrl_t RxFIFOCtrl;
+
+void pushRxFIFO(can_message_t can_message);
+int32_t popRxFIFO(can_message_t **can_message, uint8_t msglen);
+    
+
+#endif /* _RXFIFO_H */

+ 1 - 0
module_Template/FIFO缓冲区2/readme.txt

@@ -0,0 +1 @@
+简单的缓冲区示例2,可用作数据接收和发送

+ 67 - 41
module_Template/分时调度系统/TimeScheduleSystem.c

@@ -1,7 +1,7 @@
 /************************************/
 /* @Author: @woshiashuai            */
 /* @Version: V1.0                   */
-/* @Date: 2023-02-12 13:06:48       */
+/* @Date: 2023-02-13 10:49:00       */
 /* @Description:                    */
 /* V1.0: create                     */
 /************************************/
@@ -10,7 +10,8 @@
 TSS_t *TSS_head = NULL; // 分时调度系统工作链表头节点
 
 /**
-  * @brief  分时调度事件初始化 加入到初始化中
+  * @brief  分时调度事件初始化
+	*	@note		加入到初始化中
   * @param  TSS: 事件指针
   * @param  targetTicks: 目标计数值 = 事件调度周期 / 调度器周期 例如: 100 = 500ms / 5ms
   * @param  callback: 事件回调函数
@@ -23,33 +24,25 @@ unsigned char TSS_init(TSS_t *TSS, unsigned int targetTicks, void (* callback)(v
     memset(TSS, 0, sizeof(TSS_t));
     TSS->targetTicks = targetTicks;
     TSS->callback = callback;
-
-    TSS_t *TSS_target = TSS_head;
-    while(TSS_target) {
-        if(TSS_target == TSS) return 3;
-        TSS_target = TSS_target->next;
-    }
-    TSS->state = 1; // 加入工作链表则改变状态为在工作链表
-    TSS->next = TSS_head;
-    TSS_head = TSS;
     return 0;
 }
 /**
-  * @brief  分时调度事件循环处理的内部方法
+  * @brief  分时调度事件执行(循环)处理的内部方法
+	*	@note		None
   * @param  TSS: 事件指针
   * @retval None
   */
 static void TSS_whileHandle(TSS_t *TSS)
 {
-    // 分时调度结果是可执行
-    if(TSS->result) {
-        TSS->callback(); // 执行绑定的回调函数
-        TSS->ticks = 0; // 防止因手动切换状态导致的ticks不为0
-        TSS->result = 0; // 切换分时调度结果为等待中
-    }
+    // 分时调度结果是等待中或跳过调度则退出
+    if(!TSS->result || TSS->skip) return ;
+		TSS->callback(); // 执行绑定的回调函数
+		TSS->ticks = 0; // 防止因手动切换状态导致的ticks不为0
+		TSS->result = 0; // 切换分时调度结果为等待中
 }
 /**
-  * @brief  分时调度事件循环处理 加入到主循环中
+  * @brief  分时调度事件执行(循环)处理
+	*	@note		加入到主循环中
   * @param  None
   * @retval None
   */
@@ -62,23 +55,24 @@ void TSS_while(void)
 }
 /**
   * @brief  分时调度事件调度处理的内部方法
+	*	@note		None
   * @param  TSS: 事件指针
   * @retval None
   */
 static void TSS_timerHandle(TSS_t *TSS)
 {
-    // 分时调度结果是等待中
-    if(!TSS->result) {
-        TSS->ticks += 1; // 计数自加
-        // 计数大于等于目标计数
-        if(TSS->ticks >= TSS->targetTicks) {
-            TSS->ticks = 0; // 计数清零
-            TSS->result = 1; // 切换分时调度结果为可执行
-        }
-    }
+    // 分时调度结果是可执行或跳过调度则退出
+    if(TSS->result || TSS->skip) return ;
+		TSS->ticks += 1; // 计数自加
+		// 计数大于等于目标计数
+		if(TSS->ticks >= TSS->targetTicks) {
+				TSS->ticks = 0; // 计数清零
+				TSS->result = 1; // 切换分时调度结果为可执行
+		}
 }
 /**
-  * @brief  分时调度事件调度处理 加入到调度器中
+  * @brief  分时调度事件调度处理
+	*	@note		加入到调度器中
   * @param  None
   * @retval None
   */
@@ -92,13 +86,14 @@ void TSS_timer(void)
 
 
 /**
-  * @brief  分时调度事件挂起处理 将事件从工作链表中去掉
+  * @brief  分时调度事件挂起处理
+	*	@note		主要用于将事件从工作链表中取下
   * @param  TSS: 事件指针
   * @retval 0: 挂起成功 1: 事件未初始化/初始化失败 2: 事件不在工作链表中(可能已被挂起)
   */
 unsigned char TSS_pending(TSS_t *TSS)
 {
-    if((TSS->targetTicks == 0) || (TSS->callback == NULL) || (TSS->next == NULL)) return 1;
+    if((TSS->targetTicks == 0) || (TSS->callback == NULL)) return 1;
     TSS_t *TSS_target = TSS_head;
     TSS_t *TSS_last = NULL;
     while(TSS_target) {
@@ -121,13 +116,14 @@ unsigned char TSS_pending(TSS_t *TSS)
     return 2;
 }
 /**
-  * @brief  分时调度事件恢复处理
+  * @brief  分时调度事件启动处理
+	*	@note		主要用于将事件加入到工作链表中
   * @param  TSS: 事件指针
-  * @retval 0: 恢复成功 1: 事件未初始化/初始化失败 2: 事件已在工作链表中(可能已被恢复)
+  * @retval 0: 启动成功 1: 事件未初始化/初始化失败 2: 事件已在工作链表中(可能已被恢复)
   */
-unsigned char TSS_resume(TSS_t *TSS)
+unsigned char TSS_start(TSS_t *TSS)
 {
-    if((TSS->targetTicks == 0) || (TSS->callback == NULL) || (TSS->next == NULL)) return 1;
+    if((TSS->targetTicks == 0) || (TSS->callback == NULL)) return 1;
     TSS_t *TSS_target = TSS_head;
     while(TSS_target) {
         if(TSS_target == TSS) return 2;
@@ -142,6 +138,7 @@ unsigned char TSS_resume(TSS_t *TSS)
 
 /**
   * @brief  分时调度事件设置计数值处理
+	*	@note		None
   * @param  TSS: 事件指针
   * @param  ticks: 设置的计数值
   * @retval None
@@ -152,6 +149,7 @@ void TSS_setTicks(TSS_t *TSS, unsigned char ticks)
 }
 /**
   * @brief  分时调度事件获取计数值处理
+	*	@note		None
   * @param  TSS: 事件指针
   * @retval 事件计数值
   */
@@ -160,7 +158,8 @@ unsigned int TSS_getTicks(TSS_t *TSS)
     return TSS->ticks;
 }
 /**
-  * @brief  分时调度事件设置目标计数值处理 主要用于修改事件执行周期,若较上次改小则可能立即触发事件执行
+  * @brief  分时调度事件设置目标计数值处理
+	*	@note		主要用于修改事件执行周期,若较上次改小则可能立即触发事件执行
   * @param  TSS: 事件指针
   * @param  result: 设置的目标计数值
   * @retval None
@@ -170,7 +169,8 @@ void TSS_setTargetTicks(TSS_t *TSS, unsigned char targetTicks)
    TSS->targetTicks = targetTicks;
 }
 /**
-  * @brief  分时调度事件获取目标计数值处理 主要用于查看事件执行周期
+  * @brief  分时调度事件获取目标计数值处理
+	*	@note		主要用于查看事件执行周期
   * @param  TSS: 事件指针
   * @retval 事件目标计数值
   */
@@ -179,7 +179,8 @@ unsigned int TSS_TargetTicks(TSS_t *TSS)
     return TSS->targetTicks;
 }
 /**
-  * @brief  分时调度事件设置结果值处理 主要用于立即切换事件结果为1:可执行
+  * @brief  分时调度事件设置结果值处理
+	*	@note		主要用于立即切换事件结果为1:可执行
   * @param  TSS: 事件指针
   * @param  result: 设置的结果值
   * @retval None
@@ -189,7 +190,8 @@ void TSS_setResult(TSS_t *TSS, unsigned char result)
    TSS->result = result;
 }
 /**
-  * @brief  分时调度事件获取结果值处理 一般获取到的事件结果多为0:等待中,因为事件执行后即清零
+  * @brief  分时调度事件获取结果值处理 
+  * @note		一般获取到的事件结果多为0:等待中,因为在事件执行后事件结果值即清零
   * @param  TSS: 事件指针
   * @retval 事件结果值 0: 等待中 1: 可执行
   */
@@ -199,7 +201,8 @@ unsigned char TSS_getResult(TSS_t *TSS)
 }
 
 /**
-  * @brief  分时调度事件设置状态值处理 手动操作此函数无效,因为事件状态只与事件是否存在于工作链表中有关
+  * @brief  分时调度事件设置状态值处理
+  * @note		手动操作此函数无效,因为事件状态只与事件是否存在于工作链表中有关
   * @param  TSS: 事件指针
   * @param  state: 设置的状态值
   * @retval None
@@ -209,7 +212,8 @@ void TSS_setState(TSS_t *TSS, unsigned char state)
 //   TSS->state = state;
 }
 /**
-  * @brief  分时调度事件获取状态值处理 主要用于查看事件是否存在于工作链表中
+  * @brief  分时调度事件获取状态值处理
+  * @note		主要用于查看事件是否存在于工作链表中
   * @param  TSS: 事件指针
   * @retval 事件的状态值 0:不在工作链表 1:在工作链表
   */
@@ -217,3 +221,25 @@ unsigned char TSS_getState(TSS_t *TSS)
 {
     return TSS->state;
 }
+
+/**
+	* @brief  分时调度事件设置跳过值处理 
+  * @note		主要用于事件仍在工作链表中的启动或挂起,相较于把事件从工作链表取下和恢复,此操作更快
+	* @param  TSS: 事件指针
+  * @param  state: 设置的跳过值
+  * @retval None
+  */
+void TSS_setSkip(TSS_t *TSS, unsigned char skip)
+{
+   TSS->skip = skip;
+}
+/**
+  * @brief  分时调度事件获取跳过值处理
+	*	@note		主要用于查看事件是否跳过事件调度,事件仍在工作链表中的启动或挂起
+  * @param  TSS: 事件指针
+	* @retval 事件的跳过值 0:不跳过调度 1: 跳过调度
+  */
+unsigned char TSS_getSkip(TSS_t *TSS)
+{
+    return TSS->skip;
+}

+ 4 - 1
module_Template/分时调度系统/TimeScheduleSystem.h

@@ -12,6 +12,7 @@ typedef struct TimeScheduleSystem{
     unsigned int targetTicks;
     unsigned char result : 1; // 0:等待中 1:可执行
     unsigned char state : 1; // 0:不在工作链表 1:在工作链表
+		unsigned char skip : 1; // 0:不跳过调度 1:跳过调度
     void (* callback)(void);
     struct TimeScheduleSystem *next;
 } TSS_t;
@@ -21,7 +22,7 @@ void TSS_while(void);
 void TSS_timer(void);
 
 unsigned char TSS_pending(TSS_t *TSS);
-unsigned char TSS_resume(TSS_t *TSS);
+unsigned char TSS_start(TSS_t *TSS);
 
 void TSS_setTicks(TSS_t *TSS, unsigned char ticks);
 unsigned int TSS_getTicks(TSS_t *TSS);
@@ -31,6 +32,8 @@ void TSS_setResult(TSS_t *TSS, unsigned char result);
 unsigned char TSS_getResult(TSS_t *TSS);
 void TSS_setState(TSS_t *TSS, unsigned char state);
 unsigned char TSS_getState(TSS_t *TSS);
+void TSS_setSkip(TSS_t *TSS, unsigned char skip);
+unsigned char TSS_getSkip(TSS_t *TSS);
 
 
 #ifdef __cplusplus

+ 9 - 3
module_Template/分时调度系统/main.c

@@ -20,11 +20,17 @@ int main()
     int ret = 0;
     // 1.初始化事件
     ret = TSS_init(&myTSS1, 100, myTSS1_callback); // 100 * 5ms = 500ms周期
-    if(!ret) printf("myTSS1 init success\n");
+    if(!ret) {
+        TSS_start(&myTSS1);
+        printf("myTSS1 init success\n");
+    }
     else printf("myTSS1 init fail : %d\n", ret);
     ret = TSS_init(&myTSS2, 200, myTSS2_callback); // 200 * 5ms = 1000ms周期
-    if(!ret) printf("myTSS1 init success\n");
-    else printf("myTSS1 init fail : %d\n", ret);
+    if(!ret) {
+        TSS_start(&myTSS2);
+        printf("myTSS2 init success\n");
+    }
+    else printf("myTSS2 init fail : %d\n", ret);
 
     while(1) {
         TSS_while(); // 2.事件循环