serial8250_enable_ms 函数

时间: 2023-11-02 15:05:28 浏览: 35
serial8250_enable_ms 函数是用于启用8250串行端口的Modem控制功能的函数。Modem控制功能允许计算机与外部Modem设备通信,并进行拨号、呼叫等操作。该函数在Linux内核中被调用,用于启用Modem控制功能,它的实现代码如下: static void serial8250_enable_ms(struct uart_8250_port *up) { unsigned char mcr = serial_in(up, UART_MCR); mcr |= UART_MCR_OUT2; mcr &= ~(UART_MCR_LOOP | UART_MCR_AFE); serial_out(up, UART_MCR, mcr); serial_out(up, UART_IER, UART_IER_MSI); } 在该函数中,首先读取串行端口的Modem控制寄存器(UART_MCR),然后将OUT2位设置为1,这将启用Modem控制功能。接着,将UART_MCR_LOOP和UART_MCR_AFE位清零,这是为了确保不使用环回模式和自动流控制。最后,将UART_IER_MSI位设置为1,这将启用Modem状态中断。这样,串行端口就可以与Modem设备通信,并实现拨号、呼叫等操作。
相关问题

void Uprintf(const char* fmt,...) { va_list ap; char s[256]; uint32_t retry=0; va_start(ap, fmt); vsprintf(s, fmt, ap); va_end(ap); // ??????? fflush(stdout); DelayMS_Test(1); memcpy(MCU_log_TxBuf, s, strlen(s)); /* Clear enable bit for start source interrupt */ Modbus_Start_Send_Ready(); R_Config_DTC_ThirdPartTXD_Stop(); R_Config_DTC_ThirdPartTXD_Start(strlen(s)); R_Config_SCI1_ThirdPart_Serial_Send(MCU_log_TxBuf,( strlen(s))); MCU_log_tx_end_flg = 0; do{ retry++; }while(MCU_log_tx_end_flg != 1); }

这段代码是一个自定义的打印函数 Uprintf,它使用了可变参数列表和 vsprintf 函数将格式化的输出字符串存储到字符数组 s 中。然后通过 memcpy 函数将 s 中的内容复制到 MCU_log_TxBuf 中。接着调用 Modbus_Start_Send_Ready 函数,设置开始发送的标志位,并停止第三方 DTC 传输。然后通过 R_Config_SCI1_ThirdPart_Serial_Send 函数将 MCU_log_TxBuf 中的数据发送出去,并等待发送完成。最后通过 while 循环等待 MCU_log_tx_end_flg 标志位被设置为 1,表示发送完成。 需要注意的是,该代码中的一些函数和变量是特定于某个 MCU 或者工程的,可能需要根据实际情况进行修改。另外,该函数中有一些延时和等待的操作,可能会影响程序的实时性和性能,需要谨慎使用。

linux内核uart驱动,使用队列解耦原有的功能函数

Linux内核UART驱动通常使用队列来解耦原有的功能函数,以提高代码的可读性和可维护性。这种方法的基本思想是将不同的功能分割成独立的模块,每个模块都有一个输入队列和一个输出队列。 输入队列用于接收来自UART接口的数据,处理数据并将结果放入输出队列中。输出队列中的数据可以是控制命令、状态信息或者其他需要传递给上层应用程序的数据。这种方法的优点是可以使编写驱动程序更加简单,易于维护和扩展。 以下是一个使用队列解耦原有功能函数的UART驱动程序的示例: ```c #include <linux/module.h> #include <linux/init.h> #include <linux/fs.h> #include <linux/cdev.h> #include <linux/slab.h> #include <linux/uaccess.h> #include <linux/serial_core.h> #define BUFFER_SIZE 1024 struct uart_device { struct cdev cdev; struct uart_port port; struct mutex mutex; struct work_struct work; struct tasklet_struct tasklet; spinlock_t lock; wait_queue_head_t read_queue; wait_queue_head_t write_queue; char *buf; int head; int tail; }; static int uart_driver_open(struct inode *inode, struct file *file) { struct uart_device *dev; dev = container_of(inode->i_cdev, struct uart_device, cdev); file->private_data = dev; return 0; } static int uart_driver_release(struct inode *inode, struct file *file) { return 0; } static ssize_t uart_driver_read(struct file *file, char __user *buf, size_t count, loff_t *offset) { struct uart_device *dev = file->private_data; ssize_t ret; if (count == 0) return 0; if (wait_event_interruptible(dev->read_queue, dev->head != dev->tail)) return -ERESTARTSYS; mutex_lock(&dev->mutex); if (dev->head > dev->tail) { ret = min_t(ssize_t, count, dev->head - dev->tail); if (copy_to_user(buf, dev->buf + dev->tail, ret)) { ret = -EFAULT; goto out; } dev->tail += ret; } else { ret = min_t(ssize_t, count, BUFFER_SIZE - dev->tail); if (copy_to_user(buf, dev->buf + dev->tail, ret)) { ret = -EFAULT; goto out; } dev->tail = (dev->tail + ret) % BUFFER_SIZE; } out: mutex_unlock(&dev->mutex); return ret; } static ssize_t uart_driver_write(struct file *file, const char __user *buf, size_t count, loff_t *offset) { struct uart_device *dev = file->private_data; ssize_t ret; if (count == 0) return 0; if (wait_event_interruptible(dev->write_queue, dev->head != ((dev->tail - 1 + BUFFER_SIZE) % BUFFER_SIZE))) return -ERESTARTSYS; mutex_lock(&dev->mutex); if (dev->tail > dev->head) { ret = min_t(ssize_t, count, BUFFER_SIZE - dev->tail); if (copy_from_user(dev->buf + dev->tail, buf, ret)) { ret = -EFAULT; goto out; } dev->tail += ret; } else { ret = min_t(ssize_t, count, dev->head - dev->tail); if (copy_from_user(dev->buf + dev->tail, buf, ret)) { ret = -EFAULT; goto out; } dev->tail = (dev->tail + ret) % BUFFER_SIZE; } out: mutex_unlock(&dev->mutex); return ret; } static void uart_driver_work(struct work_struct *work) { struct uart_device *dev = container_of(work, struct uart_device, work); struct uart_port *port = &dev->port; unsigned char c; int i; mutex_lock(&dev->mutex); while (uart_chars_avail(port)) { c = uart_get_char(port); if (dev->head == ((dev->tail - 1 + BUFFER_SIZE) % BUFFER_SIZE)) { /* Buffer is full, drop the incoming character */ continue; } dev->buf[dev->head] = c; dev->head = (dev->head + 1) % BUFFER_SIZE; } mutex_unlock(&dev->mutex); wake_up_interruptible(&dev->read_queue); } static void uart_driver_tasklet(unsigned long data) { struct uart_device *dev = (struct uart_device *)data; struct uart_port *port = &dev->port; unsigned char c; int i; spin_lock(&dev->lock); while (uart_chars_avail(port)) { c = uart_get_char(port); if (dev->head == ((dev->tail - 1 + BUFFER_SIZE) % BUFFER_SIZE)) { /* Buffer is full, drop the incoming character */ continue; } dev->buf[dev->head] = c; dev->head = (dev->head + 1) % BUFFER_SIZE; } spin_unlock(&dev->lock); wake_up_interruptible(&dev->read_queue); } static void uart_driver_start(struct uart_port *port) { struct uart_device *dev = container_of(port, struct uart_device, port); INIT_WORK(&dev->work, uart_driver_work); tasklet_init(&dev->tasklet, uart_driver_tasklet, (unsigned long)dev); spin_lock_init(&dev->lock); init_waitqueue_head(&dev->read_queue); init_waitqueue_head(&dev->write_queue); mutex_init(&dev->mutex); dev->buf = kzalloc(BUFFER_SIZE, GFP_KERNEL); dev->head = 0; dev->tail = 0; uart_write_wakeup(port); } static void uart_driver_stop(struct uart_port *port) { struct uart_device *dev = container_of(port, struct uart_device, port); cancel_work_sync(&dev->work); tasklet_kill(&dev->tasklet); spin_lock_irq(&dev->lock); dev->head = dev->tail = 0; spin_unlock_irq(&dev->lock); kfree(dev->buf); } static struct uart_ops uart_driver_ops = { .tx_empty = uart_tx_empty, .set_mctrl = uart_set_mctrl, .get_mctrl = uart_get_mctrl, .stop_tx = uart_stop_tx, .start_tx = uart_start_tx, .send_xchar = uart_send_xchar, .stop_rx = uart_stop_rx, .enable_ms = uart_enable_ms, .break_ctl = uart_break_ctl, .startup = uart_driver_start, .shutdown = uart_driver_stop, }; static struct uart_driver uart_driver = { .owner = THIS_MODULE, .driver_name = "uart_driver", .dev_name = "ttyUART", .major = 0, .minor = 0, .nr = 1, .cons = NULL, .ops = &uart_driver_ops, }; static int __init uart_driver_init(void) { dev_t devno; int ret; ret = alloc_chrdev_region(&devno, 0, 1, "uart_driver"); if (ret < 0) return ret; cdev_init(&uart_driver.cdev, &uart_driver_ops); uart_driver.cdev.owner = THIS_MODULE; ret = cdev_add(&uart_driver.cdev, devno, 1); if (ret < 0) { unregister_chrdev_region(devno, 1); return ret; } uart_register_driver(&uart_driver); return 0; } static void __exit uart_driver_exit(void) { uart_unregister_driver(&uart_driver); cdev_del(&uart_driver.cdev); unregister_chrdev_region(uart_driver.cdev.dev, 1); } module_init(uart_driver_init); module_exit(uart_driver_exit); MODULE_AUTHOR("Your Name"); MODULE_LICENSE("GPL"); ``` 在这个驱动程序中,我们使用了两个输入队列和一个输出队列。`read_queue` 用于接收来自 UART 的数据,`write_queue` 用于接收要发送到 UART 的数据,`buf` 用于存储接收到的数据。 `wait_event_interruptible` 函数用于等待数据到达队列。`mutex_lock` 和 `mutex_unlock` 函数用于保护共享数据结构。`wake_up_interruptible` 函数用于唤醒等待在队列上的进程。 `uart_driver_work` 和 `uart_driver_tasklet` 函数用于从 UART 中接收数据,并将接收到的数据放入输入队列中。 `uart_driver_start` 和 `uart_driver_stop` 函数用于初始化和清除输入队列和输出队列中的数据。`uart_driver_ops` 结构体包含了驱动程序中使用的 UART 操作。`uart_driver` 结构体包含了驱动程序的基本信息。 通过使用队列解耦原有的功能函数,我们可以将驱动程序中的不同部分分割成独立的模块,使得代码更加简洁、易于维护和扩展。

相关推荐

最新推荐

recommend-type

yolov5-face-landmarks-opencv

yolov5检测人脸和关键点,只依赖opencv库就可以运行,程序包含C++和Python两个版本的。 本套程序根据https://github.com/deepcam-cn/yolov5-face 里提供的训练模型.pt文件。转换成onnx文件, 然后使用opencv读取onnx文件做前向推理,onnx文件从百度云盘下载,下载 链接:https://pan.baidu.com/s/14qvEOB90CcVJwVC5jNcu3A 提取码:duwc 下载完成后,onnx文件存放目录里,C++版本的主程序是main_yolo.cpp,Python版本的主程序是main.py 。此外,还有一个main_export_onnx.py文件,它是读取pytorch训练模型.pt文件生成onnx文件的。 如果你想重新生成onnx文件,不能直接在该目录下运行的,你需要把文件拷贝到https://github.com/deepcam-cn/yolov5-face 的主目录里运行,就可以生成onnx文件。
recommend-type

setuptools-0.6c8-py2.5.egg

文件操作、数据分析和网络编程等。Python社区提供了大量的第三方库,如NumPy、Pandas和Requests,极大地丰富了Python的应用领域,从数据科学到Web开发。Python库的丰富性是Python成为最受欢迎的编程语言之一的关键原因之一。这些库不仅为初学者提供了快速入门的途径,而且为经验丰富的开发者提供了强大的工具,以高效率、高质量地完成复杂任务。例如,Matplotlib和Seaborn库在数据可视化领域内非常受欢迎,它们提供了广泛的工具和技术,可以创建高度定制化的图表和图形,帮助数据科学家和分析师在数据探索和结果展示中更有效地传达信息。
recommend-type

5-3.py

5-3
recommend-type

Java八股文.pdf

"Java八股文"是一个在程序员社群中流行的术语,特别是在准备技术面试时。它指的是一系列在Java编程面试中经常被问到的基础知识点、理论概念和技术细节。这个术语的命名来源于中国古代科举考试中的“八股文”,一种具有固定格式和套路的文章形式。 在Java编程的上下文中,"Java八股文"通常包括以下几个方面:"Java八股文"是一个在程序员社群中流行的术语,特别是在准备技术面试时。它指的是一系列在Java编程面试中经常被问到的基础知识点、理论概念和技术细节。这个术语的命名来源于中国古代科举考试中的“八股文”,一种具有固定格式和套路的文章形式。 在Java编程的上下文中,"Java八股文"通常包括以下几个方面:"Java八股文"是一个在程序员社群中流行的术语,特别是在准备技术面试时。它指的是一系列在Java编程面试中经常被问到的基础知识点、理论概念和技术细节。这个术语的命名来源于中国古代科举考试中的“八股文”,一种具有固定格式和套路的文章形式。 在Java编程的上下文中,"Java八股文"通常包括以下几个方面:"Java八股文"是一个在程序员社群中流行的术语,特别是在准备技术面试时。它
recommend-type

麦肯锡咨询顾问必备宝典.ppt

麦肯锡咨询顾问必备宝典.ppt
recommend-type

zigbee-cluster-library-specification

最新的zigbee-cluster-library-specification说明文档。
recommend-type

管理建模和仿真的文件

管理Boualem Benatallah引用此版本:布阿利姆·贝纳塔拉。管理建模和仿真。约瑟夫-傅立叶大学-格勒诺布尔第一大学,1996年。法语。NNT:电话:00345357HAL ID:电话:00345357https://theses.hal.science/tel-003453572008年12月9日提交HAL是一个多学科的开放存取档案馆,用于存放和传播科学研究论文,无论它们是否被公开。论文可以来自法国或国外的教学和研究机构,也可以来自公共或私人研究中心。L’archive ouverte pluridisciplinaire
recommend-type

实现实时数据湖架构:Kafka与Hive集成

![实现实时数据湖架构:Kafka与Hive集成](https://img-blog.csdnimg.cn/img_convert/10eb2e6972b3b6086286fc64c0b3ee41.jpeg) # 1. 实时数据湖架构概述** 实时数据湖是一种现代数据管理架构,它允许企业以低延迟的方式收集、存储和处理大量数据。与传统数据仓库不同,实时数据湖不依赖于预先定义的模式,而是采用灵活的架构,可以处理各种数据类型和格式。这种架构为企业提供了以下优势: - **实时洞察:**实时数据湖允许企业访问最新的数据,从而做出更明智的决策。 - **数据民主化:**实时数据湖使各种利益相关者都可
recommend-type

2. 通过python绘制y=e-xsin(2πx)图像

可以使用matplotlib库来绘制这个函数的图像。以下是一段示例代码: ```python import numpy as np import matplotlib.pyplot as plt def func(x): return np.exp(-x) * np.sin(2 * np.pi * x) x = np.linspace(0, 5, 500) y = func(x) plt.plot(x, y) plt.xlabel('x') plt.ylabel('y') plt.title('y = e^{-x} sin(2πx)') plt.show() ``` 运行这段
recommend-type

JSBSim Reference Manual

JSBSim参考手册,其中包含JSBSim简介,JSBSim配置文件xml的编写语法,编程手册以及一些应用实例等。其中有部分内容还没有写完,估计有生之年很难看到完整版了,但是内容还是很有参考价值的。