简体   繁体   English

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

[英]Serial Linux embedded Driver with GPIO

i'm trying to develop a driver to communicate with a device. 我正在尝试开发与设备进行通信的驱动程序。 My driver use sysfs to communicate with userspace, and use rs232 to send/receive information from extern device. 我的驱动程序使用sysfs与用户空间进行通信,并使用rs232从外部设备发送/接收信息。 My Boad and the other device communicate through rs232, but i don't know how to initialise this communication in driver with my rx,tx, cts/rts. 我的Boad和其他设备通过rs232通信,但是我不知道如何用我的rx,tx,cts / rts在驱动程序中初始化此通信。 I see lot of information about tty. 我看到了很多关于tty的信息。 But nothing about using directly GPIO for rs232 communication. 但是没有任何关于直接使用GPIO进行rs232通信的事情。

The structure 结构

User -> Board 用户->董事会

|-----rx------| | ----- rx ------ |
|-----tx------| | ----- tx ------ |
|-----cts-----| | ----- cts ----- |

device 设备

If someone have an idea :) 如果有人有主意:)

Thanks you 谢谢

I went through a similar problem very recently in my professional career. 我最近在职业生涯中遇到了类似的问题。 We ran out of hardware UARTs and needed to implement a UART protocol using a single wire on GPIO. 我们用完了硬件UART,需要使用GPIO上的单线来实现UART协议。

Now, if I am understanding you correctly (or did I miss the specific architecture you are asking about?), you are trying to implement this on a microprocessor of some sort that can (or is) running linux. 现在,如果我正确地理解了您(或者我是否错过了您要问的特定体系结构?),您正在尝试在可以(或正在)运行linux的某种微处理器上实现该功能。 Depending on your hardware and what kind of debug tools/programmers you have available, you pretty much have two options to get basic bare-metal (read: no OS) UART communications running that can be extended (and often simplified) with serial port configuration in the linux kernel at the OS level. 根据您的硬件和可用的调试工具/编程器的种类,您几乎有两种选择可以运行基本的裸机(读取:无操作系统)UART通信,该通信可以通过串行端口配置进行扩展(并且通常可以简化)在操作系统级别的linux内核中。 I won't go into detail on configuring serial ports at the OS level, but if you can do it on bare metal, you can do it in an OS; 我不会在操作系统级别上详细配置串行端口,但是如果您可以在裸机上进行配置,则可以在操作系统中进行配置。 I will focus on the two bare-bones solutions. 我将重点介绍两种简单的解决方案。

EDIT: I now realize that you are indeed in a full blown OS. 编辑:我现在意识到,您的确确实处于完整的OS中。 Everything below is for the firmware that you will have to develop and associate with the calls Gautham Kantharaju described. 下面的所有内容都是针对固件的,您必须开发该固件并将其与Gautham Kantharaju所述的呼叫相关联。 So the software UART may not be entirely helpful. 因此,软件UART可能并不完全有用。

These are: 这些是:

  1. There are hardware UART ports on your microcontroller/microprocessor that already have dedicated registers for UART configuration and FIFOs. 微控制器/微处理器上的硬件UART端口已经具有用于UART配置和FIFO的专用寄存器。
  2. You only have access to the GPIO module and only have access to the pure GPIO functions - output logic high/low, interrupt configuration (interrupt on rising edge, falling edge; send interrupt to vector or DMA request, etc). 您只能访问GPIO模块,而且只能访问纯GPIO功能-输出逻辑高/低,中断配置(在上升沿,下降沿中断;向矢量或DMA请求发送中断等)。 and an input data register. 和一个输入数据寄存器。

In either case, you need to look through your microprocessor's datasheets and reference manual to first learn about how its UART registers work. 无论哪种情况,您都需要仔细阅读微处理器的数据表和参考手册,以首先了解其UART寄存器的工作原理。 You will also almost definitely find application notes for implementing and enabling a UART on your chip. 您几乎肯定还会找到在芯片上实现和启用UART的应用笔记。 It is pretty standard across hardware with just minor differences between them. 这是跨硬件的相当标准,它们之间只有很小的差异。 There are almost always code examples that accomplish these tasks for you, but depending on your needs, you will likely have to modify at least some of the configuration settings. 几乎总是有代码示例为您完成这些任务,但是根据您的需要,您可能必须至少修改一些配置设置。

