当前位置: 首页 > news >正文

uc/os-II 原理及应用(八) 系统裁减以及移植到51单片机上

两个习题

在这里插入图片描述

  1. 先了解下CPU上函数调用的过程:

    • 一个程序取得函数地址,先保护现场将局部变量及参数压栈,再将调用函数的参数压栈,然后跳转到函数位置,将参数出栈,执行代码,结束后返回到调用位置,再恢复现场。但在MCU中,为了效率与其通常的业务场景可能并不这么做,对于局部变量不会专门保存与恢复。
    • 在多任务系统中,如果多个任务并发的调用一个函数,可能会产生干扰,简单的说是线程不安全。
      如果一个函数被多个任务并发的调用而不产生干扰(线程安全),就是可重入函数。
    • 参考窥探Keil4 C51的函数调用
  2. 各个任务用来存储各自任务堆栈内容的空间是任务堆栈;各个任务在运行时使用的堆栈是系统堆栈。
    在任务切换时,系统堆栈的内容要到重新保存到被中止任务的堆栈空间,要运行的任务的堆栈内存复制到系统堆栈上来。
    任务没有在运行时任务堆栈空间的内容只是备份,所以是那些内容是任务堆栈映像。

移植记录

先使用Keil4 建立一个工程 ucosii_c51,建立两组User与uCOS-II,在User中加入main.c,在uCOS-II中加入uCOS-II的源码

在这里插入图片描述
在这里插入图片描述


的uCOS-II的目录下新建 os_cfg.h,os_cpu.h,app_cfg.h 三个头文件,把os_cfg_r.h的内容先复制到os_cfg.h中来
然后修改os_cfg.h来对uCOS-II系统进行裁减,先做到最小配置

