FIFO_笔记

参考文章:

linux 有名管道(FIFO):http://blog.youkuaiyun.com/firefoxbug/article/details/8137762

http://blog.youkuaiyun.com/firefoxbug/article/details/7358715


FIFO以文件形式存在于文件系统中,创建进程与访问进程不需要存在亲缘关系。

先入先出,读从开始返回数据,写将数据添加到末尾,不支持类似于lseek()等文件定位操作。

传送无格式字节流。

往往是多个写进程,一个读进程。

FIFO的打开规则:

  1. 如果当前打开操作是为而打开FIFO时,若已经有相应进程为写而打开该FIFO,则当前打开操作将成功返回;否则,可能阻塞直到有相应进程为写而打开该FIFO(当前打开操作设置了阻塞标志);或者,成功返回(当前打开操作没有设置阻塞标志)。
  2. 如果当前打开操作是为而打开FIFO时,如果已经有相应进程为读而打开该FIFO,则当前打开操作将成功返回;否则,可能阻塞直到有相应进程为读而打开该FIFO(当前打开操作设置了阻塞标志);或者,返回ENXIO错误(当前打开操作没有设置阻塞标志)。
一旦设置了阻塞标志,调用mkfifo建立好之后,那么管道的两端读写必须分别打开,有任何一方未打开,则在调用open的时候就阻塞

管道写:

//pipe_read.c

#include <stdio.h>  
#include <stdlib.h>  
#include <string.h>  
#include <fcntl.h>  
#include <limits.h>  
#include <sys/types.h>  
#include <sys/stat.h>  
  
#define FIFO_NAME "/tmp/my_fifo"  
#define BUFFER_SIZE PIPE_BUF  
  
int main()  
{  
    int pipe_fd;  
    int res;  
  
    int open_mode = O_RDONLY;  
    char buffer[BUFFER_SIZE + 1];  
    int bytes = 0;  
  
    memset(buffer, '\0', sizeof(buffer));  
  
    printf("Process %d opeining FIFO O_RDONLY\n", getpid());  
    pipe_fd = open(FIFO_NAME, open_mode);  
    printf("Process %d result %d\n", getpid(), pipe_fd);  
  
    if (pipe_fd != -1)  
    {  
        do{  
            res = read(pipe_fd, buffer, BUFFER_SIZE);  
            bytes += res;  
        printf("%d\n",bytes);
        }while(res > 0);  
        close(pipe_fd);  
    }  
    else  
    {  
        exit(EXIT_FAILURE);  
    }  
  
    printf("Process %d finished, %d bytes read\n", getpid(), bytes);  
    exit(EXIT_SUCCESS);  
}


管道读:

//pipe_write.c

#include <stdio.h>  
#include <stdlib.h>  
#include <string.h>  
#include <fcntl.h>  
#include <limits.h>  
#include <sys/types.h>  
#include <sys/stat.h>  
  
#define FIFO_NAME "/tmp/my_fifo"  
#define BUFFER_SIZE PIPE_BUF  
#define TEN_MEG (1024 * 100)  
  
int main()  
{  
    int pipe_fd;  
    int res;  
    int open_mode = O_WRONLY;  
  
    int bytes = 0;  
    char buffer[BUFFER_SIZE + 1];  
  
    if (access(FIFO_NAME, F_OK) == -1)  
    {  
        res = mkfifo(FIFO_NAME, 0777);  
        if (res != 0)  
        {  
            fprintf(stderr, "Could not create fifo %s\n", FIFO_NAME);  
            exit(EXIT_FAILURE);  
        }  
    }  
  
    printf("Process %d opening FIFO O_WRONLY\n", getpid());  
    pipe_fd = open(FIFO_NAME, open_mode);  
    printf("Process %d result %d\n", getpid(), pipe_fd);  
  
   //sleep(20);
    if (pipe_fd != -1)  
    {  
        while (bytes < TEN_MEG)  
        {  
            res = write(pipe_fd, buffer, BUFFER_SIZE);  
            if (res == -1)  
            {  
                fprintf(stderr, "Write error on pipe\n");  
                exit(EXIT_FAILURE);  
            }  
            bytes += res;  
        printf("%d\n",bytes);
        }  
        close(pipe_fd);  
    }  
    else  
    {  
        exit(EXIT_FAILURE);  
    }  
  
    printf("Process %d finish\n", getpid());  
    exit(EXIT_SUCCESS);  
}



