用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
mkdir -p /dev/shm
改成:
mount -t tmpfs -o size=2048k,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;
}