启用 DMA 的 UART Tx 模式

2024-01-06

我已经为 UART 在传输模式下编写了一个简单的设备驱动程序,并启用了 DMA 和中断。 我使用的硬件是 omap 4460 pandaboard,其中加载了 Linux 3.4。

下面我分享一下相关部分的代码。 在开放阶段:

    dma_map = ioremap(UART4_DMA_REG,0x1350);
    if(dma_map == NULL) {
        printk(KERN_INFO " unable to io_remap DMA region\n");
        return -ENOMEM;
    }   

    printk(KERN_INFO "DMA mapping successful\n");

    irq_val = request_irq(45,uart_handler,IRQF_DISABLED,"uart_int",NULL);
    if(irq_val) {
        printk(KERN_INFO "cannot assign the requested irq\n");
        return -1;
    }
    else {
        printk(KERN_INFO "Requested irq successful\n"); 
    }

其中 UART4_DMA_REG 是 DMA 寄存器 0x​​4a056000 的基地址,请求的 irq 是 45,是 sDMA 中断的第 1 行。 初始化 UART 寄存器并启用 DMA 后。 现在用户调用 write 函数将 100 字节数据复制到内核空间的缓冲区中。

下面的代码显示了 write 函数:

ssize_t uart_write(struct file *filp,const char __user *buff, size_t count, loff_t *offp)
{
    int no_of_bytes;
    int maxbytes;
    struct device *udevice = &devi;
    int ret_mask;

    char *kbuf = kmalloc(100,GFP_KERNEL|GFP_DMA); 
    maxbytes = BUFF_SIZE - *offp;
    if(count > maxbytes)//overflow of buffer
        no_of_bytes = maxbytes;
    else
        no_of_bytes = count;    
    if(no_of_bytes == 0)
        printk(KERN_INFO "Nothing is there to write to device\n");

    bytes_written = no_of_bytes - copy_from_user(kbuf,buff,no_of_bytes);//copy_from_user()returns remaining bytes.
    printk(KERN_INFO "Write Completed\n");
    Uindex = 0;
    *offp += bytes_written;

    ret_mask = dma_set_coherent_mask(udevice,DMA_BIT_MASK(32));
    if(!ret_mask)
        printk(KERN_INFO "set mask success \n");
    else
        printk(KERN_INFO "SET MASK NOT SUCCESS \n");

    bus_addr = dma_map_single(udevice,kbuf,size,DMA_TO_DEVICE); 
    printk(KERN_INFO "dma_map_single completed");
    dma_init(); 
    return bytes_written;
}

dma_init();该函数初始化 DMA 寄存器并在软件触发模式下启用通道。

