ソースを参照

[update] optimize directory structure

Signed-off-by: liuxinaliang <liuxianliang@rt-thread.com>
liuxinaliang 5 年 前
コミット
f4811a2252

+ 34 - 27
README.md

@@ -2,33 +2,23 @@
 
 ## 1. 简介
 
-- cmux 软件包,是 RT-Thread 针对 GSM0707 / GSM0710 功能实现的软件包。它可是实现在一个真实物理通道上虚拟出多个通道,在一条物理串口接口上实现多个数据链路连接,使得可以同时在一个物理串口接口上存在多个会话。通过多路复用协议和蜂窝模组通讯,使得可以在拨号上网时可以同时拨打电话和收发短信
+- cmux 软件包,其功能为在一个真实物理通道上虚拟出多个通道,使得可以同时在一个物理串口接口上存在多个会话。两个模块仅使用一个真实物理串口连接,可以使用软件包虚拟出多组串口,通过虚拟出的不同串口用于不同的通信场景。例如板载串口资源受限时,可以使用软件包以实现使用多个串口的目的
 
-  cmux 软件包特点如下:
-
-  - 支持多种蜂窝模块;
-  
-  * 可以添加 PPP 功能
+-  cmux 的常见使用场景有: 蜂窝模块的串口复用功能 -- GSM0707 / GSM0710 协议,使用 cmux( gsm ) + ppp 组合可以实现在实现 PPP 拨号上网的同时,提供 AT 命令和 MODEM 数据通道,实时获取模块状态而无需退出 PPP 功能。通过多路复用协议和蜂窝模组通讯,使得可以在拨号上网时可以同时拨打电话和收发短信。
 
