点击打开链接

概述

MSM平台AP和CP封装到一个芯片,共享内容。所以之前也说过,高通的MSM解决方案中,CP的代码都是由AP放到指定地址的内存中以供CP运行。那上传完代码,CP开始跑之后,AP/CP之间的通信又是怎么弄的呢? 
其实也是在内存中开辟一段共享内存进行通信的。高通文档中有介绍以下三种。

  • SMD : Shared Memory Driver
  • SMEM : Shared Memory Manager
  • SMSM : Shared State Machine

来看一下上面三种共享内存的具体说明:

SMEM :

  • Shared memory service, provides basic SMEM allocation services
  • Section of physical RAM is located at a predetermined location, sharing between 
    processors
  • Provides low-level interprocessor communication primitives (apps processor to 
    modem processor) that can be called from interrupt context

SMSM:

  • Shared memory state machine
  • Provides low-level synchronization between different processors

SMD :

  • Shared memory driver
  • Provides multiple data channels

smd channel setup过程

1.首先Modem会调用sio_open()等函数接口,根据port id打开一个smd port。smd_sio_open()函数会被调用。然后smdi_alloc_channel_info()函数会在shared memory分配一个port.

2.在AP端,msm_smd_probe()会启动一个wrker thread,叫smd_channel_probe_worker()。这个函数会detect所有已经被modem端分配过的smd channel。通过这一步之后,驱动函数就可以通过smd channel名字打开一个smd channel。

实际在smd_init_dt.c的 msm_smd_probe()函数中添加log输出结果为:

  1. <6>[0.538769] [0:swapper/0:1] msm_smd_probe remote_pid=1
  2. <6>[0.539232] [0:swapper/0:1] msm_smd_probe remote_pid=4
  3. <6>[0.539665] [0:swapper/0:1] msm_smd_probe remote_pid=6
    • 1
    • 2
    • 3
    • 1
    • 2
    • 3

当然这个结果是根据dtsi文件定义里读出来的内容。

  1. qcom,smd-modem {
  2. compatible = "qcom,smd";
  3. qcom,smd-edge = <0>;
  4. qcom,smd-irq-offset = <0x0>;
  5. qcom,smd-irq-bitmask = <0x1000>;
  6. interrupts = <0 25 1>;
  7. label = "modem";
  8. };
  9. ...
  10. qcom,smd-wcnss {
  11. compatible = "qcom,smd";
  12. qcom,smd-edge = <6>;
  13. qcom,smd-irq-offset = <0x0>;
  14. qcom,smd-irq-bitmask = <0x20000>;
  15. interrupts = <0 142 1>;
  16. label = "wcnss";
  17. };
  18. ...
  19. qcom,smd-rpm {
  20. compatible = "qcom,smd";
  21. qcom,smd-edge = <15>;
  22. qcom,smd-irq-offset = <0x0>;
  23. qcom,smd-irq-bitmask = <0x1>;
  24. interrupts = <0 168 1>;
  25. label = "rpm";
  26. qcom,irq-no-suspend;
  27. qcom,not-loadable;
  28. };
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28

上面定义的edge,用来根据edge_to_pids变量来转换成remote pid。edge对应的值是以下枚举类型。

  1. enum {
  2. SMD_APPS_MODEM = 0,
  3. SMD_APPS_QDSP,
  4. SMD_MODEM_QDSP,
  5. SMD_APPS_DSPS,
  6. SMD_MODEM_DSPS,
  7. SMD_QDSP_DSPS,
  8. SMD_APPS_WCNSS,
  9. SMD_MODEM_WCNSS,
  10. SMD_QDSP_WCNSS,
  11. SMD_DSPS_WCNSS,
  12. SMD_APPS_Q6FW,
  13. SMD_MODEM_Q6FW,
  14. SMD_QDSP_Q6FW,
  15. SMD_DSPS_Q6FW,
  16. SMD_WCNSS_Q6FW,
  17. SMD_APPS_RPM,
  18. SMD_MODEM_RPM,
  19. SMD_QDSP_RPM,
  20. SMD_WCNSS_RPM,
  21. SMD_TZ_RPM,
  22. SMD_NUM_TYPE,
  23. };
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

然后在smd_channel_probe_worker()->scan_alloc_table函数中添加log。

  1. static void smd_channel_probe_worker(struct work_struct *work)
  2. {
  3. struct smd_alloc_elm *shared;
  4. struct remote_proc_info *r_info;
  5. unsigned tbl_size;
  6. r_info = container_of(work, struct remote_proc_info, probe_work);
  7. //ID_CH_ALLOC_TBL,SMEM_CHANNEL_ALLOC_TBL_2 到底是什么??
  8. shared = smem_get_entry(ID_CH_ALLOC_TBL, &tbl_size,
  9. r_info->remote_pid, 0);
  10. if (!shared) {
  11. pr_err("%s: allocation table not initialized\n", __func__);
  12. return;
  13. }
  14. mutex_lock(&smd_probe_lock);
  15. scan_alloc_table(shared, r_info->ch_allocated, PRI_ALLOC_TBL,
  16. tbl_size / sizeof(*shared),
  17. r_info);
  18. shared = smem_get_entry(SMEM_CHANNEL_ALLOC_TBL_2, &tbl_size,
  19. r_info->remote_pid, 0);
  20. if (shared)
  21. scan_alloc_table(shared,
  22. &(r_info->ch_allocated[SMEM_NUM_SMD_STREAM_CHANNELS]),
  23. SEC_ALLOC_TBL,
  24. tbl_size / sizeof(*shared),
  25. r_info);
  26. mutex_unlock(&smd_probe_lock);
  27. }
  28. static void scan_alloc_table(struct smd_alloc_elm *shared,
  29. char *smd_ch_allocated,
  30. int table_id,
  31. unsigned num_entries,
  32. struct remote_proc_info *r_info)
  33. {
  34. if (!smd_alloc_channel(&shared[n], table_id, r_info)) {
  35. pr_info("shared[%d].name = %s, r_info->remote_pid = %d table_id=%d\n",n,shared[n].name,r_info->remote_pid,table_id);
  36. smd_ch_allocated[n] = 1;
  37. }
  38. else
  39. SMD_INFO(
  40. "Probe skipping proc %d, tbl %d, ch %d, not allocated\n",
  41. r_info->remote_pid, table_id, n);
  42. }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49

