zoukankan      html  css  js  c++  java
  • RL_RTX函数

    1 延时:os_itv_set(usFrequency) //设置延时周期,配合os_itv_wait使用;os_itv_wait() 是绝对延迟是包含调用前的时间, os_dly_wait() 是相对延迟 ,不包含调用前的时间
    二 调度方式:时间片调度,合作式调度;抢占式调度。
    2.1 时间片式调度:使能后对相同优先级(需指定时间片)的几个任务在时间片用完切换,或者遇到阻塞式API调用时间片没有用完也切换。

    2.2合作式调度:对相同优先级任务,若时间片调度被禁止则运行在合作式调度下,此时在遇到阻塞式API调用或者调用主动切换函数os_tsk_pass (),实际中不常用

    2.3抢占式调度:基于不同的任务优先级(被抢占)或者阻塞式API调用,对于重要的模块应用,响应时间快和任务何时被执行是确定的。

    三临界段 中断锁任务锁:为保证实时性,RTX不提供临界段操作和中断锁开关函数(与freertos/USOS不同),但用户可以通过给调度器上锁(任何中断都没有关闭)和关闭RTOS的内核定时器来禁止OS进行抢占式调度(也即任务锁),tsk_lock /unlock():不能再ISR中使用不支持嵌套、时间越短越好(和时间有关相关的时间片、延时都不再工作);
    使用场合:防止多任务同时调用一个函数(如printf)/共享的外设硬件如串口(多任务调用进行发送)

    四任务间同步和通讯:

    4.1事件标志组:可解决裸机程序下中断与任务间同步(flag)、多任务访问全局变量冲突(volitle)、任务超时(这个裸机程序下很复杂)问题。每个任务创建时有16个标志组。

        中断中要使用isr_evt_set ,不要在ISR中进行复杂的处理(消息解析处理)可将处理设置成优先级较高的任务(isr_evt_set 后可得到立即执行),M3/M4建议NVIC分组为4.os_evt_clr

    • os_evt_get、os_evt_set、os_evt_clr
    • os_evt_wait_and(flags,timeout),flags中16个位响应的bit同时置位。flags||timeout其一满足就返回,返回前已经设置的flags已经清零、os_evt_wait_or
    • isr_evt_set

    4.1信号量:可以用作任务间或任务与ISR间的同步,或者共享资源的管理(多少个资源占用初始值就等于几)。先定义一个信号量OS_SEM semaphore //是一个U32型的数组(2个元素)

    os_sem_init (semaphore,Val_fault)//初始化信号量,第一个参数可以是semaphore/&semaphore,用于同步时初始值为0,调用os_sem_wait时挂起知道其他地方xx_sem_send
    os_sem_send semaphore)
    isr_sem_send semaphore)
    os_sem_waitsemaphore)

    5 互斥信号量:对共享资源管理最重要的就是互斥量,用法和二进制信号量差不多(但逻辑刚好相反),互斥量初值为0,初始化后,先os_mut_wait (&mutex, 0xffff)//0XFFFF表示永久等待,若初值为0表示共享资源空闲

    可以使用,使用中时互斥量加1表示共享资源正被使用;使用完调用os_mut_release (&mutex);归还信号量(减一=0,以释放资源)

    五消息邮箱(队列):消息邮箱可以在ISR与任务或者任务间进行传递信息(传递的是地址而不是真实的内容),用消息邮箱而不直接用数组的原因:可支持超时,解决中断和任务间的同步,解决多任务间消息共享的冲突,FIFO便于消息的处理共有8个函数:


      os_mbx_declare :声明一个包含多少条消息的的邮箱,其实就是宏定义一个U32型的静态数组
      os_mbx_init:就是将定义的邮箱初始化成队列

      os_mbx_check :发消息前先检查是否已满,收消息前检查是否为空,任务间支持超时。
      os_mbx_send
      os_mbx_wait
      isr_mbx_check :中断中使用,不支持超时
      isr_mbx_receive
      isr_mbx_send

    六定时器组(用户定时器):使用方法:
    OS_ID  OneShotTimerID1/* 定时器句柄 */

    OneShotTimerID1= os_tmr_create (10, 1)//创建一个延时10个系统周期的定时器1,

    void os_tmr_call ( U16 info );    /*定时器回调函数的参数,可用于区分不同的定时器,用SWITCH进行处理*/,此函数在RTX_Conf_CM.c文件中,在其中支持ISR开头的APP函数调用,只支持单次定时器

    如果需要周期的,需要反复创建。

    七内存管理:ANSI中的内存分配容易造成内存碎片且执行的时间是不确定的,为了解决这个问题,RTX采用固定大小内存块的形式进行内存池的分配,操作上分4字节和8字节对其操作的API函数:
    #define _declare_box(  
        pool,          /* 内存池变量名 */
        size,          /* 内存块大小,单位字节 */
        cnt )          /* 内存池中内存块的个数 */
        U32 pool[((size+3)/4)*(cnt) + 3] //声明一个固定大小的n歌内存块相当于分配一个二维数组,多余的12字节是将内存块地址组成链表。

    #define _declare_box8(  
        pool,          /* 内存池变量名 */
        size,          /* 内存块大小,单位字节 */
        cnt )          /* 内存池中内存块的个数 */
        U64 pool[((size+7)/8)*(cnt) + 2]

    _init_box_init_box/_init_bo/_init_box _init_box_init_box8 (mpool, sizeof (mpool), PoolPerBlockSize) //将其形成链表

    void *_alloc_box ( void* box_mem )

    int _free_box (   mpool  mpool,    /* 内存池首地址 */     void* box );      /* 要释放的内存块首地址 */

    八 SVC调用用户函数:运行在用户非特权模式下的APP是不能操作有关内核硬件的寄存器,若需要操作只能通过SVC触发进入特权级模式下在修改。使用方法:

    第1步:添加SVC_Table.s文件

    第2步:使用属性__svc(x)声明函数,x从1开始,范围1-255。函数名随便命名,但是x的数值一
    定要保证是连续递增的。
    void __svc(1)  SVC_1_FunCall(uint8_t _arg1, uint16_t _arg2, uint32_t _arg3, uint64_t *_arg4);
    void __svc(2)  SVC_2_FunCall(void);

    第3步:写__SVC_x的实际函数(统一改成这种命名方式是为了跟RTX系统的调用方式__SVC_0统一)

     第4步:将定义的两个函数添加到SVC_Table.s文件里面
    首先使用IMPORT 命令声明下,类似C语言中的extern。然后添加到SVC_Table列表下,整体添加
    后的效果如下(红色字体是用户添加的):
                    AREA    SVC_TABLE, CODE, READONLY
     
                    EXPORT  SVC_Count
     
    SVC_Cnt         EQU    (SVC_End-SVC_Table)/4
    SVC_Count       DCD     SVC_Cnt
     
    ; Import user SVC functions here.
            IMPORT  __SVC_1
            IMPORT  __SVC_2
     
                    EXPORT  SVC_Table
    SVC_Table
    ; Insert user SVC functions here. SVC 0 used by RTL Kernel.
                   DCD     __SVC_1                 ; user SVC function
           DCD     __SVC_2                 ; user SVC function
     
    SVC_End
     
                    END

    至此,RTX中SVC中断的调用就实现了。实际应用的时候,用户只需调用函数SVC_1_FunCall和
    SVC_1_FunCall即可,这两个函数就是在SVC中断里面实现的

    九用独立看门狗检测多任务的执行:通过创建一个高优先级的看门狗监视任务,其它所有低优先级的任务通过事件标志组都给看门狗任务发通知,都收到后才进行喂狗操作,否则不喂狗就发生复位,需要注意的是,看门狗复位的时间应该比所有任务触发标志组的时间长一些

    十 RTX下的低功耗:根据最低功耗,最快启动时间、可使用的唤醒中断从睡眠、停止、待机模式(1.8V电源域关闭,进入后SRAM和寄存器内容丢失。
    只有备份的寄存器和待机电路维持供电通过外WKUP 引脚上升沿、RTC闹钟(闹钟A和闹钟B)、RTC唤
    醒事件、RTC入侵事件、RTC 时间戳事件、NRST引脚外部复位和IWDG 复位,唤醒后除了电源控制盒状态寄存器所有寄存器复位)中选择一种。在初始化时选择DBGMCU_Config(DBGMCU_SLEEP,ENABLE) 或者 DBGMCU_Config(DBGMCU_STOP, ENABLE)或者PWR_EnterSTANDBYMode,在空闲任务中执行_WFI/WFE进入低功耗模式,唤醒源唤醒(停止模式下sram、所有寄存器、IO状态都保留,唤醒后使用HSI时钟,如果选择HSE则需要进行重新的初始化系统时钟)。待机模式:初始化时RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);   
      /* 使能WKUP 引脚PA0,用于将系统从待机模式唤醒 */
      PWR_WakeUpPinCmd(ENABLE);进入可通过PWR_EnterSTANDBYMode();  唤醒可通过WakeupPIN

    10.1RTX提供的TICKNESS的方法:在空闲任务中计算到下一个最高优先级任务的时间,然后设置一个RTC闹钟中断(时间就是计算出来的时间),然后进入停机模式。。。,RTC闹钟中断先执行RTC的ISR,然后执行停机模式后面的代码,系统时钟初始化,详细见安富莱低功耗模式tickness.

  • 相关阅读:
    javaee_正则表达式基础和常用表达式
    hello2源代码分析
    servlet_filterj简介
    hello1的web.xml解析
    Annotation
    注入(Injection)
    容器(Container)
    Building Tool(Maven/Gradle)
    JavaWeb的历史与发展趋势
    Build Tools
  • 原文地址:https://www.cnblogs.com/jieruishu/p/9378990.html
Copyright © 2011-2022 走看看