IoT/HCIP实验-3/LiteOS操作系统内核实验(任务、内存、信号量、CMSIS..)
文章目录
- 概述
- HelloWorld 工程
- C/C++配置
- 编译器主配置
- Makefile脚本
- 烧录器主配置
- 运行结果
- 程序调用栈
- 任务管理实验
- 实验结果
- osal 系统适配层
- osal_task_create
- 其他实验
- 实验源码
- 内存管理实验
- 互斥锁实验
- 信号量实验
- CMISIS接口实验
- 还是得JlINK
- CMSIS 简介
- LiteOS->CMSIS
- 任务间消息交互
- 执行结果
- 其他
概述
本实验基于LiteOS Studio 工具进行物联网终端的开发,使用LiteOS操作系统进行物联网开发板的控制。实验主要目的:
- 掌握LiteOS Studio的使用
- 掌握LiteOS操作系统任务的使用
- 掌握LiteOS操作系统内存管理的使用
- 掌握LiteOS操作系统互斥量和信号量使用
熟悉LCD屏幕的使用(在实验4中)熟悉开发板的LED和按键使用(在实验4中)- OSAL接口使用
- CMSIS接口使用(CMSIS任务和消息队列接口使用等)
@History
在进行本实验前,请先阅读 #<IDE/IoT/搭建物联网(LiteOS)集成开发环境,基于 LiteOS Studio + GCC + JLink>#,文中较详细的介绍了LiteOS Studio的搭建和使用方法,文中我们也提及了LiteOS工程(LiteOS_Lab_HCIP),但没有使用它,而是直接使用了BearPi-IoT_Std_LiteOS 源码。为了贴合实验指导书的步骤,我们在这里选用 LiteOS_Lab_HCIP源码。
在写本文前,我已经尝试了不同形式的物联网开发IDE,分别如下几篇文章中:
#<IDE/IoT/搭建物联网(LiteOS)集成开发环境,基于 LiteOS Studio + GCC + JLink>#
#<IDE/IoT/搭建物联网(LiteOS)集成开发环境,基于 VSCode + IoT Link 插件>#
#<IDE/IoT/搭建物联网(LiteOS)集成开发环境,基于 VSCode + GitBash + GCC工具>#
如果主要目标是为了完成HCIP-IOT实验,我是建议选用指导书中指定的LiteOS Studio开发环境,不仅是因为贴合指导书中的步骤,减少不必要的麻烦。华为云IoTDA中提及的VSCode + IoT Link 模式,由于要使用低版本的VSCode,让人很不爽,配置和调试操作都体验不咋地。相比较而言,LiteOS Studio 虽然是基于VSCode的,但其与你已经安装的VSCode不会产生环境变量或软件安装层次的冲突,算是优势吧。
HelloWorld 工程
请参见 #<IDE/IoT/搭建物联网(LiteOS)集成开发环境,基于 LiteOS Studio + GCC + JLink># 完成此部分实验。
C/C++配置
c_cpp_properties.json 是 VSCode 中 C/C++ 扩展的核心配置文件,主要用于配置代码分析和开发环境,确保 IntelliSense(智能代码补全、错误检查等)能够准确理解项目结构和编译器行,需要作出如下修改,
编译器主配置
关于目标板卡配置、组件配置、编译器,参见前文提到的 #<IDE/IoT/搭建物联网(LiteOS)集成开发环境,基于 LiteOS Studio + GCC + JLink>#,不再赘述。编译器配置下的Makefile脚本选择H:\HuaWeiYun\LiteOS_Lab_HCIP\targets\STM32L431_BearPi\GCC下的Makefile文件。
Makefile脚本
这块在HCIP-IoT实验手册中并没有提及。Makefile(脚本)最终编译哪个示例工程,是由LiteOS_Lab_HCIP\targets\STM32L431_BearPi.config文件决定的。
最简单的改变该文件的方法是,从\Demos各示例程序文件夹下拷贝defaults.sdkconfig全部内容,当然,也可以借助menuconfig和genconfig生成,那就稍微复杂些了,可以参考本专栏下其他文章。
烧录器主配置
烧录器、调试器配置,参见前文提到的 #<IDE/IoT/搭建物联网(LiteOS)集成开发环境,基于 VSCode + IoT Link 插件>#,采用ST-Link+OpenOCD模式。烧录文件要编译成功后才有哦。但还是建议使用JLink模式。
但还是建议使用JLink模式。这一节使用ST-Link+OpenOCD,体验很差劲。
运行结果
小熊派开发板的这个串口,感觉不太顶用,我就拔插过两三次,感觉就有接触不良的情况偶发啦。
程序调用栈
LiteOS_Lab_HCIP\targets\STM32L431_BearPi\Src\main.c
int main(void)
{UINT32 uwRet = LOS_OK;HardWare_Init();uwRet = LOS_KernelInit();if (uwRet != LOS_OK) {return LOS_NOK;}extern void shell_uart_init(int baud);shell_uart_init(115200);link_test(); //第一步(void)LOS_Start();return 0;
}static int link_test() {int ret = -1;UINT32 uwRet = LOS_OK;UINT32 handle;TSK_INIT_PARAM_S task_init_param;memset (&task_init_param, 0, sizeof (TSK_INIT_PARAM_S));task_init_param.uwArg = (unsigned int)NULL;task_init_param.usTaskPrio = 2;task_init_param.pcName =(char *) "link_main";task_init_param.pfnTaskEntry = (TSK_ENTRY_FUNC)link_main; //第二步task_init_param.uwStackSize = 0x1000;uwRet = LOS_TaskCreate(&handle, &task_init_param);if(LOS_OK == uwRet){ret = 0;}return ret;
}
LiteOS_Lab_HCIP\iot_link\link_main.c
int link_main(void *args) {...
#ifdef CONFIG_LINKDEMO_ENABLEextern int standard_app_demo_main(void);(void) standard_app_demo_main(); //第三步
#endif...
}
LiteOS_Lab_HCIP\targets\STM32L431_BearPi\Demos\hello_world_demo\hello_world_demo.c
//任务入口函数
static int app_hello_world_entry() {while (1) {printf("Hello World! This is BearPi!\r\n");osal_task_sleep(4*1000);}
}//第四步
int standard_app_demo_main() {osal_task_create("helloworld",app_hello_world_entry,NULL,0x400,NULL,2);return 0;
}
任务管理实验
新添加任务入口函数并创建任务
void *task1 = NULL, *task2 = NULL; int num = 0;
//添加任务2
static int hcip_iot_task(void) {while (1) {printf("This is task2!\r\n");#if 1if (num == 3) {osal_task_kill(task1);}#endifosal_task_sleep(4*1000);}
}//宏控制的本项目下的任务创建接口/每个示例下该函数声明相同
int standard_app_demo_main() {task1 = osal_task_create("helloworld",app_hello_world_entry,NULL,0x400,NULL,2);//新创建任务task2 = osal_task_create("task2",hcip_iot_task,NULL,0x400,NULL,2);return 0;
}
实验结果
任务添加测试, 两个任务同时运行,
如上,任务1和任务2同时执行,同时打印输出。
任务删除测试,
如上,任务1被关闭后,周任务2在执行。
几个注意事项:
1、在编译或重新编译前前,要先关闭串口,否则可能使得IDE卡主,不能执行编译过程,必须得重启软件。
2、在烧录器配置烧录.hex文件时,遇到过显示烧录成功(且复位过)但是不生效的情况,可以多尝试几次或配置烧录.bin文件。
osal 系统适配层
在这里我们简单看看osal适配层的实现方法,后期我们会单独讲解。
个人觉得osal与cmsis有些类似,在上述os目录下,osal和linux/ucos_ii等系统目录平级,cmsis目录在liteos之下,如下图,
OSAL定义统一的系统调用接口(如线程管理、通信),使应用无需关注底层内核(如LiteOS与Linux的差异)。例如,鸿蒙通过OSAL层兼容Linux与LiteOS内核。 CMSIS 为Cortex处理器提供标准外设访问API(如寄存器映射)及RTOS接口(CMSIS-RTOS2),确保代码可跨RTOS(如FreeRTOS、RTX5)复用。
osal_task_create
//osal 操作系统适配层函数
void* osal_task_create(const char *name,int (*task_entry)(void *args), void *args,int stack_size,void *stack,int prior) {void *ret = NULL;if((NULL != s_os_cb) &&(NULL != s_os_cb->ops) &&(NULL != s_os_cb->ops->task_create)) {ret = s_os_cb->ops->task_create(name, task_entry,args,stack_size,stack,prior);}return ret;
}
osal_task_create 函数调用堆栈分析,
其他实验
互斥锁、内存管理、信号量实验,统一参见如下代码。
实验源码
#define SWITCH_TEST_HELLO 0
#define SWITCH_TEST_TASK 0
#define SWITCH_TEST_MUTEX 1
#define SWITCH_TEST_MEM 0
#define SWITCH_TEST_SEMP 0//任务句柄
void *task1 = NULL, *task2 = NULL; int num = 0;#if SWITCH_TEST_MUTEX
//需要保护的公共资源
uint32_t public_value = 0;
//互斥锁
osal_mutex_t public_value_mutex;
#endif
//信号量实验
osal_semp_t sync_semp = NULL;#if SWITCH_TEST_HELLO
static int app_hello_world_entry()
{while (1){printf("Hello World! This is BearPi!\r\n");osal_task_sleep(4*1000);}
}
#endif#if SWITCH_TEST_TASK
static int hcip_iot_task(void) {while (1) {printf("This is task2, num:%d \r\n", ++num);#if 1if (num == 3) {osal_task_kill(task1);}#endifosal_task_sleep(4*1000);}
}
#endif#if SWITCH_TEST_MUTEX
//互斥锁/任务1入口
static int mutex_task1_entry() {while (1) {if (true == osal_mutex_lock(public_value_mutex)) {printf("task1: lock a mutex.\r\n");public_value += 10;printf("task1: public_value = %ld.\r\n", public_value);printf("task1: sleep...\r\n");osal_task_sleep(10); //msprintf("task1: continue...\r\n");printf("task1: unlock a mutex.\r\n");osal_mutex_unlock(public_value_mutex);if (public_value > 60) break; } //if} //whilereturn 0;
}//互斥锁/任务2入口
static int mutex_task2_entry() {while (1) {if (true == osal_mutex_lock(public_value_mutex)) {printf("task2: lock a mutex.\r\n");public_value += 5;printf("task2: public_value = %ld.\r\n", public_value);printf("task2: unlock a mutex.\r\n");osal_mutex_unlock(public_value_mutex);if (public_value > 50) break; #if 0 //task2 not sleeposal_task_sleep(10); //ms#endif} //if} //whilereturn 0;
}
#endif#if SWITCH_TEST_MEM
//内存管理实验/任务1
static int mem_access_task_entry() {uint32_t i = 0; //for looksize_t mem_size = 0; //uint8_t *mem_ptr = NULL; //内存块指针//loopwhile (1) {//每次循环申请的块大小扩一倍mem_size = 1 << i++;//执行申请操作mem_ptr = osal_malloc(mem_size);//successif (NULL != mem_ptr) {printf("access %d bytes memory success!\r\n", mem_size);osal_free(mem_ptr);mem_ptr = NULL;printf("free memory success!\r\n");}else {printf("access %d bytes memory failed!\r\n", mem_size);return 0;}}return 0;
}
#endif//信号量实验
#if SWITCH_TEST_SEMP
//信号量实验/任务1
static int semp_task1_entry() {printf("task1: post a semp.\r\n");osal_semp_post(sync_semp);printf("task1: end.\r\n");
}//信号量实验/任务1
static int semp_task2_entry() {printf("task2: watting for a semp...\r\n");osal_semp_pend(sync_semp);printf("task2: access a semp.\r\n");
}
#endif//示例初始化函数
int standard_app_demo_main() {
//原HelloWorld
#if SWITCH_TEST_HELLOosal_task_create("helloworld",app_hello_world_entry,NULL,0x400,NULL,2);
#endif//互斥锁实验
#if SWITCH_TEST_MUTEX//创建互斥锁osal_mutex_create(&public_value_mutex);//创建任务 //const char *name,int (*task_entry)(void *args), void *args,int stack_size,void *stack,int priortask1 = osal_task_create("mutex_task1", mutex_task1_entry, NULL, 0x400, NULL, 12);//创建任务 //const char *name,int (*task_entry)(void *args), void *args,int stack_size,void *stack,int priortask2 = osal_task_create("mutex_task2", mutex_task2_entry, NULL, 0x400, NULL, 11);
#endif//内存实验
#if SWITCH_TEST_MEM//创建任务task2 = osal_task_create("mem_task", mem_access_task_entry, NULL, 0x400, NULL, 11);
#endif//信号量实验
#if SWITCH_TEST_SEMP//创建信号量 /数量1初始值0osal_semp_create(&sync_semp, 1, 0);//任务1优先级低,负责释放信号量task1 = osal_task_create("semp_task1", semp_task1_entry, NULL, 0x400, NULL, 12);//任务2优先级高,先进入等待/申请信号量的状态task2 = osal_task_create("semp_task2", semp_task2_entry, NULL, 0x400, NULL, 11);
#endifreturn 0;
}
内存管理实验
互斥锁实验
如上实验结果,如果高优先级的任务不睡眠,则低优先级任务必要要等到高优先级任务退出后才有机会执行。
信号量实验
这里,semp_task2_entry优先级高,会先执行,进入pend等待信号量状态,函数会使得当前任务进入阻塞状态,从而让出 CPU 资源给其他任务使用,如这里优先级稍低的semp_task1_entry任务。待task1释放信号量后,task2被唤醒继续执行。
CMISIS接口实验
与FreeRTOS一样,LiteOS也支持CMSIS,这简直是福利。在以下目录 LiteOS_Lab_HCIP\iot_link\os\liteos\cmsis
还是得JlINK
前面几个小实验,纯粹是为了体验OpenOCD模式,但真的很难用啊。在进行CMSIS实验时,哈哈也不知道是咋鼓捣的,基于STLink+OpenOCD的调试环境,它之间罢工了。在配置文件、OpenOCD版本等方向尝试修复无果。
于是乎,我又乖乖的将板载的STLink刷成了JLink,该过程参考 #<IDE/IoT/搭建物联网(LiteOS)集成开发环境,基于 LiteOS Studio + GCC + JLink># 文章。这个二次烧录Jlink固件的过程,也很崎岖…
1、在 #<IDE/IoT/搭建物联网(LiteOS)集成开发环境,基于 VSCode + IoT Link 插件>#文中,提到了使用 STLinkReflash 将JLink 刷回 STLink 也不顺利。
2、在第一步中,通过STM32 ST-LINK Utility升级了调试器固件。
3、在上述两步基础上,再尝试使用 STLinkReflash 将STLink刷成JLink是失败的。后来,我重新安装了 STlink驱动、更换了usb接口、重启过电脑,等一系列组合拳下来,竟然成功啦。哈哈,不想再尝试了。就按照Studio官方建议,这么用吧。
4、J-Link 固件内置 J-Link GDB Server,可直接与调试工具(如 LiteOS Studio 的 GDB 客户端)通信,无需中间层协议转换。这种直接集成减少了调试链路的复杂性,提高运行效率。刷写后的 ST-Link(J-Link OB)可实现高达 1.8MHz 的下载速率,显著快于 OpenOCD + ST-Link 的组合。ST-Link没有内置GDB服务,因此要借助外部的openocd.exe做GDB服务器。
CMSIS 简介
随着 32 位处理器在嵌入式市场需求量逐渐增多,各家芯片公司推出新型芯片,伴随而
来的是开发工具、软件兼容以及代码移植等问题。在这种情况下,各个硬件平台的供应商都
寻求易于使用且高效的解决方案,其中,ARM 与 Atmel、IAR、KEIL、SEGGER 和 ST 等诸
多芯片和软件工具厂商合作,发布了一套 CMSIS 标准。
CMSIS(Cortex Microcontroller Software Interface Standard),即 ARM Cortex 微控制器软
件接口标准。CMSIS 标准提供了内核和外围设备、实时操作系统和中间组件之间的通用 API
接口,从而简化了软件的重复使用,缩短了微控制器开发人员的学习时间,并缩短了新设备
的上市时间。下图是 ARM 公司的 CMSIS 标准结构框图:
其中,CMSIS-CORE 层定义了 Cortex-M 以及 Cortex-A 处理器(Cortex-A5/A7/A9)内核
和外围设备的标准化 API。CMSIS-Pack 层包含了 CMSIS-Driver 驱动框架、CMSIS-DSP 相关
库、CMSIS-RTOS 操作系统 API、中间件 API 和 Peripheral HAL 层 API 等。根据 CMSIS 的标准,ARM 公司整合并提供了 CMSIS 软件包模板。基于 ARM 提供的 CMSIS 软件包模板,ST 官方结合自己芯片的差异进行了修改,并将其整合到了 STM32Cube 固件包中的 CMSIS 文件夹里。
LiteOS->CMSIS
除了ST的HAL支持外,LiteOS也要提供支持,以osThreadNew为例,
//cmsis_liteos2.c /定义在cmsis_os2.h中
osThreadId_t osThreadNew (osThreadFunc_t func, void *argument, const osThreadAttr_t *attr) {...uwRet = LOS_TaskCreate(&uwTid, &stTskInitParam);...
}
上述 LOS_TaskCreate 实现在 LiteOS_Lab_HCIP\iot_link\os\liteos\base\core 内核中。在osal层的任务创建函数 osal_task_create,其最后也要调用上述 LOS_TaskCreate 内核实现。 该函数的实现,我们不再深入。
任务间消息交互
#include <stdint.h>
#include <stddef.h>
#include <string.h>
#include <osal.h>
#include <cmsis_os.h> //CMSIS_OS_VER==2#define SWITCH_TEST_HELLO 0
#define SWITCH_TEST_TASK 0
#define SWITCH_TEST_MUTEX 0
#define SWITCH_TEST_MEM 0
#define SWITCH_TEST_SEMP 0
#define SWITCH_TEST_CMSIS 1//cmsis接口
#if SWITCH_TEST_CMSIS
//消息队列句柄 /void*
osMessageQueueId_t cmsis_queue;
//消息队列消息
typedef struct cmsis_msg {int a;int b;
} TMsg;///typedef void (*osThreadFunc_t) (void *argument);
//任务1 /发送消息
static void cmsis_task1_entry(void *argument) {TMsg tMsg = {0, 0};while (1) {//tMsg.a += 1;tMsg.b += 2;//(osMessageQueueId_t mq_id, const void *msg_ptr, uint8_t msg_prio, uint32_t timeout)osMessageQueuePut(cmsis_queue, &tMsg, 0, 10);//打印发送的消息printf("Send Msg a:%d b:%d\r\n", tMsg.a, tMsg.b);//睡眠osal_task_sleep(1*1000);//任务退出if (tMsg.a > 100) break;}
}///typedef void (*osThreadFunc_t) (void *argument);
//任务2 /接收消息
static void cmsis_task2_entry(void *argument) {TMsg tMsg; uint8_t msg_prio = 0;while (1) {//osStatus_t osMessageQueueGet (osMessageQueueId_t mq_id, void *msg_ptr, uint8_t *msg_prio, uint32_t timeout)osMessageQueueGet(cmsis_queue, (void*)&tMsg, &msg_prio, osWaitForever);//打印收到的消息printf("Recv Msg a:%d b:%d\r\n", tMsg.a, tMsg.b);}
}
#endifint standard_app_demo_main() {
//cmsis接口
#if SWITCH_TEST_CMSIS//创建消息队列/osMessageQueueId_t osMessageQueueNew (uint32_t msg_count, uint32_t msg_size, const osMessageQueueAttr_t *attr);cmsis_queue = osMessageQueueNew (5, sizeof(TMsg), NULL);const osThreadAttr_t thread_attr1 = {.name = "MyThread1", // 线程名称(调试用).stack_size = 1024, // 栈大小(字节).priority = osPriorityAboveNormal5 };const osThreadAttr_t thread_attr2 = {.name = "MyThread2", // 线程名称(调试用).stack_size = 1024, // 栈大小(字节).priority = osPriorityAboveNormal5};//任务1/发送消息 /osThreadId_t osThreadNew (osThreadFunc_t func, void *argument, const osThreadAttr_t *attr)osThreadId_t thread1 = osThreadNew (cmsis_task1_entry, NULL, &thread_attr1); //任务2接收消息 /osThreadId_t osThreadNew (osThreadFunc_t func, void *argument, const osThreadAttr_t *attr)osThreadId_t thread2 = osThreadNew (cmsis_task2_entry, NULL, &thread_attr2);//printf("Hello cmsis!\r\n");
#endifreturn 0;
}
执行结果
其他
怎么说呢?挺不顺的,一定要有耐心。
相关文章:

IoT/HCIP实验-3/LiteOS操作系统内核实验(任务、内存、信号量、CMSIS..)
文章目录 概述HelloWorld 工程C/C配置编译器主配置Makefile脚本烧录器主配置运行结果程序调用栈 任务管理实验实验结果osal 系统适配层osal_task_create 其他实验实验源码内存管理实验互斥锁实验信号量实验 CMISIS接口实验还是得JlINKCMSIS 简介LiteOS->CMSIS任务间消息交互…...

IT供电系统绝缘监测及故障定位解决方案
随着新能源的快速发展,光伏电站、储能系统及充电设备已广泛应用于现代能源网络。在光伏领域,IT供电系统凭借其持续供电性好、安全性高等优势成为光伏首选,但在长期运行中,例如老化、潮湿、隐裂、机械损伤等问题会影响光伏板绝缘层…...

成都鼎讯硬核科技!雷达目标与干扰模拟器,以卓越性能制胜电磁频谱战
在现代战争中,电磁频谱已成为继陆、海、空、天之后的 “第五维战场”,雷达作为电磁频谱领域的关键装备,其干扰与抗干扰能力的较量,直接影响着战争的胜负走向。由成都鼎讯科技匠心打造的雷达目标与干扰模拟器,凭借数字射…...

深入解析C++中的extern关键字:跨文件共享变量与函数的终极指南
🚀 C extern 关键字深度解析:跨文件编程的终极指南 📅 更新时间:2025年6月5日 🏷️ 标签:C | extern关键字 | 多文件编程 | 链接与声明 | 现代C 文章目录 前言🔥一、extern 是什么?&…...
在鸿蒙HarmonyOS 5中使用DevEco Studio实现录音机应用
1. 项目配置与权限设置 1.1 配置module.json5 {"module": {"requestPermissions": [{"name": "ohos.permission.MICROPHONE","reason": "录音需要麦克风权限"},{"name": "ohos.permission.WRITE…...

UR 协作机器人「三剑客」:精密轻量担当(UR7e)、全能协作主力(UR12e)、重型任务专家(UR15)
UR协作机器人正以其卓越性能在现代制造业自动化中扮演重要角色。UR7e、UR12e和UR15通过创新技术和精准设计满足了不同行业的多样化需求。其中,UR15以其速度、精度及人工智能准备能力成为自动化领域的重要突破。UR7e和UR12e则在负载规格和市场定位上不断优化…...

SpringCloudGateway 自定义局部过滤器
场景: 将所有请求转化为同一路径请求(方便穿网配置)在请求头内标识原来路径,然后在将请求分发给不同服务 AllToOneGatewayFilterFactory import lombok.Getter; import lombok.Setter; import lombok.extern.slf4j.Slf4j; impor…...
uniapp中使用aixos 报错
问题: 在uniapp中使用aixos,运行后报如下错误: AxiosError: There is no suitable adapter to dispatch the request since : - adapter xhr is not supported by the environment - adapter http is not available in the build 解决方案&…...

(转)什么是DockerCompose?它有什么作用?
一、什么是DockerCompose? DockerCompose可以基于Compose文件帮我们快速的部署分布式应用,而无需手动一个个创建和运行容器。 Compose文件是一个文本文件,通过指令定义集群中的每个容器如何运行。 DockerCompose就是把DockerFile转换成指令去运行。 …...

多种风格导航菜单 HTML 实现(附源码)
下面我将为您展示 6 种不同风格的导航菜单实现,每种都包含完整 HTML、CSS 和 JavaScript 代码。 1. 简约水平导航栏 <!DOCTYPE html> <html lang"zh-CN"> <head><meta charset"UTF-8"><meta name"viewport&qu…...
06 Deep learning神经网络编程基础 激活函数 --吴恩达
深度学习激活函数详解 一、核心作用 引入非线性:使神经网络可学习复杂模式控制输出范围:如Sigmoid将输出限制在(0,1)梯度传递:影响反向传播的稳定性二、常见类型及数学表达 Sigmoid σ ( x ) = 1 1 +...

用docker来安装部署freeswitch记录
今天刚才测试一个callcenter的项目,所以尝试安装freeswitch 1、使用轩辕镜像 - 中国开发者首选的专业 Docker 镜像加速服务平台 编辑下面/etc/docker/daemon.json文件为 {"registry-mirrors": ["https://docker.xuanyuan.me"] }同时可以进入轩…...
爬虫基础学习day2
# 爬虫设计领域 工商:企查查、天眼查短视频:抖音、快手、西瓜 ---> 飞瓜电商:京东、淘宝、聚美优品、亚马逊 ---> 分析店铺经营决策标题、排名航空:抓取所有航空公司价格 ---> 去哪儿自媒体:采集自媒体数据进…...
Caliper 配置文件解析:config.yaml
Caliper 是一个区块链性能基准测试工具,用于评估不同区块链平台的性能。下面我将详细解释你提供的 fisco-bcos.json 文件结构,并说明它与 config.yaml 文件的关系。 fisco-bcos.json 文件解析 这个文件是针对 FISCO-BCOS 区块链网络的 Caliper 配置文件,主要包含以下几个部…...
【HTTP三个基础问题】
面试官您好!HTTP是超文本传输协议,是互联网上客户端和服务器之间传输超文本数据(比如文字、图片、音频、视频等)的核心协议,当前互联网应用最广泛的版本是HTTP1.1,它基于经典的C/S模型,也就是客…...

多模态大语言模型arxiv论文略读(108)
CROME: Cross-Modal Adapters for Efficient Multimodal LLM ➡️ 论文标题:CROME: Cross-Modal Adapters for Efficient Multimodal LLM ➡️ 论文作者:Sayna Ebrahimi, Sercan O. Arik, Tejas Nama, Tomas Pfister ➡️ 研究机构: Google Cloud AI Re…...
实现弹窗随键盘上移居中
实现弹窗随键盘上移的核心思路 在Android中,可以通过监听键盘的显示和隐藏事件,动态调整弹窗的位置。关键点在于获取键盘高度,并计算剩余屏幕空间以重新定位弹窗。 // 在Activity或Fragment中设置键盘监听 val rootView findViewById<V…...

QT: `long long` 类型转换为 `QString` 2025.6.5
在 Qt 中,将 long long 类型转换为 QString 可以通过以下两种常用方法实现: 方法 1:使用 QString::number() 直接调用 QString 的静态方法 number(),将数值转换为字符串: long long value 1234567890123456789LL; …...
[Java恶补day16] 238.除自身以外数组的乘积
给你一个整数数组 nums,返回 数组 answer ,其中 answer[i] 等于 nums 中除 nums[i] 之外其余各元素的乘积 。 题目数据 保证 数组 nums之中任意元素的全部前缀元素和后缀的乘积都在 32 位 整数范围内。 请 不要使用除法,且在 O(n) 时间复杂度…...

华为云Flexus+DeepSeek征文|DeepSeek-V3/R1 商用服务开通全流程与本地部署搭建
华为云FlexusDeepSeek征文|DeepSeek-V3/R1 商用服务开通全流程与本地部署搭建 前言 如今大模型其性能出色,华为云 ModelArts Studio_MaaS大模型即服务平台华为云内置了大模型,能助力我们轻松驾驭 DeepSeek-V3/R1,本文中将分享如何…...

智能仓储的未来:自动化、AI与数据分析如何重塑物流中心
当仓库学会“思考”,物流的终极形态正在诞生 想象这样的场景: 凌晨3点,某物流中心灯火通明却空无一人。AGV机器人集群根据实时订单动态规划路径;AI视觉系统在0.1秒内扫描包裹信息;数字孪生平台正模拟次日峰值流量压力…...
高防服务器能够抵御哪些网络攻击呢?
高防服务器作为一种有着高度防御能力的服务器,可以帮助网站应对分布式拒绝服务攻击,有效识别和清理一些恶意的网络流量,为用户提供安全且稳定的网络环境,那么,高防服务器一般都可以抵御哪些网络攻击呢?下面…...

自然语言处理——循环神经网络
自然语言处理——循环神经网络 循环神经网络应用到基于机器学习的自然语言处理任务序列到类别同步的序列到序列模式异步的序列到序列模式 参数学习和长程依赖问题基于门控的循环神经网络门控循环单元(GRU)长短期记忆神经网络(LSTM)…...

【论文阅读28】-CNN-BiLSTM-Attention-(2024)
本文把滑坡位移序列拆开、筛优质因子,再用 CNN-BiLSTM-Attention 来动态预测每个子序列,最后重构出总位移,预测效果超越传统模型。 文章目录 1 引言2 方法2.1 位移时间序列加性模型2.2 变分模态分解 (VMD) 具体步骤2.3.1 样本熵(S…...
根据万维钢·精英日课6的内容,使用AI(2025)可以参考以下方法:
根据万维钢精英日课6的内容,使用AI(2025)可以参考以下方法: 四个洞见 模型已经比人聪明:以ChatGPT o3为代表的AI非常强大,能运用高级理论解释道理、引用最新学术论文,生成对顶尖科学家都有用的…...

select、poll、epoll 与 Reactor 模式
在高并发网络编程领域,高效处理大量连接和 I/O 事件是系统性能的关键。select、poll、epoll 作为 I/O 多路复用技术的代表,以及基于它们实现的 Reactor 模式,为开发者提供了强大的工具。本文将深入探讨这些技术的底层原理、优缺点。 一、I…...

SpringTask-03.入门案例
一.入门案例 启动类: package com.sky;import lombok.extern.slf4j.Slf4j; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cache.annotation.EnableCach…...
什么?连接服务器也能可视化显示界面?:基于X11 Forwarding + CentOS + MobaXterm实战指南
文章目录 什么是X11?环境准备实战步骤1️⃣ 服务器端配置(CentOS)2️⃣ 客户端配置(MobaXterm)3️⃣ 验证X11 Forwarding4️⃣ 运行自定义GUI程序(Python示例)5️⃣ 成功效果 自用
outline: none 用于移除元素获得焦点时默认的轮廓线 broder:0 用于移除边框 font-size:0 用于设置字体不显示 list-style: none 消除<li> 标签默认样式 margin: xx auto 版心居中 width:100% 通栏 vertical-align 作用于行内元素 / 表格单元格ÿ…...