Nucleus 实时操作系统中断(上)

Interrupts in the Nucleus SE RTOS

所有现代微处理器和微控制器都有某种中断设施。这种能力对于提供许多应用程序所需的响应能力是必不可少的。当然,响应性和可预测性也是使用实时操作系统背后的一个关键目标,因此这两个主题确实存在轻微的冲突。使用中断可能会损害操作系统的实时完整性。这一主题,以及冲突的解决方法,目前不讲。在这里,我们将了解Nucleus SE使用的中断处理策略。

在所有情况下,中断都不是由Nucleus SE控制的,它们是在中断发生时根据优先级进行处理的,并以通常的方式进行矢量化。它们的执行时间只是从运行主线应用程序代码和调度程序的可用时间中“偷走”的。显然,这意味着所有的中断服务程序都应该简单、简短和快速。

本机中断和托管中断

Nucleus SE确实提供了两种处理中断的方法:“本机”中断服务例程没有什么特别的,并且与操作系统交互的机会有限(至少在选择优先级调度器时是这样);“托管”中断服务例程可以进行更广泛的API调用。

通过一些进入/退出宏,与Nucleus SE应用程序一起使用的中断服务例程可以被指定为本机或托管的。

本机中断

Nucleus SE本机中断是标准的中断服务例程,您可以将其视为“非托管的”。当am中断可能以很高的频率发生并且需要以非常低的开销进行服务时,通常使用它们。由于许多现代嵌入式编译器都支持通过interrupt关键字编写中断服务例程,所以这个例程很可能是用C编写的。唯一保存的上下文信息是编译器认为必要的信息。这导致本机中断例程可以执行的操作有很大的限制,我们将很快看到。

要构造Nucleus SE本机中断服务例程,只需按通常的方式编写ISR,包括在开始时调用NUSE_NISR_Enter()宏,在末尾调用NUSE_NISR_Exit()。这些宏在nuse_types.h中定义,只需将全局变量nuse_Task_State设置为nuse_NISR_CONTEXT。

托管中断

如果您需要在ISR可以执行的操作方面有更大的灵活性,Nucleus SE管理的中断可能是解决方案。与本机中断的关键区别是上下文保存。托管中断不仅仅允许编译器堆叠几个寄存器,而是在输入时保存完整的任务上下文(在上下文块中)。然后从当前任务的上下文块中加载当前任务的上下文。这考虑到了当前任务可能被ISR代码的操作改变的可能性;当优先级调度器正在使用时,这是完全可能的。包含了对Nucleus SE上下文保存和恢复的完整描述。

显然,完整的上下文保存比由本机中断执行的几个寄存器的堆栈开销更高。这是额外灵活性的代价,也是为什么可以选择处理中断的方法的原因。

托管中断是使用NUSE_managed_ISR()宏构造的,该宏在NUSE_types.h中定义。此宏构造包含以下序列的函数:

  • task context save
  • set NUSE_Task_State to NUSE_MISR_CONTEXT
  • call user-supplied ISR code function
  • restore NUSE_Task_State to previous setting
  • task context restore

宏接受两个参数:中断的名称,用作构造的例程的函数名;包含用户提供的ISR逻辑的函数名。

本文后面将介绍Nucleus SE实时时钟ISR,它是受管ISR的一个示例。

中断服务例程的API调用

可以从本机或托管ISR调用的API函数的范围取决于选择了哪个调度程序。一般来说,优先级调度程序的使用为在API函数调用的结果下调用调度程序提供了许多机会,这在本机ISR中是一个问题。

使用优先级调度程序从本机ISR调用API

允许使用优先级调度程序从本机ISR调用有限范围的API函数。这一限制是由于Nucleus SE API的灵活性造成的–许多调用都会导致任务准备就绪,并且本地ISR不可能调用调度器(因为任务上下文未被保存)。如果不启用任务阻塞,则具有更大的灵活性。