输出的log结果为:

  1. //以下log里边shared[x]中,x代表port ID,和打印所有的qc_smd_ch_xxx.log里边的ID对应!
  2. <6>[0.544016][0:kworker/0:1:34] shared[4].name = rpm_requests, r_info->remote_pid = 6 table_id=1
  3. <6>[10.294419][0:kworker/0:1:34] shared[1].name = IPCRTR, r_info->remote_pid = 1 table_id=1
  4. <6>[10.295081][0:kworker/0:1:34] shared[2].name = SSM_RTR_MODEM_APPS, r_info->remote_pid = 1 table_id=1
  5. <6>[10.848152][0:kworker/0:1:34] shared[3].name = sys_mon, r_info->remote_pid = 1 table_id=1
  6. <6>[10.863365][0:kworker/0:1:34] shared[4].name = DIAG_2_CMD, r_info->remote_pid = 1 table_id=1
  7. <6>[10.864631][0:kworker/0:1:34] shared[5].name = DIAG_2, r_info->remote_pid = 1 table_id=1
  8. <6>[10.866978][0:kworker/0:1:34] shared[6].name = DIAG_CNTL, r_info->remote_pid = 1 table_id=1
  9. <6>[10.868057][0:kworker/0:1:34] shared[7].name = DIAG_CMD, r_info->remote_pid = 1 table_id=1
  10. <6>[10.869126][0:kworker/0:1:34] shared[8].name = DIAG, r_info->remote_pid = 1 table_id=1
  11. <6>[10.874224][0:kworker/0:1:34] shared[9].name = apr_audio_svc, r_info->remote_pid = 1 table_id=1
  12. <6>[10.874991][0:kworker/0:1:34] shared[10].name = apr_apps2, r_info->remote_pid = 1 table_id=1
  13. <6>[12.453190][0:kworker/0:1:34] shared[1].name = IPCRTR, r_info->remote_pid = 4 table_id=1
  14. <6>[12.454124][0:kworker/0:1:34] shared[2].name = sys_mon, r_info->remote_pid = 4 table_id=1
  15. <6>[12.455103][0:kworker/0:1:34] shared[3].name = APPS_RIVA_CTRL, r_info->remote_pid = 4 table_id=1
  16. <6>[12.456004][0:kworker/0:1:34] shared[4].name = APPS_RIVA_DATA, r_info->remote_pid = 4 table_id=1
  17. <6>[12.583796][0:kworker/0:1:34] shared[5].name = WCNSS_CTRL, r_info->remote_pid = 4 table_id=1
  18. <6>[12.584751][0:kworker/0:1:34] shared[6].name = WLAN_CTRL, r_info->remote_pid = 4 table_id=1
  19. <6>[12.836919][0:kworker/0:1:34] shared[7].name = APPS_RIVA_BT_CMD, r_info->remote_pid = 4 table_id=1
  20. <6>[12.837876][0:kworker/0:1:34] shared[8].name = APPS_RIVA_BT_ACL, r_info->remote_pid = 4 table_id=1
  21. <6>[12.838729][0:kworker/0:1:34] shared[9].name = APPS_RIVA_ANT_CMD, r_info->remote_pid = 4 table_id=1
  22. <6>[12.839399][0:kworker/0:1:34] shared[10].name = APPS_RIVA_ANT_DATA, r_info->remote_pid = 4 table_id=1
  23. <6>[12.843247][0:kworker/0:1:34] shared[11].name = APPS_FM, r_info->remote_pid = 4 table_id=1
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

这里显示的都是在启动的时候扫描smd之后,调用smd_alloc_channel()函数初始化相应的数据结构之后的结果。 
在smd_alloc_channel()函数中,会根据上面的名字,初始化一个platform device!!之后也是会根据这个名字来注册platform driver。这些platform driver当然可以在/sys/devices/platform/目录下是看得到的。

  1. //smd相关的platform设备会根据SIM卡或者网络条件有不同。
  2. root@gtelwifiue:/sys/devices/platform # ls
  3. APPS_FM.6
  4. APPS_RIVA_ANT_CMD.6
  5. APPS_RIVA_ANT_DATA.6
  6. APPS_RIVA_BT_ACL.6
  7. APPS_RIVA_BT_CMD.6
  8. APPS_RIVA_CTRL.6
  9. APPS_RIVA_DATA.6
  10. DIAG.0
  11. DIAG_2.0
  12. DIAG_2_CMD.0
  13. DIAG_CMD.0
  14. DIAG_CNTL.0
  15. IPCRTR.0
  16. IPCRTR.6
  17. SSM_RTR_MODEM_APPS.0
  18. SVC0000000e:00000001.1
  19. SVC0000000f:00000001.1
  20. SVC0000000f:00000001.2
  21. SVC00000010:00000002.1
  22. SVC00000016:00000101.1
  23. SVC00000017:00000001.1
  24. SVC00000018:00000001.1
  25. SVC0000001c:00000001.1
  26. SVC0000001c:00000101.1
  27. SVC00000022:00000001.1
  28. SVC0000002b:00000001.1
  29. SVC00000034:00000101.1
  30. SVC000000e8:00000101.1
  31. SVC00000100:00000100.1
  32. SVC00000100:00000100.2
  33. WCNSS_CTRL.6
  34. WLAN_CTRL.6
  35. alarmtimer
  36. apr_apps2.0
  37. apr_audio_svc.0
  38. msm_hsusb
  39. msm_hsusb_host
  40. power
  41. reg-dummy
  42. regulatory.0
  43. rpm_requests.15
  44. sec-thermistor
  45. secgpio_dvs
  46. snd-soc-dummy
  47. sys_mon.0
  48. sys_mon.6
  49. uevent
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49