You should see some form of registers with: 您应该看到带有以下形式的寄存器:

  1. Some form of an enable register to effectively give power to the module. 某种形式的使能寄存器可以有效地为模块供电。 This can involve ungating a clock register (the module can't function without a clock) and some other steps that may be more hardware specific. 这可能涉及取消时钟寄存器的工作(模块没有时钟就无法运行)和其他一些可能与硬件有关的步骤。
  2. Registers to set the flow control. 注册以设置流量控制。 There can be many here. 这里可以有很多。 Ones for enabling flow control all together, whether the CTS line is active high/low, whether to enable interrupts and where the interrupt flag is, etc. 用于一起启用流控制,CTS线是处于高/低电平有效状态,是否允许中断以及中断标志在何处等。
  3. General UART config (likely this will be part of the initialization phase as some UARTs [Freescale's ARM for example] may be initialized by writing to the configuration register. These are where you will see number of stop bits, number of data bits, parity bits, etc. There is a lot that can be configured using UARTs... It is a very mature standard. 通用UART配置(这可能是初始化阶段的一部分,因为某些UART [例如飞思卡尔的ARM]可以通过写入配置寄存器进行初始化。在这些位置,您将看到停止位的数量,数据位的数量,奇偶校验位等等。使用UART可以配置很多...这是一个非常成熟的标准。
  4. Your FIFO registers and how to access them. 您的FIFO寄存器以及如何访问它们。

Again, your library/application stack will likely include examples that offer macros and functions to accomplish all of these configuration options and in many cases the default config will work. 同样,您的库/应用程序堆栈可能会包含提供宏和函数以完成所有这些配置选项的示例,并且在许多情况下,默认配置将起作用。 You may need to go into your serial driver (commonly serial.c) and alter the code to fit your needs, but if you know what is going on with the registers and configuration, it will be a lot easier to understand which settings to mess 您可能需要进入串行驱动程序(通常为serial.c)并更改代码以适合您的需求,但是如果您知道寄存器和配置的工作情况,那么更容易理解搞乱哪些设置


Now, if it is the latter, you need to implement a software UART. 现在,如果是后者,则需要实现软件UART。 There are many examples out there but it won't do you any good unless you learn the ins and out of the port control of GPIO pins as well as the nitty gritty of what the UART hardware accomplishes. 那里有很多示例,但是除非您了解GPIO引脚的输入和输出端口控制以及UART硬件完成的功能的本质,否则它对您没有任何帮助。 It sounds a lot harder than it is. 听起来比实际困难得多。 You will hopefully have two lines: one for RX and one for TX. 希望您有两行:一条用于RX,另一条用于TX。 If you don't need flow control, then that's all you need. 如果您不需要流控制,那么这就是您所需要的。 Otherwise, you will need an RTS and CTS line. 否则,您将需要RTS和CTS线路。 These are just simple GPIOs that control direction with an "active" logic level (can be high or low depending on the hardware - READ YOUR DATASHEET) driven on the RTS pin to indicate a request to send and an acknowledgement from the CTS line indicating that transmission can now begin. 这些只是简单的GPIO,它们以RTS引脚驱动的“活动”逻辑电平(取决于硬件,高或低-读数据表)来控制方向,以指示发送请求和来自CTS线的确认,指示传输现在可以开始了。

Assuming no flow control for a moment, let's start with a simple receive. 假设暂时没有流控制,让我们从简单的接收开始。 Basically, you will need to do some form of an interrupt on the start bit. 基本上,您将需要在起始位上执行某种形式的中断。 In the interrupt's handler, start a hardware timer of some kind (Yet another register/module you will have to configure), and either sample the RX line at periodic intervals until the end of the data frame (start_bit + data_bits + stop_bit(s) + parity_bit) or use the timer to time how long a line was held high/low and perform some math in another function (NOT IN THE INTERRUPT HANDLER!). 在中断的处理程序中,启动某种硬件计时器(还需要配置另一个寄存器/模块),然后以周期性的间隔对RX行进行采样,直到数据帧结束为止(start_bit + data_bits + stop_bit(s)) + parity_bit)或使用计时器来计时多长时间将一条线保持在高/低电平状态,并在其他功能中执行一些数学运算(不要在中断处理程序中!)。 In most cases, you will want the former kind of timer, but if there is an interesting device with a specific handshaking involved, you may need to be more flexible with the timing and opt for the second form of sampling incoming data. 在大多数情况下,您将需要前一种计时器,但是如果有有趣的设备涉及特定的握手,则可能需要在计时方面更加灵活,并选择第二种形式的传入数据采样。 Also, a buffer would be very useful and indispensable when debugging, so you may very well want to keep that in mind as you go about implementing this. 另外,在调试时,缓冲区将非常有用且必不可少,因此在执行此操作时,您可能非常想记住这一点。

To transmit, You will need to disable interrupts (or mask them) so that your transmission will not be interrupted (especially important for a single wire implentation). 要进行传输,您将需要禁用中断(或屏蔽它们),以使您的传输不会被中断(对于单线连接尤其重要)。 Then you will have to parse through your data to determine whether each bit is a 1 or 0 (active high or low) and set a hardware timer for one "bit time" (inverse of baud rate). 然后,您将必须解析数据以确定每个位是1还是0(高电平有效或低电平有效),并为一个“位时间”(波特率的倒数)设置一个硬件计时器。

If flow control is needed, you will just have to add another simple polling method before you go into active receive so that the device knows it is "allowed" to communicate. 如果需要流控制,则在进入活动接收之前,您只需添加另一种简单的轮询方法,以使设备知道“允许”进行通信。

If parity bits are enabled, those will also need to be processed either during transmission to be sent out with the data or after a receive to determine whether the data was transferred successfully. 如果启用了奇偶校验位,则还需要在传输过程中将奇偶校验位与数据一起发送出去,或者在接收之后还要确定数据是否已成功传输。

A Google search for "software uart" will yield many examples from ATMEL for their AVR chips and others detailing how to go about implementing one. 谷歌搜索“软件uart”将从ATMEL的AVR芯片中获得许多示例,而其他示例则详细说明了如何实施。 This app note is good for the basics and underlying theory and the code linked in ZIP on this page really helps explain how to code it . 此应用笔记对基础知识和基础理论很有用,本页上ZIP链接的代码确实有助于解释如何进行编码


Hopefully this gave you some good jumping off points. 希望这能给您一些好的起点。

@Makit, 1) First go through the processor's Technical Reference Manual (TRM) . @ Makit,1)首先阅读处理器的技术参考手册(TRM) Understand how to configure UART port to which external device is connected to. 了解如何配置与外部设备连接的UART端口。 Need to write/develop a firmware (OS independent code) where you will be configuring some of the uart registers for ex: Line control register (LCR) , where-in will configure start, parity, stop bit(8N1) and need to configure baudrate according to formula in the TRM and assign the appropriate values to DLL and DLH registers. 需要编写/开发固件(与操作系统无关的代码),在其中您将要配置一些uart寄存器,例如: 线路控制寄存器(LCR) ,其中in将配置开始,奇偶校验,停止位(8N1)并需要进行配置根据TRM中的公式进行波特率传输,并将适当的值分配给DLL和DLH寄存器。 After this ---> 2) Start with developing character device driver with common file operations (open, close, read and write). 之后---> 2)从开发具有通用文件操作(打开,关闭,读取和写入)的字符设备驱动程序开始。 After that, need to map identified uart port registers using " ioremap_nocache " kernel api and use return value (pointer value) to read/write external device using ioread[8|16|32]/iowrite[8|16|32] . 之后,需要使用“ ioremap_nocache ”内核api映射已标识的uart端口寄存器,并使用返回值(指针值)通过ioread [8 | 16 | 32] / iowrite [8 | 16 | 32]来读取/写入外部设备。 Uart device driver will use firmware code developed to configure uart registers, read and write to external device. Uart设备驱动程序将使用开发的固件代码来配置uart寄存器,读写外部设备。 Please feel free to feedback :-). 请随时反馈:-)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM