标题:
牛人自制的STM32实时操作系统
[打印本页]
作者:
IKNOW
时间:
2020-4-10 10:30
标题:
牛人自制的STM32实时操作系统
作者
https://bbs.csdn.net/topics/300000723
实现硬件 STM32F10vet6
1,内存使用量统计
硬件系统启动使用:
系统堆栈(系统启动的时候需要使用) 80个字节
操作系统内核使用:
任务表 96+16个字节
注:20个字节/任务 * 8(默认任务个数)
信号量 32个字节
注:4个字节/信号量 * 8(默认信号量个数)
消息队列 54个字节
注: 默认8条消息/队列 * 3 (默认3个消息队列)
空闲任务(Idle) 96个字节
注:每个任务最少需要96个字节的堆栈,推荐256个字节
RAM使用统计:
一个原始的系统总共占用内存约为400个字节
其中内核占用内存不到300个字节
(注:根据armlink指示,另外还有96个字节的数据用于LIBSPACE.O文件,
这个查明,其实是开发环境在为main主函数初始化的时候用到)
2,代码量(包括ROM里面的只读数据)统计
内核 1200 个字节
信号量 300 个字节
消息队列 500 个字节
ROM使用统计
原始的系统代码小于2K
其中内核代码小于1.2K
单片机源程序如下:
#include "BenOSCore.h"
/*当前OS中所有的任务*/
I8U TaskNUM=0;
TCB BenOSTCBTable[MAX_TASK_NUM];
/*当前运行的任务*/
TCB *BenOSCurTCB;
/*当前准备新运行的任务*/
TCB *BenOSNewTCB;
I8U BenOSScheLock=0; /* 0 = enable */
/*无聊,所以把堆栈初始化模块用汇编写一遍,但愿性能会高点*/
__asm STACK_TYPE *BenOSTaskStkInit (void (*task),STACK_TYPE *ptos)
{
THUMB
PRESERVE8
PUSH {R4-R6,LR}
MOV R4,R0
MOV R0,R1
MOV R5,#0x1000000
STR R5,[R0,#0]
SUBS R0,R0,#4
STR R4,[R0,#0]
MVN R5,#1
SUBS R0,R0,#4
STR R5,[R0,#0]
MOV R5,#0x2
SUBS R0,R0,#4
STR R5,[R0,#0]
MOV R5,#0x3
SUBS R0,R0,#4
STR R5,[R0,#0]
MOV R5,#0x4
SUBS R0,R0,#4
STR R5,[R0,#0]
ASRS R5,R5,#1
SUBS R0,R0,#4
STR R5,[R0,#0]
SUBS R0,R0,#4
STR R1,[R0,#0]
MOV R5,#0x5
SUBS R0,R0,#4
STR R5,[R0,#0]
MOV R5,#0x6
SUBS R6,R0,#4
MOV R0,R6
STR R5,[R6,#0]
MOV R5,#0x7
SUBS R0,R0,#4
STR R5,[R0,#0]
MOV R5,#0x8
SUBS R0,R0,#4
STR R5,[R0,#0]
MOV R5,#0x8
SUBS R0,R0,#4
STR R5,[R0,#0]
MOV R5,#0x10
SUBS R0,R0,#4
STR R5,[R0,#0]
MOV R5,#0x11
SUBS R0,R0,#4
STR R5,[R0,#0]
MOV R5,#0x12
SUBS R6,R0,#4
MOV R0,R6
STR R5,[R6,#0]
POP {R4-R6,PC}
}
/*Thumb2指令集中无串操作指令,不过可以用字对齐进行优化*/
/*考虑到Thumb2指令中,32位指令执行效率并不高,所以这里暂时不作优化*/
void _mem_clr (I8U *pdest, I32 size)
{
while (size > 0) {
*pdest++ = (I8)0;
size--;
}
}
void _mem_copy (I8U *pdest, I8U *psrc, I16U size)
{
while (size > 0) {
*pdest++ = *psrc++;
size--;
}
}
/*在TCB表中取一个空闲的节点,给新任务使用*/
/*对BenOSTCBTable表这个有序表进行插入排序*/
/*将优先级高的任务放在前面*/
TCB* BenOSGetFreeTCB(PRIORITY_TYPE prio)
{
TCB *pTCB;
I32 index=0,orgIndex;
pTCB = &(BenOSTCBTable[0]);
for (index = 0;index < TaskNUM+1;index++)
{
pTCB = BenOSTCBTable+index;
/*已经是空闲TCB了,就直接使用*/
if (NULL == pTCB->pStackTop)
{
return (TCB*)pTCB;
}
/*若新任务优先级比较低,则向后继续找*/
if (pTCB->CurPriority >= prio)
{
continue;
}
else /*pTCB->CurPriority < prio 找到了该插入的位置了*/
{
/*保存当前位置*/
orgIndex = index;
/*从当前节点遍历到最后一个使用了的节点*/
for( index = TaskNUM+1 ; index > orgIndex ; index-- )
{
pTCB = BenOSTCBTable+index;
/*将前一个节点的数据,保存到当前节点*/
_mem_copy((I8U *)(pTCB),(I8U *)(pTCB-1),sizeof(TCB));
}
_mem_clr((I8U *)(pTCB-1),sizeof(TCB)) ;
return (TCB*)(pTCB-1);
}
}
return (TCB*)NULL;
}
/*
*时钟中断函数
*/
void SysTick_Handler()
{
I8 index;
TCB *pTCB;
I8U flagFirstTask=0;
INT_Stat stat = 0;
stat = BenOS_INT_Save();
/*初始化*/
BenOSNewTCB = NULL;
/*禁止调度*/
if (BenOSScheLock != 0)
{
BenOS_INT_Restore(stat);
return;
}
for (index = 0;index < TaskNUM;index++)
{
pTCB = BenOSTCBTable+index;
/*该任务在睡眠状态,必须将所有时延都--*/
if (pTCB->TCBDelay > 0)
{
pTCB->TCBDelay--;
continue;
}
/*该任务被挂起*/
if (pTCB->TaskStat == BenOS_Task_Pend)
{
continue;
}
/*是否找到了应该调度进去的就绪任务*/
if (flagFirstTask==0)
{
/*找到了最高优先级的任务,
并且比当前任务优先级高*/
if (BenOSCurTCB->CurPriority < pTCB->CurPriority)
{
flagFirstTask = 1;
BenOSNewTCB = pTCB;
continue;
}
/*找到了比当前优先级低的任务*/
if (BenOSCurTCB->CurPriority > pTCB->CurPriority)
{
if (BenOSNewTCB == NULL)
{
flagFirstTask = 1;
BenOSNewTCB = pTCB;
continue ;
}
else
{
flagFirstTask = 1;
continue ;
}
}
/*找到了最高优先级的任务,
并且跟当前任务优先级相等*/
if (BenOSCurTCB->CurPriority == pTCB->CurPriority)
{
/*该任务在当前任务之后*/
if ((pTCB > BenOSCurTCB)||(pTCB == BenOSCurTCB))
{
flagFirstTask = 1;
BenOSNewTCB = pTCB;
continue ;
}
/*在当前任务之前或者就是当前任务
则还需要继续向后搜索第一个同优先级的任务*/
if ((pTCB < BenOSCurTCB)
&&(BenOSNewTCB == NULL))
{
BenOSNewTCB = pTCB;
continue;
}
}
continue;
}
}
if (BenOSNewTCB != BenOSCurTCB)
{
BenOSCtxSw();
}
BenOS_INT_Restore(stat);
}
/*
*在非中断中 调度新的任务 并且切换
*/
void BenOSTaskSche()
{
INT_Stat stat = 0;
stat = BenOS_INT_Save();
if (BenOSScheLock != 0)
{
BenOS_INT_Restore(stat);
return;
}
if (BenOSNewTCB != BenOSCurTCB)
{
BenOSCtxSw();
}
BenOS_INT_Restore(stat);
}
/*
* 创建新的任务
*/
TASK_TYPE* BenOSCreateTask(void* task, STACK_TYPE *stack,PRIORITY_TYPE prio)
{
TCB *pTCB;
INT_Stat stat = 0;
stat = BenOS_INT_Save();
pTCB = BenOSGetFreeTCB(prio);
if (NULL == pTCB)
{
BenOS_INT_Restore(stat);
return NULL;
}
pTCB->pStackTop = BenOSTaskStkInit(task, stack);
pTCB->CurPriority = prio;
pTCB->TCBDelay = 0;
TaskNUM++;
BenOS_INT_Restore(stat);
return pTCB;
}
/*idle任务堆栈默认为128个字节*/
STACK_TYPE idleStack[IDLE_TASK_STACK_SIZE];
I32U IdleConuter=0;
void BenOSIdleTask()
{
INT_Stat stat = 0;
while(1)
{
stat = BenOS_INT_Save();
IdleConuter++;
BenOS_INT_Restore(stat);
}
}
/*操作系统启动(并且将优先级较低的IDLE任务创建)*/
void BenOSStart()
{
INT_Stat stat = 0;
stat = BenOS_INT_Save();
BenOSCurTCB = BenOSTCBTable;
if (BenOSCurTCB == NULL)
{
BenOS_INT_Restore(stat);
return;
}
BenOS_INT_Restore(stat);
BenOSCreateTask((void*)BenOSIdleTask,&idleStack[IDLE_TASK_STACK_SIZE-1],0);
BenOSStartTask();
}
void BenOSTimeDly (I32 ticks)
{
INT_Stat stat = 0;
I8 index;
TCB *pTCB;
stat = BenOS_INT_Save();
BenOSCurTCB->TCBDelay = ticks;
BenOSNewTCB = NULL;
/*从当前任务向后遍历,
第一个最大的优先级的任务
就是需要调度进去的任务*/
for (index = 0; index < TaskNUM;index++)
{
pTCB = BenOSTCBTable+index;
/*跳过睡眠任务*/
if (pTCB->TCBDelay != 0)
{
continue;
}
/*跳过挂起任务*/
if (pTCB->TaskStat == BenOS_Task_Pend)
{
continue;
}
/*找到了最高优先级的任务,
并且比当前任务优先级高*/
if (BenOSCurTCB->CurPriority < pTCB->CurPriority)
{
BenOSNewTCB = pTCB;
break;
}
/*找到了比当前优先级低的任务*/
if (BenOSCurTCB->CurPriority > pTCB->CurPriority)
{
/*如果当前任务之前有同优先级的就绪任务,
则选择该任务,否则就使用*/
if (BenOSNewTCB == NULL)
{
BenOSNewTCB = pTCB;
}
break;
}
/*找到了最高优先级的任务,
并且跟当前任务优先级相等*/
if (BenOSCurTCB->CurPriority == pTCB->CurPriority)
{
/*该任务在当前任务之后*/
if ((pTCB > BenOSCurTCB))
{
BenOSNewTCB = pTCB;
break ;
}
/*在当前任务之前或者就是当前任务
则还需要继续向后搜索第一个同优先级的任务*/
if (((pTCB < BenOSCurTCB)||(pTCB == BenOSCurTCB))
&&(BenOSNewTCB == NULL))
{
BenOSNewTCB = pTCB;
continue;
}
}
}
BenOS_INT_Restore(stat);
BenOSTaskSche();
}
/*
* 初始化任务数据,并创建IDLE任务
*/
I8 BenOSInit()
{
I32 index=0;
INT_Stat stat = 0;
stat = BenOS_INT_Save();
for (index = 0;index < MAX_TASK_NUM;index++)
{
_mem_clr((I8U*)BenOSTCBTable,sizeof(TCB)*MAX_TASK_NUM);
}
for(index=0;index<MAX_SEM_NUM;index++)
{
BenOSSemaphore[index] = -1;
}
for (index=0;index<MAX_QUEUE_NUMBER;index++)
{
MsgQueueFlag[index]=0;
}
BenOSCurTCB = NULL;
BenOSNewTCB = NULL;
BenOS_INT_Restore(stat);
return BenOS_OK;
}
/*
* 恢复任务运行
*/
void BenOSTaskResume(TASK_TYPE *task)
{
I32 index=0;
TCB *pTCB;
INT_Stat stat = 0;
stat = BenOS_INT_Save();
task->TaskStat = BenOS_Task_Run;
/*从头向后遍历,第一最大的优先级就是需要调度进去的任务*/
for (index = 0 ; index < TaskNUM;index++)
{
pTCB = BenOSTCBTable+index;
if ((pTCB->TCBDelay == 0) && (pTCB->TaskStat !=BenOS_Task_Pend) )
{
BenOSNewTCB = pTCB;
break;
}
}
BenOS_INT_Restore(stat);
BenOSTaskSche();
}
……………………
…………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码
所有资料51hei提供下载:
系统.7z
(143.71 KB, 下载次数: 75)
2020-4-10 13:20 上传
点击文件名下载附件
benOS
下载积分: 黑币 -5
作者:
nsj21n
时间:
2020-4-11 08:29
大神级,学习了!
作者:
HWL0541
时间:
2020-4-11 09:09
真是牛人,顶一下
作者:
smartphone
时间:
2020-4-12 12:26
看技术帖虽然一点都不懂 但是要顶
作者:
007.7
时间:
2021-6-11 17:40
从B站评论过来顶一下啊
作者:
act117
时间:
2023-4-20 10:06
B站来的,学习了
作者:
li64331218
时间:
2023-4-20 14:43
必须顶起啊!辛苦了
作者:
odddouglas
时间:
2024-7-16 15:40
顶, 前来学习观望
作者:
huaishang
时间:
2024-7-16 16:41
大神级,学习了!
作者:
sfd123
时间:
2024-7-19 07:26
厉害啊!膜拜一个!
作者:
Ubuntu312
时间:
2024-8-6 08:56
我看有人说是从B站找过来的,请问一下有视频的链接吗,能分享一下观摩一二吗。
作者:
西点钟灵毓秀
时间:
2024-8-6 09:26
还是下载来看看,适不适合自己试用
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1