qc_smd_ch_xxx.log

  1. Primary allocation table:
  2. ID|CHANNEL NAME |T|PROC |STATE |FIFO SZ|RDPTR |WRPTR |FLAGS |DATAPEN
  3. -------------------------------------------------------------------------------
  4. 4|rpm_requests |P|APPS |OPENED |0x00400|0x00188|0x00188|DCCiwRsB|0x00000
  5. | | |RPM |OPENED |0x00400|0x000A0|0x000A0|DCCiwrsB|0x00000
  6. -------------------------------------------------------------------------------
  7. 5|rpm_requests |P|MDMSW| Access Restricted
  8. | | |RPM | Access Restricted
  9. -------------------------------------------------------------------------------
  10. 6|rpm_requests |P|WCNSS| Access Restricted
  11. | | |RPM | Access Restricted
  12. -------------------------------------------------------------------------------
  13. 7|rpm_requests |P|TZ | Access Restricted
  14. | | |RPM | Access Restricted
  15. -------------------------------------------------------------------------------
  16. APPS <-> MDMSW Primary allocation table:
  17. ID|CHANNEL NAME |T|PROC |STATE |FIFO SZ|RDPTR |WRPTR |FLAGS |DATAPEN
  18. -------------------------------------------------------------------------------
  19. 0|DS |S|APPS |OPENED |0x02000|0x00000|0x00000|DCCiwrsB|0x00000
  20. | | |MDMSW|OPENED |0x02000|0x00000|0x00000|dCciwrsb|0x00000
  21. -------------------------------------------------------------------------------
  22. 1|IPCRTR |P|APPS |OPENED |0x02000|0x00F28|0x00F28|DCCiwrsB|0x00000
  23. | | |MDMSW|OPENED |0x02000|0x00DAC|0x00DAC|DCCiwrsB|0x00000
  24. -------------------------------------------------------------------------------
  25. 2|SSM_RTR_MODEM_APPS |P|APPS |CLOSED |0x02000|0x00000|0x00000|dcciwrsb|0x00000
  26. | | |MDMSW|OPENING|0x02000|0x00000|0x00000|DCCiwrSb|0x00000
  27. -------------------------------------------------------------------------------
  28. 3|sys_mon |P|APPS |OPENED |0x00400|0x002BE|0x002BE|DCCiwrsB|0x00000
  29. | | |MDMSW|OPENED |0x00400|0x00060|0x00060|DCCiwrsB|0x00000
  30. -------------------------------------------------------------------------------
  31. 4|DIAG_2_CMD |P|APPS |OPENED |0x02000|0x00000|0x00000|DCCiwrsb|0x00000
  32. | | |MDMSW|OPENED |0x02000|0x00000|0x00000|DCCiwrsb|0x00000
  33. -------------------------------------------------------------------------------
  34. 5|DIAG_2 |P|APPS |OPENED |0x02000|0x00000|0x00000|DCCiwrsb|0x00000
  35. | | |MDMSW|OPENED |0x02000|0x00000|0x00000|DCCiwrsb|0x00000
  36. -------------------------------------------------------------------------------
  37. 6|DIAG_CNTL |P|APPS |OPENED |0x02000|0x00083|0x00083|DCCiwrsb|0x00000
  38. | | |MDMSW|OPENED |0x02000|0x00471|0x00471|DCCiwrsB|0x00000
  39. -------------------------------------------------------------------------------
  40. 7|DIAG_CMD |P|APPS |OPENED |0x02000|0x00000|0x00000|DCCiwrsb|0x00000
  41. | | |MDMSW|OPENED |0x02000|0x00000|0x00000|DCCiwrsb|0x00000
  42. -------------------------------------------------------------------------------
  43. 8|DIAG |P|APPS |OPENED |0x02000|0x00000|0x00000|DCCiwrsb|0x00000
  44. | | |MDMSW|OPENED |0x02000|0x00026|0x00026|DCCiwrsB|0x00000
  45. -------------------------------------------------------------------------------
  46. 9|apr_audio_svc |P|APPS |OPENED |0x02000|0x0064E|0x0064E|DCCiwrsB|0x00000
  47. | | |MDMSW|OPENED |0x02000|0x01C70|0x01C70|DCCiwrsB|0x00000
  48. -------------------------------------------------------------------------------
  49. 10|apr_apps2 |P|APPS |CLOSED |0x02000|0x00000|0x00000|dcciwrsb|0x00000
  50. | | |MDMSW|OPENING|0x02000|0x00000|0x00000|DCCiwrSb|0x00000
  51. -------------------------------------------------------------------------------
  52. 11|DATA1 |P|APPS |CLOSED |0x02000|0x00000|0x00000|dcciwrsb|0x00000
  53. | | |MDMSW|OPENING|0x02000|0x00000|0x00000|dCciwrSb|0x00000
  54. -------------------------------------------------------------------------------
  55. 12|DATA2 |P|APPS |CLOSED |0x02000|0x00000|0x00000|dcciwrsb|0x00000
  56. | | |MDMSW|OPENING|0x02000|0x00000|0x00000|dCciwrSb|0x00000
  57. -------------------------------------------------------------------------------
  58. 13|DATA3 |P|APPS |CLOSED |0x02000|0x00000|0x00000|dcciwrsb|0x00000
  59. | | |MDMSW|OPENING|0x02000|0x00000|0x00000|dCciwrSb|0x00000
  60. -------------------------------------------------------------------------------
  61. 14|DATA4 |P|APPS |CLOSED |0x02000|0x00000|0x00000|dcciwrsb|0x00000
  62. | | |MDMSW|OPENING|0x02000|0x00000|0x00000|dCciwrSb|0x00000
  63. -------------------------------------------------------------------------------
  64. 15|DATA11 |S|APPS |CLOSED |0x02000|0x00000|0x00000|dcciwrsb|0x00000
  65. | | |MDMSW|OPENING|0x02000|0x00000|0x00000|dCciwrSb|0x00000
  66. -------------------------------------------------------------------------------
  67. 16|DATA40 |P|APPS |CLOSED |0x02000|0x00000|0x00000|dcciwrsb|0x00000
  68. | | |MDMSW|OPENING|0x02000|0x00000|0x00000|dcciwrSb|0x00000
  69. -------------------------------------------------------------------------------
  70. 17|DATA5_CNTL |P|APPS |OPENED |0x00400|0x001AA|0x001AA|DCCiwrsB|0x00000
  71. | | |MDMSW|OPENED |0x00400|0x00208|0x00208|DCCiwrsB|0x00000
  72. -------------------------------------------------------------------------------
  73. 18|DATA6_CNTL |P|APPS |OPENED |0x00400|0x00338|0x00338|DCCiwrsB|0x00000
  74. | | |MDMSW|OPENED |0x00400|0x00363|0x00363|DCCiwrsB|0x00000
  75. -------------------------------------------------------------------------------
  76. 19|DATA7_CNTL |P|APPS |OPENED |0x00400|0x001A2|0x001A2|DCCiwrsB|0x00000
  77. | | |MDMSW|OPENED |0x00400|0x001F7|0x001F7|DCCiwrsB|0x00000
  78. -------------------------------------------------------------------------------
  79. 20|DATA8_CNTL |P|APPS |OPENED |0x00400|0x001A2|0x001A2|DCCiwrsB|0x00000
  80. | | |MDMSW|OPENED |0x00400|0x001F7|0x001F7|DCCiwrsB|0x00000
  81. -------------------------------------------------------------------------------
  82. 21|DATA9_CNTL |P|APPS |OPENED |0x00400|0x001A2|0x001A2|DCCiwrsB|0x00000
  83. | | |MDMSW|OPENED |0x00400|0x001F7|0x001F7|DCCiwrsB|0x00000
  84. -------------------------------------------------------------------------------
  85. 22|DATA12_CNTL |P|APPS |OPENED |0x00400|0x001A2|0x001A2|DCCiwrsB|0x00000
  86. | | |MDMSW|OPENED |0x00400|0x001F7|0x001F7|DCCiwrsB|0x00000
  87. -------------------------------------------------------------------------------
  88. 23|DATA13_CNTL |P|APPS |OPENED |0x00400|0x001A2|0x001A2|DCCiwrsB|0x00000
  89. | | |MDMSW|OPENED |0x00400|0x001F7|0x001F7|DCCiwrsB|0x00000
  90. -------------------------------------------------------------------------------
  91. 24|DATA14_CNTL |P|APPS |OPENED |0x00400|0x001A2|0x001A2|DCCiwrsB|0x00000
  92. | | |MDMSW|OPENED |0x00400|0x001F7|0x001F7|DCCiwrsB|0x00000
  93. -------------------------------------------------------------------------------
  94. 25|DATA15_CNTL |P|APPS |CLOSED |0x00400|0x00000|0x00000|dcciwrsb|0x00000
  95. | | |MDMSW|OPENING|0x00400|0x00000|0x00000|DCCiwrSb|0x00000
  96. -------------------------------------------------------------------------------
  97. 26|DATA16_CNTL |P|APPS |CLOSED |0x00400|0x00000|0x00000|dcciwrsb|0x00000
  98. | | |MDMSW|OPENING|0x00400|0x00000|0x00000|DCCiwrSb|0x00000
  99. -------------------------------------------------------------------------------
  100. 27|DATA40_CNTL |P|APPS |CLOSED |0x02000|0x00000|0x00000|dcciwrsb|0x00000
  101. | | |MDMSW|OPENING|0x02000|0x00000|0x00000|DCCiwrSb|0x00000
  102. -------------------------------------------------------------------------------
  103. APPS <-> WCNSS Primary allocation table:
  104. ID|CHANNEL NAME |T|PROC |STATE |FIFO SZ|RDPTR |WRPTR |FLAGS |DATAPEN
  105. -------------------------------------------------------------------------------
  106. 1|IPCRTR |P|APPS |OPENED |0x02000|0x00168|0x00168|DCCiwrsB|0x00000
  107. | | |WCNSS|OPENED |0x02000|0x000D8|0x000D8|DCCiwrsB|0x00000
  108. -------------------------------------------------------------------------------
  109. 2|sys_mon |P|APPS |OPENED |0x00400|0x00267|0x00267|DCCiwRsB|0x00000
  110. | | |WCNSS|OPENED |0x00400|0x003D4|0x003D4|DCCiwrsB|0x00000
  111. -------------------------------------------------------------------------------
  112. 3|APPS_RIVA_CTRL |P|APPS |OPENED |0x02000|0x00062|0x00062|DCCiwrsb|0x00000
  113. | | |WCNSS|OPENED |0x02000|0x00282|0x00282|DCCiwrsB|0x00000
  114. -------------------------------------------------------------------------------
  115. 4|APPS_RIVA_DATA |P|APPS |OPENED |0x02000|0x00000|0x00000|DCCiwrsb|0x00000
  116. | | |WCNSS|OPENED |0x02000|0x00000|0x00000|DCCiwrsb|0x00000
  117. -------------------------------------------------------------------------------
  118. 5|WCNSS_CTRL |P|APPS |OPENED |0x02000|0x01638|0x01638|DCCiwrsB|0x00000
  119. | | |WCNSS|OPENED |0x02000|0x00175|0x00175|DCCiwrsB|0x00000
  120. -------------------------------------------------------------------------------
  121. 6|WLAN_CTRL |P|APPS |OPENED |0x02000|0x00277|0x00277|DCCiwrsB|0x00000
  122. | | |WCNSS|OPENED |0x02000|0x01115|0x01115|DCCiwrsB|0x00000
  123. -------------------------------------------------------------------------------
  124. 7|APPS_RIVA_BT_CMD |P|APPS |OPENED |0x02000|0x0182C|0x0182C|DCCiwrsB|0x00000
  125. | | |WCNSS|OPENED |0x02000|0x01AE5|0x01AE5|DCCiwrsB|0x00000
  126. -------------------------------------------------------------------------------
  127. 8|APPS_RIVA_BT_ACL |P|APPS |OPENED |0x02000|0x01904|0x01904|DCCiwrsB|0x00000
  128. | | |WCNSS|OPENED |0x02000|0x015E8|0x015E8|DCCiwrsB|0x00000
  129. -------------------------------------------------------------------------------
  130. 9|APPS_RIVA_ANT_CMD |P|APPS |CLOSED |0x00400|0x00000|0x00000|dcciwrsb|0x00000
  131. | | |WCNSS|OPENING|0x00400|0x00000|0x00000|DCCiwrSb|0x00000
  132. -------------------------------------------------------------------------------
  133. 10|APPS_RIVA_ANT_DATA |P|APPS |CLOSED |0x00800|0x00000|0x00000|dcciwrsb|0x00000
  134. | | |WCNSS|OPENING|0x00800|0x00000|0x00000|DCCiwrSb|0x00000
  135. -------------------------------------------------------------------------------
  136. 11|APPS_FM |P|APPS |CLOSED |0x02000|0x00000|0x00000|dcciwrsb|0x00000
  137. | | |WCNSS|OPENING|0x02000|0x00000|0x00000|DCCiwrSb|0x00000
  138. -------------------------------------------------------------------------------
  139.  
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143