始终允许以下API调用:

NUSE_Task_Current()

NUSE_Task_Check_Stack()

NUSE_Task_Information()

NUSE_Task_Count()

NUSE_Partition_Pool_Information()

NUSE_Partition_Pool_Count()

NUSE_Mailbox_Information()

NUSE_Mailbox_Count()

NUSE_Queue_Information()

NUSE_Queue_Count()

NUSE_Pipe_Information()

NUSE_Pipe_Count()

NUSE_Semaphore_Information()

NUSE_Semaphore_Count()

NUSE_Event_Group_Information()

NUSE_Event_Group_Count()

NUSE_Signals_Send()

NUSE_Timer_Control()

NUSE_Timer_Get_Remaining()

NUSE_Timer_Reset()

NUSE_Timer_Information()

NUSE_Timer_Count()

NUSE_Clock_Set()

NUSE_Clock_Retrieve()

NUSE_Release_Information()

但是,唯一真正有用的是NUSE_Signals_Send(),因为这提供了一个很好的方法来指示任务需要一些工作。

如果禁用了阻塞(这意味着许多API调用可能无法使任务就绪),则可以使用许多其他API函数:

NUSE_Partition_Allocate()

NUSE_Partition_Deallocate()

NUSE_Mailbox_Send()

NUSE_Mailbox_Receive()

NUSE_Mailbox_Reset()

NUSE_Queue_Send()

NUSE_Queue_Receive()

NUSE_Queue_Jam()

NUSE_Queue_Reset()

NUSE_Pipe_Send()

NUSE_Pipe_Receive()

NUSE_Pipe_Jam()

NUSE_Pipe_Reset()

NUSE_Semaphore_Obtain()

NUSE_Semaphore_Release()

NUSE_Semaphore_Reset()

NUSE_Event_Group_Set()

NUSE_Event_Group_Retrieve()

但是,唯一真正有用的是NUSE_Signals_Send(),因为这提供了一个很好的方法来指示任务需要一些工作。

如果禁用了阻塞(这意味着许多API调用可能无法使任务就绪),则可以使用许多其他API函数:

NUSE_Task_Suspend()

NUSE_Task_Resume()

NUSE_Task_Sleep()

NUSE_Task_Relinquish()

NUSE_Task_Reset()

NUSE_Signals_Receive()

来自托管ISR或具有非优先级调度程序的本机ISR的API调用

当使用run-to-completion、round-robin或time-sliced调度器时,可以从ISR调用范围更广的API函数。如果使用类似的ISR优先级,则受管调度器有助于提高ISR的优先级。这是因为允许调用可能导致调度不同的任务。NUSE_Reschedule()中的代码有助于此功能,该代码检测调用的上下文是ISR,并禁止上下文切换(允许它在ISR结束时发生)。调度程序操作的完整细节在前面的一篇文章中介绍过。

一个关键的要求是ISR中的API调用不能导致当前任务的挂起,例如等待一个资源。换句话说,这种调用应该在suspend选项设置为NUSE_NO_suspend的情况下进行。

鉴于此规定,可使用以下API调用:

NUSE_Task_Current()

NUSE_Task_Check_Stack()

NUSE_Task_Information()

NUSE_Task_Count()

NUSE_Task_Suspend()

NUSE_Task_Resume()

NUSE_Task_Reset()

NUSE_Partition_Allocate()

NUSE_Partition_Deallocate()

NUSE_Partition_Pool_Information()

NUSE_Partition_Pool_Count()

NUSE_Mailbox_Send()

NUSE_Mailbox_Receive()

NUSE_Mailbox_Reset()

NUSE_Mailbox_Information()

NUSE_Mailbox_Count()

NUSE_Queue_Send()

NUSE_Queue_Receive()

NUSE_Queue_Jam()

NUSE_Queue_Reset()

NUSE_Queue_Information()

NUSE_Queue_Count()

