v2.4.2014.0811 SmartOS实现系统任务调度,一次性编译测试通过
从该版本开始,在Sys.h的最后加上重要更新日志
This commit is contained in:
parent
486e6cad99
commit
67b81d9716
169
List.h
169
List.h
|
@ -113,5 +113,174 @@ private:
|
||||||
if(_count >= _total) ChangeSize(_count * 2);
|
if(_count >= _total) ChangeSize(_count * 2);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
/*
|
||||||
|
// 双向链表
|
||||||
|
template <class T> class DblLinkedList;
|
||||||
|
|
||||||
|
// 双向链表节点
|
||||||
|
template <class T> class DblLinkedNode
|
||||||
|
{
|
||||||
|
T* _nextNode;
|
||||||
|
T* _prevNode;
|
||||||
|
|
||||||
|
// 友元类。允许链表类控制本类私有成员
|
||||||
|
friend class DblLinkedList<T>;
|
||||||
|
|
||||||
|
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 T> 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_
|
#endif //_List_H_
|
||||||
|
|
94
Sys.cpp
94
Sys.cpp
|
@ -29,6 +29,8 @@ void TSys::Reset() { NVIC_SystemReset(); }
|
||||||
#define IRQ_STACK_SIZE 0x100
|
#define IRQ_STACK_SIZE 0x100
|
||||||
uint IRQ_STACK[IRQ_STACK_SIZE]; // MSP 中断嵌套堆栈
|
uint IRQ_STACK[IRQ_STACK_SIZE]; // MSP 中断嵌套堆栈
|
||||||
|
|
||||||
|
#pragma arm section code
|
||||||
|
|
||||||
force_inline void Set_SP()
|
force_inline void Set_SP()
|
||||||
{
|
{
|
||||||
__set_PSP(__get_MSP());
|
__set_PSP(__get_MSP());
|
||||||
|
@ -250,6 +252,9 @@ TSys::TSys()
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
Interrupt.Init();
|
Interrupt.Init();
|
||||||
|
|
||||||
|
_TaskCount = 0;
|
||||||
|
memset(_Tasks, 0, ArrayLength(_Tasks));
|
||||||
}
|
}
|
||||||
|
|
||||||
TSys::~TSys()
|
TSys::~TSys()
|
||||||
|
@ -344,3 +349,92 @@ uint TSys::Crc(const void* rgBlock, int len, uint crc)
|
||||||
return crc;
|
return crc;
|
||||||
}
|
}
|
||||||
#endif
|
#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
|
||||||
|
|
38
Sys.h
38
Sys.h
|
@ -79,6 +79,29 @@ public:
|
||||||
|
|
||||||
// CRC32校验
|
// CRC32校验
|
||||||
uint Crc(const void* rgBlock, int len, uint crc = 0);
|
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函数之前执行构造函数(!!!!!)
|
extern TSys Sys; //创建一个全局的Sys对象 会在main函数之前执行构造函数(!!!!!)
|
||||||
|
@ -104,3 +127,18 @@ __inline void debug_printf( const char *format, ... ) {}
|
||||||
|
|
||||||
|
|
||||||
#endif //_Sys_H_
|
#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语言实现
|
||||||
|
*/
|
||||||
|
|
Loading…
Reference in New Issue