原创 物联网系统中TCP低功耗产品长连接状态下降低功耗功能的实现方案

2024-10-10 14:42 73 0 分类: 物联网


01

概述


TCP协议广泛应用于可靠性要求较高的应用场景,如网页浏览、文件传输、电子邮件等。它提供了可靠的数据传输和流控制机制,能够确保数据的完整性和有序性。然而,由于TCP协议在传输过程中引入了较多的控制信息,因此相比于UDP协议,TCP的传输速度较慢。


02

功耗的组成


低功耗技术就是一系列的降低功耗的技术。

在了解低功耗技术之前,我们必须先了解功耗的构成。

一个SOC芯片的功耗由两部分组成:动态功耗和静态功耗。

动态功耗是设备运行时或者说信号改变时所消耗的功耗;

静态功耗是设备上电但是信号没有改变时所消耗的功耗;

这里要注意的是:在设备运行时,也需要消耗静态功耗的,因为设备运行时也是上电状态。功耗分类把静态功耗单独拿出来,只是为了理论分析方便。

2.1 动态功耗

动态功耗可以分为:

1. 翻转功耗(有的地方称为开关功耗,但是笔者认为这个名字不准确,因为开关包含的功耗很多,其实是从英文switching power翻译过来,从switching可以看到,名称想表现是动作。所以称为翻转功耗比较准确)

2. 短路功耗(或者称为内部功耗,英文是internal power)

2.1.1 翻转功耗(switching power)

Switching power 是一个门电路对输出电容进行充电和放电需要的功耗。简单的说就是一个门电路输出从0变到1和从1变到0所需要消耗的功耗。

Switching power 是动态功耗最主要的组成部分。

1. Switching power 和电压,翻转率,负载电容有关;

2. Switching power和数据无关,也就传输的数据不会影响翻转功耗,但是数据的翻转率会影响翻转功耗;

3. Switching power和传输的大小也无关

由这个公式我们很容易得到如果想减少功耗,那么方法就是:

1. 降低电压;

2. 降低翻转率;

3. 减少负载电容

当然,这些方法的前提永远是芯片的功能要满足要求。功率再低,功能不满足的芯片和板砖有什么区别,起码板砖还能拍人。

芯片的功能要满足要求这个基础就决定了这些方法有一些限制,比如不可能把电压降到0,不可能让信号永远不翻转,不可能电容减少到0。这些都是前提。

2.1.2 内部功耗(internal power)

内部功耗又可以称为短路功耗,因为主要原因是由于短路造成的。短路功耗是因为在输入信号进行翻转时,信号的翻转不可能瞬时完成,因此PMOS和NMOS不可能总是一个截止另外一个导通,总有那么一段时间是使PMOS和NMOS同时导通,那么从电源VDD到地VSS之间就有了通路,就形成了短路电流。

后面的部分就是短路功耗。tsc是短路电流持续的时间,Ipeak是总的短路电流(包含了内部电容充电的电流)

由于传输中短路持续的时间特别短,短路功耗相比翻转功耗来说小很多。所以一般情况下会忽略短路功耗,把翻转功耗就当作动态功耗。

但是值得注意的是,有的情况下,还是要考虑短路功耗,比如如何处理门控模块的悬空的输出的时候。

2.2 静态功耗

静态功耗是由于漏电流引起的,在CMOS 门中,漏电流主要来自4个源头:

1. 亚阈值漏电流(Sub-threshold Leakage, ISUB): 亚阈值泄漏电流是晶体管应当截止时流过的电流.

2. 栅极漏电流(Gate Leakage, Igate): 由于栅极氧化物隧穿和热载流子注入,从栅极直接通过氧化物流到衬底的电流。

3. 栅极感应漏电流(Gate Induced Drain Leakage, IGIDL): 结泄漏电流发生在源或漏扩散区处在与衬底不同电位的情况下。结泄漏电流与其他泄漏电流相比时通常都很小。

4. 反向偏置结泄漏(Reverse Bias Junction Leakage ,IREV):由少数载流子漂移和在耗尽区产生电子/空穴对引起。

2.2.1亚阈值漏电流(Sub-threshold Leakage)

亚阈值漏电流(Sub-threshold Leakage)发生在CMOS gate没有完全关断时。

VT是阈值电压;可以看到,阈值电压越高,漏电功耗就越低。但是阈值电压越高,对应的翻转速度就会越慢,延时就会越大,性能就越差。

1. 可以通过调整VDD/VT来降低漏电流,从而减少漏电功耗。

2. 增加VT会带来性能损失,只能在满足功能需求前提下增加VT;

3. ISUB只和VDD/VT有关,和信号翻转这些都没关系。这是一个工艺强相关的电流,RTL设计对其无影响。

亚阈值泄漏电流随温度呈指数增长(Vth)。这大大增加了设计低功率系统的复杂性。即使在室温下的泄漏是可以接受的,在最坏的情况下,温度会超过芯片的设计目标。