NUSE_Pipe_Send()

NUSE_Pipe_Receive()

NUSE_Pipe_Jam()

NUSE_Pipe_Reset()

NUSE_Pipe_Information()

NUSE_Pipe_Count()

NUSE_Semaphore_Obtain()

NUSE_Semaphore_Release()

NUSE_Semaphore_Reset()

NUSE_Semaphore_Information()

NUSE_Semaphore_Count()

NUSE_Event_Group_Set()

NUSE_Event_Group_Retrieve()

NUSE_Event_Group_Information()

NUSE_Event_Group_Count()

NUSE_Signals_Send()

NUSE_Timer_Control()

NUSE_Timer_Get_Remaining()

NUSE_Timer_Reset()

NUSE_Timer_Information()

NUSE_Timer_Count()

NUSE_Clock_Set()

NUSE_Clock_Retrieve()

NUSE_Release_Information()

一些API调用是不允许的,因为它们与当前任务相关:

NUSE_Task_Relinquish()

NUSE_Signals_Receive()

NUSE_Task_Sleep()

实时时钟ISR

实时时钟(RTC)ISR是Nucleus SE提供的唯一完整的中断服务例程。除了为Nucleus SE提供所有所需的定时功能外,它还可以作为如何编写受管中断的示例。

RTC ISR操作

RTC ISR提供的设施已在前面的一篇文章中概述,其中涵盖了Nucleus SE中的系统时间这一广泛主题。根据应用程序的配置方式,所有功能都是可选的。这是RTC ISR的完整代码。

#if NUSE_TIMER_NUMBER != 0

{

      U8 timer;

      for (timer=0; timer

<nuse_timer_number; timer++)="">     
{

            if
(NUSE_Timer_Status[timer])

            {

                  
   if (–NUSE_Timer_Value[timer] == 0)

                 
{

                       
NUSE_Timer_Expirations_Counter[timer]++;

                       
#if NUSE_TIMER_EXPIRATION_ROUTINE_SUPPORT ||

                           
NUSE_INCLUDE_EVERYTHING

                          
if (NUSE_Timer_Expiration_Routine_Address[timer]

                              
!= NULL)

                          
{

                             
((PF1)NUSE_Timer_Expiration_Routine_Address[timer])

                              
NUSE_Timer_Expiration_Routine_Parameter[timer]);

                          
}

                       
#endif

                       
/* reschedule? */

              
             if
(NUSE_Timer_Reschedule_Time[timer] != 0)

              
             {                   
/* yes: set up time */

                             
NUSE_Timer_Value[timer] =

                                
NUSE_Timer_Reschedule_Time[timer];

                       
}

                       
else

                       
{                   
/* no: disable */

                             
NUSE_Timer_Status[timer] = FALSE;                              

                       
}

                
 }

            }

      }

}

#endif

#if NUSE_SYSTEM_TIME_SUPPORT || NUSE_INCLUDE_EVERYTHING

   NUSE_Tick_Clock++;

#endif

#if NUSE_TASK_SLEEP || NUSE_INCLUDE_EVERYTHING

{

      U8 task;

      for (task=0; task

<nuse_task_number; task++)="">      {

            if (NUSE_Task_Timeout_Counter[task]
!= 0)

            {

              
   NUSE_Task_Timeout_Counter[task]–;

                 
if (NUSE_Task_Timeout_Counter[task] == 0)

                 
{

             
          NUSE_Wake_Task(task);

                 
}

            }

      }

}

#endif

#if NUSE_SCHEDULER_TYPE == NUSE_TIME_SLICE_SCHEDULER

    if (–NUSE_Time_Slice_Ticks == 0)

    {

          NUSE_Reschedule();

    }

#endif

我们将研究RTC ISR的四个功能领域:

计时器

如果配置了任何应用程序计时器,ISR将通过递减其计数器值来循环为每个计时器提供服务。如果计时器过期(即计数器达到零),则两个操作将生效:

