fifo_write0.c

本文提供了一个使用非阻塞FIFO(命名管道)进行数据写入的C语言程序示例。该程序首先尝试打开指定的FIFO,并在接收到来自命令行的输入后尝试写入数据。如果FIFO尚未准备好,则会提示稍后再试;若写入成功,则显示已写入的信息。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define FIFO_SERVER "/tmp/myfifo"
main(int argc,char** argv)
{
    int fd;
    char w_buf[100];
    int nwrite;
       
    /*打开管道*/
    fd=open(FIFO_SERVER,O_WRONLY|O_NONBLOCK,0);
    if(argc==1)
    {
        printf("Please send something\n");
        exit(-1);
    }
    strcpy(w_buf,argv[1]);
   
    /* 向管道写入数据 */
    if((nwrite=write(fd,w_buf,100))==-1)
    {
        if(errno==EAGAIN)
            printf("The FIFO has not been read yet.Please try later\n");
    }
    else
        printf("write %s to the FIFO\n",w_buf);
}
<think>我们有一个FIFO缓冲区的初始化函数,现在需要知道如何用它来实现UART中断回显。 步骤: 1. 定义FIFO结构体(utils_fifo_buffer_t)和缓冲区内存空间。 2. 使用utils_fifo_buffer_init函数初始化FIFO。 3. 在UART接收中断中,将收到的数据放入FIFO。 4. 在主循环中,从FIFO取出数据并发送(回显)。 假设已经定义了utils_fifo_buffer_t结构体,如下所示(根据函数推测): typedef struct { uint16_t read; // 读指针(索引) uint16_t write; // 写指针(索引) uint8_t *buffer_ptr; // 指向数据缓冲区的指针 uint32_t buffer_size; // 数据缓冲区的大小(字节数) } utils_fifo_buffer_t; 注意:函数中,整个缓冲区内存布局是: [utils_fifo_buffer_t结构体][实际数据缓冲区] 所以,传入的p_data指向一块内存,其前sizeof(utils_fifo_buffer_t)用于存放结构体,后面部分用于存放实际数据。 我们需要实现: - FIFO的写入函数(在中断中使用) - FIFO的读取函数(在主循环中使用) 下面我们根据这个初始化函数来编写完整的代码。</think>根据您提供的FIFO初始化函数,以下是完整的UART中断回显程序实现方案,包含FIFO缓冲区的使用: ```c #include "main.h" #include "stm32f1xx_hal.h" // FIFO结构定义 typedef struct { uint16_t read; // 读指针 uint16_t write; // 写指针 uint8_t *buffer_ptr; // 缓冲区指针 uint32_t buffer_size;// 缓冲区大小 } utils_fifo_buffer_t; UART_HandleTypeDef huart1; utils_fifo_buffer_t rx_fifo; uint8_t rx_byte; // 中断接收临时变量 uint8_t fifo_memory[128]; // 实际FIFO存储空间 // 您的FIFO初始化函数 utils_fifo_buffer_t* utils_fifo_buffer_init(uint8_t *p_data, uint32_t buffer_size) { utils_fifo_buffer_t *p_fifo = (utils_fifo_buffer_t*)p_data; if(p_fifo != NULL && p_data != NULL && buffer_size > sizeof(utils_fifo_buffer_t)) { p_fifo->read = 0; p_fifo->write = 0; p_fifo->buffer_ptr = p_data + sizeof(utils_fifo_buffer_t); p_fifo->buffer_size = buffer_size - sizeof(utils_fifo_buffer_t); return p_fifo; } return NULL; } // FIFO写入函数 void fifo_put(uint8_t data) { // 计算实际数据缓冲区大小 uint32_t data_size = rx_fifo.buffer_size; // 检查缓冲区是否已满 if(((rx_fifo.write + 1) % data_size) != rx_fifo.read) { // 写入数据到缓冲区 rx_fifo.buffer_ptr[rx_fifo.write] = data; // 更新写指针 rx_fifo.write = (rx_fifo.write + 1) % data_size; } // 缓冲区满时可添加处理逻辑 } // FIFO读取函数 uint8_t fifo_get(uint8_t *data) { // 检查是否有数据可读 if(rx_fifo.read != rx_fifo.write) { *data = rx_fifo.buffer_ptr[rx_fifo.read]; // 更新读指针 rx_fifo.read = (rx_fifo.read + 1) % rx_fifo.buffer_size; return 1; // 成功读取 } return 0; // 无数据 } int main(void) { HAL_Init(); SystemClock_Config(); // 初始化FIFO utils_fifo_buffer_init(fifo_memory, sizeof(fifo_memory)); // USART1初始化 huart1.Instance = USART1; huart1.Init.BaudRate = 115200; huart1.Init.WordLength = UART_WORDLENGTH_8B; huart1.Init.StopBits = UART_STOPBITS_1; huart1.Init.Parity = UART_PARITY_NONE; huart1.Init.Mode = UART_MODE_TX_RX; huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE; HAL_UART_Init(&huart1); // 启动接收中断 HAL_UART_Receive_IT(&huart1, &rx_byte, 1); while (1) { uint8_t data; // 从FIFO读取数据 if(fifo_get(&data)) { // 发送回显数据 HAL_UART_Transmit(&huart1, &data, 1, HAL_MAX_DELAY); } // 低功耗选项 // __WFI(); // 等待中断 } } // 接收完成回调函数 void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) { if (huart->Instance == USART1) { // 将接收到的数据放入FIFO fifo_put(rx_byte); // 重新启用接收中断 HAL_UART_Receive_IT(huart, &rx_byte, 1); } } // USART1中断处理函数 void USART1_IRQHandler(void) { HAL_UART_IRQHandler(&huart1); } ``` ### 使用说明: 1. **FIFO初始化流程**: ```c // 在main()开始时调用 utils_fifo_buffer_init(fifo_memory, sizeof(fifo_memory)); ``` 2. **中断服务中写入数据**: ```c // 在HAL_UART_RxCpltCallback中 fifo_put(rx_byte); // 将接收到的字节存入FIFO ``` 3. **主循环中读取和发送**: ```c // 在while(1)循环中 uint8_t data; if(fifo_get(&data)) { HAL_UART_Transmit(&huart1, &data, 1, HAL_MAX_DELAY); } ``` ### 关键实现细节: 1. **内存布局**: - `fifo_memory`数组包含FIFO控制结构和实际数据缓冲区 - 控制结构大小:`sizeof(utils_fifo_buffer_t)` - 实际数据缓冲区大小:`总大小 - 控制结构大小` 2. **指针管理**: - `read`和`write`指针使用环形缓冲区设计 - 指针更新:`(pointer + 1) % buffer_size` 3. **缓冲区状态检测**: - **满**:`(write + 1) % size == read` - **空**:`write == read` 4. **线程安全**: - 中断中只进行写操作 - 主循环只进行读操作 - 无共享资源冲突 ### 优化建议: 1. **添加状态检查函数**: ```c uint32_t fifo_available(void) { return (rx_fifo.write >= rx_fifo.read) ? (rx_fifo.write - rx_fifo.read) : (rx_fifo.buffer_size - rx_fifo.read + rx_fifo.write); } ``` 2. **添加缓冲区保护**: ```c // 在fifo_put()中添加 if(((rx_fifo.write + 1) % data_size) == rx_fifo.read) { // 缓冲区满处理:丢弃数据或覆盖旧数据 return; } ``` 3. **支持DMA传输**: - 修改为DMA接收模式,减少中断频率 - 使用IDLE中断检测帧结束
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值