linux posix shared memory: bus error

时间:2022-07-08 21:21:29

    用posix shared memory在两个进程之间传输600KB的数据,但是写进程在写数据的时候,老是出现bus error的错误,网上搜了一下信息,这个错误应该是由于posix shared memory文件大小有限制,申请了600KB,查看/dev/shm/cam也有600KB,但是实际上可写的没有600KB,写了下面的小程序验证。

编译方法:arm-linux-gcc -o shmtest shmtest.c -lrt
运行:
shmtest 65536 程序正常运行
shmtest 65537 程序出错
说明文件大小限制在64KB, 但是一直找不到修改 posix shared memory文件大小的方法。 后来发现在挂载文件系统时,把dev目录大小限制在64KB,而shm就在dev目录下,应该是这个问题。
    /etc/init.d/rcS中原来 挂载文件系统脚本代码:
        mount -t tmpfs -o size=64k,mode=0755 none /dev
        mkdir -p /dev/shm
    改成:
        mount -t tmpfs -o size=2048k,mode=0755 none /dev
        mkdir -p /dev/shm
        mount -t tmpfs -o size=1024k none /dev/shm
    tmpfs
    问题解决。

测试程序源码:
shmtest.c:

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h> /* ftruncate */
#include <assert.h>
#include <errno.h>
#include <fcntl.h> /* Defines O_* constants */
#include <sys/stat.h> /* Defines mode constants */
#include <sys/mman.h>
#include <limits.h>


typedef struct __cam_img_s {
unsigned char *addr;
unsigned char *r, *w, *v;
unsigned char *img_dat;
unsigned long size;
}cam_img_t;


static cam_img_t *g_cam_img = NULL;


static cam_img_t *zbar_processor_get_cam_mmap(void)
{
    g_cam_img = (cam_img_t *)calloc(1, sizeof(cam_img_t));
    printf("%d %s, g_cam_img addr=%p\n", __LINE__, __func__, g_cam_img);

    return g_cam_img;
}


static unsigned char * create_img_map(const char *name, unsigned int size)
{
    int fd = -1;
    unsigned char *addr = NULL;

    fd = shm_open(name, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR);
    if (fd < 0) {
        printf("create img share memory err(%s)\n", strerror(errno));    
        return NULL;
    }
    
    if (ftruncate(fd, size) == -1) {
        printf("set mmap file size(%u) err(%s)\n", size, strerror(errno));

       close(fd);

        return NULL;
    }

    addr = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
    if (MAP_FAILED == addr) {
        printf("mmap err(%s)\n", strerror(errno));
        close(fd);
        return NULL;
    }
    close(fd);
    return addr;
}

int main(int argc, const char *argv[])
{
        int img_size = 640*480*2;


        if (argc > 1)
            img_size = atoi(argv[1]);
        printf("img size=%d\n", img_size);

       cam_img_t *cam_img_ptr = zbar_processor_get_cam_mmap();

        memset(cam_img_ptr, 0, sizeof(*cam_img_ptr));
        cam_img_ptr->size = img_size;
        cam_img_ptr->addr = create_img_map("/cam", cam_img_ptr->size + 3);
        if (cam_img_ptr->addr) {
            cam_img_ptr->r = cam_img_ptr->addr;
            cam_img_ptr->w = cam_img_ptr->addr + 1;
           cam_img_ptr->v = cam_img_ptr->addr + 2;
           cam_img_ptr->img_dat = cam_img_ptr->addr + 3;
           *cam_img_ptr->r = *cam_img_ptr->w = *cam_img_ptr->v = 0;
        }

        while (1) {
                memset(cam_img_ptr->img_dat, 0, cam_img_ptr->size); // 这里会bus error
               sleep(1);
         }
         return 0;
}