如果配置了计时器过期例程,并且计时器具有指向函数的有效(非空)指针(在NUSE_timer_expiration_Routine_Address[]),则执行例程,并从NUSE_timer_expiration_Routine_parameter[]接收参数。

如果计时器有一个重定时时间(即NUSE_timer_reschedule_time[]中的非零值),则计时器将重新加载该值。

应用程序计时器在上一篇文章中有更详细的描述。

系统时钟

如果配置了系统时钟,那么NUSE_Tick_clock的值只会递增。关于系统时间的进一步讨论可以在上一篇文章中找到。

任务睡眠

如果启用了任务休眠(即配置了API调用NUSE_task_sleep()),则会检查每个任务的超时计数器(NUSE_task_timeout_counter[]中的条目),如果不是零,则递减。如果任何计数器达到零,则相应的任务将被唤醒。

时间片调度

如果正在使用时间片调度程序,则时间片计数器(NUSE_time_slice_Ticks)将递减。如果达到零,则调用调度程序。对NUSE_Reschedule()的调用负责重置计数器。

有管理的中断

对RTC ISR是受管中断的原因进行一些解释可能是有用的,因为在正确的情况下,用户可能希望将其重新编码为本机中断,以减少开销。例如,如果只使用系统时间工具(即没有应用程序计时器、没有任务睡眠和时间片调度器),则本机中断就可以了。管理中断的需求如下:

如果使用了计时器并配置了过期例程,这些例程可能会(从中断上下文)进行API调用,从而导致重新调度。它们受到与从isr发出的API调用相同的限制(请参阅本章前面的部分)。

如果优先级调度程序正在使用中,任务休眠到期可能需要调度更高优先级的任务。

如果正在使用时间片调度程序,它肯定会从RTC ISR调用,因此必须使用托管中断。

Nucleus 实时操作系统中断(上)的更多相关文章

  1. Nucleus 实时操作系统中断(下)

    Nucleus 实时操作系统中断(下) Nucleus RTOS兼容性 由于中断在Nucleus SE中的实现方式与Nucleus rto截然不同,因此不应期望有特定的兼容性.Nucleus RTOS ...

  2. dsp5509的中断系统

    1. DSP5509有32个中断,中断分为软件中断和硬件中断,同时软件中断不可以屏蔽.软件中断由指令触发.55x在中断时DSP会自动保存ST0_55.ST1_55.ST2_55三个寄存器. 2. 其中 ...

  3. Nucleus PLUS的启动、执行线程和中断处理

    nucleus系统是实时嵌入式操作系统,具有实时.任务抢先.多任务内核,当中95%的代码由C语言写成,极易移植.开放的源代码使得配置和裁剪方便,再加上体积小(所有二进制映像可仅20K).响应高速等特性 ...

  4. Nucleus PLUS简单介绍

    近些年来,随着嵌入式系统飞速的发展,嵌入式实时操作系统广泛地应用在制造工业.过程控制.通讯.仪器仪表.汽车.船舶.航空航天.军事.装备.消费类产 品等方面.今天嵌入式系统带来的工业年产值超过了1万亿美 ...

  5. S3C2440上RTC时钟驱动开发实例讲解(转载)

    嵌入式Linux之我行,主要讲述和总结了本人在学习嵌入式linux中的每个步骤.一为总结经验,二希望能给想入门嵌入式Linux的朋友提供方便.如有错误之处,谢请指正. 共享资源,欢迎转载:http:/ ...

  6. Hadoop生态上几个技术的关系与区别:hive、pig、hbase 关系与区别

    初接触Hadoop技术的朋友肯定会对它体系下寄生的个个开源项目糊涂了,我敢保证Hive,Pig,HBase这些开源技术会把你搞的有些糊涂,不要紧糊涂的不止你一个,如某个菜鸟的帖子的疑问,when to ...

  7. 【翻译】运行于x86机器上的FreeBSD的PCI中断

    来源 http://people.freebsd.org/~jhb/papers/bsdcan/2007/article/article.html 摘要 在拥有多个独立设备的计算机里一个重要的元素是一 ...

  8. 系统中断与SA_RESTART

    今天在调试程序时,sem_timedwait居然返回了一个Interrupted system call,错误码为EINTR.系统中断这东西我一向只闻其名,不见其"人",不想今天遇 ...

  9. MCS-51系统中断优先级的软扩展

    摘要:鉴于MCS-51系统只提供“二级中断嵌套”,提出扩展51系统中断优先级的纯软件方法.其利用51系统内建的中断允许寄存器IE和中断优先级寄存器IP,通过屏蔽字机制来实现:以C51的形式,给出这种扩 ...