每个port名字和对应的生成的节点之间的关系,可以再msm8916.dtsi文件中找得到。 
比如在msm_smd_pkt.c文件中,parse_smdpkt_devicetree()函数中可以看到在读qcom,smdpkt-dev-name的信息,然后后面会根据这个名字调用device_create()函数!!虽然msm_smd_tty.c对应的”qcom,smdtty”中没有用”qcom,smdpkt-dev-name”定义设备名字,但一般在alias{}那里都定义了一个别名,好像都是根据这个别名来定的设备的名字!!

  1. aliases {
  2. sdhc1 = &sdhc_1; /* SDC1 eMMC slot */
  3. sdhc2 = &sdhc_2; /* SDC2 SD card slot */
  4. /* smdtty devices */
  5. smd0 = &smdtty_ds;
  6. smd1 = &smdtty_apps_fm;
  7. smd2 = &smdtty_apps_riva_bt_acl;
  8. smd3 = &smdtty_apps_riva_bt_cmd;
  9. smd4 = &smdtty_mbalbridge;
  10. smd5 = &smdtty_apps_riva_ant_cmd;
  11. smd6 = &smdtty_apps_riva_ant_data;
  12. smd7 = &smdtty_data1;
  13. smd8 = &smdtty_data4;
  14. smd11 = &smdtty_data11;
  15. smd21 = &smdtty_data21;
  16. smd36 = &smdtty_loopback;
  17. //spi0 = &spi_0; /* SPI0 controller device */
  18. i2c0 = &i2c_0; /* I2C0 controller device */
  19. i2c1 = &i2c_1; /* I2C1 controller device */
  20. i2c5 = &i2c_5; /* I2C5 controller device */
  21. i2c6 = &i2c_6; /* I2C6 NFC qup6 device */
  22. i2c4 = &i2c_4; /* I2C4 controller device */
  23. };
  24. qcom,smdtty {
  25. compatible = "qcom,smdtty";
  26. smdtty_ds: qcom,smdtty-ds {
  27. qcom,smdtty-remote = "modem";
  28. qcom,smdtty-port-name = "DS";
  29. };
  30. smdtty_apps_fm: qcom,smdtty-apps-fm {
  31. qcom,smdtty-remote = "wcnss";
  32. qcom,smdtty-port-name = "APPS_FM";
  33. };
  34. smdtty_apps_riva_bt_acl: smdtty-apps-riva-bt-acl {
  35. qcom,smdtty-remote = "wcnss";
  36. qcom,smdtty-port-name = "APPS_RIVA_BT_ACL";
  37. };
  38. smdtty_apps_riva_bt_cmd: qcom,smdtty-apps-riva-bt-cmd {
  39. qcom,smdtty-remote = "wcnss";
  40. qcom,smdtty-port-name = "APPS_RIVA_BT_CMD";
  41. };
  42. smdtty_mbalbridge: qcom,smdtty-mbalbridge {
  43. qcom,smdtty-remote = "modem";
  44. qcom,smdtty-port-name = "MBALBRIDGE";
  45. };
  46. smdtty_apps_riva_ant_cmd: smdtty-apps-riva-ant-cmd {
  47. qcom,smdtty-remote = "wcnss";
  48. qcom,smdtty-port-name = "APPS_RIVA_ANT_CMD";
  49. };
  50. smdtty_apps_riva_ant_data: smdtty-apps-riva-ant-data {
  51. qcom,smdtty-remote = "wcnss";
  52. qcom,smdtty-port-name = "APPS_RIVA_ANT_DATA";
  53. };
  54. smdtty_data1: qcom,smdtty-data1 {
  55. qcom,smdtty-remote = "modem";
  56. qcom,smdtty-port-name = "DATA1";
  57. };
  58. smdtty_data4: qcom,smdtty-data4 {
  59. qcom,smdtty-remote = "modem";
  60. qcom,smdtty-port-name = "DATA4";
  61. };
  62. smdtty_data11: qcom,smdtty-data11 {
  63. qcom,smdtty-remote = "modem";
  64. qcom,smdtty-port-name = "DATA11";
  65. };
  66. smdtty_data21: qcom,smdtty-data21 {
  67. qcom,smdtty-remote = "modem";
  68. qcom,smdtty-port-name = "DATA21";
  69. };
  70. smdtty_loopback: smdtty-loopback {
  71. qcom,smdtty-remote = "modem";
  72. qcom,smdtty-port-name = "LOOPBACK";
  73. qcom,smdtty-dev-name = "LOOPBACK_TTY";
  74. };
  75. };
  76. //tty和pkt不一样,分别对应msm_smd_tty.c和msm_smd_pkt.c文件!!
  77. qcom,smdpkt {
  78. compatible = "qcom,smdpkt";
  79. qcom,smdpkt-data5-cntl {
  80. qcom,smdpkt-remote = "modem";
  81. qcom,smdpkt-port-name = "DATA5_CNTL";
  82. qcom,smdpkt-dev-name = "smdcntl0";
  83. };
  84. qcom,smdpkt-data6-cntl {
  85. qcom,smdpkt-remote = "modem";
  86. qcom,smdpkt-port-name = "DATA6_CNTL";
  87. qcom,smdpkt-dev-name = "smdcntl1";
  88. };
  89. qcom,smdpkt-data7-cntl {
  90. qcom,smdpkt-remote = "modem";
  91. qcom,smdpkt-port-name = "DATA7_CNTL";
  92. qcom,smdpkt-dev-name = "smdcntl2";
  93. };
  94. qcom,smdpkt-data8-cntl {
  95. qcom,smdpkt-remote = "modem";
  96. qcom,smdpkt-port-name = "DATA8_CNTL";
  97. qcom,smdpkt-dev-name = "smdcntl3";
  98. };
  99. qcom,smdpkt-data9-cntl {
  100. qcom,smdpkt-remote = "modem";
  101. qcom,smdpkt-port-name = "DATA9_CNTL";
  102. qcom,smdpkt-dev-name = "smdcntl4";
  103. };
  104. qcom,smdpkt-data12-cntl {
  105. qcom,smdpkt-remote = "modem";
  106. qcom,smdpkt-port-name = "DATA12_CNTL";
  107. qcom,smdpkt-dev-name = "smdcntl5";
  108. };
  109. qcom,smdpkt-data13-cntl {
  110. qcom,smdpkt-remote = "modem";
  111. qcom,smdpkt-port-name = "DATA13_CNTL";
  112. qcom,smdpkt-dev-name = "smdcntl6";
  113. };
  114. qcom,smdpkt-data14-cntl {
  115. qcom,smdpkt-remote = "modem";
  116. qcom,smdpkt-port-name = "DATA14_CNTL";
  117. qcom,smdpkt-dev-name = "smdcntl7";
  118. };
  119. qcom,smdpkt-data15-cntl {
  120. qcom,smdpkt-remote = "modem";
  121. qcom,smdpkt-port-name = "DATA15_CNTL";
  122. qcom,smdpkt-dev-name = "smdcntl9";
  123. };
  124. qcom,smdpkt-data16-cntl {
  125. qcom,smdpkt-remote = "modem";
  126. qcom,smdpkt-port-name = "DATA16_CNTL";
  127. qcom,smdpkt-dev-name = "smdcntl10";
  128. };
  129. qcom,smdpkt-data17-cntl {
  130. qcom,smdpkt-remote = "modem";
  131. qcom,smdpkt-port-name = "DATA17_CNTL";
  132. qcom,smdpkt-dev-name = "smdcntl11";
  133. };
  134. qcom,smdpkt-data22 {
  135. qcom,smdpkt-remote = "modem";
  136. qcom,smdpkt-port-name = "DATA22";
  137. qcom,smdpkt-dev-name = "smd22";
  138. };
  139. qcom,smdpkt-data23-cntl {
  140. qcom,smdpkt-remote = "modem";
  141. qcom,smdpkt-port-name = "DATA23_CNTL";
  142. qcom,smdpkt-dev-name = "smdcnt_rev0";
  143. };
  144. qcom,smdpkt-data24-cntl {
  145. qcom,smdpkt-remote = "modem";
  146. qcom,smdpkt-port-name = "DATA24_CNTL";
  147. qcom,smdpkt-dev-name = "smdcnt_rev1";
  148. };
  149. qcom,smdpkt-data25-cntl {
  150. qcom,smdpkt-remote = "modem";
  151. qcom,smdpkt-port-name = "DATA25_CNTL";
  152. qcom,smdpkt-dev-name = "smdcnt_rev2";
  153. };
  154. qcom,smdpkt-data26-cntl {
  155. qcom,smdpkt-remote = "modem";
  156. qcom,smdpkt-port-name = "DATA26_CNTL";
  157. qcom,smdpkt-dev-name = "smdcnt_rev3";
  158. };
  159. qcom,smdpkt-data27-cntl {
  160. qcom,smdpkt-remote = "modem";
  161. qcom,smdpkt-port-name = "DATA27_CNTL";
  162. qcom,smdpkt-dev-name = "smdcnt_rev4";
  163. };
  164. qcom,smdpkt-data28-cntl {
  165. qcom,smdpkt-remote = "modem";
  166. qcom,smdpkt-port-name = "DATA28_CNTL";
  167. qcom,smdpkt-dev-name = "smdcnt_rev5";
  168. };
  169. qcom,smdpkt-data29-cntl {
  170. qcom,smdpkt-remote = "modem";
  171. qcom,smdpkt-port-name = "DATA29_CNTL";
  172. qcom,smdpkt-dev-name = "smdcnt_rev6";
  173. };
  174. qcom,smdpkt-data30-cntl {
  175. qcom,smdpkt-remote = "modem";
  176. qcom,smdpkt-port-name = "DATA30_CNTL";
  177. qcom,smdpkt-dev-name = "smdcnt_rev7";
  178. };
  179. qcom,smdpkt-data31-cntl {
  180. qcom,smdpkt-remote = "modem";
  181. qcom,smdpkt-port-name = "DATA31_CNTL";
  182. qcom,smdpkt-dev-name = "smdcnt_rev8";
  183. };
  184. qcom,smdpkt-data40-cntl {
  185. qcom,smdpkt-remote = "modem";
  186. qcom,smdpkt-port-name = "DATA40_CNTL";
  187. qcom,smdpkt-dev-name = "smdcntl8";
  188. };
  189. qcom,smdpkt-apr-apps2 {
  190. qcom,smdpkt-remote = "modem";
  191. qcom,smdpkt-port-name = "apr_apps2";
  192. qcom,smdpkt-dev-name = "apr_apps2";
  193. };
  194. qcom,smdpkt-loopback {
  195. qcom,smdpkt-remote = "modem";
  196. qcom,smdpkt-port-name = "LOOPBACK";
  197. qcom,smdpkt-dev-name = "smd_pkt_loopback";
  198. };
  199. }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144
    • 145
    • 146
    • 147
    • 148
    • 149
    • 150
    • 151
    • 152
    • 153
    • 154
    • 155
    • 156
    • 157
    • 158
    • 159
    • 160
    • 161
    • 162
    • 163
    • 164
    • 165
    • 166
    • 167
    • 168
    • 169
    • 170
    • 171
    • 172
    • 173
    • 174
    • 175
    • 176
    • 177
    • 178
    • 179
    • 180
    • 181
    • 182
    • 183
    • 184
    • 185
    • 186
    • 187
    • 188
    • 189
    • 190
    • 191
    • 192
    • 193
    • 194
    • 195
    • 196
    • 197
    • 198
    • 199
    • 200
    • 201
    • 202
    • 203
    • 204
    • 205
    • 206
    • 207
    • 208
    • 209
    • 210
    • 211
    • 212
    • 213
    • 214
    • 215
    • 216
    • 217
    • 218
    • 219
    • 220
    • 221
    • 222
    • 223
    • 224
    • 225
    • 226
    • 227
    • 228
    • 229
    • 230
    • 231
    • 232
    • 233
    • 234
    • 235
    • 236
    • 237
    • 238
    • 239
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144
    • 145
    • 146
    • 147
    • 148
    • 149
    • 150
    • 151
    • 152
    • 153
    • 154
    • 155
    • 156
    • 157
    • 158
    • 159
    • 160
    • 161
    • 162
    • 163
    • 164
    • 165
    • 166
    • 167
    • 168
    • 169
    • 170
    • 171
    • 172
    • 173
    • 174
    • 175
    • 176
    • 177
    • 178
    • 179
    • 180
    • 181
    • 182
    • 183
    • 184
    • 185
    • 186
    • 187
    • 188
    • 189
    • 190
    • 191
    • 192
    • 193
    • 194
    • 195
    • 196
    • 197
    • 198
    • 199
    • 200
    • 201
    • 202
    • 203
    • 204
    • 205
    • 206
    • 207
    • 208
    • 209
    • 210
    • 211
    • 212
    • 213
    • 214
    • 215
    • 216
    • 217
    • 218
    • 219
    • 220
    • 221
    • 222
    • 223
    • 224
    • 225
    • 226
    • 227
    • 228
    • 229
    • 230
    • 231
    • 232
    • 233
    • 234
    • 235
    • 236
    • 237
    • 238
    • 239