#ifndef __OS_CFG_H__
#define __OS_CFG_H__/* ---------------------- MISCELLANEOUS ----------------------- */
#define OS_APP_HOOKS_EN           0u   /* Application-defined hooks are called from the uC/OS-II hooks */
#define OS_ARG_CHK_EN             0u   /* Enable (1) or Disable (0) argument checking                  */
#define OS_CPU_HOOKS_EN           0u   /* uC/OS-II hooks are found in the processor port files         */#define OS_DEBUG_EN               0u   /* Enable(1) debug variables                                    */#define OS_EVENT_MULTI_EN         1u   /* Include code for OSEventPendMulti()                          */
#define OS_EVENT_NAME_EN          0u   /* Enable names for Sem, Mutex, Mbox and Q                      */#define OS_LOWEST_PRIO           20u   /* Defines the lowest priority that can be assigned ...         *//* ... MUST NEVER be higher than 254!                           */#define OS_MAX_EVENTS            10u   /* Max. number of event control blocks in your application      */
#define OS_MAX_FLAGS              5u   /* Max. number of Event Flag Groups    in your application      */
#define OS_MAX_MEM_PART           5u   /* Max. number of memory partitions                             */
#define OS_MAX_QS                 4u   /* Max. number of queue control blocks in your application      */
#define OS_MAX_TASKS             20u   /* Max. number of tasks in your application, MUST be >= 2       */#define OS_SCHED_LOCK_EN          1u   /* Include code for OSSchedLock() and OSSchedUnlock()           */#define OS_TICK_STEP_EN           1u   /* Enable tick stepping feature for uC/OS-View                  */
#define OS_TICKS_PER_SEC        100u   /* Set the number of ticks in one second                        *//* --------------------- TASK STACK SIZE ---------------------- */
#define OS_TASK_TMR_STK_SIZE    128u   /* Timer      task stack size (# of OS_STK wide entries)        */
#define OS_TASK_STAT_STK_SIZE   128u   /* Statistics task stack size (# of OS_STK wide entries)        */
#define OS_TASK_IDLE_STK_SIZE   128u   /* Idle       task stack size (# of OS_STK wide entries)        *//* --------------------- TASK MANAGEMENT ---------------------- */
#define OS_TASK_CHANGE_PRIO_EN    0u   /*     Include code for OSTaskChangePrio()                      */
#define OS_TASK_CREATE_EN         1u   /*     Include code for OSTaskCreate()                          */
#define OS_TASK_CREATE_EXT_EN     0u   /*     Include code for OSTaskCreateExt()                       */
#define OS_TASK_DEL_EN            1u   /*     Include code for OSTaskDel()                             */
#define OS_TASK_NAME_EN           0u   /*     Enable task names                                        */
#define OS_TASK_PROFILE_EN        1u   /*     Include variables in OS_TCB for profiling                */
#define OS_TASK_QUERY_EN          1u   /*     Include code for OSTaskQuery()                           */
#define OS_TASK_REG_TBL_SIZE      1u   /*     Size of task variables array (#of INT32U entries)        */
#define OS_TASK_STAT_EN           0u   /*     Enable (1) or Disable(0) the statistics task             */
#define OS_TASK_STAT_STK_CHK_EN   1u   /*     Check task stacks from statistic task                    */
#define OS_TASK_SUSPEND_EN        1u   /*     Include code for OSTaskSuspend() and OSTaskResume()      */
#define OS_TASK_SW_HOOK_EN        0u   /*     Include code for OSTaskSwHook()                          *//* ----------------------- EVENT FLAGS ------------------------ */
#define OS_FLAG_EN                0u   /* Enable (1) or Disable (0) code generation for EVENT FLAGS    */
#define OS_FLAG_ACCEPT_EN         1u   /*     Include code for OSFlagAccept()                          */
#define OS_FLAG_DEL_EN            1u   /*     Include code for OSFlagDel()                             */
#define OS_FLAG_NAME_EN           1u   /*     Enable names for event flag group                        */
#define OS_FLAG_QUERY_EN          1u   /*     Include code for OSFlagQuery()                           */
#define OS_FLAG_WAIT_CLR_EN       1u   /* Include code for Wait on Clear EVENT FLAGS                   */
#define OS_FLAGS_NBITS           16u   /* Size in #bits of OS_FLAGS data type (8, 16 or 32)            *//* -------------------- MESSAGE MAILBOXES --------------------- */
#define OS_MBOX_EN                0u   /* Enable (1) or Disable (0) code generation for MAILBOXES      */
#define OS_MBOX_ACCEPT_EN         1u   /*     Include code for OSMboxAccept()                          */
#define OS_MBOX_DEL_EN            1u   /*     Include code for OSMboxDel()                             */
#define OS_MBOX_PEND_ABORT_EN     1u   /*     Include code for OSMboxPendAbort()                       */
#define OS_MBOX_POST_EN           1u   /*     Include code for OSMboxPost()                            */
#define OS_MBOX_POST_OPT_EN       1u   /*     Include code for OSMboxPostOpt()                         */
#define OS_MBOX_QUERY_EN          1u   /*     Include code for OSMboxQuery()                           *//* --------------------- MEMORY MANAGEMENT -------------------- */
#define OS_MEM_EN                 0u   /* Enable (1) or Disable (0) code generation for MEMORY MANAGER */
#define OS_MEM_NAME_EN            1u   /*     Enable memory partition names                            */
#define OS_MEM_QUERY_EN           1u   /*     Include code for OSMemQuery()                            *//* ---------------- MUTUAL EXCLUSION SEMAPHORES --------------- */
#define OS_MUTEX_EN               0u   /* Enable (1) or Disable (0) code generation for MUTEX          */
#define OS_MUTEX_ACCEPT_EN        1u   /*     Include code for OSMutexAccept()                         */
#define OS_MUTEX_DEL_EN           1u   /*     Include code for OSMutexDel()                            */
#define OS_MUTEX_QUERY_EN         1u   /*     Include code for OSMutexQuery()                          *//* ---------------------- MESSAGE QUEUES ---------------------- */
#define OS_Q_EN                   0u   /* Enable (1) or Disable (0) code generation for QUEUES         */
#define OS_Q_ACCEPT_EN            1u   /*     Include code for OSQAccept()                             */
#define OS_Q_DEL_EN               1u   /*     Include code for OSQDel()                                */
#define OS_Q_FLUSH_EN             1u   /*     Include code for OSQFlush()                              */
#define OS_Q_PEND_ABORT_EN        1u   /*     Include code for OSQPendAbort()                          */
#define OS_Q_POST_EN              1u   /*     Include code for OSQPost()                               */
#define OS_Q_POST_FRONT_EN        1u   /*     Include code for OSQPostFront()                          */
#define OS_Q_POST_OPT_EN          1u   /*     Include code for OSQPostOpt()                            */
#define OS_Q_QUERY_EN             1u   /*     Include code for OSQQuery()                              *//* ------------------------ SEMAPHORES ------------------------ */
#define OS_SEM_EN                 0u   /* Enable (1) or Disable (0) code generation for SEMAPHORES     */
#define OS_SEM_ACCEPT_EN          1u   /*    Include code for OSSemAccept()                            */
#define OS_SEM_DEL_EN             1u   /*    Include code for OSSemDel()                               */
#define OS_SEM_PEND_ABORT_EN      1u   /*    Include code for OSSemPendAbort()                         */
#define OS_SEM_QUERY_EN           1u   /*    Include code for OSSemQuery()                             */
#define OS_SEM_SET_EN             1u   /*    Include code for OSSemSet()                               *//* --------------------- TIME MANAGEMENT ---------------------- */
#define OS_TIME_DLY_HMSM_EN       1u   /*     Include code for OSTimeDlyHMSM()                         */
#define OS_TIME_DLY_RESUME_EN     1u   /*     Include code for OSTimeDlyResume()                       */
#define OS_TIME_GET_SET_EN        1u   /*     Include code for OSTimeGet() and OSTimeSet()             */
#define OS_TIME_TICK_HOOK_EN      1u   /*     Include code for OSTimeTickHook()                        *//* --------------------- TIMER MANAGEMENT --------------------- */
#define OS_TMR_EN                 0u   /* Enable (1) or Disable (0) code generation for TIMERS         */
#define OS_TMR_CFG_MAX           16u   /*     Maximum number of timers                                 */
#define OS_TMR_CFG_NAME_EN        1u   /*     Determine timer names                                    */
#define OS_TMR_CFG_WHEEL_SIZE     8u   /*     Size of timer wheel (#Spokes)                            */
#define OS_TMR_CFG_TICKS_PER_SEC 10u   /*     Rate at which timer management task runs (Hz)            */#endif