-  目前 CMUX 功能支持 Luat Air720模块,后续会接入更多蜂窝模块。
-
-  
-
-  对 CMUX 有疑惑,或者对 CMUX 感兴趣的开发者欢迎入群详细了解。
-
-  QQ群:749347156 [<传送门>](https://jq.qq.com/?_wv=1027&k=5KcuPGI)
+  cmux 软件包特点如下:
 
-  CMUX 详细介绍:[<文档>](./docs/cmux_basic.md)
+  - 可以由一个真实串口虚拟出多个串口
+  - 支持多种蜂窝模块
+  - 可以添加 PPP 功能
 
-  通过 CMUX 使用 PPP_DEVICE 文档:[<使用文档>](./docs/cmux_port.md)
+  目前 CMUX 的 GSM 功能支持 Luat Air720, SIM7600, SIM800C 模块,后续会接入更多蜂窝模块。
 
   ### 1.1 框架图
 
   ![](docs/figures/cmux_frame.png)
 
-- CMUX 软件包实现得是 cmux-client 的内容
-  
-- CMUX 是一种类似于传输层的协议,用户使用时无法感知该层
+- CMUX 是一种类似于传输层的协议,用户使用时无法感知该层;数据传输依赖一个真实串口传输,cmux 层负责解析数据用以分发到不同的 virtual uart ;从而实现一个真实串口虚拟出多个 UART 的目的
 
 - CMUX 在应用场景中多用于 UART, 如有必要也可以支持 SPI 方式
   
@@ -37,13 +27,17 @@
 cmux
 ├───docs 
 │   └───figures                     // 文档使用图片	
-├───class    
-│   └───cmux_air720.c               // 针对不同设备
-├───sample                          // 示例文件
-│   └─── sample.c     
 ├───inc                             // 头文件
+│   │───gsm
+│   │   └─── cmux_chat.h    
 │   └─── cmux.h       
-├───src                             // 移植文件
+├───sample                          // 示例文件
+│   └─── cmux_sample_gsm.c     
+├───src                             // 源码文件
+│   ├───gsm
+│   │   ├─── cmux_chat.c 
+│   │   └─── cmux_gsm.c  
+│   ├─── cmux_utils.c
 │   └─── cmux.c
 ├───LICENSE                         // 软件包许可证
 ├───README.md                       // 软件包使用说明
@@ -65,14 +59,15 @@ cmux 软件包遵循 Apache-2.0 许可,详见 LICENSE 文件。
 ```c
   [*] cmux protocol for rt-thread.  --->
       [ ] using cmux debug feature (NEW)
-      (10) set cmux max frame list length (NEW)
+      [*] using for gsm0710 protocol (NEW)
+      (5) set cmux max frame list length (NEW)
       (uart2) the real cmux serial prot (NEW)
       (3) the number of cmux modem port (NEW)
-      (AT+CMUX=0,0,5,127,10,3,30,10,2) the command for cmux function (NEW)
       Version (latest)  --->
 ```
 
 - **using cmux debug feature:** 开启调试日志功能
+- **using for gsm0710 protocol:** 打开以支持蜂窝模块
 - **set cmux max frame list length:** 设置虚拟端口的 frame 链的最大长度
 - **the real cmux serial prot:** cmux 使用的真实串口名称
 - **the number of cmux modem port:** 蜂窝模块支持的虚拟串口数量
@@ -188,13 +183,14 @@ msh >[D/main] cmux control channel has been open.
 [D/main] 6 ,Recieve  
 OK
 ```
-在使用 PPP 功能的同时,可以使用虚拟出的 cmux_at 串口同时读取模块信号强度值,具体可以参考[<移植文档>](./docs/cmux_port.md)
+在使用 PPP 功能的同时,可以使用虚拟出的 cmux_at 串口同时读取模块信号强度值,具体可以参考[<使用文档>](./docs/cmux_port.md)
 
 ## 4. 注意事项
 
 * 使用 PPP 功能详情参考 [PPP_DEVICE](https://github.com/RT-Thread-packages/ppp_device)
 * 只有在虚拟串口注册到 rt_device 框架后才能通过 rt_device_find 找到虚拟串口,要注意先后顺序
 * 虚拟串口 attach 后并不能直接使用,必须通过 rt_device_open 打开后才能使用,符合 rt_device 的操作流程
+* 只有进入 cmux 的命令,没有退出 cmux 的命令;所以说,只能通信模块硬重启,而不能软重启,使用时候要注意
 
 ## 5. 联系方式
 
@@ -202,6 +198,17 @@ OK
 
 Email: liuxianliang@rt-thread.com
 
-## 6. 致谢
+
+
+对 CMUX 有疑惑,或者对 CMUX 感兴趣的开发者欢迎入群详细了解。
+
+QQ群:749347156 [<传送门>](https://jq.qq.com/?_wv=1027&k=5KcuPGI)
+
+## 6. 相关文档
+CMUX 详细介绍:[<文档>](./docs/cmux_basic.md)
+
+通过 CMUX 使用 PPP_DEVICE 文档:[<使用文档>](./docs/cmux_port.md)
+
+## 7. 致谢
 
 感谢网友 @ya-jeks 在 github 上的 gsmmux 参考代码

+ 7 - 4
SConscript

@@ -1,14 +1,17 @@
 from building import *
 
 cwd = GetCurrentDir()
-path = [cwd + '/inc']
+path  = [cwd + '/inc']
+path += [cwd + '/inc/gsm']
 src  = Glob('src/*.c')
-src += Glob('sample/sample.c')
 
-src += Glob('class/cmux_air720.c')
+src += Glob('sample/cmux_sample_gsm.c')
+
+if GetDepend(['CMUX_USING_GSM']):
+    src += Glob('src/gsm/*.c')
 
 if GetDepend(['PKG_USING_PPP_DEVICE']):
-	SrcRemove(src, "src/cmux_chat.c")
+	SrcRemove(src, "src/gsm/cmux_chat.c")
 
 group = DefineGroup('cmux', src, depend = ['PKG_USING_CMUX'], CPPPATH = path)
 

+ 23 - 15
docs/cmux_basic.md

@@ -96,13 +96,17 @@ STM32F407 + Air720H(手动拼接命令测试)
 cmux
 ├───docs 
 │   └───figures                     // 文档使用图片	
-├───class    
-│   └───cmux_air720.c               // 针对不同设备
-├───sample                          // 示例文件
-│   └─── sample.c     
 ├───inc                             // 头文件
+│   │───gsm
+│   │   └─── cmux_chat.h    
 │   └─── cmux.h       
-├───src                             // 移植文件
+├───sample                          // 示例文件
+│   └─── cmux_sample_gsm.c     
+├───src                             // 源码文件
+│   ├───gsm
+│   │   ├─── cmux_chat.c 
+│   │   └─── cmux_gsm.c  
+│   ├─── cmux_utils.c
 │   └─── cmux.c
 ├───LICENSE                         // 软件包许可证
 ├───README.md                       // 软件包使用说明
@@ -114,21 +118,22 @@ cmux
 1. CMUX 的帧结构介绍
 
    ```c
-   typedef struct cmux_buffer
+   struct cmux_buffer
    {
      rt_uint8_t data[CMUX_BUFFER_SIZE];
      rt_uint8_t *read_point;                          // 用于读取 CMUX 数据的指针
      rt_uint8_t *write_point;                         // 指向 CMUX 数据区的指针
      rt_uint8_t *end_point;                           // 指向 CMUX 数据区末尾的指针
      int flag_found;                                  // 是否找到 0xF9 帧头
-   } cmux_buffer;
+   };
    
