Ver Fonte

增加单向链表模板,增加分时调度系统模板

woshiashuai há 2 anos atrás
pai
commit
d2a2fcbb42

+ 219 - 0
module_Template/分时调度系统/TimeScheduleSystem.c

@@ -0,0 +1,219 @@
+/************************************/
+/* @Author: @woshiashuai            */
+/* @Version: V1.0                   */
+/* @Date: 2023-02-12 13:06:48       */
+/* @Description:                    */
+/* V1.0: create                     */
+/************************************/
+#include "TimeScheduleSystem.h"
+
+TSS_t *TSS_head = NULL; // 分时调度系统工作链表头节点
+
+/**
+  * @brief  分时调度事件初始化 加入到初始化中
+  * @param  TSS: 事件指针
+  * @param  targetTicks: 目标计数值 = 事件调度周期 / 调度器周期 例如: 100 = 500ms / 5ms
+  * @param  callback: 事件回调函数
+  * @retval 0: 初始化成功 1: 参数二为零 2: 参数三为空 3: 事件已存在
+  */
+unsigned char TSS_init(TSS_t *TSS, unsigned int targetTicks, void (* callback)(void))
+{
+    if(targetTicks == 0) return 1;
+    if(callback == NULL) return 2;
+    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  分时调度事件循环处理的内部方法
+  * @param  TSS: 事件指针
+  * @retval None
+  */
+static void TSS_whileHandle(TSS_t *TSS)
+{
+    // 分时调度结果是可执行
+    if(TSS->result) {
+        TSS->callback(); // 执行绑定的回调函数
+        TSS->ticks = 0; // 防止因手动切换状态导致的ticks不为0
+        TSS->result = 0; // 切换分时调度结果为等待中
+    }
+}
+/**
+  * @brief  分时调度事件循环处理 加入到主循环中
+  * @param  None
+  * @retval None
+  */
+void TSS_while(void)
+{
+    TSS_t *TSS_target;
+    for(TSS_target = TSS_head; TSS_target; TSS_target = TSS_target->next) {
+        TSS_whileHandle(TSS_target);
+    }
+}
+/**
+  * @brief  分时调度事件调度处理的内部方法
+  * @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; // 切换分时调度结果为可执行
+        }
+    }
+}
+/**
+  * @brief  分时调度事件调度处理 加入到调度器中
+  * @param  None
+  * @retval None
+  */
+void TSS_timer(void)
+{
+    TSS_t *TSS_target;
+    for(TSS_target = TSS_head; TSS_target; TSS_target = TSS_target->next) {
+        TSS_timerHandle(TSS_target);
+    }
+}
+
+
+/**
+  * @brief  分时调度事件挂起处理 将事件从工作链表中去掉
+  * @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;
+    TSS_t *TSS_target = TSS_head;
+    TSS_t *TSS_last = NULL;
+    while(TSS_target) {
+        // 查找事件是否存在
+        if(TSS_target == TSS) {
+            // 是否在头节点
+            if(TSS_last == NULL) {
+                TSS_head = TSS_target->next; // 在头节点则将下一个节点作为新的头节点
+            } else {
+                // 不在头节点则将下一个节点链接到上一个节点
+                TSS_last->next = TSS_target->next;
+                TSS_head = TSS_last;
+            }
+            TSS->state = 0; // 退出工作链表则改变状态为不在工作链表
+            return 0;
+        }
+        TSS_last = TSS_target;
+        TSS_target = TSS_target->next;
+    }
+    return 2;
+}
+/**
+  * @brief  分时调度事件恢复处理
+  * @param  TSS: 事件指针
+  * @retval 0: 恢复成功 1: 事件未初始化/初始化失败 2: 事件已在工作链表中(可能已被恢复)
+  */
+unsigned char TSS_resume(TSS_t *TSS)
+{
+    if((TSS->targetTicks == 0) || (TSS->callback == NULL) || (TSS->next == NULL)) return 1;
+    TSS_t *TSS_target = TSS_head;
+    while(TSS_target) {
+        if(TSS_target == TSS) return 2;
+        TSS_target = TSS_target->next;
+    }
+    TSS->state = 1; // 加入工作链表则改变状态为在工作链表
+    TSS->next = TSS_head;
+    TSS_head = TSS;
+    return 0;
+}
+
+
+/**
+  * @brief  分时调度事件设置计数值处理
+  * @param  TSS: 事件指针
+  * @param  ticks: 设置的计数值
+  * @retval None
+  */
+void TSS_setTicks(TSS_t *TSS, unsigned char ticks)
+{
+   TSS->ticks = ticks;
+}
+/**
+  * @brief  分时调度事件获取计数值处理
+  * @param  TSS: 事件指针
+  * @retval 事件计数值
+  */
+unsigned int TSS_getTicks(TSS_t *TSS)
+{
+    return TSS->ticks;
+}
+/**
+  * @brief  分时调度事件设置目标计数值处理 主要用于修改事件执行周期,若较上次改小则可能立即触发事件执行
+  * @param  TSS: 事件指针
+  * @param  result: 设置的目标计数值
+  * @retval None
+  */
+void TSS_setTargetTicks(TSS_t *TSS, unsigned char targetTicks)
+{
+   TSS->targetTicks = targetTicks;
+}
+/**
+  * @brief  分时调度事件获取目标计数值处理 主要用于查看事件执行周期
+  * @param  TSS: 事件指针
+  * @retval 事件目标计数值
+  */
+unsigned int TSS_TargetTicks(TSS_t *TSS)
+{
+    return TSS->targetTicks;
+}
+/**
+  * @brief  分时调度事件设置结果值处理 主要用于立即切换事件结果为1:可执行
+  * @param  TSS: 事件指针
+  * @param  result: 设置的结果值
+  * @retval None
+  */
+void TSS_setResult(TSS_t *TSS, unsigned char result)
+{
+   TSS->result = result;
+}
+/**
+  * @brief  分时调度事件获取结果值处理 一般获取到的事件结果多为0:等待中,因为事件执行后即清零
+  * @param  TSS: 事件指针
+  * @retval 事件结果值 0: 等待中 1: 可执行
+  */
+unsigned char TSS_getResult(TSS_t *TSS)
+{
+    return TSS->result;
+}
+
+/**
+  * @brief  分时调度事件设置状态值处理 手动操作此函数无效,因为事件状态只与事件是否存在于工作链表中有关
+  * @param  TSS: 事件指针
+  * @param  state: 设置的状态值
+  * @retval None
+  */
+void TSS_setState(TSS_t *TSS, unsigned char state)
+{
+//   TSS->state = state;
+}
+/**
+  * @brief  分时调度事件获取状态值处理 主要用于查看事件是否存在于工作链表中
+  * @param  TSS: 事件指针
+  * @retval 事件的状态值 0:不在工作链表 1:在工作链表
+  */
+unsigned char TSS_getState(TSS_t *TSS)
+{
+    return TSS->state;
+}

+ 40 - 0
module_Template/分时调度系统/TimeScheduleSystem.h

@@ -0,0 +1,40 @@
+#ifndef TIMESCHEDULESYSTEM_H
+#define TIMESCHEDULESYSTEM_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <string.h>
+
+typedef struct TimeScheduleSystem{
+    unsigned int ticks;
+    unsigned int targetTicks;
+    unsigned char result : 1; // 0:等待中 1:可执行
+    unsigned char state : 1; // 0:不在工作链表 1:在工作链表
+    void (* callback)(void);
+    struct TimeScheduleSystem *next;
+} TSS_t;
+
+unsigned char TSS_init(TSS_t *TSS, unsigned int targetTicks, void (* callback)(void));
+void TSS_while(void);
+void TSS_timer(void);
+
+unsigned char TSS_pending(TSS_t *TSS);
+unsigned char TSS_resume(TSS_t *TSS);
+
+void TSS_setTicks(TSS_t *TSS, unsigned char ticks);
+unsigned int TSS_getTicks(TSS_t *TSS);
+void TSS_setTargetTicks(TSS_t *TSS, unsigned char targetTicks);
+unsigned int TSS_TargetTicks(TSS_t *TSS);
+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);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // TIMESCHEDULESYSTEM_H

