From 67b81d9716f0938e292cdcc3acf26941e18c99ab Mon Sep 17 00:00:00 2001 From: nnhy Date: Sun, 10 Aug 2014 18:58:17 +0000 Subject: [PATCH] =?UTF-8?q?v2.4.2014.0811=09SmartOS=E5=AE=9E=E7=8E=B0?= =?UTF-8?q?=E7=B3=BB=E7=BB=9F=E4=BB=BB=E5=8A=A1=E8=B0=83=E5=BA=A6=EF=BC=8C?= =?UTF-8?q?=E4=B8=80=E6=AC=A1=E6=80=A7=E7=BC=96=E8=AF=91=E6=B5=8B=E8=AF=95?= =?UTF-8?q?=E9=80=9A=E8=BF=87=20=E4=BB=8E=E8=AF=A5=E7=89=88=E6=9C=AC?= =?UTF-8?q?=E5=BC=80=E5=A7=8B=EF=BC=8C=E5=9C=A8Sys.h=E7=9A=84=E6=9C=80?= =?UTF-8?q?=E5=90=8E=E5=8A=A0=E4=B8=8A=E9=87=8D=E8=A6=81=E6=9B=B4=E6=96=B0?= =?UTF-8?q?=E6=97=A5=E5=BF=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- List.h | 169 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Sys.cpp | 94 +++++++++++++++++++++++++++++++ Sys.h | 38 +++++++++++++ 3 files changed, 301 insertions(+) diff --git a/List.h b/List.h index 33e55bea..f73104d7 100644 --- a/List.h +++ b/List.h @@ -113,5 +113,174 @@ private: if(_count >= _total) ChangeSize(_count * 2); } }; +/* +// 双向链表 +template class DblLinkedList; +// 双向链表节点 +template class DblLinkedNode +{ + T* _nextNode; + T* _prevNode; + + // 友元类。允许链表类控制本类私有成员 + friend class DblLinkedList; + +public: + void Initialize() + { + _nextNode = NULL; + _prevNode = NULL; + } + + T* Next() const { return _nextNode; } + T* Prev() const { return _prevNode; } + + void SetNext( T* next ) { _nextNode = next; } + void SetPrev( T* prev ) { _prevNode = prev; } + // 是否有下一个节点链接 + bool IsLinked() const { return _nextNode != NULL; } + + // 从链表中删除。需要修改前后节点的指针指向,但当前链表仍然指向之前的前后节点 + void RemoveFromList() + { + T* next = _nextNode; + T* prev = _prevNode; + + if(prev) prev->_nextNode = next; + if(next) next->_prevNode = prev; + } + + // 完全脱离链表。不再指向其它节点 + void Unlink() + { + T* next = _nextNode; + T* prev = _prevNode; + + if(prev) prev->_nextNode = next; + if(next) next->_prevNode = prev; + + _nextNode = NULL; + _prevNode = NULL; + } +}; + +// 双向链表 +template class DblLinkedList +{ + T* _first; + T* _last; + +public: + void Initialize() + { + _first = Tail(); + _last = Head(); + } + + // 计算链表节点数 + int Count() + { + T* ptr; + T* ptrNext; + int num = 0; + + for(ptr = FirstNode(); (ptrNext = ptr->Next()) != NULL; ptr = ptrNext) + { + num++; + } + + return num; + } + + T* FirstNode() const { return _first ; } + T* LastNode () const { return _last ; } + bool IsEmpty () const { return _first == Tail(); } + + T* FirstValidNode() const { T* res = _first; return res->Next() ? res : NULL; } + T* LastValidNode () const { T* res = _last ; return res->Prev() ? res : NULL; } + + T* Head() const { return (T*)((uint)&_first - offsetof(T, _nextNode)); } + T* Tail() const { return (T*)((uint)&_last - offsetof(T, _prevNode)); } + +private: + + // 在两个节点之间插入新节点 + void Insert( T* prev, T* next, T* node ) + { + node->_nextNode = next; + node->_prevNode = prev; + + next->_prevNode = node; + prev->_nextNode = node; + } + +public: +#if defined(_DEBUG) + BOOL Exists( T* searchNode ) + { + T* node = FirstValidNode(); + while( node != NULL && node != searchNode ) + { + if (node == node->Next()) + { + ASSERT(FALSE); + } + node = node->Next(); + } + return (node == NULL? FALSE: TRUE); + } +#endif + + void InsertBeforeNode( T* node, T* nodeNew ) + { + if(node && nodeNew && node != nodeNew) + { + nodeNew->RemoveFromList(); + + Insert( node->Prev(), node, nodeNew ); + } + } + + void InsertAfterNode( T* node, T* nodeNew ) + { + if(node && nodeNew && node != nodeNew) + { + nodeNew->RemoveFromList(); + + Insert( node, node->Next(), nodeNew ); + } + } + + void LinkAtFront( T* node ) + { + InsertAfterNode( Head(), node ); + } + + void LinkAtBack( T* node ) + { + InsertBeforeNode( Tail(), node ); + } + + // 释放第一个有效节点 + T* ExtractFirstNode() + { + T* node = FirstValidNode(); + + if(node) node->Unlink(); + + return node; + } + + // 释放最后一个有效节点 + T* ExtractLastNode() + { + T* node = LastValidNode(); + + if(node) node->Unlink(); + + return node; + } +}; +*/ #endif //_List_H_ diff --git a/Sys.cpp b/Sys.cpp index fc7d73cc..ecb35cb9 100644 --- a/Sys.cpp +++ b/Sys.cpp @@ -29,6 +29,8 @@ void TSys::Reset() { NVIC_SystemReset(); } #define IRQ_STACK_SIZE 0x100 uint IRQ_STACK[IRQ_STACK_SIZE]; // MSP 中断嵌套堆栈 +#pragma arm section code + force_inline void Set_SP() { __set_PSP(__get_MSP()); @@ -250,6 +252,9 @@ TSys::TSys() #endif Interrupt.Init(); + + _TaskCount = 0; + memset(_Tasks, 0, ArrayLength(_Tasks)); } TSys::~TSys() @@ -344,3 +349,92 @@ uint TSys::Crc(const void* rgBlock, int len, uint crc) return crc; } #endif + +#define __TASK__MODULE__ 1 +#ifdef __TASK__MODULE__ +// 创建任务,返回任务编号。priority优先级,dueTime首次调度时间us,period调度间隔us,-1表示仅处理一次 +uint TSys::AddTask(Func func, uint dueTime, int period) +{ + // 屏蔽中断,否则可能有线程冲突 + SmartIRQ irq; + + // 找一个空闲位给它 + int i = 0; + while(i < ArrayLength(_Tasks) && _Tasks[i++] != NULL); + assert_param(i < ArrayLength(_Tasks)); + + Task* task = new Task(); + _Tasks[i - 1] = task; + task->ID = i; + task->Callback = func; + task->Period = period; + task->NextTime = Time.CurrentMicrosecond() + dueTime; + + _TaskCount++; + debug_printf("添加任务%d 0x%08x\r\n", task->ID, func); + + return task->ID; +} + +void TSys::RemoveTask(uint taskid) +{ + assert_param(taskid > 0); + assert_param(taskid <= _TaskCount); + + Task* task = _Tasks[taskid - 1]; + _Tasks[taskid - 1] = NULL; + if(task) + { + debug_printf("删除任务%d 0x%08x\r\n", task->ID, task->Callback); + delete task; + + _TaskCount--; + } +} + +void TSys::Start() +{ + debug_printf("系统准备就绪,开始循环处理%d个任务!\r\n", _TaskCount); + + _Running = true; + while(_Running) + { + //uint minTime = 0xFFFFFFFF; // 最小等待时间 + uint now = Time.CurrentMicrosecond(); // 当前时间 + for(int i=0; i < ArrayLength(_Tasks); i++) + { + Task* task = _Tasks[i]; + if(task && task->NextTime <= now) + { + // 先计算下一次时间 + task->NextTime += task->Period; + task->Callback(); + + // 如果只是一次性任务,在这里清理 + if(task->Period < 0) + { + _Tasks[i] = NULL; + delete task; + } + } + } + + //if(minTime > 0) Delay(minTime); + } + debug_printf("系统停止调度,共有%d个任务!\r\n", _TaskCount); +} + +void TSys::Stop() +{ + debug_printf("系统停止!\r\n"); + _Running = false; + + // 销毁所有任务 + /*for(int i=0; i < ArrayLength(_Tasks); i++) + { + Task* task = _Tasks[i]; + if(task) delete task; + } + memset(_Tasks, 0, ArrayLength(_Tasks));*/ +} +#endif diff --git a/Sys.h b/Sys.h index 495d7773..305bca16 100644 --- a/Sys.h +++ b/Sys.h @@ -79,6 +79,29 @@ public: // CRC32校验 uint Crc(const void* rgBlock, int len, uint crc = 0); + +private: + + // 任务类 + class Task + { + public: + int ID; // 编号 + Func Callback; // 回调 + int Period; // 周期us + int NextTime; // 下一次执行时间 + }; + + Task* _Tasks[32]; + int _TaskCount; + bool _Running; + +public: + // 创建任务,返回任务编号。dueTime首次调度时间us,period调度间隔us,-1表示仅处理一次 + uint AddTask(Func func, uint dueTime = 0, int period = 0); + void RemoveTask(uint taskid); + void Start(); // 开始系统大循环 + void Stop(); }; extern TSys Sys; //创建一个全局的Sys对象 会在main函数之前执行构造函数(!!!!!) @@ -104,3 +127,18 @@ __inline void debug_printf( const char *format, ... ) {} #endif //_Sys_H_ + +/* +v2.4.2014.0811 实现系统多任务调度,一次性编译测试通过,多任务小灯例程4k + 实现以太网精简协议TinyIP,ARP/ICMP/TCP/UDP,混合网络例程7.5k + 增加看门狗、定时器模块 +v2.3.2014.0806 使用双栈增加稳定性,增加RTM优化编译,核心函数强制内联,自动堆栈越界检查 +v2.2.2014.0801 增加引脚保护机制,避免不同模块使用相同引脚导致冲突而难以发现错误 +v2.1.2014.0728 增加中断管理模块,全面接管中断向量表,支持动态修改中断函数,支持多中断共用中断函数。F0需配置RAM从0x200000C0开始 +v2.0.2014.0725 使用C++全新实现SmartOS,支持系统时钟、IO、USART、日志、断言、Spi、NRF24L01、SPIFlash、CAN、Enc28j60,GD32超频 + +v1.3.2014.0624 增加Spi模块和NRF24L01+模块的支持 +v1.2.2014.0604 支持GD32芯片 +v1.1.2014.0513 支持F0/F1的GPIO和串口功能 +v1.0.2014.0506 建立嵌入式系统框架SmartOS,使用纯C语言实现 +*/