在os_cpu.h 中定义一些必要的数据类型及CPU相关配置

#ifndef __OS_CPU_H__
#define __OS_CPU_H__#include <REGX52.H>#define OS_STK_GROWTH	    1u				   // 栈增长方向#define OS_CRITICAL_METHOD  0u				   // 不安全模式下#define OS_ENTER_CRITICAL() EA=0			   // 关中断
#define OS_EXIT_CRITICAL()  EA=1			   // 开中断#define OS_TASK_SW()        OSCtxSw()typedef unsigned char     BOOLEAN;
typedef unsigned char     INT8U;
typedef signed char       INT8S;
typedef unsigned int      INT16U;
typedef signed int        INT16S;
typedef unsigned long int INT32U;
typedef signed long int   INT32S;
typedef float 			  FP32;
typedef double            FP64;typedef INT8U             OS_STK;#endif

添加一个源文件os_cpu_c.c
在里面实现任务堆栈初始化函数OSTaskStkInit,以及一些系统必须的钩子。

#ifndef OS_MASTER_FILE
#include <ucos_ii.h>
#endifOS_STK *OSTaskStkInit(void (*task)(void *p_arg),void *p_arg,OS_STK *ptos,INT16U opt)
{OS_STK *stk = ptos;(void)(task);(void)(p_arg);(void)(opt);*stk++ = 16;                     // context length of task stack*stk++ = ((INT16U)task) & 0xff;  // low(task)*stk++ = ((INT16U)task) >> 8;    // HIGH(task)*stk++ = 0;                      // for push PSW*stk++ = 0;                      // for push ACC*stk++ = 0;                      // for push B*stk++ = 0;                      // for push DPL*stk++ = 0;                      // for push DPH*stk++ = 0;                      // for push R0*stk++ = ((INT16U)p_arg) & 0xff; // for push R1  LOW(p_arg)*stk++ = ((INT16U)p_arg) >> 8;   // for push R2  , HIGH(p_arg)*stk++ = 0x1;                    // for push R3   , type of ptr*stk++ = 0;                      // for push R4*stk++ = 0;                      // for push R5*stk++ = 0;                      // for push R6*stk++ = 0;                      // for push R7return ptos;
}void OSInitHookBegin(void) {}
void OSInitHookEnd(void) {}void OSTaskCreateHook(OS_TCB *ptcb) { (void)ptcb; }
void OSTaskDelHook(OS_TCB *ptcb) { (void)ptcb; }void OSTaskIdleHook(void) {}void OSTaskReturnHook(OS_TCB *ptcb) { (void)ptcb; }void OSTaskStatHook(void) {}void OSTCBInitHook(OS_TCB *ptcb) { (void)ptcb; }
void OSTimeTickHook(void) {}