void dma_init()
{
    unsigned int ccr_val;
    unsigned int csdp_val;
    irq_line = 1; //for tx line 1 is considered
    dma_cha_line = 0; //for tx line 0 is considered

    /* Interrupt Enabled in DMA4_IRQENABLE_Lj and DMA4_CICRi registers */       
    iowrite32(0x1,(dma_map + 0x0018 + (4 * irq_line)));//to unmask the interrupt DMA4_IRQENABLE_Lj  
    iowrite32(0x8,(dma_map + 0x0088 + (0x60 * dma_cha_line)));//condition to generate interrupt CICR reg

    /* Set the Read Port & Write Port access in CSDP */
    csdp_val = ioread32(dma_map + 0x0090 + (0x60 * dma_cha_line));
    csdp_val &= ~(0x3 << 7);//Source 
    csdp_val &= ~(0x3 << 14);//Destination
    csdp_val &= ~(0x3 << 16);//Writing mode without posted
    csdp_val &= ~(0x1 << 21);//little endian source
    csdp_val &= ~(0x1 << 19);//little endian destination
    csdp_val &= ~(0x1 << 13);//destination not packed
    csdp_val &= ~(0x1 << 6);//source not packed
    csdp_val &= ~(0x3);//ES is set to 8 bits    
    iowrite32(csdp_val,(dma_map + 0x0090 + (0x60 * dma_cha_line)));

    /* CEN register configuration */
    iowrite32(100,(dma_map + 0x0094 +(0x60 * dma_cha_line)));//EN is set to 1   

    /* CFN register configuration */
    iowrite32(1,(dma_map + 0x0098 +(0x60 * dma_cha_line)));//FN is set to 1 

    /* Set the Channel Source & Destination start address */
    iowrite32(bus_addr,(dma_map + 0x009C + (0x60 * dma_cha_line)));//Source
    iowrite32(io_map,(dma_map + 0x00a0 + (0x60 * dma_cha_line)));//Destination

    /* CCR configuration */ 
    ccr_val = ioread32(dma_map + 0x0080 + (0x60 * dma_cha_line));       
    /* Set the Read Port & Write Port addressing mode in CCR */
    /*
    ccr_val &= ~(0x3 << 12);//Source - constant address mode 
    ccr_val |= (0x1 << 14);//Destination - post incremented address mode-set 14th bit and clear 15th bit
    ccr_val &= ~(0x1 << 15);    
    */
    ccr_val |= (0x1 << 12);//source - post incremented address mode-set 12th bit and clear 13th bit
    ccr_val &= ~(0x1 << 13);    
    ccr_val &= ~(0x3 << 14);//destination- constant address mode - clear 14 and 15th bit 
    ccr_val |=  (0x1 << 26);//high priority on write
    ccr_val &=  ~(0x1 << 6);//low priority on read 
    ccr_val &= ~(0x1f);//CCR[4:0]
    ccr_val &=  ~(0x3 << 19);//CCR [19:20] to 0
    ccr_val |= (0x1 << 7);// Set the channel enable bit in CCR 
    iowrite32(ccr_val,(dma_map + 0x0080 + (0x60 * dma_cha_line)));

    /*CSEI,CSFI,CDEI,CDFI*/
    iowrite32(1,(dma_map + 0x00a4 +(0x60 * dma_cha_line)));
    iowrite32(1,(dma_map + 0x00a8 +(0x60 * dma_cha_line)));
    iowrite32(1,(dma_map + 0x00ac +(0x60 * dma_cha_line)));
    iowrite32(1,(dma_map + 0x00b0 +(0x60 * dma_cha_line))); 


    printk(KERN_INFO "DMA registers configured\n");
}

现在的问题是:一旦通道启用(在调用 dma_init() 之后),ISR(handler) 就会被调用并进入无限循环。在写入模式下我的 ISR 应该包含什么?


经过这么多次的打击和尝试,我已经解决了这些问题。首先,由于这是一个字符设备,因此每个 DMA 请求必须进行 1 个元素的 DMA 传输。我之前已将其配置为每个 DMA 请求传输 1 个块。其次,根据元素传输的编程指南,无需配置 DMA4_CEN 和 DMA4_CFN 寄存器。但据观察,只有配置了这些寄存器才能工作

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