至此,就知道在哪里会初始化smd channel,然后AP检测到smd channel之后打开相应的smd channel等内容了。相应的节点创建也可以知道了,但这些节点不管smd channel有没有打开都会创建!! 
在Ril代码中,可以看到有打开/dev/smd0等节点。 
这些节点的ops函数组其实都差不多,msm_smd_pkt.c中是smd_pkt_fops,msm_smd_tty中是smd_tty_ops。 
都是在调用到之后,才根据文件名等,再找出来是哪个smd channel,然后调用smd_named_open_on_edge函数打开smd channel。读写等操作的话,还要看当初smd_alloc_channel()的时候的相应的channel是packet传输还是stream传输!!这个估计都不是AP这边决定的,但可以在smd_alloc_channel()函数中打log查看每个smd channel的类型。

SMD_DBG()这种函数用来输出smd等log信息。看这些内容可以在/d/ipc_logging下看的到的,如果是SMD_INFO和SMD_DBG内容就是在/d/ipc_logging/smd目录下。这个是因为~~看下面代码注释

  1. //msm_smd_debug_mask这个默认没有打开debug信息,需要调试更多可以加一个MSM_SMD_DEBUG。
  2. #define SMD_DBG(x...) do { \
  3. if (msm_smd_debug_mask & MSM_SMD_DEBUG) \
  4. IPC_LOG_SMD(KERN_DEBUG, x); \
  5. } while (0)
  6. #define SMD_INFO(x...) do { \
  7. if (msm_smd_debug_mask & MSM_SMD_INFO) \
  8. IPC_LOG_SMD(KERN_INFO, x); \
  9. } while (0)
  10. //如果smd_log_ctx已经像下面这样定义,那就是到/d/ipc_logging目录下找相应名字的文件夹下看
  11. //或者如果不想的话,就可以把smd_log_ctx的定义去掉,直接打印到内核里边。当然内核的debug level那块自己需要改一下!!
  12. smd_log_ctx = ipc_log_context_create(NUM_LOG_PAGES, "smd", 0);
  13. #define IPC_LOG_SMD(level, x...) do { \
  14. if (smd_log_ctx) \
  15. ipc_log_string(smd_log_ctx, x); \
  16. else \
  17. printk(level x); \
  18. } while (0)
  19.  
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