随机推荐

  1. hdu5033 最大仰望角

    题意:       给你n个楼房排成一条直线,楼房可以看成是宽度为1的线段,然后给你m组询问,每组询问给你一个坐标,输出在当前坐标仰望天空的可视角度. 思路:       n比较大,O(n*m)肯定跪 ...

  2. 基于react hooks,antd4 配置生成表单并自动排列

    react后台项目,大多都是表单处理,比如下列4种常见1*n布局 (如果手工编码,大量的Row,Col, Form.Item的嵌套,排列,如果加上联动处理,代码将十分臃肿,不易维护) 一行一列 一行两 ...

  3. 【js】Leetcode每日一题-解码异或后数组

    [js]Leetcode每日一题-解码异或后数组 [题目描述] 未知 整数数组 arr 由 n 个非负整数组成. 经编码后变为长度为 n - 1 的另一个整数数组 encoded ,其中 encode ...

  4. sql常识-RIGHT JOIN

    SQL RIGHT JOIN 关键字 RIGHT JOIN 关键字会右表 (table_name2) 那里返回所有的行,即使在左表 (table_name1) 中没有匹配的行. RIGHT JOIN ...

  5. 多变量高斯(MVN)概率建模的两种方案

    摘要:在我们的时序异常检测应用中,设计了对时序数据进行多变量高斯(MVN)建模的算法方案进行异常检测,本文对基于tensorflow的两种MVN建模方案进行了总结. 1.基于custom choles ...

  6. 使用TK框架中selectByPrimaryKey

    使用TK框架中selectByPrimaryKey(Object key),需要注意要在entity里注明哪个字段是主键,否则会不知道哪个是PrimaryKey会随机一个字段就报错. 如下: 引入 i ...

  7. 23.Quick QML-简单且好看的图片浏览器-支持多个图片浏览、缩放、旋转、滑轮切换图片

    之前我们已经学习了Image.Layout布局.MouseArea.Button.GroupBox.FileDialog等控件. 所以本章综合之前的每章的知识点,来做一个图片浏览器,使用的Qt版本为Q ...

  8. JavaWeb——JDBC

    内容索引 1. JDBC基本概念 2. 快速入门 3. 对JDBC中各个接口和类详解 JDBC: 1. 概念:Java DataBase Connectivity Java 数据库连接, Java语言 ...

  9. 腾讯云原生混合云-第三方集群弹EKS应对突发流量的利器

    作者 何鹏飞,腾讯云专家产品经理,曾作为容器私有云.TKEStack的产品经理兼架构师,参与腾讯云内部业务.外部客户容器化改造方案设计,目前负责云原生混合云产品方案设计工作. 胡晓亮,腾讯云专家工程师 ...

  10. CRM的未来发展前景有哪些?

    随着时代的发展,近年来越来越多的国内中小企业开始采用CRM客户关系管理系统,CRM从此不再是大企业的专利,也开始让中小企业得以不断成长.国内CRM行业的发展越来越快, 它的前景是什么?今天小Z就来给大 ...