da1469x使用记录(代码片段)

while(1) while(1)     2023-03-09     389

关键词:

1 低功耗管理

参考资料:

  1. da1469x_software_platform_reference
  2. 《STM32F103 FreeRTOS开发手册V1.1》主要看FreeRTOS的介绍

1.1 进入休眠与退出休眠的总概览

FreeRTOS 就是通过在处理器处理空闲任务的时候将处理器设置为低功耗模式来降低能耗。一般会在空闲任务的钩子函数中执行低功耗相关处理,比如设置处理器进入低功耗模式、关闭其他外设时钟、降低系统主频等等。
这里就需要使用FreeRTOS的Tickless 模式,即当处理器进入空闲任务周期以后就关闭系统节拍中断(滴答定时器中断),只有当其他中断发生或者其他任务需要处理的时候处理器才会被从低功耗模式中唤醒。

1.2 FreeRTOS低功耗管理分析

这部分低功耗管理主要由FreeRTOS系统处理

1.2.1 Tickless 具体实现

总体请参考《STM32F103 FreeRTOS开发手册V1.1》中Tickless 相关章节
重点关注如下几个:

  1. #define configUSE_TICKLESS_IDLE 2 定义为 2,是因为portSUPPRESS_TICKS_AND_SLEEP()由用户自己实现(这里是由DA1469X提供),如下:

    #define portSUPPRESS_TICKS_AND_SLEEP( x )       prvSystemSleep( x )
    

    函数prvSystemSleep( x )sdk\\free_rtos\\portable\\GCC\\DA1469x\\port.c 中。

  2. configPRE_SLEEP_PROCESSING ()configPOST_SLEEP_PROCESSING()
    在真正的低功耗设计中不仅仅是将处理器设置到低功耗模式就行了,还需要做一些其他的处理,比如:
    ● 将处理器降低到合适的频率,因为频率越低功耗越小,甚至可以在进入低功耗模式以后
    关闭系统时钟。
    ● 修改时钟源,晶振的功耗肯定比处理器内部的时钟源高,进入低功耗模式以后可以切换
    到内部时钟源,比如 STM32 的内部 RC 振荡器。
    ● 关闭其他外设时钟,比如 IO 口的时钟。
    ● 关闭板子上其他功能模块电源,这个需要在产品硬件设计的时候就要处理好,比如可以通过 MOS 管来控制某个模块电源的开关,在处理器进入低功耗模式之前关闭这些模块的电源。
    FreeRTOS 为我们提供了一个宏来完成这些操作,它就是 configPRE_SLEEP_PROCESSING(),这个宏的具体实现内容需要用户去编写。如果在进入低功耗模式之前我们降低了处理器频率、关闭了某些外设时钟等的话,那在退出低功耗模式以后就 需 要 恢 复 处 理 器 频 率 、 重 新 打 开 外 设 时 钟 等 , 这 个 操 作 在 宏 configPOST_SLEEP_PROCESSING() 中完成,同样的这个宏的具体内容也需要用户去编写。
    使用举例:

    在DA1469x的SDK代码中如下:

    #define configPRE_SLEEP_PROCESSING( x )
    #define configPOST_SLEEP_PROCESSING()
    

    configPRE_SLEEP_PROCESSING 具体应用位置:
    prvSystemSleep -> pm_sleep_enter -> apply_wfi -> configPRE_SLEEP_PROCESSING( sleep_period );
    configPOST_SLEEP_PROCESSING 具体应用位置:
    prvSystemSleep -> pm_sleep_enter -> system_wake_up -> sys_init_wake_up -> configPOST_SLEEP_PROCESSING();

    而这里并没有定义具体函数,可由用户自己定义,比如可以通过 MOS 管来控制某个模块电源的开关

1.2.2 空闲任务具体实现

当 FreeRTOS 的调度器启动以后就会自动的创建一个空闲任务,即当调用函数 vTaskStartScheduler()启动任务调度器的时候此函数就会自动创建空闲任务,而DA1469x的低功耗就是在空闲任务中实现的。

#define portSUPPRESS_TICKS_AND_SLEEP( x )       prvSystemSleep( x )
static portTASK_FUNCTION( prvIdleTask, pvParameters )

	...
	for( ;; )
	
		...
		#if ( configUSE_TICKLESS_IDLE != 0 )
		
					if( xExpectedIdleTime >= configEXPECTED_IDLE_TIME_BEFORE_SLEEP )
					
						traceLOW_POWER_IDLE_BEGIN(); /*进入 tickless idle 前需要做的处理,没做任何处理*/
						portSUPPRESS_TICKS_AND_SLEEP( xExpectedIdleTime );/*该函数即 prvSystemSleep( x ) */
						traceLOW_POWER_IDLE_END();  /*退出 tickless idle 后需要做的处理,没做任何处理*/
					
					else
					
						mtCOVERAGE_TEST_MARKER();
					
		
		#endif /* configUSE_TICKLESS_IDLE */
	