以下是qc_smdpkt_xxx.log:

  1. [ 11247.679255802] <SMD_PKT>: ch_notify: DATA event in smd_pkt_dev id:0
  2. [ 11247.679286896] <SMD_PKT>: check_and_wakeup_reader: wake_up smd_pkt_dev id:0
  3. [ 11247.679292469] <SMD_PKT>: check_and_wakeup_writer: 1000 bytes write space in smd_pkt_dev id:0
  4. [ 11247.679332781] <SMD_PKT>: smd_pkt_poll sets POLLIN for smd_pkt_dev id: 0
  5. [ 11247.679372521] <SMD_PKT>: Begin smd_pkt_read on smd_pkt_dev id:0 buffer_size 5086
  6. [ 11247.679430594] <SMD_PKT>: smd_pkt_read unlocked smd_pkt_dev id:0 wakeup_source
  7. [ 11247.679436479] <SMD_PKT>: Finished smd_pkt_read on smd_pkt_dev id:0 20 bytes
  8. [ 11247.679462677] <SMD_PKT>: check_and_wakeup_reader: No packet in smd_pkt_dev id:0
  9. [ 11253.959471134] <SMD_PKT>: Begin smd_pkt_write on smd_pkt_dev id:0 data_size 13
  10. [ 11253.959521967] <SMD_PKT>: Finished smd_pkt_write on smd_pkt_dev id:0 13 bytes
  11. [ 11253.959942853] <SMD_PKT>: ch_notify: DATA event in smd_pkt_dev id:0
  12. [ 11253.959981186] <SMD_PKT>: check_and_wakeup_reader: wake_up smd_pkt_dev id:0
  13. [ 11253.959982748] <SMD_PKT>: smd_pkt_poll sets POLLIN for smd_pkt_dev id: 0
  14. [ 11253.959985248] <SMD_PKT>: check_and_wakeup_writer: 1000 bytes write space in smd_pkt_dev id:0
  15. [ 11253.960014207] <SMD_PKT>: Begin smd_pkt_read on smd_pkt_dev id:0 buffer_size 5086
  16. [ 11253.960050561] <SMD_PKT>: smd_pkt_read unlocked smd_pkt_dev id:0 wakeup_source
  17. [ 11253.960054780] <SMD_PKT>: Finished smd_pkt_read on smd_pkt_dev id:0 20 bytes
  18. [ 11253.960072123] <SMD_PKT>: check_and_wakeup_reader: No packet in smd_pkt_dev id:0
  19. [ 11260.707648550] <SMD_PKT>: Begin smd_pkt_write on smd_pkt_dev id:0 data_size 13
  20. [ 11260.707704800] <SMD_PKT>: Finished smd_pkt_write on smd_pkt_dev id:0 13 bytes
  21. [ 11260.708084957] <SMD_PKT>: ch_notify: DATA event in smd_pkt_dev id:0
  22. [ 11260.708118811] <SMD_PKT>: check_and_wakeup_reader: wake_up smd_pkt_dev id:0
  23. [ 11260.708123290] <SMD_PKT>: check_and_wakeup_writer: 1000 bytes write space in smd_pkt_dev id:0
  24. [ 11260.708154540] <SMD_PKT>: packet_arrival_worker locking smd_pkt_dev id:0 wakeup source
  25. [ 11260.708218654] <SMD_PKT>: smd_pkt_poll sets POLLIN for smd_pkt_dev id: 0
  26. [ 11260.708571415] <SMD_PKT>: Begin smd_pkt_read on smd_pkt_dev id:0 buffer_size 5086
  27. [ 11260.708609384] <SMD_PKT>: smd_pkt_read unlocked smd_pkt_dev id:0 wakeup_source
  28. [ 11260.708613863] <SMD_PKT>: Finished smd_pkt_read on smd_pkt_dev id:0 20 bytes
  29. [ 11260.708631832] <SMD_PKT>: check_and_wakeup_reader: No packet in smd_pkt_dev id:0
  30. [ 11264.686568250] <SMD_PKT>: Begin smd_pkt_write on smd_pkt_dev id:0 data_size 13
  31. [ 11264.686618146] <SMD_PKT>: Finished smd_pkt_write on smd_pkt_dev id:0 13 bytes
  32. [ 11264.686985281] <SMD_PKT>: ch_notify: DATA event in smd_pkt_dev id:0
  33. [ 11264.687013979] <SMD_PKT>: check_and_wakeup_reader: wake_up smd_pkt_dev id:0
  34. [ 11264.687018406] <SMD_PKT>: check_and_wakeup_writer: 1000 bytes write space in smd_pkt_dev id:0
  35. [ 11264.687091062] <SMD_PKT>: smd_pkt_poll sets POLLIN for smd_pkt_dev id: 0
  36. [ 11264.687141010] <SMD_PKT>: packet_arrival_worker locking smd_pkt_dev id:0 wakeup source
  37. [ 11264.687145906] <SMD_PKT>: Begin smd_pkt_read on smd_pkt_dev id:0 buffer_size 5086
  38. [ 11264.687185073] <SMD_PKT>: smd_pkt_read unlocked smd_pkt_dev id:0 wakeup_source
  39. [ 11264.687189917] <SMD_PKT>: Finished smd_pkt_read on smd_pkt_dev id:0 20 bytes
  40. [ 11264.687207937] <SMD_PKT>: check_and_wakeup_reader: No packet in smd_pkt_dev id:0
  41. [ 11271.507262281] <SMD_PKT>: Begin smd_pkt_write on smd_pkt_dev id:0 data_size 13
  42. [ 11271.507305719] <SMD_PKT>: Finished smd_pkt_write on smd_pkt_dev id:0 13 bytes
  43. [ 11271.507728167] <SMD_PKT>: ch_notify: DATA event in smd_pkt_dev id:0
  44. [ 11271.507759625] <SMD_PKT>: check_and_wakeup_reader: wake_up smd_pkt_dev id:0
  45. [ 11271.507763583] <SMD_PKT>: check_and_wakeup_writer: 1000 bytes write space in smd_pkt_dev id:0
  46. [ 11271.507796604] <SMD_PKT>: smd_pkt_poll sets POLLIN for smd_pkt_dev id: 0
  47. [ 11271.507822854] <SMD_PKT>: Begin smd_pkt_read on smd_pkt_dev id:0 buffer_size 5086
  48. [ 11271.507862333] <SMD_PKT>: smd_pkt_read unlocked smd_pkt_dev id:0 wakeup_source
  49. [ 11271.507866500] <SMD_PKT>: Finished smd_pkt_read on smd_pkt_dev id:0 20 bytes
  50. [ 11271.507884364] <SMD_PKT>: check_and_wakeup_reader: No packet in smd_pkt_dev id:0
  51. [ 11274.734097551] <SMD_PKT>: Begin smd_pkt_write on smd_pkt_dev id:0 data_size 13
  52. [ 11274.734160676] <SMD_PKT>: Finished smd_pkt_write on smd_pkt_dev id:0 13 bytes
  53. [ 11274.734588697] <SMD_PKT>: ch_notify: DATA event in smd_pkt_dev id:0
  54. [ 11274.734628333] <SMD_PKT>: check_and_wakeup_reader: wake_up smd_pkt_dev id:0
  55. [ 11274.734633645] <SMD_PKT>: check_and_wakeup_writer: 1000 bytes write space in smd_pkt_dev id:0
  56. [ 11274.735154999] <SMD_PKT>: packet_arrival_worker locking smd_pkt_dev id:0 wakeup source
  57. [ 11274.735238385] <SMD_PKT>: smd_pkt_poll sets POLLIN for smd_pkt_dev id: 0
  58. [ 11274.735276614] <SMD_PKT>: Begin smd_pkt_read on smd_pkt_dev id:0 buffer_size 5086
  59. [ 11274.735333906] <SMD_PKT>: smd_pkt_read unlocked smd_pkt_dev id:0 wakeup_source
  60. [ 11274.735339374] <SMD_PKT>: Finished smd_pkt_read on smd_pkt_dev id:0 20 bytes
  61. [ 11274.735361145] <SMD_PKT>: check_and_wakeup_reader: No packet in smd_pkt_dev id:0
  62. [ 11281.493969135] <SMD_PKT>: Begin smd_pkt_write on smd_pkt_dev id:0 data_size 13
  63. [ 11281.494015593] <SMD_PKT>: Finished smd_pkt_write on smd_pkt_dev id:0 13 bytes
  64. [ 11281.496142103] <SMD_PKT>: ch_notify: DATA event in smd_pkt_dev id:0
  65. [ 11281.496202520] <SMD_PKT>: check_and_wakeup_reader: wake_up smd_pkt_dev id:0
  66. [ 11281.496207780] <SMD_PKT>: check_and_wakeup_writer: 1000 bytes write space in smd_pkt_dev id:0
  67. [ 11281.496255801] <SMD_PKT>: packet_arrival_worker locking smd_pkt_dev id:0 wakeup source
  68. [ 11281.496423249] <SMD_PKT>: smd_pkt_poll sets POLLIN for smd_pkt_dev id: 0
  69. [ 11281.496776582] <SMD_PKT>: Begin smd_pkt_read on smd_pkt_dev id:0 buffer_size 5086
  70. [ 11281.496824707] <SMD_PKT>: smd_pkt_read unlocked smd_pkt_dev id:0 wakeup_source
  71. [ 11281.496828822] <SMD_PKT>: Finished smd_pkt_read on smd_pkt_dev id:0 20 bytes
  72. [ 11281.496848614] <SMD_PKT>: check_and_wakeup_reader: No packet in smd_pkt_dev id:0
  73. [ 11284.784395968] <SMD_PKT>: Begin smd_pkt_write on smd_pkt_dev id:0 data_size 13
  74. [ 11284.784449301] <SMD_PKT>: Finished smd_pkt_write on smd_pkt_dev id:0 13 bytes
  75. [ 11284.786411332] <SMD_PKT>: ch_notify: DATA event in smd_pkt_dev id:0
  76. [ 11284.786464301] <SMD_PKT>: check_and_wakeup_reader: wake_up smd_pkt_dev id:0
  77. [ 11284.786469197] <SMD_PKT>: check_and_wakeup_writer: 1000 bytes write space in smd_pkt_dev id:0
  78. [ 11284.786477790] <SMD_PKT>: smd_pkt_poll sets POLLIN for smd_pkt_dev id: 0
  79. [ 11284.786504093] <SMD_PKT>: packet_arrival_worker locking smd_pkt_dev id:0 wakeup source
  80. [ 11284.786811645] <SMD_PKT>: Begin smd_pkt_read on smd_pkt_dev id:0 buffer_size 5086
  81. [ 11284.786848363] <SMD_PKT>: smd_pkt_read unlocked smd_pkt_dev id:0 wakeup_source
  82. [ 11284.786852582] <SMD_PKT>: Finished smd_pkt_read on smd_pkt_dev id:0 20 bytes
  83. [ 11284.786870290] <SMD_PKT>: check_and_wakeup_reader: No packet in smd_pkt_dev id:0
  84. [ 11288.184812488] <SMD_PKT>: Begin smd_pkt_write on smd_pkt_dev id:0 data_size 13
  85. [ 11288.184869311] <SMD_PKT>: Finished smd_pkt_write on smd_pkt_dev id:0 13 bytes
  86. [ 11288.187012645] <SMD_PKT>: ch_notify: DATA event in smd_pkt_dev id:0
  87. [ 11288.187054572] <SMD_PKT>: check_and_wakeup_reader: wake_up smd_pkt_dev id:0
  88. [ 11288.187060145] <SMD_PKT>: check_and_wakeup_writer: 1000 bytes write space in smd_pkt_dev id:0
  89. [ 11288.187062592] <SMD_PKT>: smd_pkt_poll sets POLLIN for smd_pkt_dev id: 0
  90. [ 11288.187099884] <SMD_PKT>: Begin smd_pkt_read on smd_pkt_dev id:0 buffer_size 5086
  91. [ 11288.187139363] <SMD_PKT>: smd_pkt_read unlocked smd_pkt_dev id:0 wakeup_source
  92. [ 11288.187143530] <SMD_PKT>: Finished smd_pkt_read on smd_pkt_dev id:0 20 bytes
  93. [ 11288.187161499] <SMD_PKT>: check_and_wakeup_reader: No packet in smd_pkt_dev id:0
  94. [ 11294.361732247] <SMD_PKT>: Begin smd_pkt_write on smd_pkt_dev id:0 data_size 13
  95. [ 11294.361781205] <SMD_PKT>: Finished smd_pkt_write on smd_pkt_dev id:0 13 bytes
  96. [ 11294.362070320] <SMD_PKT>: ch_notify: DATA event in smd_pkt_dev id:0
  97. [ 11294.362108132] <SMD_PKT>: check_and_wakeup_reader: wake_up smd_pkt_dev id:0
  98. [ 11294.362108288] <SMD_PKT>: smd_pkt_poll sets POLLIN for smd_pkt_dev id: 0
  99. [ 11294.362112403] <SMD_PKT>: check_and_wakeup_writer: 1000 bytes write space in smd_pkt_dev id:0
  100. [ 11294.362459851] <SMD_PKT>: Begin smd_pkt_read on smd_pkt_dev id:0 buffer_size 5086
  101. [ 11294.362544070] <SMD_PKT>: smd_pkt_read unlocked smd_pkt_dev id:0 wakeup_source
  102. [ 11294.362548393] <SMD_PKT>: Finished smd_pkt_read on smd_pkt_dev id:0 20 bytes
  103. [ 11294.362567299] <SMD_PKT>: check_and_wakeup_reader: No packet in smd_pkt_dev id:0
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103

