[译]Chapter 5 - Device Drivers for Azure RTOS ThreadX

[译]:https://docs.microsoft.com/zh-cn/azure/rtos/threadx/chapter5

This chapter contains a description of device drivers for Azure RTOS ThreadX. The information presented in this chapter is designed to help developers write application-specific drivers.

本章包含Azure RTOS ThreadX设备驱动程序的说明。本章中提供的信息旨在帮助开发人员编写特定于应用程序的驱动程序。

Device Driver Introduction

Communication with the external environment is an important component of most embedded applications. This communication is accomplished through hardware devices that are accessible to the embedded application software. The software components responsible for managing such devices are commonly called device drivers.

Device drivers in embedded, real-time systems are inherently application dependent. This is true for two principal reasons: the vast diversity of target hardware and the equally vast performance requirements imposed on real-time applications. Because of this, it is virtually impossible to provide a common set of drivers that will meet the requirements of every application. For these reasons, the information in this chapter is designed to help users customize off-the-shelf ThreadX device drivers and write their own specific drivers.

设备驱动程序介绍

与外部环境的通信是大多数嵌入式应用程序的重要组成部分。这种通信是通过嵌入式应用软件可以访问的硬件设备来实现的。负责管理此类设备的软件组件通常称为设备驱动程序。

嵌入式实时系统中的设备驱动程序本质上依赖于应用程序。这有两个主要原因:目标硬件的多样性和对实时应用程序施加的同样巨大的性能要求。因此,几乎不可能提供一组通用驱动程序,以满足每个应用程序的需求。基于这些原因,本章中的信息旨在帮助用户自定义现成的ThreadX设备驱动程序并编写自己的特定驱动程序。

Driver Functions

ThreadX device drivers are composed of eight basic functional areas, as follows.

驱动程序功能

ThreadX设备驱动程序由八个基本功能区域组成,如下所示。

  • Driver Initialization
  • Driver Control
  • Driver Access
  • Driver Input
  • Driver Output
  • Driver Interrupts
  • Driver Status
  • Driver Termination

With the exception of initialization, each driver functional area is optional. Furthermore, the exact processing in each area is specific to the device driver.

  • 驱动程序初始化
  • 驾驶员控制
  • 驱动程序访问
  • 驱动程序输入
  • 驱动程序输出
  • 驱动程序中断
  • 驱动程序状态
  • 驱动器终止

除了初始化,每个驱动程序功能区域都是可选的。此外,每个区域中的精确处理具体于设备驱动程序。

Driver Initialization

This functional area is responsible for initialization of the actual hardware device and the internal data structures of the driver. Calling other driver services is not allowed until initialization is complete.

 备注

The driver's initialization function component is typically called from the tx_application_define function or from an initialization thread.

驱动程序初始化

该功能区负责初始化实际硬件设备和驱动程序的内部数据结构。在初始化完成之前,不允许调用其他驱动程序服务。

备注

驱动程序的初始化函数组件通常从tx_application_define函数或初始化线程调用。

Driver Control

After the driver is initialized and ready for operation, this functional area is responsible for run-time control. Typically, run-time control consists of making changes to the underlying hardware device. Examples include changing the baud rate of a serial device or seeking a new sector on a disk.

驾驶员控制

在驱动程序初始化并准备好操作后,该功能区负责运行时控制。通常,运行时控制包括对底层硬件设备进行更改。例如,更改串行设备的波特率或在磁盘上寻找新扇区。

Driver Access

Some device drivers are called only from a single application thread. In such cases, this functional area is not needed. However, in applications where multiple threads need simultaneous driver access, their interaction must be controlled by adding assign/ release facilities in the device driver. Alternatively, the application may use a semaphore to control driver access and avoid extra overhead and complication inside the driver.

驱动程序访问

