从共享内存中取地图

 

//头文件
#include <sys/mman.h>
#include <sys/stat.h>
#include <memory>
#include <atomic>
#include <slam/SlamMapUpdateRange.h>


//1.共享内存结构体定义
#define MEMORY_SIZE 100 << 20   //内存预留100MB
 struct MapSharedMemory
    {
        std::atomic<bool> is_busy_;	//空闲标志位
        int size_x;	//地图长
        int size_y;	//地图宽
        int8_t map_data[MEMORY_SIZE];	//地图内存
    };
//2.初始化共享内存
    bool OpenSharedMemory() //初始化成功后/dev/shm/目录下会出现map_share_mem,大小应该等于sizeof(MapSharedMemory)
    {
	    shareId = shm_open("/map_share_mem", O_CREAT|O_RDWR|O_EXCL, 0777);
	    if(shareId < 0)
	    {
		    shareId = shm_open("/map_share_mem", O_RDWR, 0777);

	    }else
	    {
		    ftruncate(shareId, sizeof(MapSharedMemory));
	    }
        if (shareId >= 0)
        {
            shm_ptr = (MapSharedMemory*)mmap(NULL, sizeof(MapSharedMemory), PROT_READ|PROT_WRITE, MAP_SHARED, this->shareId, 0);            
        }
        if (shm_ptr != nullptr)
        {
            shm_ptr->is_busy_ = false;
            return true;
        }
        return false;
    }


//3.更新地图,
	订阅 topic: "slam/SlamMapUpdateRange".
	topic 类型为: slam::SlamMapUpdateRange
	在回调中激活地图更新
    void CopyShareMemoryThread(const slam::SlamMapUpdateRange::ConstPtr& msg)
    {
        if(!this->shm_ptr->is_busy_.exchange(true)) // 确保其他进程没有在写入或读取共享内存
        {
            if (msg->x_max - msg->x_min + 1 == shm_ptr->size_x && msg->y_max - msg->y_min + 1 == shm_ptr->size_y) // 整图更新(10000x10000 约50ms)
            {
				const int copy_size = shm_ptr->size_x * shm_ptr->size_y;
                std::memcpy(&slam_map_data_[0], shm_ptr->map_data, copy_size);
            }
            else // 局部更新(一般<5ms)
            {
                for (int x(msg->x_min); x <= msg->x_max; x++)
                {
                    const int offset(x * shm_ptr->size_y + msg->y_min);
                    const int copy_size(msg->y_max - msg->y_min + 1);
                    std::memcpy(&slam_map_data_[offset], shm_ptr->map_data + offset, copy_size);
                }          
            }    
            shm_ptr->is_busy_ = false;            
        }
    }

sharedMemory.h

/*
 * sharedMemory.h
 *
 *  Created on: 2020��7��29��
 *      Author: wayne.shen
 */

#ifndef SRC_MEDUSA_PLUGIN_OBJECTDETECTOR_SHAREDMEMORY_H_
#define SRC_MEDUSA_PLUGIN_OBJECTDETECTOR_SHAREDMEMORY_H_

#ifdef __cplusplus
extern "C"{
#endif

#include "mds_media.h"

typedef struct sharedMemory SharedImage;

int updateSharedImage(MdsImgBuf *imageBuf , void *ptr , int size , SharedImage* sharedAddr);
SharedImage *initSharedMemory(char *memoryFile);

#ifdef __cplusplus
}
#endif

#endif /* SRC_MEDUSA_PLUGIN_OBJECTDETECTOR_SHAREDMEMORY_H_ */

sharedMemory.cpp

/*
 * sharedMemory.cpp
 *
 *  Created on: 2020��7��29��
 *      Author: wayne.shen
 */

#define _DEBUG_

#include <EcoLog.h>

#include "sharedMemory.h"
#include <sys/mman.h>
#include <sys/stat.h>        /* For mode constants */
#include <unistd.h>
#include <fcntl.h>
#include <stdio.h>
#include <memory>
#include <string.h>
#include <atomic>

struct sharedMemory{
	std::atomic<bool> isUsing;
	std::atomic<bool> isUpdated;
	MdsPixFmt pixFmt;
	long int ts;
	double isp_exposure;
	double isp_gain;
	int bufSize;
	int width;
	int height;
	char imageData[2000000];
};

static int sharedFd;

SharedImage *initSharedMemory(char *memoryFile)
{
	SharedImage *sharedAddr = NULL;
	sharedFd = shm_open(memoryFile , O_CREAT|O_RDWR|O_EXCL, 0777);
	if(sharedFd < 0)
	{
		sharedFd = shm_open(memoryFile , O_RDWR, 0777);

	}else
	{
		ftruncate(sharedFd, sizeof(SharedImage));
	}


	if(sharedFd >= 0)
	{
		void *shm = mmap(NULL , sizeof(SharedImage) , PROT_READ|PROT_WRITE, MAP_SHARED, sharedFd , 0);
		close(sharedFd);
		if(shm != NULL)
		{
			sharedAddr = (SharedImage *)shm;
			sharedAddr->isUsing = false;
			sharedAddr->isUpdated = false;
		}
	}
	ECO_LOGL("shared memory:%p\n" , sharedAddr);
	return sharedAddr;
}

void OpenSharedMemory()
{
	shm_ptr = nullptr;
	shareId = shm_open("/map_share_mem", O_CREAT|O_RDWR|O_EXCL, 0777);
	if(shareId < 0)
	{
		shareId = shm_open("/map_share_mem", O_RDWR, 0777);

	}else
	{
		ftruncate(shareId, sizeof(MapSharedMamory));
	}
	if (shareId >= 0)
	{
		shm_ptr = (MapSharedMamory*)mmap(NULL, sizeof(MapSharedMamory), PROT_READ|PROT_WRITE, MAP_SHARED, this->shareId, 0);
		close(shareId);
		if (shm_ptr != nullptr)
		{
			shm_ptr->is_busy_ = false;
		}

	}
}


int updateSharedImage(MdsImgBuf *imageBuf , void *ptr , int size , SharedImage *sharedAddr)
{
	if(!sharedAddr->isUsing.exchange(true) )
	{
		ECO_LOGL("update memory:%lld %p %d %d %d\n" ,imageBuf->ts , sharedAddr , size , imageBuf->width , imageBuf->height);
		sharedAddr->pixFmt = imageBuf->pixFmt;
		sharedAddr->ts = imageBuf->ts;
		sharedAddr->isp_exposure = imageBuf->isp_exposure;
		sharedAddr->isp_gain = imageBuf->isp_gain;
		sharedAddr->bufSize = size;
		sharedAddr->width = imageBuf->width;
		sharedAddr->height = imageBuf->height;
		memcpy(sharedAddr->imageData , ptr , size);

		sharedAddr->isUpdated = true;
		sharedAddr->isUsing = false;
	}
	return 0;
}

void detectSharedMemory()
{
   if(this->sharedAddr == NULL)
      return ;
   // 设置使用中标志,防止发送端在使用时修改内容。
   if(!this->sharedAddr->isUsing.exchange(true))
   {
//        this->sharedAddr->isUsing = 1;
      if(this->sharedAddr->isUpdated)
      {
         // todo 处理数据程序
         ECO_LOGL("detect memory:%d\n" , this->sharedAddr->bufSize);
         // 处理数据后设置更新标志位
         this->sharedAddr->isUpdated = false;
      }
      // 修改处理后使用中标志位释放使用权
      this->sharedAddr->isUsing = false;
   }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

☜@_@达奚黑雁

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值