后续,,

smd,smem,smsm等共享内存所占据的内存范围,大小?? 
/system/bin/smdexe 这个代码在哪里,都干嘛的?init.rc里边这样定义了一个service,但没有找到代码,后续需要说明。

  1. service SMD-daemon /system/bin/smdexe
  2. class main
  3. user root
  4. group system radio inet net_raw
    • 1
    • 2
    • 3
    • 4
    • 1
    • 2
    • 3
    • 4

这个service注册还在oemclientreceiver.cpp文件中添加了下面的一段内容。

  1. ProcessInfo allowedProcess[] = {
  2. ...
  3. { AID_SYSTEM, -1, "/system/bin/smdexe" },
  4. ...
  5. };
    • 1
    • 2
    • 3
    • 4
    • 5
    • 1
    • 2
    • 3
    • 4
    • 5

debug需要的一些log抓取

Some diag related issues seen when doing factory/RF tests are hard to debug and related to multiple technical areas, like diag/smd/usb/qmsl based tools. 
we always need comprehensive logs from all sides to begin our analysis and finally find root cause.

Here is a list of what logs are expected to be provided to Qcom to begin analysis.

QMSL log, Port trace log, USB analyzer log, diag debugfs status dump, ipc logging for diag smd channels, and ramdump with matchable elfs.

