• RT-Thread 下的文件内容对比 MSH shell cmd 命令实现方法


    前言

    • 在使用 RT-Thread 时,需要对两个文件的内容进行比较,顺手写了一个测试的 MSH shell 命令,经过优化,发现功能可以使用

    • RT-Thread 下支持多种文件系统,如FAT等,可以通过 USB、串口 的 Ymodem 等协议把文件导出到电脑上进行内容的分析,如果文件一时间无法导出,需要确认两个文件内容是否相同,怎么办?就写个简单的文件内容对比测试命令即可

    相关代码

    • RT-Thread 的 MSH shell cmd 代码,存放的位置可以随意,如可以放在专门的测试代码目录的文件中,或者main.c 中,只有构建编译到即可
    #ifdef DFS_USING_POSIX
    #include 
    #include 
    #endif /* DFS_USING_POSIX */
    
    static void _buffer_dump(char *buffer, int size)
    {
        int i;
        for(i = 0; i < size / 8; i++)
        {
            rt_kprintf("%02x %02x %02x %02x ",
                *(buffer + i * 8),
                *(buffer + i * 8 + 1),
                *(buffer + i * 8 + 2),
                *(buffer + i * 8 + 3));
    
            rt_kprintf("%02x %02x %02x %02x\r\n",
                *(buffer + i * 8 + 4),
                *(buffer + i * 8 + 5),
                *(buffer + i * 8 + 6),
                *(buffer + i * 8 + 7));
        }
    }
    
    int file_compare(int argc, char **argv)
    {
        int fd1 = -1;
        int fd2 = -1;
        int diff_count = 0;
        int dump_line = 1;
        int total_count = 0;
    
        char *rbuf1 = RT_NULL;
        char *rbuf2 = RT_NULL;
    
        rt_kprintf("%s : argc = %d\n", __func__, argc);
    
        if (argc < 3)
        {
            rt_kprintf("[Usage] : %s : file_path1 file_path2 \n", __func__);
            return -1;
        }
    
        if (argc > 3)
        {
            dump_line = atoi(argv[3]);
        }
    
        rt_kprintf("%s : argv[0] = %s \n", __func__, argv[0]);
        rt_kprintf("%s : file_path1= %s \n", __func__, argv[1]);
        rt_kprintf("%s : file_path2= %s \n", __func__, argv[2]);
    
        fd1 = open(argv[1], O_RDONLY, 0);
        if (fd1 < 0)
        {
            rt_kprintf("%s : file_path1 open fail\n", __func__);
            return -1;
        }
    
        fd2 = open(argv[2], O_RDONLY, 0);
        if (fd2 < 0)
        {
            rt_kprintf("%s : file_path2 open fail\n", __func__);
            close(fd1);
            return -1;
        }
    
        rbuf1 = rt_malloc(4096);
        if (!rbuf1)
        {
            rt_kprintf("%s : rbuf1 memory failed\n", __func__);
            close(fd1);
            close(fd2);
            return -1;
        }
    
        rt_memset(rbuf1, 0, 4096);
    
        rbuf2 = rt_malloc(4096);
        if (!rbuf2)
        {
            rt_kprintf("%s : rbuf2 memory failed\n", __func__);
            rt_free(rbuf1);
            close(fd1);
            close(fd2);
            return -1;
        }
    
        rt_memset(rbuf2, 0, 4096);
    
        rt_kprintf("%s : compare enter\n", __func__);
    
        while (read(fd1, rbuf1, 4096) > 0)
        {
            total_count++;
            if ((read(fd2, rbuf2, 4096) > 0))
            if (rt_memcmp(rbuf1, rbuf2, 4096) != 0)
            {
                diff_count++;
                rt_kprintf("%s : compare fail, count = %d\n", __func__, total_count);
                if (dump_line > 0x00)
                {
                    rt_kprintf("%s : dump file1 = %s \n", __func__, argv[1]);
                    _buffer_dump(rbuf1, 4096);
                    rt_kprintf("%s : dump file2 = %s \n", __func__, argv[2]);
                    _buffer_dump(rbuf2, 4096);
                    dump_line--;
                }
                //return -1; /* continue compare */
            }
        }
    
        close(fd1);
        close(fd2);
        rt_kprintf("%s : compare end!\n", __func__);
        rt_kprintf("%s : total_count = %d, diff_count = %d!\n", __func__, total_count, diff_count);
        rt_free(rbuf1);
        rt_free(rbuf2);
    
        return 0;
    }
    MSH_CMD_EXPORT(file_compare, file_compare);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122

    命令解释

    • 命令的格式: file_compare file1 file2 diff_page_number

    • file1 与 file2 是 两个文件,可以有路径,没有路径就是当前 shell 运行的目录下

    • diff_page_number 默认打印一个page,这里是 4K 字节,也就是每次4K 字节进行对比,如果发现内容不相同,就打印出这4K字节的数据

    运行效果

    msh />file_compare output/batch_0_ts_0.bin ref_output/rf_009_CONV_005_ts_DWH_bid0.bin
    file_compare : argc = 3
    file_compare : argv[0] = file_compare 
    file_compare : file_path1= output/batch_0_ts_0.bin 
    file_compare : file_path2= ref_output/rf_009_CONV_005_ts_DWH_bid0.bin 
    file_compare : compare enter
    file_compare : compare fail, count = 83
    file_compare : dump file1 = output/batch_0_ts_0.bin 
    14 00 0f 00 17 00 02 00
    00 1e 00 00 0b 04 0d 00
    00 1c 00 00 14 00 18 00
    07 03 10 06 0d 02 3d 00
    12 12 2f 03 00 00 17 00
    17 00 0c 00 14 00 01 00
    00 1d 03 00 07 06 0f 00
    00 13 00 00 10 00 17 00
    07 0e 16 0a 0f 04 37 00
    0d 15 26 08 00 00 10 00
    16 00 0f 00 16 00 00 00
    00 1b 00 00 0b 01 0d 00
    00 1c 00 00 11 00 16 00
    
    .....
    
    
    file_compare : dump file2 = ref_output/rf_009_CONV_005_ts_DWH_bid0.bin 
    14 00 0f 00 17 00 02 00
    00 1e 00 00 0b 04 0d 00
    00 1c 00 00 14 00 18 00
    07 03 10 06 0d 02 3d 00
    12 12 2f 03 00 00 17 00
    17 00 0c 00 14 00 01 00
    00 1d 03 00 07 06 0f 00
    00 13 00 00 10 00 17 00
    07 0e 16 0a 0f 04 37 00
    0d 15 26 08 00 00 10 00
    16 00 0f 00 16 00 00 00
    00 1b 00 00 0b 01 0d 00
    00 1c 00 00 11 00 16 00
    07 05 10 08 0c 03 3c 00
    11 0e 30 02 00 00 16 00
    18 00 0d 00 18 00 01 00
    00 1e 02 00 07 07 10 00
    
    .......
    
    
    0d 00 00 1f 00 00 00 00
    file_compare : compare fail, count = 84
    file_compare : compare fail, count = 85
    file_compare : compare fail, count = 86
    file_compare : compare fail, count = 87
    file_compare : compare fail, count = 88
    file_compare : compare fail, count = 89
    file_compare : compare fail, count = 90
    file_compare : compare fail, count = 91
    file_compare : compare fail, count = 92
    file_compare : compare fail, count = 93
    file_compare : compare fail, count = 94
    file_compare : compare fail, count = 95
    file_compare : compare fail, count = 96
    file_compare : compare fail, count = 97
    file_compare : compare fail, count = 98
    file_compare : compare fail, count = 99
    file_compare : compare fail, count = 100
    file_compare : compare fail, count = 101
    file_compare : compare fail, count = 102
    file_compare : compare fail, count = 103
    file_compare : compare fail, count = 104
    file_compare : compare fail, count = 105
    file_compare : compare fail, count = 106
    file_compare : compare fail, count = 107
    file_compare : compare fail, count = 108
    file_compare : compare fail, count = 109
    file_compare : compare fail, count = 110
    file_compare : compare fail, count = 111
    file_compare : compare fail, count = 112
    file_compare : compare fail, count = 113
    file_compare : compare fail, count = 114
    file_compare : compare fail, count = 115
    file_compare : compare fail, count = 116
    file_compare : compare fail, count = 117
    file_compare : compare fail, count = 118
    file_compare : compare fail, count = 119
    file_compare : compare fail, count = 120
    file_compare : compare fail, count = 121
    file_compare : compare fail, count = 122
    file_compare : compare fail, count = 123
    file_compare : compare fail, count = 124
    file_compare : compare fail, count = 125
    file_compare : compare fail, count = 126
    file_compare : compare fail, count = 127
    file_compare : compare fail, count = 128
    file_compare : compare fail, count = 129
    file_compare : compare fail, count = 130
    file_compare : compare fail, count = 131
    file_compare : compare fail, count = 132
    file_compare : compare fail, count = 133
    file_compare : compare fail, count = 134
    file_compare : compare fail, count = 135
    file_compare : compare fail, count = 136
    file_compare : compare fail, count = 137
    file_compare : compare fail, count = 138
    file_compare : compare fail, count = 139
    file_compare : compare fail, count = 140
    file_compare : compare fail, count = 141
    file_compare : compare fail, count = 142
    file_compare : compare fail, count = 143
    file_compare : compare fail, count = 144
    file_compare : compare fail, count = 145
    file_compare : compare fail, count = 146
    file_compare : compare fail, count = 147
    file_compare : compare fail, count = 148
    file_compare : compare fail, count = 149
    file_compare : compare fail, count = 150
    file_compare : compare fail, count = 151
    file_compare : compare fail, count = 152
    file_compare : compare fail, count = 153
    file_compare : compare fail, count = 154
    file_compare : compare fail, count = 155
    file_compare : compare fail, count = 156
    file_compare : compare fail, count = 157
    file_compare : compare fail, count = 158
    file_compare : compare fail, count = 159
    file_compare : compare fail, count = 160
    file_compare : compare end!
    file_compare : total_count = 160, diff_count = 78!
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 如以上,比对结果是失败的,默认把比对失败的第一个4K 大小的 buffer 二进制打印出来,可以复制出来使用文件对比工具,如 Beyond Compare 进行数据差异对比

    • 两个文件内容相同时的对比结果

    msh />file_compare output/batch_0_ts_0.bin ref_output/rf_009_CONV_005_ts_DWH_bid0.bin
    file_compare : argc = 3
    file_compare : argv[0] = file_compare 
    file_compare : file_path1= output/batch_0_ts_0.bin 
    file_compare : file_path2= ref_output/rf_009_CONV_005_ts_DWH_bid0.bin 
    file_compare : compare enter
    file_compare : compare end!
    file_compare : total_count = 160, diff_count = 0!
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    小结

    • 熟悉 RT-Thread MSH shell cmd 命令的编写方法,如命令行后面的参数的个数、参数的处理方法

    • shell cmd 参数的个数:argc ,命令本身算一个,也就是 file_compare f1 f2,argc = 3,其中 argv[0] = file_compare , argv[1] = f1, argv[2] = f2

    • 默认 RT-Thread 的 shell cmd 长度有限制,如果命令行很长,需要在RT-Thread 中进行配置

    在这里插入图片描述

  • 相关阅读:
    十年回望,中国物联网平台消亡史
    Mac-postman存储文件目录
    GMT安装与使用
    我最佩服的一位学生!他是哈工大在读NLP博士积累28W粉丝
    给女朋友开发个小程序低价点外卖吃还能赚钱
    3. 并发编程概述
    设计模式--访问者模式(Visitor Pattern)
    flink sql 毫秒转date ms转date
    ABAP工具箱 V1.0(附实现思路)
    8.4 数据结构——选择排序
  • 原文地址:https://blog.csdn.net/tcjy1000/article/details/127933792