2.2.2栅极漏电流(Gate Leakage)

栅极泄漏电流发生在一个电压加到栅上时(例如当门导通时)载流子遂穿通过薄栅介质的情况下。

泄漏电流与介质厚度有极强的关系。工艺中通过选择合适厚度的介质将栅泄漏电流限制到一个可接受的水平上。泄漏电流还取决于栅极电压。通过使晶体管堆叠起来并使截止晶体管靠近电源/地线可以使栅泄漏电流减小。

在以往的技术节点中,漏电电流一直以亚阈值漏电为主。但是从90nm开始,门极漏电几乎是亚阈值漏电的1/3。在某些情况下,在65nm工艺下,它可以等于亚阈值泄漏。低于65nm,high-k介电材料必须进行保持门级泄漏电流检查,这似乎是唯一有效减少门泄漏电流的方法。

其他两种流电流占比比较小,所以一般不做分析。

Ipeak为泄露电流,减少静态功耗的方法就是减小VDD和Ipeak。

2.3 不同结构的功耗组成

SOC中不同结构的对功耗的消耗是不一样的。有几个功耗大户如下:

1. 时钟树功耗:时钟树的功耗通常占整个SOC功耗的40%左右,这是因为时钟是一直在翻转的信号,所以动态功耗特别大。所以门控时钟技术就特别重要。

2. CPU: CPU是SOC主控制器,工作时CPU一般都必须要打开,随着CPU频率越来越高,功耗也越来越大。所以现在的多核,大小核就比较流行,不同场景下用不同功耗的CPU核;

3. GPU: GPU是并行处理单元,由于其算力主要来自多个模块并行计算,为了正常工作,通常需要很多模块同时运算,功耗也很大,所以很多SOC都不带GPU或者默认关掉;

4. 存储器:DDR这些存储器作为SOC主存也需要时刻使用,也是功耗消耗的大户。

SOC还有其他模块,但是时钟树,CPU/GPU, 存储器占了绝大部分的功耗。在AI芯片的时代,CCN IP也是功耗的主要来源,和GPU比较类似。


03

组件的使用


1 Gitee链接地址

Demo位于amaziot_bloom_os_sdk\sample\libraries\5.19-app_low_power

Gitee源码地址:https://gitee.com/ning./hongdou

Github源码地址:https://github.com/ayumid/hongdou

编译指令:.\build.bat -l .\amaziot_bloom_os_sdk\sample\libraries\5.19-app_low_power

2 组件功能介绍

组件实现了 TCP 通信下的低功耗。

设备上电后会连接 TCP 服务器,之后发送登录字符串“login”,服务器回复字符串“login_resp”后,设备会进入低功耗状态。低功耗状态下,设备每隔60s会给服务器发送心跳字符串“heart”。当设备在低功耗状态下,服务器发送“wakeup”,设备会唤醒。服务器发送“suspend”,设备会重新进入低功耗。测试平均功耗大概是5mA左右(参考下方固件测试图)。

组件提供一个GPIO控制,如果硬件设计中是MCU+AM430EV5,通过这个IO,可以唤醒MCU。

3 代码讲解

1 low_power_gpio_init

功能:该函数用于,组件提供的用于唤醒主控MCU的GPIO。

参数:无

返回值:无

示例:


low_power_gpio_init();

2 low_power_gpio_out

功能:该函数用于,GPIO输出,用于适当的时间唤醒主控MCU。

参数:

参数

释义

val

输出电平

返回值:0

示例:


low_power_gpio_out(1)

3 low_power_send_msg

功能:该函数用于,发送消息给主任务。

参数:

参数

释义

msgId

消息ID

extra

按需使用,额外信息

data

按需使用,额外数据

返回值:无

示例:


low_power_send_msg(LOW_POWER_CMD_SUSPEND, 1, NULL);

4 low_power_set_mcu_wake

功能:该函数用于,唤醒mcu。

参数:

参数

释义

ad

消息指针

wake

gpio输出状态

返回值:无

示例:


low_power_set_mcu_wake(ad, 1);

5 low_power_wakeup_internal

功能:该函数用于,关闭网络连接。

参数:

参数

释义

ad

消息指针

返回值:文件指针

示例:


low_power_net_close(ad);

6 low_power_net_send

功能:该函数用于,发送数据。

参数:

参数

释义

ad

消息指针

data

数据指针

sz

数据长度

返回值:无

示例:


low_power_net_send();

7 low_power_net_init

功能:该函数用于,发送数据。

参数:

参数

释义

ad

消息指针

返回值:无

示例:


low_power_net_init(ad);

8 low_power_net_connect

功能:该函数用于,连接服务器。

参数:

参数

释义

ad

消息指针

fd

套接字描述符

data

数据指针

sz

数据长度

返回值:无

示例:


ret = low_power_net_connect(ad, fd, rp->ai_addr, rp->ai_addrlen);

9 low_power_net_create

功能:该函数用于,发送数据。