1.3 DA1469x低功耗管理分析

这部分是DA1469x低功耗的具体实现

1.3.1 prvSystemSleep函数分析

prvSystemSleep 函数即 portSUPPRESS_TICKS_AND_SLEEP ,FreeRTOS系统进入空闲函数后,会执行prvSystemSleep函数,使系统进入低功耗模式,其执行步骤如下:
prvSystemSleep -> pm_sleep_enter -> apply_wfi -> goto_deepsleep();
进入休眠和退出休眠步骤

prvSystemSleep 还是属于FreeRTOS系统内,而到了pm_sleep_enter 函数才是真正处理DA1469x进入低功耗。
要点了解:

  1. 具体低功耗模式由current_sleep_mode参数决定,由sleep_mode_t pm_sleep_mode_set(sleep_mode_t mode)函数更改
  2. dg_configUSE_WDOG如果定义为1,则需要计算看门狗的时间,在看门狗复位前如要唤醒;看门狗复位计时快到时则不会进入低功耗。因此看门狗的复位时间需要注意。
  3. dg_configMIN_SLEEP_TIME 定义了最短休眠时间,默认为3ms
  4. 需要使能Tickless 模式
  5. 唤醒模式设置void pm_set_wakeup_mode(bool wait_for_xtalm),参数为true或false,When false, the system will start executing code immediately after wake-up.When true, upon wake-up the system will wait for the system clock to be switched to the appropriate clock source before continuing with code execution.

在pm_sleep_enter 函数中做的工作:

  1. 判断是否符合进入休眠的条件,不符合则退出;
  2. 计算可休眠的时间,如果时间太短不会进入休眠;
  3. 根据相应的休眠模式做准备,如关闭时钟、外设等;

2 看门狗系统

2.1 看门狗使用注意事项

  1. sys_watchdog_init 函数为初始化看门狗平台,使用看门狗都要调用该函数,且需要尽早调用;
  2. 每个任务都有相应的看门狗,各自独立,
  3. 当任务需要长时间阻塞时,需要暫停该任务的看门狗,并在阻塞停止后恢复看门狗
  4. The hardware watchdog is essentially a countdown timer, which is powered by the always on domain (PD_AON) and it will be automatically enabled as soon as the system powers up. It is decremented by 1 every ~10 ms (assuming default source clock the RC32K) and it is set to max value at reset.
  5. dg_configWDOG_RESET_VALUE ,Its default value is the maximum 0xFF, which corresponds to approximately 2.6 seconds (assuming default source clock the RC32K).
  6. The maximum number of tasks that can be monitored is defined by the configuration macro dg_configWDOG_MAX_TASKS_CNT. Its default value is 6 (the absolute maximum is 32).
    4~6点总结:看门狗计数定时器是永久上电(相对休眠或工作模式而言),默认时钟源是RC32K,约10ms计数值减1,当复位值为默认值0xFF时,看门狗复位周期是2.6S(255*10=2550ms);默认可以注册6个任务看门狗,最大可设置为32个(即最大任务数)
  7. This results to a maximum watchdog time-out of 84 seconds. If the RCX is used as a source clock, the time-out time is even longer, depending on the RCX frequency.看门狗复位之间可达84秒甚至更长,取决于时钟源RCX
  8. 看门狗时钟源选择低速时钟 #define dg_configUSE_LP_CLK ( LP_CLK_32768 )

2.2 看门狗相关函数分析

  1. int8_t sys_watchdog_register(bool notify_trigger)
    Register current task in sys_watchdog module,Returned identifier shall be used in all other calls to sys_watchdog from current task.
int8_t wdog_id;
wdog_id = sys_watchdog_register(false);

参数notify_trigger为 true 或 false,当 dg_configWDOG_NOTIFY_TRIGGER_TMO 被定义时才起作用,dg_configWDOG_NOTIFY_TRIGGER_TMO的功能是,使用定时器周期的通知看门狗

  1. void sys_watchdog_set_latency(int8_t id, uint8_t latency)
    给看门狗复位延长一段时间,比如计数值为10,使用该函数增加延时5,那么计数完5之后,再从10开始倒计时,通常用于一段需要长时间计算的代码中,使用该函数后只延时一次,后面看门狗计时不会增加这部分值

蓝牙ble之da1469x的应用(代码片段)

