Qualcomm Share Memory

本文详细介绍了Qualcomm平台中AP与MODEM间的共享内存(SMEM)机制,包括其地址空间映射与管理方式、通信策略机制如PROC_COMM、smem_alloc、SMD通道及基于SMD的RPC远程函数调用机制。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

发现baidu文库里有个smem机制总结全的,顺便分享下

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

(共享内存2个基本点:1在本身内存内记录分配信息  2互斥访问或数据一致性  

       3(可选).如果要快速响应的必须加相互中断通知)

 

地址空间的映射与管理

SMEM_HEAP:(该图版本较老)

typedef enum

{ SMEM_MEM_FIRST,

  SMEM_PROC_COMM = SMEM_MEM_FIRST,

  SMEM_FIRST_FIXED_BUFFER = SMEM_PROC_COMM,

  SMEM_HEAP_INFO,

  ……

} smem_mem_type;1Mshare memory分为N个条目。最终实际固定了每个条目的起始地址和长度。  (详见APlinux kernelsmd.csmem_alloc2分配函数,可知不能通常意义的malloc,只是简单的动态的在尾部增长数据块,不能正真意义的回收内存空间;

总共是1M的共享内存,其中64SMD通道占用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共享内存空间的映射。第1个条目为proc_comm.其中包括最重要的条目heap_info.这个条目记录了1M share memory的每个条目的起始地址和长度。

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

上述结构体包含的struct smem_heap_entry 是记录每个条目的地址空间信息,这个一个最多记载512个条目地址信息的数组,经常是依据smem_mem_type条目号来寻找地址信息。

 

 


APMODEM等通信的几种策略机制:

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

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

3.下面是建立在smem_alloc这个机制上面的SMD。就是循环缓冲区,一端不停的写,另一端不停的读。类似于进程间通信,对上层包装成串口驱动一样的设备。实现机制同样是写数据和中断。读数据回调上层的注册函数。实现代码见smd.c,可不关心,和我们没太多联系。
使用SMD机制通道的接口是串口驱动类似的接口,smd_open,smd_write,smd_read,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
目前SMD36组通道,一般成对使用。一个MODEMAP,一个APMODEM。目前有GPSDS, 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);//RMNET

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

smd_open("SMD_RPCCALL", &smd_channel, NULL, rpcrouter_smdnotify); //smd_rpcrouter.c

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


4.最后是RPC。这个就是远程函数调用。实现机制是建立在SMD通道之上的一个机制。使用SMD通道2,命名为RPCCALL,通道3 RPCRPY。这个见smd_rpcrouter_device.csmd_rpcrouter.c。主要用法是APP调用MODEM的函数,其中可选项是MODEM端执行完函数后,是否回调APP的一个函数。在RPC中,留了一个OEM_RAPI给我们扩展。具体扩展见qualcomm文档80-VM896-1(附件)。可在KERNEL或应用程序扩展。(应用程序扩展编译时要注意不要包文档里面要求的头文件,否则编译有问题,其他按文档要求就可以)。

RPC:这个的应用最多;

比如AMSS调用kernel上报电池电量在msm_battery.c             msm_rpc_register_client("battery", BATTERY_RPC_PROG,BATTERY_RPC_VER_2_1,

      1, msm_batt_cb_func);注册clinet端函数。对应AMSSservies端。

 

msm_rpc_register_XXX----à Smd_rpcrouter_clients.c&Smd_rpcrouter_servies.c----(通过msm_rpc_write等函数接口)---------à smd_rpcrouter.c--àrpcrouter_smd_xprt.c--àsmd_open

 

另外smd_rpcrouter.c 中的rpcrouter_init ----->msm_rpcrouter_init_devicessmd_rpcrouter_device.c)建立一个class_create(THIS_MODULE, "oncrpc");设备节点。

smd_rpcrouter_device.c实现这个驱动节点的write ;read;poll,ioctl等标准操作。这些操作通过msm_rpc_write等同样调用smd_rpcrouter.c的接口。

应用层的vender/qcom/proprietary/oncrpcliboncrpc.so操作这个驱动节点。(这样在上层直接建议与MODEM的通信,可以不在kernel开源自己的代码)

              Hard/msm7K/librpc的librpc.so操作这个驱动节点。

### Linux Kernel SMEM Explanation and Usage In the context of embedded systems or mobile platforms like Android devices, `smem` (shared memory) is an area used by various components within the system to share data efficiently. This concept plays a crucial role especially when dealing with limited resources where efficient communication between different parts of hardware and software becomes essential. For instance, in Qualcomm-based SoCs (System on Chip), `smem` serves as a shared region that allows multiple processors such as CPU, DSP, GPU, etc., along with peripheral modules to communicate through predefined regions without direct interaction[^1]. The structure of `smem` typically includes headers defining its size and version followed by entries each representing specific information blocks allocated for particular purposes. These can range from simple flags indicating states to complex structures holding configuration parameters required during boot-up sequences or runtime operations. When working with tools designed specifically for interacting with these areas—such as `android-smemcap`, which requires extraction using commands similar to `'tar -xvf Android-smemcap.tar'` before installation onto targets—it's important to understand how applications access this resource safely while ensuring no conflicts arise due to simultaneous accesses from other entities sharing the same space[^2]. To interact programmatically with `smem`, developers often rely on APIs provided either directly by the operating system or custom libraries tailored towards accessing low-level functionalities not exposed otherwise. In practice, manipulating `smem` involves careful handling considering potential race conditions and synchronization issues across heterogeneous architectures present inside modern smartphones or tablets running Linux kernels optimized for power efficiency alongside performance demands. ```c #include <linux/smem.h> // Example C code snippet demonstrating basic usage pattern. struct smem_platform_data { int id; }; static struct smem_platform_data *pdata; void example_smem_usage(void){ pdata = smem_get(SMEM_ID); // Obtain pointer to desired section based on ID defined elsewhere. } ```
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值