在嵌入式开发中,遇到 `Undefined symbol FlexCAN_RxFIFO_FilterTable` 错误通常表明链接器无法找到该符号的定义。此类错误可能由多种原因引起,包括但不限于缺少必要的库文件、未正确配置外设驱动程序或项目设置不当。 ### 常见原因与解决方案 #### 1. 缺少外设驱动支持 FlexCAN 是飞思卡尔(现为恩智浦)Kinetis 系列微控制器中的一个常见模块,用于实现 CAN 总线通信功能。如果项目中使用了 FlexCAN 模块但未包含其对应的驱动程序或库文件,则可能导致此错误[^1]。 - **解决方法**:确保项目中已正确添加并配置了 FlexCAN 的驱动代码。通常这些驱动文件可以从 MCU 厂商提供的 SDK 中获取。例如,在 NXP 提供的 MCUXpresso SDK 中,FlexCAN 相关的驱动文件通常位于 `drivers/flexcan` 目录下。 #### 2. 配置选项未启用 某些情况下,项目配置中可能没有启用 FlexCAN 模块相关的功能,导致编译器忽略相关代码段。 - **解决方法**:检查项目的配置头文件(如 `pin_mux.h` 或 `clock_config.h`),确认是否启用了 FlexCAN 模块及其 FIFO 功能。此外,还需检查是否定义了与 FlexCAN FIFO 过滤器表相关的宏定义,例如 `FSL_FEATURE_FLEXCAN_HAS_RX_FIFO_FILTER_TABLE`。 #### 3. 库版本不兼容 如果使用的 SDK 或中间件版本较旧,而代码中引用了新版本才支持的功能,则也可能出现此类问题。 - **解决方法**:升级到最新版本的 SDK 和工具链,确保所有组件之间的兼容性。同时查阅官方文档,确认 `FlexCAN_RxFIFO_FilterTable` 是否在当前版本中可用。 #### 4. 手动实现缺失函数 在某些轻量级项目或自定义平台上,开发者可能需要手动实现部分底层驱动逻辑。 - **解决方法**:若确定当前环境不支持自动处理 FIFO 过滤器表的功能,可尝试根据数据手册和应用笔记自行编写相关初始化代码。例如: ```c void FlexCAN_InitRxFIFOFilterTable(CAN_Type *base, const flexcan_rx_fifo_filter_table_t *config) { uint32_t i; for (i = 0; i < config->numFilters; i++) { base->RXFIR[i] = config->filters[i]; } } ``` 此函数假设存在一个结构体 `flexcan_rx_fifo_filter_table_t` 包含过滤器数量及具体配置值。 --- ### 示例代码片段 以下是一个简化的 FlexCAN 初始化示例,展示如何配置接收 FIFO 及其过滤器表: ```c #include "fsl_flexcan.h" // 定义过滤器表 flexcan_rx_fifo_filter_table_t rxFifoFilterTable = { .numFilters = 1, .filters = (uint32_t[]){0x12345678} // 示例过滤器值 }; int main(void) { can_config_t config; CAN_GetDefaultConfig(&config); config.enableLoopBack = false; config.enableSelfWakeup = true; CAN_Init(CAN0, &config, CLOCK_GetFreq(kCLOCK_BusClk)); // 初始化接收 FIFO 过滤器表 FlexCAN_InitRxFIFOFilterTable(CAN0, &rxFifoFilterTable); while (1) { // 主循环 } } ``` 请注意,实际代码需根据具体的硬件平台和 SDK 版本进行调整。 --- ### 调试建议 - 使用调试器查看符号表,确认 `FlexCAN_RxFIFO_FilterTable` 是否存在于最终生成的 `.elf` 文件中。 - 检查链接脚本,确保所有必要的段(如 `.text`, `.data`, `.bss`)都被正确映射。 - 启用详细的编译和链接日志,以帮助定位具体哪个阶段遗漏了该符号的引入。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值