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;
}

执行结果

在这里插入图片描述

其他

怎么说呢?挺不顺的,一定要有耐心。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.pswp.cn/pingmian/83779.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

mysql的分页场景下,页数越大查询速度越慢的解决方法

一 问题描述 select * from table limit 0,10扫描满足条件的10行&#xff0c;返回10行&#xff0c; 但当limit 99989,10的时候数据读取就很慢,limit 99989,10的意思扫描满足条件的99999行&#xff0c;扔掉前面的99989行&#xff0c;返回最后的10行&#xff0c;这样速度就会很慢…

MDP的 Commands模块

文章目录 Isaac Lab Commands 模块详细指南&#x1f4cb; 模块概述&#x1f3d7;️ 模块架构&#x1f3aa; 命令类型详解1. &#x1f6ab; 空命令 (NullCommand)2. &#x1f3c3; 速度命令 (VelocityCommand)&#x1f3b2; 均匀分布速度命令 (UniformVelocityCommand)&#x1f…

全流程开源!高德3D贴图生成系统,白模一键生成真实感纹理贴图

导读 MVPainter 随着3D生成从几何建模迈向真实感还原&#xff0c;贴图质量正逐渐成为决定3D资产视觉表现的核心因素。我们团队自研的MVPainter系统&#xff0c;作为业内首个全流程开源的3D贴图生成方案&#xff0c;仅需一张参考图与任意白模&#xff0c;即可自动生成对齐精确…

Levenberg-Marquardt算法详解和C++代码示例

Levenberg-Marquardt&#xff08;LM&#xff09;算法是非线性最小二乘问题中常用的一种优化算法&#xff0c;它融合了高斯-牛顿法和梯度下降法的优点&#xff0c;在数值计算与SLAM、图像配准、机器学习等领域中应用广泛。 一、Levenberg-Marquardt算法基本原理 1.1 问题定义 …

理解网络协议

1.查看网络配置 : ipconfig 2. ip地址 : ipv4(4字节, 32bit), ipv6, 用来标识主机的网络地址 3.端口号(0~65535) : 用来标识主机上的某个进程, 1 ~ 1024 知名端口号, 如果是服务端的话需要提供一个特定的端口号, 客户端的话是随机分配一个端口号 4.协议 : 简单来说就是接收数据…

如何计算光伏工程造价预算表?

在光伏工程的推进过程中&#xff0c;造价预算表的编制是至关重要的环节&#xff0c;传统的光伏工程造价预算编制方法&#xff0c;往往依赖人工收集数据、套用定额&#xff0c;再进行繁琐的计算与汇总&#xff0c;不仅效率低下&#xff0c;而且容易出现人为误差&#xff0c;导致…

新闻速递|Altair 与佐治亚理工学院签署合作备忘录,携手推动航空航天领域创新

近日&#xff0c;全球计算智能领域领先企业 Altair 与佐治亚理工学院正式签署合作备忘录&#xff0c;旨在深化航空航天领域的技术创新合作。 根据协议&#xff0c;佐治亚理工学院的航空航天系统设计实验室 (ASDL) 将获得 Altair 的技术支持&#xff0c;运用仿真与数据分析 (DA)…

PLSQLDeveloper配置OracleInstantClient连接Oracle数据库

PL/SQLDeveloper配置Oracle Instant Client连接Oracle数据库 文章目录 PL/SQLDeveloper配置Oracle Instant Client连接Oracle数据库 1. Oracle Instant Client下载与配置1. Oracle Instant Client下载2. Oracle Instant Client解压配置1. 解压2. 配置 2. PL/SQL Developer下载、…

数据库系统学习

关系型数据库 关系型数据库建立在关系模型基础上的数据库&#xff0c;关系型数据库是由多张能相互相连的二维表组成的数据库 优点&#xff1a; 都是使用表结构&#xff0c;格式一致&#xff0c;易于维护使用通用的sql语言操作&#xff0c;使用方便&#xff0c;可用于复杂查询…

美国大休斯顿都会区电网数据