...耗管理分析1.3.1prvSystemSleep函数分析2看门狗系统2.1看门狗使用注意事项2.2看门狗相关函数分析3蓝牙BLE系统3.1蓝牙BLE设备参数ble_dev_params_t3.2蓝牙B 查看详情

da14531学习笔记经验总结(代码片段)

...录一次,为了方便调试,DA14531还支持外部flash。使用外部flash时,首先需要根据硬件配置flash对应管脚然后连接烧录就可以了OTP正式生产的时候就需要将外部flash去掉,烧录OTP。OTP烧录分为两部分,OTPheader和固... 查看详情

da14531学习笔记经验总结(代码片段)

...录一次,为了方便调试,DA14531还支持外部flash。使用外部flash时,首先需要根据硬件配置flash对应管脚然后连接烧录就可以了OTP正式生产的时候就需要将外部flash去掉,烧录OTP。OTP烧录分为两部分,OTPheader和固... 查看详情

使用aop以及自定义注解实现业务日志的收集(代码片段)

直接上代码自定义注解:MyLog@Target(ElementType.METHOD)@Retention(RetentionPolicy.RUNTIME)public@interfaceMyLogStringvalue()default"";//value值是说明,会被记录到数据库里面自定义日志的实体类SysLog@Da 查看详情

automatedebssnapshotsusingawslambda&cloudwatch(代码片段)

OverviewInthispost,we‘llcoverhowtoautomateEBSsnapshotsforyourAWSinfrastructureusingLambdaandCloudWatch. We‘llbuildasolutionthatcreatesnightlysnapshotsforvolumesattachedtoEC2instancesanddeletesany 查看详情

php使用twitter记录错误(代码片段)

查看详情

k8s调试环境安装(代码片段)

目录 macminikube安装centosRancher安装记录自己常用两种方式minikube或Rancher macminikube安装参考文档 minikubestart|minikubemac上安装最简单,默认使用docker运行,需要先开启Dockerbrewinstallminikube启动/停止minikubestartminikubestop常用的da 查看详情

k8s调试环境安装(代码片段)

目录 macminikube安装centosRancher安装记录自己常用两种方式minikube或Rancher macminikube安装参考文档 minikubestart|minikubemac上安装最简单,默认使用docker运行,需要先开启Dockerbrewinstallminikube启动/停止minikubestartminikubestop常用的da 查看详情

k8s调试环境安装(代码片段)

目录 macminikube安装centosRancher安装记录自己常用两种方式minikube或Rancher macminikube安装参考文档 minikubestart|minikubemac上安装最简单,默认使用docker运行,需要先开启Dockerbrewinstallminikube启动/停止minikubestartminikubestop常用的da 查看详情

lombook使用记录(代码片段)

(1)使用了@Builder的类,可以使用.build的方法进行构建,但是不能new次对象new的时候会报错"\'AgentFieDTOjivalngStingjavalangStingjavalang,Strng)isotpublcincom.asinfoacp.modules.agent.dto.AgentFleDTOC.Camotbeacessedfromoutsidepackage‘Age 查看详情

神经网络反向传播,通俗理解(代码片段)

...*(1-g(z)) LR-----1层神经网络  dL/dz简称dz_,L(a,y)使用交叉熵。   da_=dL/da= (-(y/a)+((1-y)/(1-a)))dz_=dL/da*da/dz=da_*  g‘(z)dw_=dL/dz*dz/dw=dz*xdb_= dz 2层神经网络 da_2=dL/da2=  (-(y/a)+((1-y)/(1-a)))dz_2=d... 查看详情

distpicker使用记录(代码片段)

今天使用distpicker遇到了一些问题,记录一下。 插件地址使用说明需要引入的js文件<scripttype="text/javascript"src="./././js/jquery/distpicker.data.js"></script><scripttype="text/javascript"src="./././js/jquery/distpi 查看详情

java使用rxnetty记录访问日志(代码片段)

查看详情

sql使用cursor循环遍历记录(代码片段)

查看详情

latex使用记录(代码片段)

三线表\\begintable[htbp]\\centering\\caption\\labeltab:testtabletest.\\begintabularlcl\\toprule..&..&..\\\\\\midrule..&..&..\\\\..&..&..\\\\\\bottomrule\\endtabular\\e 查看详情

[buuctf2018]onlinetool(代码片段)

0x00知识点escapeshellarg和escapeshellcmd使用不当导致rce如果应用使用escapeshellarg->escapeshellcmd这样的流程来处理输入,两个函数配合使用就会导致多个参数的注入。详细分析一下:传入的参数是:172.17.0.2'-v-da=1经过escapeshellarg处理... 查看详情

text使用dig查询dns记录(代码片段)

查看详情

ruby使用ssl加密的活动记录(代码片段)

查看详情