+ 37 - 0
module_Template/分时调度系统/main.c

@@ -0,0 +1,37 @@
+#include <stdio.h>
+#include "TimeScheduleSystem.h"
+
+TSS_t myTSS1; // 事件结构体实例
+TSS_t myTSS2;
+
+// 事件回调函数
+void myTSS1_callback(void)
+{
+    printf("11111111\n");
+}
+
+void myTSS2_callback(void)
+{
+    printf("22222222\n");
+}
+
+int main()
+{
+    int ret = 0;
+    // 1.初始化事件
+    ret = TSS_init(&myTSS1, 100, myTSS1_callback); // 100 * 5ms = 500ms周期
+    if(!ret) 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);
+
+    while(1) {
+        TSS_while(); // 2.事件循环
+    }
+}
+// 5ms定时器中断
+void timerInterrupt()
+{
+    TSS_timer(); // 3.事件调度
+}

+ 1 - 0
module_Template/分时调度系统/readme.txt

@@ -0,0 +1 @@
+分时调度系统,用法参见main.c,详细了解文件内注释

+ 67 - 0
module_Template/单向链表/linkList.c

@@ -0,0 +1,67 @@
+#include "linkList.h"
+
+/**
+  * @brief  创建链表 数据默认为0
+	* @param	n: 节点数量
+  * @retval 链表头节点
+  */
+linkListStruct *linkListCreate(uint16_t n)
+{
+    linkListStruct *head, *end;
+	
+    head = (linkListStruct *)Mymalloc.Malloc(sizeof(linkListStruct));
+    head->data = 0;
+    end = head;
+    for(uint16_t i = 1; i < n; i++) {
+        end->next = (linkListStruct *)Mymalloc.Malloc(sizeof(linkListStruct));
+        end->next->data = 0;
+        end = end->next;
+    }
+    end->next = NULL;
+
+    return head;
+}
+/**
+  * @brief  链表追加创建节点
+	* @param	list: 链表尾结点
+	* @param	data: 数据
+  * @retval 链表尾节点
+  */
+linkListStruct *linkListAppend(linkListStruct *list, uint16_t data)
+{
+    list->next = (linkListStruct *)Mymalloc.Malloc(sizeof(linkListStruct));
+    list->next->data = data;
+    list->next->next = NULL;
+	
+    return list->next;
+}
+/**
+  * @brief  链表数据求和
+	* @param	list: 链表头节点
+	* @param	deleteNum: 舍弃的头尾数据量
+	* @param	count: 数据总量
+	* @param	ratio: 乘法系数
+  * @retval 链表头节点地址
+  */
+uint32_t linkListSum(linkListStruct *list, uint8_t deleteNum, uint16_t count, float ratio)
+{
+    uint32_t sum = 0;
+    uint16_t i = 0;
+	
+    while(i < deleteNum && list->next != NULL) {
+        list = list->next;
+        i++;
+    }
+    count -= deleteNum;
+    sum += (uint32_t)(list->data * ratio);
+		printf("link list data %d : %d\n", i, (uint32_t)(list->data * ratio));
+    i += 1;
+    while(i < count && list->next != NULL) {
+        list = list->next;
+        sum += list->data * ratio;
+				printf("link list data %d : %d\n", i, (uint32_t)(list->data * ratio));
+        i++;
+    }
+		printf("link list sum : %d, count : %d\n", sum, count);
+    return sum;
+}

+ 22 - 0
module_Template/单向链表/linkList.h

@@ -0,0 +1,22 @@
+#ifndef __LINKLIST_H__
+#define __LINKLIST_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+	
+
+typedef struct linkList{
+	uint16_t data;
+  struct linkList *next;
+} linkListStruct;
+
+linkListStruct *linkListCreate(uint16_t n);
+linkListStruct *linkListAppend(linkListStruct *list, uint16_t data);
+uint32_t linkListSum(linkListStruct *list, uint8_t deleteNum, uint16_t count, float ratio);
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* __LINKLIST_H__ */
+

+ 1 - 0
module_Template/单向链表/readme.txt

@@ -0,0 +1 @@
+单向链表的创建,追加