参数:

参数

释义

ad

消息指针

返回值:无

示例:


low_power_net_create(ad);

10 low_power_net_recv

功能:该函数用于,接收服务器信息。

参数:

参数

释义

ad

消息指针

返回值:无

示例:


ret = low_power_net_recv(ad);

11 low_power_task

功能:该函数用于,主任务。

参数:

参数

释义

param

任务参数指针,可不用

返回值:无

示例:


low_power_task();

12 low_power_config

功能:该函数用于,配置低功耗相关的信息。

参数:

参数

释义

ad

消息指针

返回值:无

示例:


low_power_config();

13 low_power_init

功能:该函数用于,初始化低功耗需要的资源,任务等。

参数:无

返回值:无

示例:


low_power_init();

4 Demo实战

4.1 创建一个Demo

复制4.2_hal_UART示例工程,到同一个文件夹下,修改文件名为5.19-app_low_power,如图:

4.2 修改makefile

增加文件组件所在目录头文件路径,和源文件路径,如图:

4.3 增加头文件

使用代码编辑器,将新建的工程文件加入代码编辑器中,打开main.c,修改main.c,加入am.h等头文件,如图:

4.4 修改代码

在Phase2Inits_exit 调用低功耗初始化函数,如图:

4.5 宏定义介绍

  • low_power_uart_printf

输出日志到DEBUG 串口,日志比较少,可以输出到这个串口,如果日志比较多,需要输出到usb口,以免不必要的问题出现

  • low_power_catstudio_printf

输出日志到USB 串口,使用catstudio查看,catstudio查看日志需要更新对应版本mdb.txt文件,软件打开filtter过滤日志,只查看用户输出的日志

  • LOW_POWER_TASK_STACK_SIZE

栈空间宏定义

4.6 函数介绍

  • Phase1Inits_enter

底层初始化,本例空

  • Phase1Inits_exit

底层初始化,本例空

  • Phase2Inits_enter

底层初始化,本例空

  • Phase2Inits_exit

创建主任务,初始化消息队列,定时器,任务等。

代码片段:


int ret;
sample_ele_log_uart_printf("debug> enter main\n");

ret = OSAFlagCreate(&sample_ele_log_flag_ref);
ASSERT(ret == OS_SUCCESS);
ret = OSATimerCreate(&sample_ele_log_timer_ref);
ASSERT(ret == OS_SUCCESS);
ret = OSATaskCreate(&sample_ele_log_task_ref, sample_ele_log_task_stack, SAMPLE_ELE_LOG_TASK_STACK_SIZE, 200, "filetest-task", sample_ele_log_task, NULL);
ASSERT(ret == OS_SUCCESS);
OSATimerStart(sample_ele_log_timer_ref, 5 * 200, 5 * 200, sample_ele_log_timer_callback, 0); // 3 seconds timer

  • sample_ele_log_timer_callback

定时器回调函数,发送事件给主任务。

代码片段:


OSAFlagSet(sample_ele_log_flag_ref, SAMPLE_ELE_LOG_TASK_TIMER_CHANGE_FLAG_BIT, OSA_FLAG_OR);

  • sample_ele_log_task

日志写入任务,由事件驱动,这里5s一次。

代码片段:


while(1)
{
    status = OSAFlagWait(sample_ele_log_flag_ref, flag_mask, OSA_FLAG_OR_CLEAR, &flag_value, OSA_SUSPEND);
    ASSERT(status == OS_SUCCESS);
//        sample_ele_log_uart_printf("debug> sample_ele_log_count = %d",sample_ele_log_count);
//        sample_ele_log_uart_printf("%s[%d] freesize: %d", __FUNCTION__, __LINE__, FDI_GetFreeSpaceSize());
    if(flag_value & SAMPLE_ELE_LOG_TASK_TIMER_CHANGE_FLAG_BIT)
    {
        air_sw_log_write_data(11111.111111);
    }
    else
    {
        sample_ele_log_uart_printf("debug> open file for write error\n");
    }
}

4.7 编译

在SDK根目录打开命令行,输入命令.\build.bat -l .\amaziot_bloom_os_sdk\sample\libraries\8.5_ele_log\

4.8 生成固件

参考入门中开发工具,生成工具。

4.9 测试

测试步骤:

  • 参考编译教程,和文档开头的编译指令,进行编译
  • 按照编译教程选择对应的选项
  • 烧录

4.10 固件

TCP连接

60s一次心跳,测试1小时;

本文章源自奇迹物联开源的物联网应用知识库Cellular IoT Wiki,更多技术干货欢迎关注收藏Wiki:Cellular IoT Wiki 知识库(https://rckrv97mzx.feishu.cn/wiki/wikcnBvAC9WOkEYG5CLqGwm6PHf)

注:本文部分内容来源于网络,如有侵权,请及时联系我们。

文章评论0条评论)

登录后参与讨论
我要评论
0
0
关闭 站长推荐上一条 /2 下一条