v2.4.2014.0811 SmartOS实现系统任务调度,一次性编译测试通过

从该版本开始,在Sys.h的最后加上重要更新日志
This commit is contained in:
nnhy 2014-08-10 18:58:17 +00:00
parent 486e6cad99
commit 67b81d9716
3 changed files with 301 additions and 0 deletions

169
List.h
View File

@ -113,5 +113,174 @@ private:
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_

94
Sys.cpp
View File

@ -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首次调度时间usperiod调度间隔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
View File

@ -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首次调度时间usperiod调度间隔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
TinyIPARP/ICMP/TCP/UDP7.5k
v2.3.2014.0806 使RTM优化编译
v2.2.2014.0801 使
v2.1.2014.0728 F0需配置RAM从0x200000C0开始
v2.0.2014.0725 使C++SmartOSIOUSARTSpiNRF24L01SPIFlashCANEnc28j60GD32超频
v1.3.2014.0624 Spi模块和NRF24L01+
v1.2.2014.0604 GD32芯片
v1.1.2014.0513 F0/F1的GPIO和串口功能
v1.0.2014.0506 SmartOS使C语言实现
*/