本文将详细解释编写ISR的基本原则。边肖觉得挺实用的,就分享给大家参考。希望你看完这篇文章能有所收获。
写ISR的基本原则是:越短越好。一方面,代码不太重要。更重要的是,ISR不能调用可能会阻塞或延迟的操作。
因为ISR不在正常任务上下文中运行,也没有TCB,所以所有ISR共享一个堆栈(ISR_STACK_SIZE)。因此,ISR不能调用可能阻塞的函数。比如他们不能申请信号量,因为当信号量不可用时,内核会尝试将申请人切换到阻塞状态;但是,ISR可以释放信号量。此外,内存机制malloc()和free()使用信号量,因此ISR无法调用这些函数和任何Create或Delete机制。ISR无法通过VxWorks驱动程序执行输入输出。尽管在输入/输出系统中没有固定的限制,但大多数设备驱动程序需要任务上下文,因为它们可能会等待设备的反馈。一个重要的例外是VxWorks的Pipe机制,ISR可以用它来编写。ISR还可以调用一些VxWorks机制将消息打印到系统控制台:logMsg()、kprintf()和kputs()。
ISR无法使用浮点协处理器调用该机制。这是因为在VxWorks中,由intConnect()创建的中断驱动程序代码不保存和恢复浮点寄存器。如果ISR必须使用浮点指令,则需要使用fppArchLib中的函数显式保存和恢复浮点协处理器的寄存器。
在ISR中调用C语句时要非常小心。intConnect()机制要求中断发生时要执行的函数的地址,但不能使用非静态成员函数的地址,因此必须实现静态成员函数。并且您不能在ISR代码中实例化或删除对象。在ISR中执行的C代码应仅限于嵌入式C,不应使用异常或RTTI(运行时类型标识)。
ISR不应直接访问共享数据区。ISR继承它抢占的任务的内存上下文。如果任务没有映射共享数据区,它将无法访问内存并导致异常。为了可靠地访问共享数据区,ISR可以对映射共享数据区的任务进行相关操作。
那么在ISR中可以调用哪些机制或功能呢?
bLib
所有功能
errnoLib
errnoGet(),errnoSet()
事件库
事件发送()
fppArchLib
fppSave(),fppRestore()
intLib
intContext()、intCount()、intVecSet()、intVecGet()
intArchLib
intLock(),intUnlock()
logLib
日志消息()
lstLib
除lstFree()之外的所有功能
d>
mathALib
使用fppSave()/fppRestore()时,所有函数
msgQLib
msgQSend()
rngLib
除rngCreate()/rngDelete(),所有函数
pipeDrv
write()
selectLib
selWakeup(), selWakeupAll()
semLib
semFlush(),非互斥信号量的semGive()
semPxLib
sem_post()
sigLib
kill()
taskLib
taskSuspend(), taskResume(), taskPrioritySet(), taskPriorityGet(), taskIdVerify(), taskIdDefault(), taskIsReady(), taskIsSuspended(), taskIsPended(), taskIsDelayed(), taskTcb()
tickLib
tickAnnounce(), tickSet(), tickGet()
tyLib
tyIRd(), tyITx()
vxLib
vxTas(), vxMemProbe()
wdLib
wdStart(), wdCancel()
中断到任务的通信机制
-
共享内存。ISR可以与任务代码共享变量、缓冲区和环形缓冲区
-
信号量。ISRs可以释放信号量,任务可以接收或等待这些信号量(互斥信号量和VxMP共享信号量除外)
-
消息队列。ISR可以向消息队列发送消息(使用VxMP的共享消息队列除外)。如果队列已满,则丢弃该消息。msgQSend (msgQId, buffer, nBytes, NO_WAIT,priority)
-
管道。ISR可以向管道发送消息。如果管道已满,则丢弃该消息
-
信号。ISR可以向任务发送信号,从而导致其信号处理程序的异步调度
-
VxWorks Event。ISR可以向任务发送VxWorks Event
关于“编写ISR最基本的原则是什么”这篇文章就分享到这里了,希望
内容来源网络,如有侵权,联系删除,本文地址:https://www.230890.com/zhan/155163.html