share memory 小结(qualcom )

QUALIOMM 的AP和MODEM之间的share memory通过把共享内存的空间分成N个不定长的数据块,其中SMEM_HEAP_INFO记录每个数据块的地址信息,是否已经分配等,(只能一个宿主先分配),当然SMEM_HEAP_INFO 本身也是一个数据块。各个宿主CPU用这些数据块依照对应的数据结构进行通信,包括PROC_COMM,smem_find,以及建立在特殊数据块上的循环缓冲区smd通道,还有建立在特定通道的函数调用RPC。

共享内存两个基本点:

 1、在本身内存内记录分配信息;

 2、互斥访问或数据一致性;

 3、如果要快速相应要加相互中断通知(可选)。

地址空间的映射和管理:

SMEM_HEAP

*  All types of SMEM usage are defined in smem_mem_type.

*  The enumeration order inside smem_mem_type is not mapped as the exact order.  Refer to smem_buf_data_tbl[] for exact order of each enumeration.

*  smem_buf_data_tbl[] is declared as the size of each allocated smem_mem_type in static heap.

*  smem_get_offset() is called to count offset for each smem_mem_type in static heap when in runtime.

*  For more detail, refer to smem_boot _init().

typedef enum

{SMEM_MEM_FIRST,

SMEM_MEM_PROC = SMEM_MEM_FIRST,

SMEM_FIRST_FIXED_BUFFER = SMEM_MEM_PROC,

SMEM_HEAP_INFO,

……………………

}smem_mem_type;

将1M的share memory分为N个条目。最终实际固定了每个条目的起始地址和长度。(AP端linux kernel的smd.c的smem_alloc2分配函数,可知不能用通常意义上的alloc,只是简单的动态的在尾部曾长数据块,不能真正意义的回收内存空间;总共1M的共享内存,其中64个smd通道占用了64*8K大部分空间)。

struct smem_shared {
    struct smem_proc_comm proc_comm[4];
    unsigned version[32];
    struct smem_heap_info heap_info;
    struct smem_heap_entry heap_toc[SMD_HEAP_SIZE];//SMD_HEAP_SIZE = 512
};

这个结构对齐到share memory的起始地址,就是1M共享内存空间的映射。第一个条目proc_comm,其中包括最终要的条目heap_info.这个条目记录了1M share memory的每个条目的起始地址和长度。

上述结构中包含的struct smem_heap_info记录整个SM空间的分配情况,当前的申请地址和剩余空间。

struct smem_heap_entry是记录每个条目的地址空间信息,这是一个最多能记录512个条目地址信息的数组,通常是根据smem_mem_type条目号来寻找地址信息。


AP和MODED等通信的几种策略机制:

1、在底层数据块层次的使用是PROC_COMM,主要是最底层次的处理器间通信,不建议扩展。主要是CPU各路电源,时钟,重启等高优先级的问题。每个处理器只占4个字节。代码实现见msm_proc_comm(),就是写两个字节,发中断给CPU,等待回应。


2、另外一个是smem_alloc, smem_get_entry, smem_find.对我们目前来说,主要应用是在MODEM端写一些结构的数据到SHARE_MEMORY,AP端在合适的时候去取。这部分代码在MODEM分配内存,从AP传递,其中的几个内存管理函数比如smem_alloc是对我们屏蔽的(不能真正意义上的回收free)。注意一般是MODEM端从AP传递,反向传递不建议。


3、下面是建立在smem_alloc这个机制上的SMD,就是循环缓冲区,一端不停的写,另一端不停的读。类似于进程间通信,对上层包装成串口驱动一样的设备。实现机制同样是写数据和中断。读数据回调上层的注册函数,实现代码smd.c。使用SMD机制通道的接口是串口驱动类似的接口,smd_open ,smd_read, smd_write, smd_read_avail,可参考smd_nema.c.比如smd_open("GPSNMEA",&nmea_devp->ch,nmea_devp,nmea_notify);其中nmea_notify是有数据要读的回调函数。在nmea_notify里面去看smd_read_avail多少可读,然后smd_read去读,写就直接调用smd_write.

目前SMD有36组通道,一般成对是使用,一个MODEM向AP,一个AP向MODEM,目前有GPS,DS,DIAG,BT,RPC等使用。

SMD循环缓冲区的应用较多,可在kernel中搜索smd_open,如下:

smd_open("SMD_DIAG",&ctxt->ch,ctxt,smd_diag_notify);

smd_open(p->chname,&p->ch,dev,smd_net_notify);

smd_open("GPSNMEA",&nmea_devp->ch,nmea->devp,nmea_notify);

smd_open("SMD_RPCCALL",&smd_channel, NULL, rpcrouter_smdnotify);

smd_open(name,&info->ch,info,smd_tty_notify);//虚拟出tty设备给应用


4、最后是RPC(remote process call)远程函数调用。实现机制是建立在SMD通道之上的一个机制。使用SMD通道2,命名为RPCCALL,通道3RPCRPY。这个详见smd_rpcrouter_device.c 和smd_rpcrouter.c 。主要用法是,APP调用MODEM函数,其中可选项是MODEM端执行函数之后,是否回调APP的一个函数。在RPC中,留了一个OEM_RAPI 给我们扩展。RPC这个应用最多:

eg:AMSS 调用kernel上报电池电量在msm_battery.c中,

msm_rpc_register_client("battery",BATTERY_RPC_PROG,BATTERY_RPC_VER_2_1,1,msm_battery_cb_func);注册client端函数。对应AMSS的server端。

msm_rpc_register_XXX---->Smd_rpcrouter_client.c & Smd_rpc_router_server.c-----通过msm_rpc_write等函数接口--->smd_rpcroutr.c--->rpcrouter_smd_xprt.c---->smd_open().


另外,smd_rpcrouter.c中的rpcrouter_init---->msm_rpcrouter_init_devices(smd_rpcrouter_device.c)建立一个class_creae(THIS_MODULE,oncrpc)设备节点。smd_rpcrouter_device.c实现这个节点的write,read,pull,iotcl等标准操作。这些操作通过条用msm_rpc_write等同样调用smd_rpcrouter.c的接口。

应用层的vendor/qcom/proprietary/oncrpc/的liboncrpc.so操作这个驱动节点。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值