添加四个源文件 os_cpu_asm_OSCtxSw.c,os_cpu_asm_OSIntCtxSw.c,os_cpu_asm_OSStartHighRdy.c,os_cpu_asm_OSTimerISR.c分别来实现OSCtxSw,OSIntCtxSw,OSStartHighRdy,OSTimerISR; 并且均配置生成RSC文件
在这里插入图片描述
到时个在生成的SRC文件上修改,要更加方便一点


在os_core.c 中可以看到以下代码

/*$PAGE*/
/*
*********************************************************************************************************
*                                          START MULTITASKING
*
* Description: This function is used to start the multitasking process which lets uC/OS-II manages the
*              task that you have created.  Before you can call OSStart(), you MUST have called OSInit()
*              and you MUST have created at least one task.
*
* Arguments  : none
*
* Returns    : none
*
* Note       : OSStartHighRdy() MUST:
*                 a) Call OSTaskSwHook() then,
*                 b) Set OSRunning to OS_TRUE.
*                 c) Load the context of the task pointed to by OSTCBHighRdy.
*                 d_ Execute the task.
*********************************************************************************************************
*/void  OSStart (void)
{if (OSRunning == OS_FALSE) {OS_SchedNew();                               /* Find highest priority's task priority number   */OSPrioCur     = OSPrioHighRdy;OSTCBHighRdy  = OSTCBPrioTbl[OSPrioHighRdy]; /* Point to highest priority task ready to run    */OSTCBCur      = OSTCBHighRdy;OSStartHighRdy();                            /* Execute target specific code to start task     */}
}

大致明白OSStartHighRdy 应该要实现什么
在os_cpu_asm_OSStartHighRdy.c写下

#include <REGX52.H>
#ifndef  OS_MASTER_FILE
#include <ucos_ii.h>
#endifvoid OSStartHighRdy(void){INT8U* stkptr;INT8U len;INT8U idx;INT8U dat;
#if OS_TASK_SW_HOOK_EN > 0uOSTaskSwHook();  
#endifOSRunning = OS_TRUE;stkptr = (INT8U*)(OSTCBHighRdy->OSTCBStkPtr);len = *(INT8U*)stkptr;for(idx = 0u + sizeof(len);idx < len; ++idx){dat = stkptr[idx];}
}

在keil里开启输出汇编
在这里插入图片描述
然后再SRC文件改一下,加入到工程中来
在这里插入图片描述

把任务堆栈映像到系统堆栈来,然后popall把系统堆栈里的内容恢复到CPU里面去,利用RETI指令跳转到任务函数中去。



现在编译一下,出现了 error C249: 'DATA': SEGMENT TOO LARGE,可以试着把编译内存模式改为大型
在这里插入图片描述


to be continue …


http://www.mrgr.cn/news/83566.html

相关文章:

  • 华纳云:在centos7中tomcat内存怎么设置?
  • 给DevOps加点料:融入安全性的DevSecOps
  • 解锁3D模型转换:STL转OBJ全攻略
  • Python的循环
  • 第34天:安全开发-JavaEE应用反射机制攻击链类对象成员变量方法构造方法
  • android分区和root
  • Redis高频知识点
  • 项目实战--网页五子棋(用户模块)(1)
  • wow-agent 学习笔记
  • 记一次sealos部署k8s集群之delete了第一台master如何恢复
  • LeetCode热题100-合并两个有序链表【JavaScript讲解】
  • 学习华为熵减,激发组织活力
  • LangChain 学习笔记 1 简介
  • Open FPV VTX开源之默认MAVLink设置
  • C#中的Array数组,List集合和ArrayList集合--07
  • Springboot——钉钉(站内)实现登录第三方应用
  • Day04-后端Web基础——Maven基础
  • Vue2+OpenLayers接入天地图API实现搜索定位和点击获取经纬度及地址功能(提供Gitee源码)
  • Oracle 使用dbms_stats.gather_table_stats来进行表analyse,收集表统计信息
  • FastApi Swagger 序列化问题
  • 2024 Java若依(RuoYi)框架视频教程(课件+示例代码+视频)
  • Mysql常见知识点
  • C#范围表达式,模式匹配,逆变和协变--11
  • 每日一题(二):判断一个字符串是否是另一个字符串的排列
  • Wireshark使用
  • 算法题(33):长度最小的子数组