How the log collected: 
1. Power on device 
2. QPST recognized DIAG port 
3. Echo pr_debug for diagfwd.c/ diagchar_core.c 
4. Collect ipc_logging for smd channels 
5. Enable Port trace log 
6. Start USB analyzer log collection 
7. Begin the test - -when doing test, qmsl log is collected 
8. After see failure, stop Port trace log, stop USB analyzer log collection. 
9. Dump diag debugfs status 
10. Echo c to sysrq-trigger to trigger a panic and collect ramdump.

Where step 3-4 is done by script named “test.bat” 
If no usb analyzer, ignore step 6. 
9-10 is done by script named “diag_panic.bat”

test.bat

adb wait-for-devices 
adb shell “echo 1 >/sys/module/msm_poweroff/parameters/download_mode” 
adb shell “echo 1 > /proc/sys/kernel/sysrq” 
adb shell “echo ‘file diagfwd.c +p’ > /sys/kernel/debug/dynamic_debug/control” 
adb shell “echo ‘file diagchar_core.c +p’ > /sys/kernel/debug/dynamic_debug/control” 
adb shell cat /d/ipc_logging/smd/log_cont

diag_panic.bat

adb shell cat /sys/kernel/debug/diag/work_pending; 
adb shell cat /sys/kernel/debug/diag/status; 
adb shell cat /sys/kernel/debug/diag/table; 
adb shell cat /sys/kernel/debug/diag/mempool; 
adb shell dmesg >dmesg.txt 
adb shell “echo c > /proc/sysrq-trigger”

Appendix:

how to capture port trace log:

  1. Bring up “QPST Configuration” and Highlight the port your phone is connected to
  2. Do a Shift+right click on the highlighted item Select “Port Trace” 
    If you do not see ‘Port Trace’ in the drop-down menu, you may not have pressed ‘Shift’ while right-clicking
  3. Set the value to either Turned Off, Debugging or Debugging & Port Traffic (see below for details) Close “QPST Configuration” 
    The port trace log will be saved in following location
  4. Look for QPST Icon on right bottom of the PC, right click & then click on Open the Data Directory . You should see PortTrace_COMx.dbg (where x is the port number).

it is better you can enable the port trace before doing test. and disable it immediately after issue reproduced. 
Too much logs is not preferred and it is hard for us to do filtering and analysis.

Linux驱动基础:MSM平台AP/CP通信机制的更多相关文章

  1. linux驱动基础系列--linux spi驱动框架分析

    前言 主要是想对Linux 下spi驱动框架有一个整体的把控,因此会忽略某些细节,同时里面涉及到的一些驱动基础,比如平台驱动.设备模型等也不进行详细说明原理.如果有任何错误地方,请指出,谢谢! spi ...

  2. linux驱动基础系列--linux spi驱动框架分析(续)

    前言 这篇文章是对linux驱动基础系列--linux spi驱动框架分析的补充,主要是添加了最新的linux内核里设备树相关内容. spi设备树相关信息 如之前的文章里所述,控制器的device和s ...

  3. Linux驱动基础:msm平台,modem等framework加载

    msm平台,AP和CP封装在一起,公用一块内存.所以AP需要负责把整个modem, TZ , rpm等binary拷贝到内存中以供modem等subsystem去运行.那AP这边是怎么分配这些内存,又 ...

  4. linux驱动基础系列--Linux下Spi接口Wifi驱动分析

    前言 本文纯粹的纸上谈兵,我并未在实际开发过程中遇到需要编写或调试这类驱动的时候,本文仅仅是根据源码分析后的记录!基于内核版本:2.6.35.6 .主要是想对spi接口的wifi驱动框架有一个整体的把 ...

  5. linux驱动基础系列--Linux I2c驱动分析

    前言 主要是想对Linux I2c驱动框架有一个整体的把控,因此会忽略协议上的某些细节,同时里面涉及到的一些驱动基础,比如平台驱动.设备模型.sysfs等也不进行详细说明原理,涉及到i2c协议部分也只 ...

  6. linux驱动基础系列--Linux mmc sd sdio驱动分析

    前言 主要是想对Linux mmc子系统(包含mmc sd sdio)驱动框架有一个整体的把控,因此会忽略某些细节,同时里面涉及到的一些驱动基础,比如平台驱动.块设备驱动.设备模型等也不进行详细说明原 ...

  7. linux驱动基础系列--Linux 串口、usb转串口驱动分析

    前言 主要是想对Linux 串口.usb转串口驱动框架有一个整体的把控,因此会忽略某些细节,同时里面涉及到的一些驱动基础,比如字符设备驱动.平台驱动等也不进行详细说明原理.如果有任何错误地方,请指出, ...

  8. linux驱动基础系列--linux rtc子系统

    前言 linux驱动子系统太多了,连时钟也搞了个子系统,这导致一般的时钟芯片的驱动也会涉及到至少2个子系统,一个是时钟芯片接口子系统(比如I2c接口的时钟芯片),一个是内核给所有时钟芯片提供的rtc子 ...

  9. Linux驱动基础开发

    Linux 内核配置机制(make menuconfig.Kconfig.makefile)讲解 前面我们介绍模块编程的时候介绍了驱动进入内核有两种方式:模块和直接编译进内核,并介绍了模块的一种编译方 ...

随机推荐

  1. 使用JdbcTemplate 操作PostgreSQL,当where条件中有timestamp类型时,报错operator does not exist: timestamp w/out timezone

    今天遇到一个问题,找了还半天,Google一下,官网显示是一个bug. 思考一番肯定是类型出了问题. Controller: Service:转化时间戳 Dao: 一波转换搞定!

  2. 获取X天后的日期

    import java.util.Calendar; import java.util.Date; public class main { public static void main(String ...

  3. Vue实践经验

    多考虑应变 如果模版中绑定了 obj.xx 时,需要注意 obj 是否是异步数据,默认值是否为 null.安全起见,可在组件最外层加 v-if 判断. <template> <div ...

  4. Python安装与环境变量的配置

    python下载: Python安装包下载地址:http://www.python.org/ 根据实际的操作系统,安装合适的安装版本. Python安装: 本文以python 2.7.8(64位)为例 ...

  5. PHP Misc. 函数

    PHP 杂项函数简介 我们把不属于其他类别的函数归纳到杂项函数类别. 安装 杂项函数是 PHP 核心的组成部分.无需安装即可使用这些函数. Runtime 配置 杂项函数的行为受 php.ini 文件 ...

  6. Docker rancher 部署

    Docker-rancher #环境 centos7.4 , Docker version 17.12.0-ce #下载docker镜像 docker pull mysql:5.7 docker pu ...

  7. 自定义支持多行显示的RadioGroup

    自定义支持多行显示的RadioGroup 原生的RadioGroup继承自LinearLayout,即只能支持一横排或者一竖排的排列显示RadioButton 现在改写RadioGroup,使它支持多 ...

  8. Dynamics CRM 不同的站点地图下设置默认不同的仪表板

    CRM的默认仪表板只能设置一个,也就是说每个引用仪表板的站点地图下点开仪表板后都是看到的默认仪表板,例如我下图中的"日常维修仪表板" 那如果我要在不同的站点地图下看到的默认仪表板不 ...

  9. Android图表库MPAndroidChart(五)——自定义MarkerView实现选中高亮

    Android图表库MPAndroidChart(五)--自定义MarkerView实现选中高亮 在学习本课程之前我建议先把我之前的博客看完,这样对整体的流程有一个大致的了解 Android图表库MP ...

  10. Python excel 奇怪的通信规则

    直接: for i in range(1,n+1): print(i) if xls.getCell(i,1,1)=='id': res=[] xls.xlBook.Worksheets(i).Nam ...