vxWorks中系统任务tIsr的实现及使用

2024-05-13 04:38

本文主要是介绍vxWorks中系统任务tIsr的实现及使用,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

tIsr作为一个系统任务,看其注释,知道其有两种使用方式:

This module operates in two distinct modes depending on the module's
configuration.  If the mode is configured for "per-CPU" deferral
tasks, this module creates (as needed) a single deferral task on each
CPU in the system.  This single queue handles all deferral operations
performed by device drivers that are servicing their interrupts on
that CPU.

If the mode is configured for "per-ISR" deferral tasks, this module
creates a unique deferral task for each requester, and sets the CPU
affinity for the created task to the requested CPU index.

这个任务具体做什么任务呢?
举一个例子:
ns16550vxInt串口中断处理函数中使用到了。
当这个串口处理函数去读取这个串口中的值时,如果出现了超时没有读取完成的情况,就会把这个中断函数延后执行。

LOCAL void ns16550vxbInt(VXB_DEVICE_ID pDev){FAST NS16550VXB_CHAN * pChan = (NS16550VXB_CHAN *)(pDev->pDrvCtrl);    /* pointer to channel */FAST volatile char        intStatus;UINT8   iirValue, lsrValue;while ( pChan != NULL ){VXB_NS16550_ISR_SET(pChan);switch (intStatus){case IIR_RLS:REG_GET(LSR, pChan, lsrValue);/*read LSR to reset interrupt */intStatus = (char)lsrValue;break;case IIR_RDA:           /* received data available */case IIR_TIMEOUT:{pChan->ier &= ~(RxFIFO_BIT); /* indicate to disable Rx Int */REG_SET(IER, pChan, pChan->ier);VXB_NS16550_ISR_CLEAR(pChan);/*把这个任务延后,继续处理下一个,剩下的任务交给tIsr系统任务执行*/isrDeferJobAdd (pChan->queueId, &pChan->isrDefRd);goto nextChan;}........
}

这相当于就是把一个中断上下文转换为任务上下文来继续执行。
初始化过程

usrRoot--->usrIosCoreInit--->usrIsrDeferInit--->isrDeferLibInit

STATUS isrDeferLibInit(int		mode			/* global deferral queue mode */){
/*记录要使用的模式*/isrDeferLibMode = mode;
/*如果是ISR_DEFER_MODE_PER_CPU模式,就为每一个cpu创建一个队列,来处理这个cpu上所有的延后函数*/if (isrDeferLibMode == ISR_DEFER_MODE_PER_CPU){pCpuQueueId = (ISR_DEFER_QUEUE_ID *) calloc (vxCpuConfiguredGet (),sizeof(*pCpuQueueId));if (pCpuQueueId == NULL)return ERROR;}return OK;}
/*创建处理延后队列函数*/
LOCAL ISR_DEFER_QUEUE * isrDeferQueueCreate(VXB_DEVICE_ID	pInst,	        /* VxBus device id of requester */int			intIdx,	        /* interrupt source index */int			logicalCpuIndex	/* logical CPU index for deferral task */){char taskName[32];char *pT;cpuset_t affinity;ISR_DEFER_QUEUE *pQueue = malloc(sizeof(*pQueue));lstInit (&pQueue->list);semBInit (&pQueue->syncSem, SEM_Q_PRIORITY, SEM_EMPTY);SPIN_LOCK_ISR_INIT (&pQueue->lock, 0);/*根据不同的cpu号,设置一个独一无二的名字,cpu0---tIsr0,cpu1---tIsr1*/strcpy (taskName, "tIsr");pT = taskName + 4;if (pInst == NULL)  /* use CPU index only */{*pT++ = '0' + logicalCpuIndex % 10;*pT   = '\0';}else  /* use device unit number and interrupt index */{*pT++ = '0' + pInst->unitNumber % 10;*pT++ = '0' + intIdx % 10;strcpy (pT, pInst->pName);}/*创建对应处理的系统任务*/pQueue->tid = taskSpawn (taskName,ISR_DEFER_TASK_PRIO,ISR_DEFER_TASK_OPTS,8192, (FUNCPTR) isrDeferTask,(int) pQueue, 0, 0, 0, 0, 0, 0, 0, 0, 0);.....}
/*具体的处理函数*/
LOCAL void isrDeferTask (ISR_DEFER_QUEUE_ID queueId	/* queue for incoming deferred work */){ISR_DEFER_JOB *pJob;
/*死循环,一直等待任务的到来*/FOREVER{semBTake (&queueId->syncSem, WAIT_FOREVER);
/*获取任务,并执行*/FOREVER{SPIN_LOCK_ISR_TAKE (&queueId->lock);pJob = (ISR_DEFER_JOB *) lstGet  (&queueId->list);SPIN_LOCK_ISR_GIVE (&queueId->lock);pJob->func (pJob->pData);}}}


/*把一个任务添加到延迟队列上来*/
void isrDeferJobAdd(ISR_DEFER_QUEUE_ID queueId,	/* queue allocated by isrDeferQueueGet */ISR_DEFER_JOB *    pJob	/* job to enqueue */){SPIN_LOCK_ISR_TAKE (&queueId->lock);lstAdd (&queueId->list, &pJob->node);SPIN_LOCK_ISR_GIVE (&queueId->lock);/*添加完成后,通知isrDeferTask有任务到来了*/semGive (&queueId->syncSem);}/*从队列获取一个任务*/
ISR_DEFER_QUEUE_ID isrDeferQueueGet(VXB_DEVICE_ID  pInst,	           /* VxBus device ID of requester */int		   intIdx,	            /* interrupt source index */int		   logicalCpuIndex, /* logical CPU index for deferral task */int		   mode	            /* deferral queue mode(for future use) */){
/*如果是ISR_DEFER_MODE_PER_CPU模式,就返回对应cpu的那个队列*/if (isrDeferLibMode == ISR_DEFER_MODE_PER_CPU){if (pCpuQueueId [logicalCpuIndex] == NULL)pCpuQueueId [logicalCpuIndex] = isrDeferQueueCreate (0, 0, logicalCpuIndex);return pCpuQueueId [logicalCpuIndex];}
/*如果是另一种模式,就创建这个设备对应的队列*/return isrDeferQueueCreate (pInst, intIdx, logicalCpuIndex);}



这篇关于vxWorks中系统任务tIsr的实现及使用的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/984706

相关文章

使用DeepSeek API 结合VSCode提升开发效率

《使用DeepSeekAPI结合VSCode提升开发效率》:本文主要介绍DeepSeekAPI与VisualStudioCode(VSCode)结合使用,以提升软件开发效率,具有一定的参考价值... 目录引言准备工作安装必要的 VSCode 扩展配置 DeepSeek API1. 创建 API 请求文件2.

使用TomCat,service输出台出现乱码的解决

《使用TomCat,service输出台出现乱码的解决》本文介绍了解决Tomcat服务输出台中文乱码问题的两种方法,第一种方法是修改`logging.properties`文件中的`prefix`和`... 目录使用TomCat,service输出台出现乱码问题1解决方案问题2解决方案总结使用TomCat,

解决IDEA使用springBoot创建项目,lombok标注实体类后编译无报错,但是运行时报错问题

《解决IDEA使用springBoot创建项目,lombok标注实体类后编译无报错,但是运行时报错问题》文章详细描述了在使用lombok的@Data注解标注实体类时遇到编译无误但运行时报错的问题,分析... 目录问题分析问题解决方案步骤一步骤二步骤三总结问题使用lombok注解@Data标注实体类,编译时

Java中使用Java Mail实现邮件服务功能示例

《Java中使用JavaMail实现邮件服务功能示例》:本文主要介绍Java中使用JavaMail实现邮件服务功能的相关资料,文章还提供了一个发送邮件的示例代码,包括创建参数类、邮件类和执行结... 目录前言一、历史背景二编程、pom依赖三、API说明(一)Session (会话)(二)Message编程客

Java中List转Map的几种具体实现方式和特点

《Java中List转Map的几种具体实现方式和特点》:本文主要介绍几种常用的List转Map的方式,包括使用for循环遍历、Java8StreamAPI、ApacheCommonsCollect... 目录前言1、使用for循环遍历:2、Java8 Stream API:3、Apache Commons

C++中使用vector存储并遍历数据的基本步骤

《C++中使用vector存储并遍历数据的基本步骤》C++标准模板库(STL)提供了多种容器类型,包括顺序容器、关联容器、无序关联容器和容器适配器,每种容器都有其特定的用途和特性,:本文主要介绍C... 目录(1)容器及简要描述‌php顺序容器‌‌关联容器‌‌无序关联容器‌(基于哈希表):‌容器适配器‌:(

C#提取PDF表单数据的实现流程

《C#提取PDF表单数据的实现流程》PDF表单是一种常见的数据收集工具,广泛应用于调查问卷、业务合同等场景,凭借出色的跨平台兼容性和标准化特点,PDF表单在各行各业中得到了广泛应用,本文将探讨如何使用... 目录引言使用工具C# 提取多个PDF表单域的数据C# 提取特定PDF表单域的数据引言PDF表单是一

使用Python实现高效的端口扫描器

《使用Python实现高效的端口扫描器》在网络安全领域,端口扫描是一项基本而重要的技能,通过端口扫描,可以发现目标主机上开放的服务和端口,这对于安全评估、渗透测试等有着不可忽视的作用,本文将介绍如何使... 目录1. 端口扫描的基本原理2. 使用python实现端口扫描2.1 安装必要的库2.2 编写端口扫

PyCharm接入DeepSeek实现AI编程的操作流程

《PyCharm接入DeepSeek实现AI编程的操作流程》DeepSeek是一家专注于人工智能技术研发的公司,致力于开发高性能、低成本的AI模型,接下来,我们把DeepSeek接入到PyCharm中... 目录引言效果演示创建API key在PyCharm中下载Continue插件配置Continue引言

MySQL分表自动化创建的实现方案

《MySQL分表自动化创建的实现方案》在数据库应用场景中,随着数据量的不断增长,单表存储数据可能会面临性能瓶颈,例如查询、插入、更新等操作的效率会逐渐降低,分表是一种有效的优化策略,它将数据分散存储在... 目录一、项目目的二、实现过程(一)mysql 事件调度器结合存储过程方式1. 开启事件调度器2. 创