启用 DMA 的 UART Tx 模式 的相关文章

  • numpy.distutils.system_info.NotFoundError:未找到 BLAS/LAPACK 库

    我在 buildroot 中添加 scikit learn 包 但它在构建步骤中需要 scipy 依赖项 所以我添加host python scipy in python scipy mk如下 HOST PYTHON SCIPY DEPEN
  • sys_open 是如何工作的?

    我编写了一个简单的字符设备驱动程序 mydev 其中包含 打开 文件操作 在用户空间应用程序中 我打开这个驱动程序节点 使用 open dev mydev O RDONLY open 系统调用内部调用sys open 我只想知道 sys o
  • 如何检查内核中SMP是否启用或禁用?

    我想知道如何检查我正在运行的机器 内核是否配置为 SMP 当然 我可以查看内核 config文件并可以搜索它 但是 问题是假设我没有源代码 我将如何检查 SMP 配置 有没有proc文件来检查吗 下面说我没有多核 cat proc cpui
  • Linux内核设备驱动程序以DMA方式进入内核空间

    LDD3 p 453 演示dma map single使用作为参数传入的缓冲区 bus addr dma map single dev gt pci dev gt dev buffer count dev gt dma dir Q1 这个缓
  • Linux 中串行端口描述符块上的“关闭”函数

    最近我发现了一个对我来说很新的问题 我很感激建议 我正在 Linux 上使用 termios 函数进行串行通信 我实际上没有使用真正的串口 而是使用虚拟小工具串口驱动程序 dev ttyGS0 文件描述符以非阻塞方式打开 我的程序定期生成数
  • 在用户空间中启用写组合 IO 访问

    我有一个带有用户空间驱动程序的 PCIe 设备 我通过 BAR 向设备写入命令 这些命令对延迟敏感并且数据量很小 64 字节 因此我不想使用 DMA 如果我使用以下命令重新映射内核中 BAR 的物理地址ioremap wc然后将64字节写入
  • Linux 内核模块驱动程序中 THIS_MODULE 的意义是什么?

    在Linux设备驱动程序开发中 file operations结构用途struct module owner 当我们总是用以下命令初始化它时 这个结构有什么用 THIS MODULE 什么时候可以设置这个字段NULL 该字段告诉谁是所有者s
  • 类似于 ftrace 打印 CPU 编号

    我想打印当前进程或函数正在执行的 CPU 编号 类似于 ftrace 如下所示 TASK PID CPU TIMESTAMP FUNCTION
  • yocto 中图像版本控制的最佳方法

    在 Yocto 中维护映像版本的最佳方法是什么 我的意思是假设我们构建一个图像并将其提供给客户 将来我们会向客户提供错误修复 我们如何知道客户正在使用哪个版本的 yocto 图像 有没有任何标准方法可以实现这一点 谢谢你的时间 赞赏你的努力
  • 交叉编译到嵌入式 Linux ARM 设备时,针对较旧版本的 libstdc++ 和最新的 GCC

    我们需要为ARM嵌入式linux目标找到一个满足以下条件的交叉编译工具链 内核3 17 GLBC 2 18 编译一些第三方代码需要最新版本的GCC 这些要求促使我使用 crosstool ng 生成自定义交叉编译工具链 我选择了最小内核版本
  • Yocto Dunfell 错误“没有可用的食谱”,单个自定义元层中的多台机器

    我维护一个与 Dunfell 兼容的自定义 Yocto 元层 它支持基于 Microchip SAMA5D27 处理器的板 我在这一层中有几个 bbappend 文件 它们仅适用于来自 meta atmel 和其他 Microchip 特定
  • 在Linux中使用命令行检查单个线程优先级

    我可以通过转到 proc pidof task 并给出来查看应用程序中使用的线程数 猫的状态 有没有办法使用命令检查Linux中各个线程的优先级 Regards Learner 运行 ps m l 它将列出所有线程和特定 PID 的优先级
  • 添加 request_mem_region 后,我的驱动程序每次第一次访问都会失败,并显示“忙”消息

    好吧 这对我来说真的很奇怪 我有一个模拟的 CAN 总线驱动程序 它是一个 Linux 内核模块 然后我有一个在用户空间中运行的测试应用程序 它通过打开文件描述符并发送来访问驱动程序ioctl 消息 现在 CAN 总线驱动程序只是我一直采用
  • Linux 内核中的 DMA 映射和 DMA 引擎是什么?

    Linux 内核中的 DMA 映射和 DMA 引擎是什么 DMA映射API和DMA引擎API何时可以在Linux设备驱动程序中使用 任何真正的 Linux 设备驱动程序示例作为参考都会很棒 Linux 内核中的 DMA 映射和 DMA 引擎
  • Linux内核中断处理程序互斥保护?

    我是否需要保护我的中断处理程序被同一中断多次调用 鉴于以下代码 我不确定应该进行的系统调用 我在当前的实现中遇到了罕见的随机死锁 void interrupt handler void down interruptible sem or u
  • glBufferSubData什么时候返回? [复制]

    这个问题在这里已经有答案了 我想将一个非常大的内存块的内容传输到足够大的 GPU 缓冲区 然后立即更改 CPU 上的内存内容 伪代码是这样的 glBindBuffer very large buffer glBufferSubData ve
  • 超低延迟硬实时多线程 x86 代码的意外周期性行为

    我正在具有 RT 优先级的专用 CPU 上循环运行代码以进行多次迭代 并希望长时间观察其行为 我发现代码有一个非常奇怪的周期性行为 简而言之 这就是代码的作用 Arraythread while 1 if flag Multiply mat
  • 使用Linux虚拟鼠标驱动

    我正在尝试实施一个虚拟鼠标驱动程序根据基本 Linux 设备驱动程序书 有一个用户空间应用程序 它生成坐标以及内核模块 See 虚拟鼠标驱动程序和用户空间应用程序代码 http www embeddedlinux org cn Essent
  • Alsa 带有来自调制解调器的 PCM 接口

    我有一个基于 imx28 CPU 的定制板 CPU 的串行端口连接到调制解调器的 PCM 输出 我必须为调制解调器的 PCM 接口开发一个驱动程序 使其成为 ALSA SoC 的一部分 您能指出内核树 中与我的设置重新组合的一些驱动程序吗
  • 如何检测来自 QNX 中 ncurses 的屏幕调整大小事件?

    我无法配置为接收有关使用 ncurses QNX Momentics 更改终端大小的事件 我使用Putyy作为终端 通过COM端口传输数据 我的问题是如何实现使用远程终端时接收屏幕变化事件 FILE fcons fopen dev ser1