-   typedef struct cmux_frame {
+    struct cmux_frame
+   {
      rt_uint8_t channel;                             // 地址域
      rt_uint8_t control;                             // 数据帧类型, SABM,UIH,UA; 控制域
      int data_length;                                // 数据长度
      rt_uint8_t *data;                               // 实际数据
-} cmux_frame;
+   };
    ```
    
 2. CMUX 不同帧类型介绍
@@ -160,19 +165,22 @@ cmux
 1. 需要实现的结构体
 
    ```c
-   typedef struct cmux
+   struct cmux
    {
        struct rt_device *dev;                        /* device object */
        const struct cmux_ops *ops;                   /* cmux device ops interface */
-       cmux_set_command_t cmd;                       /* CMUX start AT command */
        struct cmux_buffer *buffer;                   /* cmux buffer */
-       rt_thread_t *recv_tid;                        /* recieve thread point */
-       rt_uint8_t vcom_num;                          /* the cmux port number array */
-       struct cmux_vcom *vcom;                       /* virual serial device */
+       struct cmux_frame *frame;                     /* cmux frame point */
+       rt_thread_t recv_tid;                         /* receive thread point */
+       rt_uint8_t vcom_num;                          /* the cmux port number */
+       struct cmux_vcoms *vcoms;                     /* array */
+   
+       struct rt_event *event;                       /* internal communication */
+   
        rt_slist_t *list;                             /* cmux list */
    
        void *user_data;                              /* reserve */
-   }cmux;
+   };
    
    struct cmux_ops
    {

+ 9 - 2
docs/cmux_port.md

@@ -1,4 +1,4 @@
-# PPP 功能使用
+# 功能使用
 
 在 CMUX 中使用 PPP_DEVICE 与直接使用 PPP_DEVICE 的使用差别不大;使用最新版本的 PPP_DEVICE 可以做到 cmux 的兼容效果,无论是打开 cmux 功能均可以正常使用 PPP_DEVICE。
 
@@ -89,4 +89,11 @@
    MSH_CMD_EXPORT(ready, ready);
    ```
 
-   还在考虑直接使用 at_client 功能,敬请期待。
+   还在考虑直接使用 at_client 功能,敬请期待。
+   
+4. 模块进入 cmux 后,无法通过命令主动退出,所以进入 cmux 需要特别注意;在 cmux_gsm.c 中修改逻辑
+
+   ![private control](./figures/private control.png)
+
+   * 模块已经进入 cmux 状态,无需使用 AT 命令进入 cmux 状态,可以不调用 modem_chat
+   * 模块状态未进入 cmux 状态,但是此次模块无任何响应,可以添加电源控制,重启设备。蜂窝模块重启时间较长,建议添加合适时间的延时,以提升系统效率

BIN
docs/figures/cmux_frame.png


BIN
docs/figures/private control.png


+ 6 - 24
inc/cmux.h

@@ -12,27 +12,10 @@
 
 #define CMUX_BUFFER_SIZE   2048
 
-#ifdef RT_USING_LIBC
-#include <lib.c>
-#else
-#define min(a,b) ((a)<=(b)?(a):(b))
-#endif
+#define CMUX_SW_VERSION           "1.0.0"
+#define CMUX_SW_VERSION_NUM       0x10000
 
-// increases buffer pointer by one and wraps around if necessary
-#define INC_BUF_POINTER(buf,p) p++; if (p == buf->end_point) p = buf->data;
-
-/* Tells, how many chars are saved into the buffer.
- *
- */
-//int cmux_buffer_length(cmux_buffer *buf);
-#define cmux_buffer_length(buff) ((buff->read_point > buff->write_point) ? (CMUX_BUFFER_SIZE - (buff->read_point - buff->write_point)) : (buff->write_point - buff->read_point))
-
-/* Tells, how much free space there is in the buffer
- */
-//int cmux_buffer_free(cmux_buffer *buf);
-#define cmux_buffer_free(buff) ((buff->read_point > buff->write_point) ? (buff->read_point - buff->write_point) : (CMUX_BUFFER_SIZE - (buff->write_point - buff->read_point)))
-
-typedef struct cmux_buffer
+struct cmux_buffer
 {
   rt_uint8_t data[CMUX_BUFFER_SIZE];                        /* cmux data buffer */
   rt_uint8_t *read_point;
@@ -41,7 +24,7 @@ typedef struct cmux_buffer
   int flag_found;                                          /* the flag whether you find cmux frame */
 } cmux_buffer;
 
-typedef struct cmux_frame
+struct cmux_frame
 {
     rt_uint8_t channel;                                   /* the frame channel */
     rt_uint8_t control;                                   /* the type of frame */
@@ -56,7 +39,7 @@ typedef struct frame
     rt_slist_t frame_list;                                /* slist for different virtual serial */
 }frame;
 
-typedef struct cmux_vcoms
+struct cmux_vcoms
 {
     struct rt_device device;                              /* virtual device */
 
@@ -67,7 +50,7 @@ typedef struct cmux_vcoms
     rt_bool_t frame_using_status;                         /* This is designed for long frame when we read data; the flag will be "1" when long frame haven't reading done */
 }cmux_vcoms;
 
-typedef struct cmux
+struct cmux
 {
     struct rt_device *dev;                                /* device object */
     const struct cmux_ops *ops;                           /* cmux device ops interface */
@@ -78,7 +61,6 @@ typedef struct cmux
     struct cmux_vcoms *vcoms;                             /* array */
 
     struct rt_event *event;                               /* internal communication */
-    struct rt_messagequeue *mq;                           /* internal communication */
 
     rt_slist_t list;                                      /* cmux list */
 

+ 0 - 0
inc/cmux_chat.h → inc/gsm/cmux_chat.h


+ 4 - 32
sample/sample.c → sample/cmux_sample_gsm.c

@@ -7,7 +7,7 @@
  * Date           Author         Notes
  * 2020-04-15    xiangxistu      the first version
  */
- 
+
 #include <cmux.h>
 #include <rtthread.h>
 
@@ -30,7 +30,7 @@
 
 struct cmux *sample = RT_NULL;
 
-int cmux_sample_start(void)
+int cmux_sample(void)
 {
     rt_err_t result;
     sample = cmux_object_find(CMUX_DEPEND_NAME);
@@ -69,36 +69,8 @@ int cmux_sample_start(void)
 end:
     return RT_EOK;
 }
+#ifdef CMUX_ATUO_INITIZATION
 INIT_APP_EXPORT(cmux_sample_start);
-MSH_CMD_EXPORT_ALIAS(cmux_sample_start, cmux_start, a sample of cmux function);
-
-int cmux_sample_stop(void)
-{
-    rt_err_t result;
-#ifdef CMUX_AT_NAME
-    result = cmux_detach(sample, CMUX_AT_NAME);
-    if(result != RT_EOK)
-    {
-        LOG_E("cmux object (%s) detach failed.", CMUX_AT_NAME);
-        goto end;
-    }
-#endif
-#ifdef CMUX_PPP_NAME
-    result = cmux_detach(sample, CMUX_PPP_NAME);
-    if(result != RT_EOK)
-    {
-        LOG_E("cmux object (%s) detach failed.", CMUX_PPP_NAME);
-        goto end;
-    }
 #endif
-    result = cmux_stop(sample);
-    if(result != RT_EOK)
-    {
-        LOG_E("cmux sample stop error.");
-        goto end;
-    }
+MSH_CMD_EXPORT_ALIAS(cmux_sample, cmux_start, a sample of cmux function);
 
-end:
-    return RT_EOK;
-}
-MSH_CMD_EXPORT_ALIAS(cmux_sample_stop, cmux_stop, a sample of cmux function);

+ 27 - 7
src/cmux.c

@@ -35,8 +35,25 @@
 #define CMUX_PF_ISSET(frame) ((frame->control & CMUX_CONTROL_PF) == CMUX_CONTROL_PF)
 #define CMUX_FRAME_IS(type, frame) ((frame->control & ~CMUX_CONTROL_PF) == type)
 
+#define min(a,b) ((a)<=(b)?(a):(b))
+
+/* increases buffer pointer by one and wraps around if necessary */
+#define INC_BUF_POINTER(buf,p) p++; if (p == buf->end_point) p = buf->data;
+
+/* Tells, how many chars are saved into the buffer */
+#define cmux_buffer_length(buff) ((buff->read_point > buff->write_point) ? (CMUX_BUFFER_SIZE - (buff->read_point - buff->write_point)) : (buff->write_point - buff->read_point))
+
+/* Tells, how much free space there is in the buffer */
+#define cmux_buffer_free(buff) ((buff->read_point > buff->write_point) ? (buff->read_point - buff->write_point) : (CMUX_BUFFER_SIZE - (buff->write_point - buff->read_point)))
+
+
 #define CMUX_RECV_READ_MAX 32
-#define CMUX_THREAD_STACK_SIZE 2048
+
+#ifdef CMUX_DEBUG
+#define CMUX_THREAD_STACK_SIZE 1024
+#else
+#define CMUX_THREAD_STACK_SIZE 512
+#endif
 #define CMUX_THREAD_PRIORITY   8
 
 #define CMUX_RECIEVE_RESET     0
@@ -44,7 +61,7 @@
 #define CMUX_RECIEVE_PROCESS   2
 #define CMUX_RECIEVE_END       3
 
-#define CMUX_EVENT_RX_NOTIFY     1   // serial incoming a byte
+#define CMUX_EVENT_RX_NOTIFY     1          /* serial incoming a byte */
 #define CMUX_EVENT_CHANNEL_OPEN  2
 #define CMUX_EVENT_CHANNEL_CLOSE 4
 #define CMUX_EVENT_CHANNEL_OPEN_REQ  8
@@ -85,7 +102,7 @@ static void hex_dump(const void *data, rt_size_t len)
             rt_sprintf(p, "%02x ", (unsigned char)src[i]);
             p += 3;
         }
-        memset(p, ' ', (maxlen - curlen) * 3);
+        rt_memset(p, ' ', (maxlen - curlen) * 3);
         p += (maxlen - curlen) * 3;
         *p++ = '|';
         *p++ = ' ';
@@ -274,6 +291,7 @@ static rt_err_t cmux_frame_push(struct cmux *cmux, int channel, struct cmux_fram
         LOG_D("new message for channel(%d) is append, Message total: %d.", channel, ++cmux->vcoms[channel].frame_index);
 
 #ifdef CMUX_DEBUG
+        LOG_D("CMUX_RX:");
         hex_dump(frame->data, frame->data_length);
 #endif
         return RT_EOK;
@@ -365,7 +383,7 @@ static struct cmux_frame *cmux_frame_parse(struct cmux_buffer *buffer)
     rt_uint8_t *data = RT_NULL;
     rt_uint8_t fcs = 0xFF;
     struct cmux_frame *frame = RT_NULL;
-    
+
     extern rt_uint8_t cmux_crctable[256];
 
     /* Find start flag */
@@ -517,7 +535,7 @@ static void cmux_recv_processdata(struct cmux *cmux, rt_uint8_t *buf, rt_size_t
             else
             {
                 /* control channel command */
-                LOG_E("control channel command haven't support.");
+                LOG_W("control channel command haven't support.");
             }
         }
         else
@@ -526,7 +544,6 @@ static void cmux_recv_processdata(struct cmux *cmux, rt_uint8_t *buf, rt_size_t
             {
             case CMUX_FRAME_UA:
                 LOG_D("This is UA frame for channel(%d).", frame->channel);
-                rt_event_send(cmux->event, CMUX_EVENT_CHANNEL_OPEN);
 
                 break;
             case CMUX_FRAME_DM:
@@ -603,7 +620,10 @@ static rt_size_t cmux_send_data(struct rt_device *dev, int port, rt_uint8_t type
         LOG_D("Couldn't write the whole postfix to the serial port for the virtual port %d. Wrote only %d bytes.", port, c);
         return 0;
     }
-
+#ifdef CMUX_DEBUG
+    LOG_D("CMUX_TX:");
+    hex_dump(data, length);
+#endif
     return length;
 }
 

+ 0 - 0
src/cmux_chat.c → src/gsm/cmux_chat.c


+ 15 - 14
class/cmux_air720.c → src/gsm/cmux_gsm.c

@@ -16,17 +16,17 @@
 #include <cmux_chat.h>
 #endif
 
-#define DBG_TAG    "cmux.air720"
-
+#define DBG_TAG    "cmux.gsm"
 #ifdef CMUX_DEBUG
 #define DBG_LVL   DBG_LOG
 #else
 #define DBG_LVL   DBG_INFO
 #endif
-
 #include <rtdbg.h>
 
-struct cmux *air720 = RT_NULL;
+#define CMUX_CMD "AT+CMUX=0,0,5,127,10,3,30,10,2"
+
+struct cmux *gsm = RT_NULL;
 
 static const struct modem_chat_data cmd[] =
 {
@@ -36,12 +36,13 @@ static const struct modem_chat_data cmd[] =
 
 static rt_err_t cmux_at_command(struct rt_device *device)
 {
-    //private control
+    /* private control, you can add power control */
 
+//    rt_thread_mdelay(5000);
     return modem_chat(device, cmd, sizeof(cmd) / sizeof(cmd[0]));
 }
 
-rt_err_t air720_cmux_start(struct cmux *obj)
+static rt_err_t cmux_gsm_start(struct cmux *obj)
 {
     rt_err_t result = 0;
     struct rt_device *device = RT_NULL;
@@ -67,18 +68,18 @@ _end:
 }
 const struct cmux_ops cmux_ops =
 {
-    air720_cmux_start,
+    cmux_gsm_start,
     RT_NULL,
     RT_NULL
 };
 
-int cmux_air720_init(void)
+int cmux_gsm_init(void)
 {
-    air720 = rt_malloc(sizeof(struct cmux));
-    rt_memset(air720, 0, sizeof(struct cmux));
-    
-    air720->ops = &cmux_ops;
+    gsm = rt_malloc(sizeof(struct cmux));
+    rt_memset(gsm, 0, sizeof(struct cmux));
+
+    gsm->ops = &cmux_ops;
 
-    return cmux_init(air720, CMUX_DEPEND_NAME, CMUX_PORT_NUMBER, RT_NULL);
+    return cmux_init(gsm, CMUX_DEPEND_NAME, CMUX_PORT_NUMBER, RT_NULL);
 }
-INIT_COMPONENT_EXPORT(cmux_air720_init);
+INIT_COMPONENT_EXPORT(cmux_gsm_init);