带GPIO的串行Linux嵌入式驱动程序

时间:2013-07-01 15:40:12

标签: serial-port driver kernel gpio

我正在尝试开发一个与设备通信的驱动程序。 我的驱动程序使用sysfs与用户空间进行通信,并使用rs232从外部设备发送/接收信息。我的Boad和其他设备通过rs232进行通信,但我不知道如何使用我的rx,tx,cts / rts在驱动程序中初始化此通信。 我看到很多关于tty的信息。但没有直接使用GPIO进行rs232通信。

结构

用户 - >董事会

| ----- ------ RX |
| ----- TX ------ |
| ----- ----- CTS |

设备

如果有人有想法:)

谢谢你

2 个答案:

答案 0 :(得分:3)

我最近在职业生涯中遇到过类似的问题。我们耗尽了硬件UART,需要在GPIO上使用单线实现UART协议。

现在,如果我正确理解你(或者我错过了你要问的具体架构?),你试图在某种可以(或正在)运行linux的微处理器上实现这一点。根据您的硬件和您可用的调试工具/程序员类型,您可以通过两种方式获得基本的裸机(读取:无操作系统)UART通信运行,可通过串行端口配置进行扩展(通常简化)在OS级别的Linux内核中。我不打算详细介绍在操作系统级别配置串口,但如果你能在裸机上完成,你可以在操作系统中完成;我将专注于两个简单的解决方案。

编辑:我现在意识到你确实处于一个完整的操作系统中。下面的所有内容都是您必须开发的固件,并与Gautham Kantharaju所描述的呼叫相关联。因此软件UART可能不完全有用。

这些是:

  1. 您的微控制器/微处理器上有硬件UART端口,它们已经有用于UART配置和FIFO的专用寄存器。
  2. 您只能访问GPIO模块,只能访问纯GPIO功能 - 输出逻辑高/低,中断配置(上升沿中断,下降沿;将中断发送到向量或DMA请求等)。和输入数据寄存器。
  3. 在任何一种情况下,您都需要查看微处理器的数据表和参考手册,以便首先了解其UART寄存器的工作原理。您几乎肯定会找到在芯片上实现和启用UART的应用笔记。它在硬件上非常标准,它们之间只有很小的差异。几乎总有代码示例可以为您完成这些任务,但根据您的需要,您可能必须至少修改一些配置设置。

    您应该看到某种形式的寄存器:

    1. 某种形式的启用寄存器可有效地为模块供电。这可能涉及取消时钟寄存器(模块无法在没有时钟的情况下运行)和其他一些可能更具硬件特定的步骤。
    2. 注册以设置流量控制。这里可以有很多。用于启用流量控制的一部分,无论CTS线路是高电平有效还是低电平,是否启用中断以及中断标志位于何处,等等。
    3. 通用UART配置(可能这将是初始化阶段的一部分,因为某些UART [例如飞思卡尔的ARM]可以通过写入配置寄存器来初始化。这些是您将看到停止位的数量,数据位数,奇偶校验位等。可以使用UART配置很多......这是一个非常成熟的标准。
    4. 您的FIFO注册以及如何访问它们。
    5. 同样,您的库/应用程序堆栈可能包含提供宏和函数的示例,以完成所有这些配置选项,并且在许多情况下,默认配置将起作用。您可能需要进入串行驱动程序(通常是serial.c)并更改代码以满足您的需求,但如果您知道寄存器和配置发生了什么,那么理解哪些设置会变得更加容易


      现在,如果是后者,则需要实现软件UART。有很多例子,但除非你了解GPIO引脚的端口控制以及UART硬件实现的细节,否则它对你没有任何好处。听起来比现在困难得多。你希望有两条线:一条用于RX,一条用于TX。如果您不需要流量控制,那么这就是您所需要的。否则,您将需要RTS和CTS线路。这些只是简单的GPIO,通过" active"来控制方向。在RTS引脚上驱动的逻辑电平(可以是高或低,具体取决于硬件 - 读取数据表)以指示发送请求,并且来自CTS线的确认指示现在可以开始传输。 / p>

      假设暂时没有流量控制,让我们从简单的接收开始。基本上,您需要在起始位上执行某种形式的中断。在中断处理程序中,启动某种硬件定时器(您必须配置的另一个寄存器/模块),并以周期性间隔对RX线进行采样,直到数据帧结束(start_bit + data_bits + stop_bit(s)+ parity_bit)或使用定时器来计算线路保持高/低的时间长度并在另一个功能中执行一些数学运算(不在中断处理器中!)。在大多数情况下,您需要前一种计时器,但如果有一个有趣的设备需要特定的握手,您可能需要更灵活的时间并选择第二种形式的输入数据采样。此外,缓冲区在调试时非常有用且必不可少,因此您可能希望在实现此目的时牢记这一点。

      要进行传输,您需要禁用中断(或屏蔽它们),以便不会中断传输(对于单线实施尤其重要)。然后,您必须解析数据,以确定每个位是1还是0(高电平有效还是低电平),并为一个"位时间"设置硬件定时器。 (波特率的倒数)。

      如果需要流量控制,您只需要在进入活动接收之前添加另一种简单的轮询方法,以便设备知道它是"允许"沟通。

      如果启用了奇偶校验位,则还需要在传输期间处理这些奇偶校验位以与数据一起发送或在接收之后处理奇偶校验位以确定数据是否已成功传输。

      Google搜索"软件uart"将从ATMEL中为AVR芯片提供许多示例,并详细说明如何实施一个。 This app note is good for the basics and underlying theory以及此页面上以ZIP格式链接的代码really helps explain how to code it


      希望这给了你一些很好的跳跃点。

答案 1 :(得分:0)

@Makit,1)首先阅读处理器的技术参考手册(TRM)。了解如何配置外部设备连接到的UART端口。需要编写/开发固件(OS独立代码),您将在其中配置一些uart寄存器,例如:线路控制寄存器(LCR),其中in-in将配置启动,奇偶校验,停止位(8N1)并需要根据TRM中的公式配置波特率,并为 DLL和DLH 寄存器分配适当的值。在此之后 ---> 2)开始使用通用文件操作(打开,关闭,读取和写入)开发字符设备驱动程序。之后,需要使用“ ioremap_nocache ”内核api映射已识别的uart端口寄存器,并使用返回值(指针值)使用 ioread [8 | 16 | 32] /读取/写入外部设备iowrite [8 | 16 | 32] 即可。 Uart设备驱动程序将使用开发的固件代码来配置uart寄存器,读写外部设备。请随时反馈: - )。