找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 5000|回复: 6
打印 上一主题 下一主题
收起左侧

牛人自制的STM32实时操作系统

  [复制链接]
跳转到指定楼层
楼主
ID:507431 发表于 2020-4-10 10:30 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
作者
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

单片机源程序如下:
  1. #include "BenOSCore.h"

  2. /*当前OS中所有的任务*/
  3. I8U                        TaskNUM=0;
  4. TCB                        BenOSTCBTable[MAX_TASK_NUM];


  5. /*当前运行的任务*/
  6. TCB                        *BenOSCurTCB;

  7. /*当前准备新运行的任务*/
  8. TCB                 *BenOSNewTCB;

  9. I8U                   BenOSScheLock=0;            /* 0 = enable                 */


  10. /*无聊,所以把堆栈初始化模块用汇编写一遍,但愿性能会高点*/
  11. __asm    STACK_TYPE *BenOSTaskStkInit (void (*task),STACK_TYPE *ptos)
  12. {
  13.                  THUMB
  14.                  PRESERVE8

  15.                  PUSH     {R4-R6,LR}
  16.          MOV      R4,R0

  17.          MOV      R0,R1
  18.          MOV      R5,#0x1000000
  19.          STR      R5,[R0,#0]

  20.          SUBS     R0,R0,#4
  21.          STR      R4,[R0,#0]
  22.          
  23.          MVN      R5,#1
  24.          SUBS     R0,R0,#4
  25.          STR      R5,[R0,#0]
  26.          
  27.          MOV      R5,#0x2
  28.          SUBS     R0,R0,#4
  29.          STR      R5,[R0,#0]
  30.          
  31.          MOV      R5,#0x3
  32.          SUBS     R0,R0,#4
  33.          STR      R5,[R0,#0]
  34.          
  35.          MOV      R5,#0x4
  36.          SUBS     R0,R0,#4
  37.          STR      R5,[R0,#0]

  38.                  ASRS     R5,R5,#1
  39.          SUBS     R0,R0,#4
  40.          STR      R5,[R0,#0]
  41.          
  42.          SUBS     R0,R0,#4
  43.          STR      R1,[R0,#0]
  44.          
  45.          MOV      R5,#0x5
  46.          SUBS     R0,R0,#4
  47.          STR      R5,[R0,#0]

  48.          MOV      R5,#0x6
  49.          SUBS     R6,R0,#4
  50.          MOV      R0,R6
  51.          STR      R5,[R6,#0]
  52.          
  53.          MOV      R5,#0x7
  54.          SUBS     R0,R0,#4
  55.          STR      R5,[R0,#0]
  56.          
  57.          MOV      R5,#0x8
  58.          SUBS     R0,R0,#4
  59.          STR      R5,[R0,#0]

  60.          MOV      R5,#0x8
  61.          SUBS     R0,R0,#4
  62.          STR      R5,[R0,#0]

  63.          MOV      R5,#0x10
  64.          SUBS     R0,R0,#4
  65.          STR      R5,[R0,#0]

  66.          MOV      R5,#0x11
  67.          SUBS     R0,R0,#4
  68.          STR      R5,[R0,#0]

  69.          MOV      R5,#0x12
  70.          SUBS     R6,R0,#4
  71.          MOV          R0,R6
  72.          STR      R5,[R6,#0]
  73.          POP      {R4-R6,PC}

  74. }


  75. /*Thumb2指令集中无串操作指令,不过可以用字对齐进行优化*/
  76. /*考虑到Thumb2指令中,32位指令执行效率并不高,所以这里暂时不作优化*/
  77. void  _mem_clr (I8U *pdest, I32 size)
  78. {
  79.     while (size > 0) {
  80.         *pdest++ = (I8)0;
  81.         size--;
  82.     }
  83. }

  84. void  _mem_copy (I8U *pdest, I8U *psrc, I16U size)
  85. {
  86.     while (size > 0) {
  87.         *pdest++ = *psrc++;
  88.         size--;
  89.     }
  90. }

  91. /*在TCB表中取一个空闲的节点,给新任务使用*/
  92. /*对BenOSTCBTable表这个有序表进行插入排序*/
  93. /*将优先级高的任务放在前面*/
  94. TCB* BenOSGetFreeTCB(PRIORITY_TYPE prio)
  95. {
  96.         TCB        *pTCB;
  97.         I32        index=0,orgIndex;

  98.         pTCB = &(BenOSTCBTable[0]);
  99.         for (index = 0;index < TaskNUM+1;index++)
  100.         {
  101.                 pTCB = BenOSTCBTable+index;

  102.                 /*已经是空闲TCB了,就直接使用*/
  103.                 if (NULL == pTCB->pStackTop)
  104.                 {
  105.                         return        (TCB*)pTCB;
  106.                 }

  107.                 /*若新任务优先级比较低,则向后继续找*/
  108.                 if (pTCB->CurPriority >= prio)
  109.                 {
  110.                         continue;
  111.                 }
  112.                 else /*pTCB->CurPriority < prio 找到了该插入的位置了*/
  113.                 {  
  114.                         /*保存当前位置*/
  115.                         orgIndex = index;

  116.                         /*从当前节点遍历到最后一个使用了的节点*/
  117.                         for( index = TaskNUM+1 ; index > orgIndex ; index-- )
  118.                         {
  119.                                 pTCB = BenOSTCBTable+index;

  120.                                 /*将前一个节点的数据,保存到当前节点*/
  121.                                 _mem_copy((I8U *)(pTCB),(I8U *)(pTCB-1),sizeof(TCB));
  122.                         }
  123.                         _mem_clr((I8U *)(pTCB-1),sizeof(TCB))  ;
  124.                                
  125.                         return (TCB*)(pTCB-1);               

  126.                 }
  127.         }

  128.         return        (TCB*)NULL;
  129. }

  130. /*
  131. *时钟中断函数
  132. */
  133. void SysTick_Handler()
  134. {
  135.         I8        index;
  136.         TCB                *pTCB;
  137.         I8U        flagFirstTask=0;
  138.         INT_Stat  stat = 0;

  139.         stat = BenOS_INT_Save();

  140.     /*初始化*/
  141.         BenOSNewTCB = NULL;

  142.         /*禁止调度*/
  143.         if (BenOSScheLock != 0)
  144.         {
  145.                 BenOS_INT_Restore(stat);
  146.                 return;
  147.         }

  148.         for (index = 0;index < TaskNUM;index++)
  149.         {
  150.                 pTCB = BenOSTCBTable+index;

  151.                 /*该任务在睡眠状态,必须将所有时延都--*/
  152.                 if (pTCB->TCBDelay > 0)
  153.                 {
  154.                         pTCB->TCBDelay--;
  155.                         continue;
  156.                 }

  157.                 /*该任务被挂起*/
  158.                 if (pTCB->TaskStat == BenOS_Task_Pend)       
  159.                 {
  160.                         continue;
  161.                 }

  162.                 /*是否找到了应该调度进去的就绪任务*/
  163.                 if (flagFirstTask==0)
  164.                 {
  165.                         /*找到了最高优先级的任务,
  166.                           并且比当前任务优先级高*/
  167.                         if (BenOSCurTCB->CurPriority < pTCB->CurPriority)
  168.                         {
  169.                                 flagFirstTask = 1;
  170.                                 BenOSNewTCB = pTCB;
  171.                                 continue;
  172.                         }

  173.                         /*找到了比当前优先级低的任务*/
  174.                         if (BenOSCurTCB->CurPriority > pTCB->CurPriority)
  175.                         {
  176.                                 if (BenOSNewTCB == NULL)
  177.                                 {
  178.                                         flagFirstTask = 1;
  179.                                         BenOSNewTCB = pTCB;
  180.                                         continue  ;       
  181.                                 }
  182.                                 else
  183.                                 {
  184.                                         flagFirstTask = 1;
  185.                                         continue  ;               
  186.                                 }
  187.                         }
  188.                        
  189.                         /*找到了最高优先级的任务,
  190.                           并且跟当前任务优先级相等*/
  191.                         if (BenOSCurTCB->CurPriority == pTCB->CurPriority)
  192.                         {
  193.                                 /*该任务在当前任务之后*/
  194.                                 if ((pTCB > BenOSCurTCB)||(pTCB == BenOSCurTCB))
  195.                                 {       
  196.                                         flagFirstTask = 1;
  197.                                         BenOSNewTCB = pTCB;
  198.                                         continue  ;               
  199.                                 }       
  200.                                 /*在当前任务之前或者就是当前任务
  201.                                   则还需要继续向后搜索第一个同优先级的任务*/
  202.                                 if ((pTCB < BenOSCurTCB)
  203.                                      &&(BenOSNewTCB == NULL))
  204.                                 {
  205.                                          BenOSNewTCB = pTCB;
  206.                                          continue;
  207.                                 }
  208.                         }


  209.                         continue;
  210.                 }

  211.                
  212.         }
  213.         if (BenOSNewTCB != BenOSCurTCB)
  214.         {
  215.                 BenOSCtxSw();
  216.         }
  217.         BenOS_INT_Restore(stat);
  218. }

  219. /*
  220. *在非中断中 调度新的任务 并且切换
  221. */
  222. void BenOSTaskSche()
  223. {
  224.         INT_Stat  stat = 0;

  225.         stat = BenOS_INT_Save();
  226.         if (BenOSScheLock != 0)
  227.         {
  228.                 BenOS_INT_Restore(stat);
  229.                 return;
  230.         }               

  231.         if (BenOSNewTCB != BenOSCurTCB)
  232.         {
  233.                 BenOSCtxSw();
  234.         }
  235.         BenOS_INT_Restore(stat);
  236. }

  237. /*
  238. * 创建新的任务
  239. */
  240. TASK_TYPE*  BenOSCreateTask(void* task, STACK_TYPE *stack,PRIORITY_TYPE prio)
  241. {
  242.         TCB        *pTCB;
  243.         INT_Stat  stat = 0;
  244.        
  245.         stat = BenOS_INT_Save();
  246.        
  247.         pTCB = BenOSGetFreeTCB(prio);

  248.         if (NULL == pTCB)
  249.         {
  250.                 BenOS_INT_Restore(stat);
  251.                 return        NULL;
  252.         }


  253.         pTCB->pStackTop = BenOSTaskStkInit(task, stack);

  254.         pTCB->CurPriority = prio;

  255.         pTCB->TCBDelay = 0;
  256.        
  257.         TaskNUM++;
  258.         BenOS_INT_Restore(stat);
  259.         return pTCB;
  260. }

  261. /*idle任务堆栈默认为128个字节*/
  262. STACK_TYPE        idleStack[IDLE_TASK_STACK_SIZE];

  263. I32U         IdleConuter=0;

  264. void BenOSIdleTask()
  265. {
  266.         INT_Stat                  stat = 0;

  267.         while(1)
  268.         {
  269.                 stat = BenOS_INT_Save();
  270.                 IdleConuter++;
  271.                 BenOS_INT_Restore(stat);
  272.         }
  273. }


  274. /*操作系统启动(并且将优先级较低的IDLE任务创建)*/
  275. void BenOSStart()
  276. {
  277.         INT_Stat  stat = 0;
  278.        
  279.         stat = BenOS_INT_Save();

  280.         BenOSCurTCB = BenOSTCBTable;
  281.         if (BenOSCurTCB == NULL)
  282.         {
  283.                 BenOS_INT_Restore(stat);
  284.                 return;
  285.         }

  286.         BenOS_INT_Restore(stat);

  287.         BenOSCreateTask((void*)BenOSIdleTask,&idleStack[IDLE_TASK_STACK_SIZE-1],0);
  288.        
  289.         BenOSStartTask();
  290. }


  291. void  BenOSTimeDly (I32 ticks)
  292. {
  293.         INT_Stat  stat = 0;
  294.         I8          index;
  295.         TCB                  *pTCB;
  296.        
  297.         stat = BenOS_INT_Save();
  298.         BenOSCurTCB->TCBDelay = ticks;

  299.         BenOSNewTCB = NULL;

  300.         /*从当前任务向后遍历,
  301.         第一个最大的优先级的任务
  302.         就是需要调度进去的任务*/
  303.         for (index = 0; index < TaskNUM;index++)
  304.         {
  305.                 pTCB = BenOSTCBTable+index;

  306.                 /*跳过睡眠任务*/
  307.                 if (pTCB->TCBDelay != 0)
  308.                 {
  309.                         continue;
  310.                 }
  311.                 /*跳过挂起任务*/
  312.                 if  (pTCB->TaskStat == BenOS_Task_Pend)       
  313.                 {                               
  314.   
  315.                         continue;
  316.                 }

  317.                 /*找到了最高优先级的任务,
  318.                   并且比当前任务优先级高*/
  319.                 if (BenOSCurTCB->CurPriority < pTCB->CurPriority)
  320.                 {
  321.                         BenOSNewTCB = pTCB;
  322.                         break;
  323.                 }

  324.                 /*找到了比当前优先级低的任务*/
  325.                 if (BenOSCurTCB->CurPriority > pTCB->CurPriority)
  326.                 {
  327.                     /*如果当前任务之前有同优先级的就绪任务,
  328.                           则选择该任务,否则就使用*/
  329.                         if (BenOSNewTCB == NULL)
  330.                         {
  331.                                 BenOSNewTCB = pTCB;
  332.                         }                                                  
  333.                         break;
  334.                 }
  335.                        
  336.                 /*找到了最高优先级的任务,
  337.                   并且跟当前任务优先级相等*/
  338.                 if (BenOSCurTCB->CurPriority == pTCB->CurPriority)
  339.                 {
  340.                         /*该任务在当前任务之后*/
  341.                         if ((pTCB > BenOSCurTCB))
  342.                         {       
  343.                                 BenOSNewTCB = pTCB;
  344.                                 break  ;               
  345.                         }       
  346.                         /*在当前任务之前或者就是当前任务
  347.                           则还需要继续向后搜索第一个同优先级的任务*/
  348.                         if (((pTCB < BenOSCurTCB)||(pTCB == BenOSCurTCB))
  349.                              &&(BenOSNewTCB == NULL))
  350.                         {
  351.                                  BenOSNewTCB = pTCB;
  352.                                  continue;
  353.                         }

  354.                 }

  355.        
  356.         }
  357.         BenOS_INT_Restore(stat);
  358.         BenOSTaskSche();       
  359. }

  360. /*
  361. * 初始化任务数据,并创建IDLE任务
  362. */

  363. I8 BenOSInit()
  364. {
  365.         I32        index=0;
  366.         INT_Stat  stat = 0;
  367.        
  368.         stat = BenOS_INT_Save();

  369.         for (index = 0;index < MAX_TASK_NUM;index++)
  370.         {
  371.                 _mem_clr((I8U*)BenOSTCBTable,sizeof(TCB)*MAX_TASK_NUM);
  372.         }                               

  373.         for(index=0;index<MAX_SEM_NUM;index++)
  374.         {       
  375.                 BenOSSemaphore[index] = -1;
  376.         }

  377.         for (index=0;index<MAX_QUEUE_NUMBER;index++)
  378.         {
  379.                 MsgQueueFlag[index]=0;
  380.         }

  381.         BenOSCurTCB = NULL;               
  382.         BenOSNewTCB = NULL;

  383.         BenOS_INT_Restore(stat);
  384.         return        BenOS_OK;

  385. }

  386. /*
  387. * 恢复任务运行
  388. */
  389. void BenOSTaskResume(TASK_TYPE *task)
  390. {
  391.         I32        index=0;
  392.         TCB                  *pTCB;
  393.         INT_Stat  stat = 0;
  394.        
  395.         stat = BenOS_INT_Save();
  396.         task->TaskStat = BenOS_Task_Run;
  397.                 /*从头向后遍历,第一最大的优先级就是需要调度进去的任务*/
  398.         for (index = 0 ; index < TaskNUM;index++)
  399.         {
  400.                 pTCB = BenOSTCBTable+index;
  401.                 if ((pTCB->TCBDelay == 0) && (pTCB->TaskStat !=BenOS_Task_Pend)          )
  402.                 {       
  403.                         BenOSNewTCB = pTCB;
  404.                         break;
  405.                 }
  406.         }
  407.        
  408.         BenOS_INT_Restore(stat);       

  409.         BenOSTaskSche();       
  410. }

  411. ……………………

  412. …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码

所有资料51hei提供下载:
系统.7z (143.71 KB, 下载次数: 54)

评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏10 分享淘帖 顶2 踩
回复

使用道具 举报

沙发
ID:64089 发表于 2020-4-11 08:29 | 只看该作者
大神级,学习了!
回复

使用道具 举报

板凳
ID:91165 发表于 2020-4-11 09:09 | 只看该作者
真是牛人,顶一下
回复

使用道具 举报

地板
ID:53978 发表于 2020-4-12 12:26 | 只看该作者
看技术帖虽然一点都不懂 但是要顶
回复

使用道具 举报

5#
ID:476903 发表于 2021-6-11 17:40 | 只看该作者
从B站评论过来顶一下啊
回复

使用道具 举报

6#
ID:1072895 发表于 2023-4-20 10:06 | 只看该作者
B站来的,学习了
回复

使用道具 举报

7#
ID:291668 发表于 2023-4-20 14:43 | 只看该作者
必须顶起啊!辛苦了
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表