某些设备驱动程序仅从单个应用程序线程调用。在这种情况下,不需要这个功能区。然而,在多线程需要同时访问驱动程序的应用程序中,必须通过在设备驱动程序中添加分配/释放工具来控制它们的交互。或者,应用程序可以使用信号量来控制驱动程序访问,并避免驱动程序内部的额外开销和复杂。

Driver Input

This functional area is responsible for all device input. The principal issues associated with driver input usually involve how the input is buffered and how threads wait for such input.

驱动程序输入

此功能区负责所有设备输入。与驱动程序输入相关的主要问题通常涉及到如何缓冲输入以及线程如何等待这样的输入。

Driver Output

This functional area is responsible for all device output. The principal issues associated with driver output usually involve how the output is buffered and how threads wait to perform output.

驱动程序输出

此功能区负责所有设备输出。与驱动程序输出相关的主要问题通常涉及到如何缓冲输出以及线程如何等待执行输出。

Driver Interrupts

Most real-time systems rely on hardware interrupts to notify the driver of device input, output, control, and error events. Interrupts provide a guaranteed response time to such external events. Instead of interrupts, the driver software may periodically check the external hardware for such events. This technique is called polling. It is less real-time than interrupts, but polling may make sense for some less real-time applications.

驱动程序中断

大多数实时系统都依赖硬件中断来通知驱动程序设备输入、输出、控制和错误事件。中断为此类外部事件提供了一个有保障的响应时间。驱动程序软件可以定期检查外部硬件是否存在此类事件,而不是中断。这种技术称为轮询。它比中断实时性要低,但是对于一些实时性较差的应用程序,轮询可能是有意义的。

Driver Status

This function area is responsible for providing run-time status and statistics associated with the driver operation. Information managed by this function area typically includes the following.

  • Current device status
  • Input bytes
  • Output bytes
  • Device error counts

驱动程序状态

此功能区域负责提供与驱动程序操作相关的运行时状态和统计信息。由此功能区域管理的信息通常包括以下内容。

  • 当前设备状态
  • 输入字节
  • 输出字节
  • 设备错误计数

Driver Termination

This functional area is optional. It is only required if the driver and/or the physical hardware device need to be shut down. After being terminated, the driver must not be called again until it is reinitialized.

驱动器终止

此功能区域是可选的。仅当驱动程序和/或物理硬件设备需要关闭时才需要。终止后,必须重新初始化驱动程序,才能再次调用该驱动程序。

Simple Driver Example

An example is the best way to describe a device driver. In this example, the driver assumes a simple serial hardware device with a configuration register, an input register, and an output register. This simple driver example illustrates the initialization, input, output, and interrupt functional areas.

简单驱动程序示例

一个例子是描述设备驱动程序的最好方法。在本例中,驱动程序假设一个简单的串行硬件设备,其中包含配置寄存器、输入寄存器和输出寄存器。这个简单的驱动程序示例演示了初始化、输入、输出和中断功能区域。

Simple Driver Initialization

The tx_sdriver_initialize function of the simple driver creates two counting semaphores that are used to manage the driver's input and output operation. The input semaphore is set by the input ISR when a character is received by the serial hardware device. Because of this, the input semaphore is created with an initial count of zero.

Conversely, the output semaphore indicates the availability of the serial hardware transmit register. It is created with a value of one to indicate the transmit register is initially available.

The initialization function is also responsible for installing the low-level interrupt vector handlers for input and output notifications. Like other ThreadX interrupt service routines, the low-level handler must call _tx_thread_context_save before calling the simple driver ISR. After the driver ISR returns, the low-level handler must call _tx_thread_context_restore.

 重要

*It is important that initialization is called before any of the other driver functions. Typically, driver initialization is called from tx_application_define.

简单驱动程序初始化

简单驱动程序的tx_sdriver_initialize 函数创建两个计数信号量,用于管理驱动程序的输入和输出操作。当串行硬件设备接收到字符时,输入ISR设置输入信号量。因此,输入信号量是以初始计数为零创建的。

