当前位置:首页 > 操作系统 > 正文内容

痞子衡嵌入式:关于恩智浦SDK2.0里业务型中止处理函数(DriverIRQHandler)的重定向注意事项

邻居的猫1个月前 (12-09)操作系统1126

  咱们好,我是痞子衡,是正派搞技能的痞子。今日痞子衡给咱们介绍的是SDK2.0里业务型中止处理函数(DriverIRQHandler)的重定向注意事项

  最近有一个 i.MXRT 客户在运用官方 SDK 外设驱动里的中止处理函数时遇到了代码重定向失效问题,客户用得是一个 XIP Flash 工程,想把程序中止向量表以及相关外设的驱动函数悉数重定向到 RAM 中以进步体系功用,但实测发现中止发生时,依然存在 Flash 拜访行为。这原本不是个大问题,由于 SDK 在规划时现已从中止处理函数命名上就做了清晰提示,可是许多客户并没有意识到,今日痞子衡就来聊聊这个论题:

一、业务型驱动函数简介

  恩智浦 SDK 软件包里的外设驱动(HAL级)正常来说供给的 API 都是面临外设装备(init、deinit、set_feature、get_status) 的通用功用函数。此外关于通讯接口类外设,一般还会有堵塞式(blocking)的数据传输功用函数。以 LPUART 外设为例,其数据传输有以下四个 API:

// 写入(发送)一个 Byte 数据(需在 FIFO 没满的状况下)
static inline void LPUART_WriteByte(LPUART_Type *base, uint8_t data);
// 读取(接纳)一个 Byte 数据(需在 FIFO 非空的状况下)
static inline uint8_t LPUART_ReadByte(LPUART_Type *base);
// 堵塞式写入(发送)多个 Byte 数据
status_t LPUART_WriteBlocking(LPUART_Type *base, const uint8_t *data, size_t length);
// 堵塞式读取(接纳)多个 Byte 数据
status_t LPUART_ReadBlocking(LPUART_Type *base, uint8_t *data, size_t length);

  堵塞式数据传输 API 本质上便是独占 CPU 时刻进行查询式传输,API 一旦调用,有必要比及数据收发结束才会回来,这样会导致 CPU 使用率不高,其一般不使用外设中止。为了结合外设中止进行高效数据传输(non-blocking),SDK2.0 中额定供给了如下业务型相关函数(仅列出了部分):

// 创立业务型数据传输句柄
void LPUART_TransferCreateHandle(LPUART_Type *base,
                                 lpuart_handle_t *handle,
                                 lpuart_transfer_callback_t callback,
                                 void *userData);
// 非堵塞式写入(发送)多个 Byte 数据
status_t LPUART_TransferSendNonBlocking(LPUART_Type *base, lpuart_handle_t *handle, lpuart_transfer_t *xfer)
// 非堵塞式读取(接纳)多个 Byte 数据
status_t LPUART_TransferReceiveNonBlocking(LPUART_Type *base,
                                           lpuart_handle_t *handle,
                                           lpuart_transfer_t *xfer,
                                           size_t *receivedBytes);
// 业务型数据传输中止处理函数
void LPUART_TransferHandleIRQ(LPUART_Type *base, void *irqHandle);

  非堵塞式数据传输 API 明显便是结合了外设中止来做数据传输,API 调用后填入一些装备后会马上回来,没有过多耗费 CPU 时刻,等外设中止发生时再进一步处理数据。这类型 API 常常和使用规划紧相关,所以也称为业务型函数(transactional API)。

  SDK 里并不是一切外设驱动里包括业务性函数,这类 API 常呈现在传输接口类外设上。关于 i.MXRT 来说,支撑此类 API 的外设有:DMA、LPUART、LPSPI、LPI2C、SAI、FLEXIO、FLEXSPI、USDHC、ENET、CAN、MIPI_DSI/CSI、SPDIF、ASRC、PDM 等。

二、业务型中止处理函数规划

  这儿持续以 LPUART 外设来详细介绍。如下 i.MXRT1011 SDK 里供给的 8 个 LPUART 例程中有 5 个是依据业务型驱动函数的,咱们就以 interrupt_transfer 的 IAR 工程为例。

  翻开这个 lpuart_interrupt_transfer 工程,找到芯片发动文件 startup_MIMXRT1011.s,在里边咱们能找到 PUBWEAK 型的 LPUART1_IRQHandler() 函数界说,这个是咱们比较常见的中止处理函数名,其代码里边便是简略跳转到另一个 PUBWEAK 型 LPUART1_DriverIRQHandler 函数。

  在 fsl_lpuart.c/.h 驱动里,找不到 LPUART1_IRQHandler() 界说,可是有 LPUART1_DriverIRQHandler() 界说。这意味着 SDK 驱动规划时,将默许的 LPUART1_IRQHandler() 函数重写的权力留给了用户,而从头规划了 LPUART1_DriverIRQHandler() 函数来寄存业务性中止处理代码,然后防止因用户自己重写中止处理函数时发生函数名重界说而去修正 fsl_lpuart.c 驱动文件的费事。

三、重定向业务型中止处理函数

  现在咱们测验重定向 lpuart_interrupt_transfer 工程,能够依照 《IAR下代码重定向的三种办法》 一文里的办法,将 fsl_lpuart.o 和 lpuart_interrupt_transfer.o 两个方针文件都重定向到 RAM 中,而且在 main 里加上复制 0x60002000 处开端的 1KB 中止向量表数据到 SRAM 中而且将 SCB->VTOR 指向对应 SRAM 的代码(这个进程能够参阅 《Cortex-M中止向量表重定向办法》 一文)。

  上述改动完结之后,编译工程检查 map 文件,咱们发现一切的相关代码都现已被链接在了 SRAM 里,可是 LPUART1_IRQHandler() 依然在 Flash 里,很明显这种状况下中止发生时,依然会有 Flash 拜访行为(暂不考虑 L1-Cache 收效的状况),这便是客户遇到的问题。

  那么怎么处理这个问题?其实 SDK 现已为你考虑到了,在 fsl_common_arm.c 文件中界说了 InstallIRQHandler() 函数(仅在 ENABLE_RAM_VECTOR_TABLE 宏存在的状况下收效),检查其源码,发现效果有两个:一、假如 SCB->VTOR 指向得不是 SRAM,那么将中止向量表从 Flash 复制到 SRAM 中,而且重置 VTOR;二、依据传入参数修正 SRAM 中的某个中止向量值。

  因而 lpuart_interrupt_transfer 例程中,假如需求完全重定向中止处理函数,记住在 main 函数里的 LPUART_TransferCreateHandle() 函数调用之后加上如下一句代码,其效果除了重定向中止向量表之外,还将表里的 LPUART1 中止向量从 LPUART1_IRQHandler() 替换为了 LPUART1_DriverIRQHandler(),这样代码重定向就完全了。

InstallIRQHandler(LPUART1_IRQn, (uint32_t)LPUART1_DriverIRQHandler);

  此刻再编译工程下载运转,发现呈现 hardfault,这是怎么回事?别急,由于 InstallIRQHandler() 函数里需求用到链接文件 MIMXRT1011xxxxx_flexspi_nor.icf 里界说的三个 Symbol,工程选项 Linker/Configuration file symbol 里有必要增加 __ram_vector_table__=1 设置,那些 Symbol 才会真实发生重定向效果。

define symbol m_interrupts_start       = 0x60002000;
define symbol m_interrupts_ram_start   = 0x20000000;

define symbol __ram_vector_table_size__        = isdefinedsymbol(__ram_vector_table__) ? 0x00000400 : 0;
define exported symbol __VECTOR_TABLE          = m_interrupts_start;
define exported symbol __VECTOR_RAM            = isdefinedsymbol(__ram_vector_table__) ? m_interrupts_ram_start : m_interrupts_start;
define exported symbol __RAM_VECTOR_TABLE_SIZE = __ram_vector_table_size__;

  至此,SDK2.0里业务型中止处理函数(DriverIRQHandler)的重定向注意事项痞子衡便介绍结束了,掌声在哪里~~~

欢迎订阅

文章会一起发布到我的 博客园主页、CSDN主页、知乎主页、微信大众号 平台上。

微信查找"痞子衡嵌入式"或许扫描下面二维码,就能够在手机上第一时刻看了哦。

扫描二维码推送至手机访问。

版权声明:本文由51Blog发布,如需转载请注明出处。

本文链接:https://www.51blog.vip/?id=640

分享给朋友:

“痞子衡嵌入式:关于恩智浦SDK2.0里业务型中止处理函数(DriverIRQHandler)的重定向注意事项” 的相关文章

windows在cygwin64下运用acme.sh批量签发Let's Encrypt的ssl证书,并用powershell重新分配iis证书

windows在cygwin64下运用acme.sh批量签发Let's Encrypt的ssl证书,并用powershell重新分配iis证书

运用条件 本脚本是在运用阿里云Windows服务器的条件,假如运用其他dns服务,请参看acme.sh的dns相关文档 装备好cygwin64、acme.sh并装备好阿里云账户,openssl最好也装置上 cygwin64装备参阅 acme.sh装备 openssl参阅,增加-certpbe PBE...

linux扫盘,Linux系统扫盘操作指南

1. `df` 显示文件系统的磁盘空间使用情况。2. `du` 显示文件或目录的磁盘使用空间。3. `fdisk` 查看和管理磁盘分区。4. `fsck` 检查和修复文件系统错误。5. `smartctl` 检查硬盘的S.M.A.R.T.信息,用于预测硬盘故障。下面是一些基本的命令示例:...

windows2007,企业级服务器的里程碑

Windows Server 2007:企业级服务器的里程碑Windows Server 2007,作为微软公司推出的一款企业级服务器操作系统,自2007年发布以来,一直以其强大的功能和稳定的性能受到广大用户的青睐。本文将详细介绍Windows Server 2007的特点、优势以及其在企业中的应用...

linux解压xz,准备环境

linux解压xz,准备环境

在Linux中,解压`.xz`文件通常使用`xz`命令。下面是解压`.xz`文件的步骤:1. 首先,确保你的系统已经安装了`xz`命令。如果没有安装,可以使用你的包管理器来安装它。例如,在基于Debian的系统上,你可以使用`aptget`来安装: ```bash sudo aptget i...

windows纸牌,经典电脑游戏的魅力与玩法解析

windows纸牌,经典电脑游戏的魅力与玩法解析

Windows纸牌是一款经典且广受欢迎的纸牌游戏,其历史可以追溯到1988年,由微软的一名暑期实习生Wes Cherry开发。这款游戏最早随Windows 3.0系统发布,旨在帮助用户熟悉鼠标操作,并逐渐成为Windows操作系统中不可或缺的一部分。 游戏规则Windows纸牌的基本规则如下:1....

笔记本安装linux,笔记本安装Linux系统的详细指南

安装Linux操作系统到笔记本上是一个相对简单但需要一些步骤的过程。以下是一个基本的指南,帮助您在笔记本上安装Linux:1. 选择Linux发行版: 最流行的Linux发行版包括Ubuntu、Fedora、Debian、CentOS和Arch Linux等。选择适合您需求的发行版。 如...