随机推荐

  • Android Studio:按钮始终出现在前面

    我有一个相对布局 我向其中添加视图 我向其中添加了一个按钮 该按钮始终显示在添加到其中的所有其他视图的前面 无论添加内容的顺序如何 怎么会 我纯粹使用 Java 编写代码 没有使用 XML 这是一个简单的示例 即使文本是最后添加的 按钮也会
  • Fabric crashlytics 新实施不起作用 |织物特性

    实施将apiSecret and apiKey in the fabric properties文件不再工作 织物属性文件 app fabric properties apiSecret xx68f6074dxxxxxc11dxxx97c1
  • Python 套接字在远程消耗所有数据之前关闭

    我正在编写一个 Python 模块 它通过 unix 套接字与 go 程序进行通信 客户端 python 模块 将数据写入套接字 服务器使用它们 Simplified version of the code used outputStrea
  • 如何将点击手势转换为 SwiftUI 地图视图中的坐标?

    我正在尝试添加一个MapAnnotation项目到我的Map 查看自MapKit 如果您在文本字段中手动添加坐标 则一切正常 但我找不到任何通过点击地图来添加坐标的方法 我在互联网上阅读了很多内容 但没有找到任何内容onTap 地图事件处理
  • 未定义错误:“current_user”未定义

    我有一个带有烧瓶的应用程序 以前可以使用 但现在我使用蓝图并尝试运行它 但出现错误 所以我想知道这就是 g user 不工作的蓝图问题 我该如何修复它 谢谢 应用程序 布局 init py from flask import Bluepri
  • Summernote div 更改时 Textarea 值发生变化

    我为 Summernote 设置了一个 div 来更改从数据库中提取的文本 div class form control div document ready function summernote summernote height 30
  • 如何在javascript中“重新启用”特殊字符序列?

    如果我有一个定义的字符串变量 例如 var testString not n new line 它的价值当然是not n new line 但如果直接使用 not n new line 测试字符串将包含新行 那么最简单的方法是什么测试字符串
  • 为什么我一定要揭开脆弱的自己?

    我创建了一个名为VerifyObject 其中包含具有类似签名的函数 typealias handlerCodeID String gt Void class func checkPause withID String runOnPause
  • 为什么嵌套的describe()块看不到外部块中定义的变量?

    我在实际代码中遇到了这个问题 但我整理了一个简单的例子来证明这一点 下面的代码工作正常 我在我的根目录中设置了一个变量describe 在我的子系统中可以访问的块describe s it blocks describe simple ob
  • Fortran SAVE 语句

    我读过有关save 英特尔 语言参考文档中的声明 但我不太明白它的作用 有人可以用简单的语言向我解释一下当save语句包含在模块中 原则上 当模块超出范围时 该模块的变量将变为未定义 除非使用 SAVE 属性声明它们 或者使用 SAVE 语
  • ViewPager2 上的 TransactionTooLargeException

    我看到了很多关于 ViewPager 的问题 但现在它已经上线了ViewPager2 我得到了一个java lang RuntimeException android os TransactionTooLargeException data
  • CKEditor - 使用数据处理器删除脚本标签

    我对 CKEditor 还很陌生 两天前开始使用它 而且我仍在与一些配置作斗争 例如从编辑器中删除标签 例如 如果用户在源模式下键入以下内容 我想将其删除 查看文档 我发现这可以使用 HTML 过滤器来完成 我这样定义了它 但它不起作用 v
  • 如何增加 JVM 内存? [复制]

    这个问题在这里已经有答案了 你好 我想知道我是否可以根据我的应用程序增加 JVM 内存 如果可以 我该如何增加 JVM 内存 我怎样才能知道 JVM 的大小 启动 JVM 时 可以调整两个参数以满足您的内存需求 Xms
  • 如何通过 Jayway JsonPath 展平带有嵌套列表的 json?

    目前我需要根据配置处理一些 json 结果 而不是硬代码 例如 json如下 data orderNo CG8310150 details skuId 4384 amount 2 skuId 4632 amount 5 orderNo CG
  • 如何让greatmonkey 检查页面上是否找到文本

    我确实在谷歌和用户脚本网站上做了一些研究 但没有成功找到答案 那么基本上我如何检查页面上是否找到特定文本 并且文本没有特殊标签或任何东西 对于 FF GM 来说 一个粗略但快速的方法 if Text you are looking for
  • Android随机多项选择测验:如何识别正确答案

    我正在尝试为 Android 创建一个随机多项选择测验 我想显示字符串数组中的随机问题 另一个字符串数组的相应答案显示在四个选项之一中 其他三个选项将来自另一个字符串数组 该数组将用于随机提供所有问题的 错误 答案 两个问题 有没有更好的方
  • Mono 不写入设置默认值

    这是我的问题 如果我只使用一个 Windows 窗体项目并且仅调用 Settings Default Save 运行时 Mono 会创建一个 user config 文件 其中包含每个设置的默认值 很好 到目前为止一切都很好 但现在我添加了
  • CSS 不显示任何内容且不透明动画且关键帧不起作用

    我有一个非常基本的 HTML 片段 其目的是从display none to display block不透明度从 0 变为 1 我使用的是 Chrome 浏览器 它使用 webkit前缀作为偏好并做了 webkit keyframes设置
  • Excel-DNA:F# 初始化错误 [错误] 方法未注册

    作为一名新手 F 开发人员 我尝试创建一个简单的 Excel DNA 函数 如下所示
  • 启用 DMA 的 UART Tx 模式

    我已经为 UART 在传输模式下编写了一个简单的设备驱动程序 并启用了 DMA 和中断 我使用的硬件是 omap 4460 pandaboard 其中加载了 Linux 3 4 下面我分享一下相关部分的代码 在开放阶段 dma map io