相反,输出信号量指示串行硬件传输寄存器的可用性。它的创建值为1,以指示传输寄存器最初可用。

初始化函数还负责安装用于输入和输出通知的低级中断向量处理程序。与其他ThreadX中断服务例程一样,低级处理程序在调用简单驱动程序ISR之前必须调用_tx_thread_context_save。在驱动程序ISR返回后,低级处理程序必须调用_tx_thread_context_restore

重要

*在任何其他驱动程序函数之前调用初始化是很重要的。通常,驱动程序初始化是从tx_application_define调用的。

VOID tx_sdriver_initialize(VOID)
{
    /* Initialize the two counting semaphores used to control
    the simple driver I/O. */
    tx_semaphore_create(&tx_sdriver_input_semaphore,
                        "simple driver input semaphore", 0);
    tx_semaphore_create(&tx_sdriver_output_semaphore,
                        "simple driver output semaphore", 1);

    /* Setup interrupt vectors for input and output ISRs.
    The initial vector handling should call the ISRs
    defined in this file. */

    /* Configure serial device hardware for RX/TX interrupt
    generation, baud rate, stop bits, etc. */
}

FIGURE 9. Simple Driver Initialization

Simple Driver Input

Input for the simple driver centers around the input semaphore. When a serial device input interrupt is received, the input semaphore is set. If one or more threads are waiting for a character from the driver, the thread waiting the longest is resumed. If no threads are waiting, the semaphore simply remains set until a thread calls the drive input function.

There are several limitations to the simple driver input handling. The most significant is the potential for dropping input characters. This is possible because there is no ability to buffer input characters that arrive before the previous character is processed. This is easily handled by adding an input character buffer.

 备注

Only threads are allowed to call the tx_sdriver_input function.

Figure 10 shows the source code associated with simple driver input.

简单驱动程序输入

简单驱动程序的输入围绕输入信号量进行。当接收到串行设备输入中断时,将设置输入信号量。如果一个或多个线程正在等待来自驱动程序的字符,则等待最长的线程将恢复。如果没有线程等待,信号量将保持设置,直到线程调用驱动器输入函数。

简单的驱动程序输入处理有几个限制。最重要的是,可能会删除输入字符。这是可能的,因为在处理前一个字符之前,无法缓冲到达的输入字符。通过添加输入字符缓冲区,可以轻松地处理这一点。

备注

仅允许线程调用 tx_sdriver_input 输入函数。

图10显示了与简单驱动程序输入相关的源代码。

