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
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/83779.shtml
英文地址,請注明出處:http://en.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 我們的代碼通常運行在瀏覽器…