美国大休斯顿都会区&#xff08;Houston-The Woodlands-Sugar Land Metropolitan Area&#xff09;电网数据。数据包括&#xff1a;发电、输电、变电、配电。而且配电线路也很完善&#xff01;下面是截图&#xff1a; 输电线路 配电线路 变电站 开关站 电厂

信创主机性能测试实例(升腾P860)

文章目录 一、引言二、基准测试&#xff08;Unixbench &#xff09;三、CPU测试&#xff08;SPEC CPU 2006&#xff09;四、GPU测试&#xff08;Glmark2&#xff09;五、IO测试&#xff08;Iozone &#xff09;六、内存基准测试&#xff08;Stream &#xff09;七、网络性能基准…

Web前端基础:HTML-CSS

1.标题 1.1标题排版 超链接 a 标签&#xff1a; 标签&#xff1a;<a href"....." target".....">央视网</a> 属性&#xff1a; href: 指定资源访问的urltarget: 指定在何处打开资源链接 _self: 默认值&#xff0c;在当前页面打开_blank: 在…

Python数学可视化:3D参数曲面与隐式曲面绘制技术

Python数学可视化&#xff1a;3D参数曲面与隐式曲面绘制技术 引言 在科学研究、工程设计和数学教学中&#xff0c;3D可视化技术是理解复杂几何形状和空间关系的重要工具。本文将介绍如何使用Python实现参数曲面和隐式曲面的3D可视化&#xff0c;通过数学公式和代码示例展示球…

传输层:udp与tcp协议

目录 再谈端口号 端口号范围划分 认识知名端口号(Well-Know Port Number) 两个问题 netstat pidof 如何学习下三层协议 UDP协议 UDP协议端格式 UDP的特点 面向数据报 UDP的缓冲区 UDP使用注意事项 基于UDP的应用层协议 TCP协议 TCP协议段格式 1.源端口号…

java 实现excel文件转pdf | 无水印 | 无限制

文章目录 目录 文章目录 前言 1.项目远程仓库配置 2.pom文件引入相关依赖 3.代码破解 二、Excel转PDF 1.代码实现 2.Aspose.License.xml 授权文件 总结 前言 java处理excel转pdf一直没找到什么好用的免费jar包工具,自己手写的难度,恐怕高级程序员花费一年的事件,也…

Keil调试模式下,排查程序崩溃简述

在Keil调试模式下&#xff0c;若程序崩溃&#xff0c;可以通过以下步骤来定位崩溃的位置&#xff1a; 一、查看调用栈&#xff08;Call Stack&#xff09; 打开调用栈窗口&#xff1a; 在Keil的调试模式下&#xff0c;点击菜单栏的“View” -> “Call Stack Window”&…

深度解析Mysql中MVCC的工作机制

MVCC,多版本并发控制 定义&#xff1a;维护一个数据的多个版本&#xff0c;使读写操作没有冲突&#xff0c;依赖于&#xff1a;隐藏字段&#xff0c;undo log日志&#xff0c;readView MVCC会为每条版本记录保存三个隐藏字段 DB_TRX_ID: 记录最近插入或修改该记录的事务IDDB_R…

uniapp+vue3实现CK通信协议(基于jjc-tcpTools)

1. TCP 服务封装 (tcpService.js) export class TcpService {constructor() {this.connections uni.requireNativePlugin(jjc-tcpTools)this.clients new Map() // 存储客户端连接this.servers new Map() // 存储服务端实例}// 创建 TCP 服务端 (字符串模式)createStringSe…

学习设计模式《十二》——命令模式

一、基础概念 命令模式的本质是【封装请求】命令模式的关键是把请求封装成为命令对象&#xff0c;然后就可以对这个命令对象进行一系列的处理&#xff08;如&#xff1a;参数化配置、可撤销操作、宏命令、队列请求、日志请求等&#xff09;。 命令模式的定义&#xff1a;将一个…

Webpack的基本使用 - babel

Mode配置 Mode配置选项可以告知Webpack使用相应模式的内置优化 默认值是production&#xff08;什么都不设置的情况下&#xff09; 可选值有&#xff1a;none | development | production; 这几个选项有什么区别呢&#xff1f; 认识source-map 我们的代码通常运行在浏览器…