UCHAR tx_sdriver_input(VOID)
{
  /* Determine if there is a character waiting. If not,
  suspend. */
  tx_semaphore_get(&tx_sdriver_input_semaphore,
  TX_WAIT_FOREVER;

  /* Return character from serial RX hardware register. */
  return(*serial_hardware_input_ptr);
}
  VOID tx_sdriver_input_ISR(VOID)
{
  /* See if an input character notification is pending. */
  if (!tx_sdriver_input_semaphore.tx_semaphore_count)
  {
    /* If not, notify thread of an input character. */
    tx_semaphore_put(&tx_sdriver_input_semaphore);
  }
}

FIGURE 10. Simple Driver Input

Simple Driver Output

Output processing utilizes the output semaphore to signal when the serial device's transmit register is free. Before an output character is actually written to the device, the output semaphore is obtained. If it is not available, the previous transmit is not yet complete.

The output ISR is responsible for handling the transmit complete interrupt. Processing of the output ISR amounts to setting the output semaphore, thereby allowing output of another character.

 备注

Only threads are allowed to call the tx_sdriver_output function.

Figure 11 shows the source code associated with simple driver output.

简单驱动程序输出

输出处理利用输出信号量在串行设备的发送寄存器空闲时发出信号。在实际写入设备之前,获得输出信号量。如果不可用,则上一个传输尚未完成。

输出ISR负责处理传输完成中断。输出ISR的处理等于设置输出信号量,从而允许输出另一个字符。

备注

仅允许线程调用tx_sdriver_output输出函数。

图11显示了与简单驱动程序输出相关的源代码。

VOID tx_sdriver_output(UCHAR alpha)
{
  /* Determine if the hardware is ready to transmit a
  character. If not, suspend until the previous output
  completes. */
  tx_semaphore_get(&tx_sdriver_output_semaphore,
                                          TX_WAIT_FOREVER);

  /* Send the character through the hardware. */
  *serial_hardware_output_ptr = alpha;
}
  
VOID tx_sdriver_output_ISR(VOID)
{
  /* Notify thread last character transmit is
  complete. */
  tx_semaphore_put(&tx_sdriver_output_semaphore);
}

FIGURE 11. Simple Driver Output

Simple Driver Shortcomings

This simple device driver example illustrates the basic idea of a ThreadX device driver. However, because the simple device driver does not address data buffering or any overhead issues, it does not fully represent real-world ThreadX drivers. The following section describes some of the more advanced issues associated with device drivers.

简单的驱动程序缺陷

这个简单的设备驱动程序示例说明了ThreadX设备驱动程序的基本思想。但是,由于简单的设备驱动程序没有解决数据缓冲或任何开销问题,因此它不能完全代表真实世界的ThreadX驱动程序。下面的部分介绍了与设备驱动程序相关的一些更高级的问题。

Advanced Driver Issues

As mentioned previously, device drivers have requirements as unique as their applications. Some applications may require an enormous amount of data buffering while another application may require optimized driver ISRs because of high-frequency device interrupts.

高级驱动程序问题

如前所述,设备驱动程序的要求与它们的应用程序一样独特。一些应用程序可能需要大量的数据缓冲,而另一个应用程序可能需要优化的驱动程序isr,因为高频设备中断。

I/O Buffering

Data buffering in real-time embedded applications requires considerable planning. Some of the design is dictated by the underlying hardware device. If the device provides basic byte I/O, a simple circular buffer is probably in order. However, if the device provides block, DMA, or packet I/O, a buffer management scheme is probably warranted.

I/O缓冲

实时嵌入式应用程序中的数据缓冲需要大量的规划。一些设计是由底层硬件设备决定的。如果设备提供基本的字节I/O,一个简单的循环缓冲区可能是合适的。然而,如果设备提供块、DMA或分组I/O,则可能需要缓冲区管理方案。

Circular Byte Buffers

Circular byte buffers are typically used in drivers that manage a simple serial hardware device like a UART. Two circular buffers are most often used in such situations—one for input and one for output.

Each circular byte buffer is comprised of a byte memory area (typically an array of UCHARs), a read pointer, and a write pointer. A buffer is considered empty when the read pointer and the write pointers reference the same memory location in the buffer. Driver initialization sets both the read and write buffer pointers to the beginning address of the buffer.

循环字节缓冲区

循环字节缓冲区通常用于管理简单串行硬件设备(如UART)的驱动程序中。两个循环缓冲区在这种情况下最常用,一个用于输入,一个用于输出。

每个循环字节缓冲区由一个字节内存区(通常是一个uchar数组)、一个读指针和一个写指针组成。当读指针和写指针引用缓冲区中相同的内存位置时,缓冲区被认为是空的。驱动程序初始化将读写缓冲区指针设置为缓冲区的起始地址。

Circular Buffer Input

The input buffer is used to hold characters that arrive before the application is ready for them. When an input character is received (usually in an interrupt service routine), the new character is retrieved from the hardware device and placed into the input buffer at the location pointed to by the write pointer. The write pointer is then advanced to the next position in the buffer. If the next position is past the end of the buffer, the write pointer is set to the beginning of the buffer. The queue full condition is handled by canceling the write pointer advancement if the new write pointer is the same as the read pointer.

Application input byte requests to the driver first examine the read and write pointers of the input buffer. If the read and write pointers are identical, the buffer is empty. Otherwise, if the read pointer is not the same, the byte pointed to by the read pointer is copied from the input buffer and the read pointer is advanced to the next buffer location. If the new read pointer is past the end of the buffer, it is reset to the beginning. Figure 12 shows the logic for the circular input buffer.

循环缓冲区输入

输入缓冲区用于保存在应用程序准备就绪之前到达的字符。当接收到输入字符时(通常在中断服务例程中),从硬件设备检索新字符,并将其放入写入指针所指向位置的输入缓冲区中。然后写指针前进到缓冲区中的下一个位置。如果下一个位置超过缓冲区的结尾,则写入指针设置为缓冲区的开头。如果新的写指针与读指针相同,则通过取消写指针前进来处理队列已满的情况。

应用程序对驱动程序的输入字节请求首先检查输入缓冲区的读写指针。如果读写指针相同,则缓冲区为空。否则,如果读指针不相同,则从输入缓冲区复制读指针指向的字节,并将读指针前进到下一个缓冲区位置。如果新的读取指针超过缓冲区的结尾,则会重置为开头。图12显示了循环输入缓冲区的逻辑。

UCHAR   tx_input_buffer[MAX_SIZE];
UCHAR   tx_input_write_ptr;
UCHAR   tx_input_read_ptr;

/* Initialization. */
tx_input_write_ptr =    &tx_input_buffer[0];
tx_input_read_ptr =     &tx_input_buffer[0];

/* Input byte ISR... UCHAR alpha has character from device. */
save_ptr = tx_input_write_ptr;
*tx_input_write_ptr++ = alpha;
if (tx_input_write_ptr > &tx_input_buffer[MAX_SIZE-1])
    tx_input_write_ptr = &tx_input_buffer[0]; /* Wrap */
if (tx_input_write_ptr == tx_input_read_ptr)
    tx_input_write_ptr = save_ptr; /* Buffer full */

/* Retrieve input byte from buffer... */
if (tx_input_read_ptr != tx_input_write_ptr)
{
  alpha = *tx_input_read_ptr++;
  if (tx_input_read_ptr > &tx_input_buffer[MAX_SIZE-1])
      tx_input_read_ptr = &tx_input_buffer[0];
}

FIGURE 12. Logic for Circular Input Buffer

 备注

*For reliable operation, it may be necessary to lockout interrupts when manipulating the read and write pointers of both the input and output circular buffers. *

备注

*为了可靠运行,在操作输入和输出循环缓冲区的读写指针时,可能需要锁定中断。*

Circular Output Buffer

The output buffer is used to hold characters that have arrived for output before the hardware device finished sending the previous byte. Output buffer processing is similar to input buffer processing, except the transmit complete interrupt processing manipulates the output read pointer, while the application output request utilizes the output write pointer. Otherwise, the output buffer processing is the same. Figure 13 shows the logic for the circular output buffer.

循环输出缓冲器

输出缓冲区用于保存在硬件设备完成发送前一个字节之前已到达输出的字符。输出缓冲区处理与输入缓冲区处理类似,只是传输完全中断处理操作输出读取指针,而应用程序输出请求使用输出写入指针。否则,输出缓冲区处理是相同的。图13显示了循环输出缓冲区的逻辑。

UCHAR   tx_output_buffer[MAX_SIZE];
UCHAR   tx_output_write_ptr;
UCHAR   tx_output_read_ptr;

/* Initialization. */
tx_output_write_ptr = &tx_output_buffer[0];
tx_output_read_ptr = &tx_output_buffer[0];

/* Transmit complete ISR... Device ready to send. */
if (tx_output_read_ptr != tx_output_write_ptr)
{
  *device_reg = *tx_output_read_ptr++;
  if (tx_output_read_reg > &tx_output_buffer[MAX_SIZE-1])
      tx_output_read_ptr = &tx_output_buffer[0];
}

/* Output byte driver service. If device busy, buffer! */
save_ptr = tx_output_write_ptr;
*tx_output_write_ptr++ = alpha;
if (tx_output_write_ptr > &tx_output_buffer[MAX_SIZE-1])
    tx_output_write_ptr = &tx_output_buffer[0]; /* Wrap */
if (tx_output_write_ptr == tx_output_read_ptr)
    tx_output_write_ptr = save_ptr; /* Buffer full! */

FIGURE 13. Logic for Circular Output Buffer

Buffer I/O Management

To improve the performance of embedded microprocessors, many peripheral device devices transmit and receive data with buffers supplied by software. In some implementations, multiple buffers may be used to transmit or receive individual packets of data.

The size and location of I/O buffers is determined by the application and/or driver software. Typically, buffers are fixed in size and managed within a ThreadX block memory pool. Figure 14 describes a typical I/O buffer and a ThreadX block memory pool that manages their allocation.

缓冲区I/O管理

为了提高嵌入式微处理器的性能,许多外围设备通过软件提供的缓冲区来传输和接收数据。在一些实现中,可以使用多个缓冲器来发送或接收单个数据包。

I/O缓冲区的大小和位置由应用程序和/或驱动程序软件决定。通常,缓冲区的大小是固定的,并在ThreadX块内存池中进行管理。图14描述了一个典型的I/O缓冲区和一个管理它们分配的ThreadX块内存池。

typedef struct TX_IO_BUFFER_STRUCT
{
      struct TX_IO_BUFFER_STRUCT *tx_next_packet;
      struct TX_IO_BUFFER_STRUCT *tx_next_buffer;
      UCHAR tx_buffer_area[TX_MAX_BUFFER_SIZE];
} TX_IO_BUFFER;

TX_BLOCK_POOL tx_io_block_pool;

/* Create a pool of I/O buffers. Assume that the pointer
"free_memory_ptr"points to an available memory area that
is 64 KBytes in size. */
tx_block_pool_create(&tx_io_block_pool,
                  "Sample IO Driver Buffer Pool",
                  free_memory_ptr, 0x10000,
                  sizeof(TX_IO_BUFFER));

FIGURE 14. I/O Buffer

TX_IO_BUFFER

The typedef TX_IO_BUFFER consists of two pointers. The tx_next_packet pointer is used to link multiple packets on either the input or output list. The tx_next_buffer pointer is used to link together buffers that make up an individual packet of data from the device. Both of these pointers are set to NULL when the buffer is allocated from the pool. In addition, some devices may require another field to indicate how much of the buffer area actually contains data.

TX IO缓冲区

typedef TX_IO_BUFFER由两个指针组成。tx_next_packet 指针用于链接输入或输出列表上的多个数据包。The tx_next_buffer用于将构成来自设备的数据包的缓冲区连接在一起。当缓冲区从池分配时,这两个指针都设置为NULL。此外,一些设备可能需要另一个字段来指示缓冲区中实际包含数据的量。

Buffered I/O Advantage

What are the advantages of a buffer I/O scheme? The biggest advantage is that data is not copied between the device registers and the application's memory. Instead, the driver provides the device with a series of buffer pointers. Physical device I/O utilizes the supplied buffer memory directly.

Using the processor to copy input or output packets of information is extremely costly and should be avoided in any high throughput I/O situation.

Another advantage to the buffered I/O approach is that the input and output lists do not have full conditions. All of the available buffers can be on either list at any one time. This contrasts with the simple byte circular buffers presented earlier in the chapter. Each had a fixed size determined at compilation.

缓冲I/O优势

缓冲区I/O方案的优点是什么?最大的优点是数据不会在设备寄存器和应用程序的内存之间复制。相反,驱动程序为设备提供一系列缓冲点。物理设备I/O直接利用所提供的缓冲存储器。

使用处理器复制输入或输出信息包的代价极高,在任何高吞吐量I/O情况下都应避免使用。

缓冲I/O方法的另一个优点是输入和输出列表没有完整的条件。所有可用缓冲区都可以随时在任一列表中。这与本章前面介绍的简单字节循环缓冲区形成了对比。每个都有一个在编译时确定的固定大小。

Buffered Driver Responsibilities

Buffered device drivers are only concerned with managing linked lists of I/O buffers. An input buffer list is maintained for packets that are received before the application software is ready. Conversely, an output buffer list is maintained for packets being sent faster than the hardware device can handle them. Figure 15 shows simple input and output linked lists of data packets and the buffer(s) that make up each packet.

缓冲的驱动程序职责

缓冲设备驱动程序只关心管理I/O缓冲区的链接列表。对于在应用程序软件准备就绪之前接收的数据包,将维护输入缓冲区列表。相反,对于发送速度比硬件设备处理的更快的数据包,保持输出缓冲区列表。图15显示了构成每个数据包的数据包和缓冲区的简单输入和输出链接列表。

Input List

Input List

Output List

Output List

FIGURE 15. Input-Output Lists

Applications interface with buffered drivers with the same I/O buffers. On transmit, application software provides the driver with one or more buffers to transmit. When the application software requests input, the driver returns the input data in I/O buffers.

 备注

In some applications, it may be useful to build a driver input interface that requires the application to exchange a free buffer for an input buffer from the driver. This might alleviate some buffer allocation processing inside of the driver.

应用程序与具有相同I/O缓冲区的缓冲驱动程序接口。在传输时,应用软件为驱动程序提供一个或多个要传输的缓冲区。当应用程序软件请求输入时,驱动程序将在I/O缓冲区中返回输入数据。

备注

在某些应用程序中,构建一个驱动程序输入接口可能很有用,该接口要求应用程序为来自驱动程序的输入缓冲区交换一个空闲缓冲区。这可能会减轻驱动程序内部的缓冲区分配处理。

Interrupt Management

In some applications, the device interrupt frequency may prohibit writing the ISR in C or to interact with ThreadX on each interrupt. For example, if it takes 25us to save and restore the interrupted context, it would not be advisable to perform a full context save if the interrupt frequency was 50us. In such cases, a small assembly language ISR is used to handle most of the device interrupts. This low-overhead ISR would only interact with ThreadX when necessary.

A similar discussion can be found in the interrupt management discussion at the end of Chapter 3.

中断管理

在某些应用中,设备中断频率可能禁止用C写入ISR或在每个中断上与ThreadX交互。例如,如果保存和恢复中断上下文需要25us,则如果中断频率为50us,则不建议执行完整上下文保存。在这种情况下,使用一个小型汇编语言ISR来处理大多数设备中断。这种低开销的ISR只在必要时与ThreadX交互。

在第3章末尾的中断管理讨论中也可以找到类似的讨论。

Thread Suspension

In the simple driver example presented earlier in this chapter, the caller of the input service suspends if a character is not available. In some applications, this might not be acceptable.

For example, if the thread responsible for processing input from a driver also has other duties, suspending on just the driver input is probably not going to work. Instead, the driver needs to be customized to request processing similar to the way other processing requests are made to the thread.

In most cases, the input buffer is placed on a linked list and an input event message is sent to the thread's input queue.

线程挂起

在本章前面介绍的简单驱动程序示例中,如果字符不可用,输入服务的调用方将暂停。在某些应用程序中,这可能是不可接受的。

例如,如果负责处理驱动程序输入的线程也有其他职责,那么仅暂停驱动程序输入可能无法工作。相反,需要定制驱动程序,以请求处理,类似于对线程发出的其他处理请求的方式。

在大多数情况下,输入缓冲区被放置在链接列表中,并将输入事件消息发送到线程的输入队列。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值