pure sdk for main

This commit is contained in:
divadiow
2025-08-27 09:51:58 +01:00
parent f0d033f1c9
commit 0571416e7c
3283 changed files with 1577720 additions and 1 deletions
+310
View File
@@ -0,0 +1,310 @@
/*********************************************************************************************
* 本文件仅仅用于低功耗休眠恢复的一些demo,不是完整的,更多的应用休眠和恢复要根据实际应用逻辑和硬件
* 去实现,demo有部分说明
********************************************************************************************/
#include "sys_config.h"
#include "typesdef.h"
#include "list.h"
#include "dev.h"
#include "devid.h"
#include "osal/string.h"
#include "osal/task.h"
#include "audio_app/audio_adc.h"
#include "audio_app/audio_dac.h"
#include "lib/video/dvp/cmos_sensor/csi.h"
#include "hal/jpeg.h"
#include "lib/video/dvp/jpeg/jpg.h"
#include "osal/msgqueue.h"
#include "osal/sleep.h"
#include "osal/semaphore.h"
#if LOWPOWER_DEMO == 1
#ifdef CONFIG_SLEEP
#include "lib/lmac/lmac_dsleep.h"
#include "lib/common/dsleepdata.h"
#endif
#include "lib/net/eloop/eloop.h"
#include "stream_frame.h"
#include "app_lcd/osd_encode_stream.h"
#ifdef CONFIG_SLEEP
//休眠定时器起来,如果需要添加io唤醒,需要自行修改
//默认用了保活方式,所以需要连接路由器成功后才会休眠
void sleep_test(uint32_t time)
{
uint32 sleep_type = 1;
struct system_sleep_param args;
memset(&args,0,sizeof(args));
args.sleep_ms = time;
//args.wkup_io_sel[0] = PA_13;//LP Module PA_8
args.wkup_io_edge = 0x00;//0: Rising; 1:Falling Edge
args.wkup_io_en = 0x00;//IO0 En
os_printf("%s:%d\tenter sleep\n",__FUNCTION__,__LINE__);
system_sleep(sleep_type, &args);
}
static void enter_lowpower_timer(struct event *ei, void *d)
{
uint32_t time = (uint32_t)d;
os_printf("%s:%d\ttime:%d\n",__FUNCTION__,__LINE__,time);
//进入休眠,休眠500ms起来
sleep_test(time);
}
//恢复顺序根据硬件以及程序逻辑去适配(比如io复用之类都要考虑)
void lowPower_resume_task(void *d)
{
//uint32_t flags;
struct os_msgqueue *msgq = (struct os_msgqueue *)d;
uint32_t res = os_msgq_get(msgq,-1);
//收到信号量,恢复对应的硬件
if(res)
{
//usb u盘的恢复
#if USB_EN
#ifdef RT_USBH
hg_usbh_register(HG_USB_HOST_CONTROLLER_DEVID);
#endif
#endif
//lcd相关恢复,由于恢复与儿童相机的原框架不匹配,这里只是对lcd简单恢复,没有任何应用恢复
#if LVGL_STREAM_ENABLE == 1 && LCD_EN == 1
uint16_t w,h;
uint16_t screen_w,screen_h;
uint8_t rotate,video_rotate;
stream *s1 = get_stream_available(R_OSD_ENCODE);
stream *s2 = get_stream_available(R_OSD_SHOW);
extern void lcd_driver_reinit();
extern void lcd_hardware_init(uint16_t *w,uint16_t *h,uint8_t *rotate,uint16_t *screen_w,uint16_t *screen_h,uint8_t *video_rotate);
lcd_hardware_init(&w,&h,&rotate,&screen_w,&screen_h,&video_rotate);
lcd_driver_reinit();
stream_self_cmd_func(s1, OSD_HARDWARE_STREAM_RESET, 0);
close_stream(s1);
close_stream(s2);
lvgl_hdl_resume();
#endif
//这里是dvp恢复
#if JPG_EN
jpg_cfg(HG_JPG0_DEVID,VPP_DATA0);
#endif
#if DVP_EN
bool csi_cfg();
bool csi_open();
csi_cfg();
csi_open();
#endif
//恢复sd
#if SDH_EN && FS_EN
extern bool fatfs_register();
fatfs_register();
#endif
}
//释放空间
os_msgq_del(msgq);
os_free(msgq);
}
static uint8_t suspend_flag = 0;
static struct os_msgqueue *msgq = NULL;
//开始进入低功耗模式,首先将自己应用层的资源释放,创建一个高优先级的线程,主要用于低功耗唤醒后,可以第一时间快速恢复外部硬件
void lowPower_start()
{
if(suspend_flag)
{
return;
}
os_printf("%s:%d\n",__FUNCTION__,__LINE__);
//lcd的休眠,如果硬件有特殊,需要额外处理
#if LVGL_STREAM_ENABLE == 1 && LCD_EN == 1
lvgl_hdl_suspend();
wait_lcd_exit();
#endif
//u盘恢复
#if USB_EN
#ifdef RT_USBH
hg_usbh_unregister(HG_USB_HOST_CONTROLLER_DEVID);
#endif
#endif
//卸载文件系统
#if SDH_EN && FS_EN
fatfs_unregister();
#endif
//开始主动关闭硬件以及硬件模块,外围硬件需要自己去关闭
os_printf("%s:%d\n",__FUNCTION__,__LINE__);
#if DVP_EN
struct vpp_device *vpp = (struct vpp_device *)dev_get(HG_VPP_DEVID);
struct dvp_device *dvp= (struct dvp_device *)dev_get(HG_DVP_DEVID);
dvp_close(dvp);
vpp_close(vpp);
#endif
os_printf("%s:%d\n",__FUNCTION__,__LINE__);
#if JPG_EN
jpg_clear_init_flag(0);
#endif
msgq = (struct os_msgqueue *)os_malloc(sizeof(struct os_msgqueue));
memset(msgq,0,sizeof(struct os_msgqueue));
os_msgq_init(msgq,1);
//创建线程任务
suspend_flag = 1;
os_task_create("resume", lowPower_resume_task, (void*)msgq, OS_TASK_PRIORITY_ABOVE_NORMAL, 0, NULL, 1024);
//os_msgq_put(msgq,msgq,0);
}
void lowPower_task_wakeup()
{
suspend_flag = 0;
os_msgq_put(msgq,msgq,0);
}
//应用层的休眠唤醒回调函数,所有操作在上面几个函数实现,不同应用实现不一样,所以上面的函数根据自己应用作改动
int32 app_sleepcb(uint16_t type, struct sys_sleepcb_param *args, void *priv)
{
uint8_t action = args->action;
uint8_t step = args->step;
uint8_t reason = args->resume.wkreason;
switch(action)
{
case SYS_SLEEPCB_ACTION_SUSPEND:
if(step == SYS_SLEEPCB_APP)
{
lowPower_start();
}
break;
case SYS_SLEEPCB_ACTION_RESUME:
if(step == SYS_SLEEPCB_APP)
{
//注意这里需要判断一下唤醒的原因,由于这里是demo,所有的原因都会唤醒
//if(reason == DSLEEP_WK_REASON_WK_DATA)
{
lowPower_task_wakeup();
}
}
break;
}
return RET_OK;
}
//这个返回1代表收到需要的数据,会唤醒,原因是DSLEEP_WK_REASON_WK_DATA
//返回0就不是匹配数据,会继续休眠
//这里demo只是检测到tcp就唤醒,如果自己的应用,还需要判断数据是否匹配等
//还有就是tcp即使不是数据包,可能也要唤醒,需要维持tcp的连接
int32 user_check_data(void *usr_wkdet_priv, uint8 *data, uint32 len)
{
//tcp的长度会超过10
if(len >= 10)
{
//判断一下是否为tcp,简单去处理了,tcp就回应一个心跳包,实际应用可能还要判断一下是否为自己需要的ip
//应用层就是唤醒后就去写卡 dvp 录像之类
if(data[9] == 0x06)
{
return 1;
}
}
return 0;
}
//应用层低功耗初始化
void app_lowpower_init()
{
sys_register_sleepcb(app_sleepcb,NULL);
dsleep_set_usr_wkdet_cb(NULL, user_check_data);
//定时休眠
eloop_add_timer(5000,EVENT_F_ENABLED,enter_lowpower_timer,(void*)5000);
}
static int32 app_sleepcb_test(uint16_t type, struct sys_sleepcb_param *args, void *priv)
{
uint8_t action = args->action;
uint8_t step = args->step;
uint8_t reason = args->resume.wkreason;
switch(action)
{
//低功耗休眠的时候会调用的接口,这里处理完毕后,尽量保证自己的线程不要再运行或者不要运行一些外设网络的东西
case SYS_SLEEPCB_ACTION_SUSPEND:
if(step == SYS_SLEEPCB_APP)
{
os_printf("##########################enter %s:%d\n",__FUNCTION__,__LINE__);
}
break;
//低功耗恢复,这里恢复可以是别原因,APP只会调用一次才对
case SYS_SLEEPCB_ACTION_RESUME:
if(step == SYS_SLEEPCB_APP)
{
//注意这里需要判断一下唤醒的原因,由于这里是demo,所有的原因都会唤醒
//if(reason == DSLEEP_WK_REASON_WK_DATA)
{
os_printf("$$$$$$$$$$$$$$$$$$$$$$$$$$$$exit %s:%d\n",__FUNCTION__,__LINE__);
}
}
break;
}
return RET_OK;
}
/********************************************************************
* type:
typedef enum {
SYSTEM_SLEEP_TYPE_SRAM_WIFI = 1,
SYSTEM_SLEEP_TYPE_WIFI_DSLEEP = 2,
SYSTEM_SLEEP_TYPE_SRAM_ONLY = 3,
SYSTEM_SLEEP_TYPE_LIGHT_SLEEP = 4,
SYSTEM_SLEEP_TYPE_RTCC = 5,
SYSTEM_SLEEP_TYPE_MAX = 6,
} SYSTEM_SLEEP_TYPE;
time:代表休眠多久时间后唤醒
* ******************************************************************/
//测试的时候可以将type设置为3(SYSTEM_SLEEP_TYPE_SRAM_ONLY),不需要连接wifi
void enter_sleep_test(uint32_t type,uint32_t time)
{
uint32 sleep_type = type;
struct system_sleep_param args;
memset(&args,0,sizeof(args));
args.sleep_ms = time;
//args.wkup_io_sel[0] = PA_13;//LP Module PA_8
args.wkup_io_edge = 0x00;//0: Rising; 1:Falling Edge
args.wkup_io_en = 0x00;//IO0 En
os_printf("%s:%d\tenter sleep\n",__FUNCTION__,__LINE__);
system_sleep(sleep_type, &args);
}
//内部测试低功耗使用
void lowpoer_sleep_test_init()
{
sys_register_sleepcb(app_sleepcb_test,NULL);
}
#endif
#endif