【CC2530 教程 十二】CC2530 Z-Stack 硬件抽象层

目录

一、硬件抽象层简介:

(1)HAL 硬件抽象层是什么?

(2)通俗易懂的解释:

(3)具体例子:

二、硬件抽象层HAL:

(1)HAL文件目录及工程结构:

(2)工程结构说明:

(3)HAL文件使用:


一、硬件抽象层简介:

(1)HAL 硬件抽象层是什么?

        硬件抽象层(Hardware Abstraction Layer,简称 HAL) 是一种软件设计模式,它的目的是将硬件的具体实现细节与软件的其他部分隔离开来。简单来说,HAL 就像是一个中间层,它站在软件和硬件之间,让软件可以通过统一的接口来操作不同的硬件,而不需要关心硬件的具体实现细节。

(2)通俗易懂的解释:

        想象一下,你是一个厨师,你需要用不同的厨具来烹饪食物。如果你每次都要直接操作各种各样的锅、碗、瓢、盆,可能会很麻烦,尤其是当厨具的种类和品牌不同时。于是,你决定用一套统一的工具来操作这些厨具,比如用一个通用的锅铲来翻炒,用一个通用的勺子来搅拌。这样,你就不需要记住每种厨具的具体操作方法,只需要掌握通用工具的使用方法即可。

        在嵌入式系统中,HAL 就像是这套通用工具。它提供了一组统一的函数接口,让软件开发者可以通过这些接口来操作硬件,而不需要直接处理硬件的复杂细节。比如,你要控制一个 LED 灯亮起,你可以通过 HAL 提供的函数来实现,而不需要直接操作硬件寄存器。

(3)具体例子:

        假设你有一个开发板,上面有多种硬件设备,比如 LED 灯、按键、串口等。如果没有 HAL,你可能需要直接操作每个硬件设备的寄存器来控制它们,这会非常复杂,尤其是当硬件设备的类型和型号不同时。有了 HAL,你可以通过调用 HAL 提供的函数来控制这些设备,比如:

// 通过 HAL 函数点亮 LED 灯
HAL_LED_On(LED1);// 通过 HAL 函数读取按键状态
uint8_t keyState = HAL_KEY_Read(KEY1);

        这些函数内部已经封装了对硬件寄存器的操作,你只需要调用这些函数即可,不需要关心硬件的具体实现。

二、硬件抽象层HAL:

(1)HAL文件目录及工程结构:

HAL的文件位于 C:\Texas Instruments\Z-Stack 3.0.2\Components\hal 文件夹中。

进入 HAL 文件,如下:

其中:

组名称说明
common存放公共文件。
include存放驱动程序接口文件。
target存放各种类型主板的驱动程序源文件。

打开这三个文件夹,有:

文件名说明
hal_assert.c实现条件合法性判断功能的源代码文件。
hal_drivers.c硬件抽象层 HAL 任务初始化及事件处理函数所在文件,是 HAL 的入口源文件。

文件名说明
hal_adc.hADC(模拟数字转换)驱动程序头文件。
hal_assert.h条件合法性判断功能的头文件。
hal_board.h各种类型主板的硬件资源配置头文件。
hal_defs.h通用定义头文件。
hal_drivers.hHAL任务初始化及事件处理函数的头文件。
hal_flash.hFLASH(存储器)驱动程序头文件。
hal_key.h按键驱动程序头文件。
hal_lcd.h显示屏驱动程序头文件。
hal_led.hLED驱动程序头文件。
hal_rpc.hRPC(Remote Procedure Call,远程过程调用)驱动程序头文件。
hal_sleep.h休眠功能驱动程序头文件。
hal_timer.h定时器驱动程序头文件。
hal_uart.h串口驱动程序头文件。

文件夹名称说明
CC2530EB针对芯片主控为CC2530的评估板相关的驱动程序。
CC2530USB针对芯片主控为CC2530的带USB转串口评估板的驱动程序。
CC2530ZNP针对芯片主控为CC2530的ZNP(ZigBee And Processor)评估板的驱动程序。
CC2538针对芯片主控为CC2538的评估板的驱动程序。
CC2538ZNP针对芯片主控为CC2538的ZNP(ZigBee And Processor)评估板的驱动程序。

 以第一个为例,打开CC2530EB有:

对应类型主板的接口源文件和程序驱动源文件。

文件名作用说明
hal_uart_dma.c实现串口通信的直接内存访问(DMA)功能,用于高效的数据传输。
hal_uart_isr.c包含串口通信的中断服务例程(ISR),处理串口的中断事件。
hal_adc.c提供模数转换(ADC)功能的实现,用于采集模拟信号并转换为数字数据。
hal_aes.c提供高级加密标准(AES)加密算法的实现,用于数据加密和解密操作。
hal_board_cfg.h包含评估板硬件配置的宏定义和配置参数,用于适配具体的硬件平台。
hal_ccm.h提供CCM(Counter with CBC-MAC)加密模式的相关定义和函数声明。
hal_dma.c实现直接内存访问(DMA)功能,用于在不同内存区域或外设之间直接传输数据。
hal_dma.h提供DMA功能的函数声明和相关宏定义,用于配置和控制DMA操作。
hal_flash.c提供对存储器(FLASH)的操作函数,包括读取、写入和擦除等操作。
hal_key.c实现按键输入的相关功能,包括按键扫描和状态检测。
hal_lcd.c提供液晶显示屏(LCD)的驱动函数,用于显示字符或图形。
hal_led.c实现LED控制功能,包括点亮、熄灭和闪烁等操作。
hal_led_cfg.h包含LED配置的宏定义,如LED引脚定义和初始状态设置。
hal_mac_cfg.h包含MAC层配置的宏定义,用于设置无线通信的相关参数。
hal_mcu.h提供微控制器(MCU)相关的函数声明和宏定义,如时钟配置和复位操作。
hal_oad.c实现无线固件更新(Over-the-Air Download,OAD)功能的源代码。
hal_oad.h提供OAD功能的函数声明和相关宏定义,用于无线固件更新操作。
hal_ota.c提供OTA(Over-the-Air)升级功能的实现,用于远程更新设备固件。
hal_ota.h包含OTA功能的函数声明和相关定义,用于支持远程固件升级。
hal_sleep.c实现低功耗睡眠模式的相关功能,用于节能操作。
hal_startup.c包含系统启动相关的代码,如初始化和主函数入口等。
hal_timer.c提供定时器功能的实现,用于精确的时间控制和延迟操作。
hal_types.h定义常用的类型和数据结构,为其他模块提供统一的数据类型声明。
hal_uart.c实现串口通信的基本功能,包括数据发送和接收操作。

(2)工程结构说明:

打开 Z-Stack 中的一个示例工程:

 打开HAL目录,分别展开Common、Include和Target目录如下:

文件夹路径作用说明
HAL/Common存放公共文件,包含通用函数实现和工具代码,可在不同项目和硬件平台上复用。
HAL/Include存放各种驱动程序的接口文件,定义函数原型、数据结构和宏等,供其他模块调用和配置。
HAL/Target存放针对特定类型主板的驱动程序源文件和配置文件,每个子文件夹对应不同的硬件平台。
HAL/Target/CC2530EB针对主控芯片为CC2530的评估板,包含该平台下的驱动实现和配置文件。
HAL/Target/CC2530USB针对带USB转串口的CC2530评估板,包含该平台下的驱动实现和配置文件。
HAL/Target/CC2530ZNP针对CC2530的ZNP评估板,包含该平台下的驱动实现和配置文件。
HAL/Target/CC2538针对主控芯片为CC2538的评估板,包含该平台下的驱动实现和配置文件。
HAL/Target/CC2538ZNP针对CC2538的ZNP评估板,包含该平台下的驱动实现和配置文件。

(3)HAL文件使用:

初始化函数:

HAL中的初始化函数位于hal_drivers.c文件为Hal_Init(),如下:

/*************************************************************************************************** @fn      Hal_Init** @brief   Hal初始化函数。** @param   task_id - Hal TaskId** @return  None**************************************************************************************************/
void Hal_Init( uint8 task_id )
{/*注册任务ID */Hal_TaskID = task_id;#ifdef CC2591_COMPRESSION_WORKAROUNDosal_start_reload_timer( Hal_TaskID, PERIOD_RSSI_RESET_EVT, PERIOD_RSSI_RESET_TIMEOUT );
#endif
}

驱动程序初始化:

HAL中的驱动程序初始化函数位于hal_drivers.c文件为HalDriverInit(),如下:

/*************************************************************************************************** @fn      Hal_DriverInit** @brief   初始化硬件(HW)- 这些需要在任何人之前初始化。*          该函数负责按正确的顺序初始化各个硬件模块,确保系统正常运行。** @param   task_id - Hal TaskId(任务ID),用于标识HAL相关的任务或事件。** @return  None**************************************************************************************************/
void HalDriverInit(void)
{/* TIMER(定时器)*/
#if (defined HAL_TIMER) && (HAL_TIMER == TRUE)// 如果定义了HAL_TIMER且其值为TRUE,则初始化定时器模块// 定时器模块用于提供精确的时间控制和延迟功能
#endif/* ADC(模数转换)*/
#if (defined HAL_ADC) && (HAL_ADC == TRUE)// 如果定义了HAL_ADC且其值为TRUE,则初始化ADC模块// ADC模块用于将模拟信号转换为数字信号HalAdcInit();
#endif/* DMA(直接内存访问)*/
#if (defined HAL_DMA) && (HAL_DMA == TRUE)// 如果定义了HAL_DMA且其值为TRUE,则初始化DMA模块// DMA模块允许在外设和内存之间直接传输数据,而无需CPU干预,提高效率// 必须在调用任何使用DMA模块的初始化函数之前调用此函数HalDmaInit();
#endif/* AES(高级加密标准)*/
#if (defined HAL_AES) && (HAL_AES == TRUE)// 如果定义了HAL_AES且其值为TRUE,则初始化AES模块// AES模块用于数据加密和解密操作HalAesInit();
#endif/* LCD(液晶显示屏)*/
#if (defined HAL_LCD) && (HAL_LCD == TRUE)// 如果定义了HAL_LCD且其值为TRUE,则初始化LCD模块// LCD模块用于显示字符或图形HalLcdInit();
#endif/* LED(发光二极管)*/
#if (defined HAL_LED) && (HAL_LED == TRUE)// 如果定义了HAL_LED且其值为TRUE,则初始化LED模块// LED模块用于控制LED的点亮、熄灭和闪烁等操作HalLedInit();
#endif/* UART(通用异步收发传输器)*/
#if (defined HAL_UART) && (HAL_UART == TRUE)// 如果定义了HAL_UART且其值为TRUE,则初始化UART模块// UART模块用于串行通信,实现数据的发送和接收HalUARTInit();
#endif/* KEY(按键)*/
#if (defined HAL_KEY) && (HAL_KEY == TRUE)// 如果定义了HAL_KEY且其值为TRUE,则初始化按键模块// 按键模块用于检测按键输入和处理按键事件HalKeyInit();
#endif/* SPI(串行外设接口)*/
#if (defined HAL_SPI) && (HAL_SPI == TRUE)// 如果定义了HAL_SPI且其值为TRUE,则初始化SPI模块// SPI模块用于与外部设备进行高速串行通信HalSpiInit();
#endif/* HID(人机接口设备)*/
#if (defined HAL_HID) && (HAL_HID == TRUE)// 如果定义了HAL_HID且其值为TRUE,则初始化HID模块// HID模块用于与人机接口设备(如键盘、鼠标等)进行通信usbHidInit();
#endif
}

        在开发过程中可以需求来使用指定的外设,例如设置 HAL_TIMER = TRUE、HAL_ADC = TRUE、HAL_DMA = TRUE、HAL_AES = TRUE、HAL_LCD = TRUE、HAL_LED = TRUE、HAL_UART = TRUE 等等,指定对应的外设对应的宏。如果不用用到,那么就不用定义。在定义了对应的宏后就会执行对应的初始化。如果需要增加这里没有的外设,可以按照协议栈的这个架构新增外设。

事件处理:

        HAL的事件处理函数为位于hal_drivers.c文件中的Hal_ProcessEvent(),它的主要作用是处理HAL层的事件,位置如下:

/*************************************************************************************************** @fn      Hal_ProcessEvent** @brief   处理 HAL 相关的事件。*          该函数根据传入的事件标志,调用相应的处理函数或执行特定的操作。** @param   task_id - Hal TaskId(任务ID),用于标识HAL相关的任务。*          events - 需要处理的事件标志,每个标志代表一种特定的事件。** @return  返回未处理的事件标志。**************************************************************************************************/
uint16 Hal_ProcessEvent(uint8 task_id, uint16 events)
{uint8 *msgPtr;  // 用于接收消息的指针(void)task_id;  // 有意未引用的参数,避免编译器警告// 检查是否有系统消息事件if (events & SYS_EVENT_MSG){msgPtr = osal_msg_receive(Hal_TaskID);  // 接收消息while (msgPtr){/* 在这里做些事情 - 目前,只是释放消息并继续 *//* 释放消息内存 */osal_msg_deallocate(msgPtr);/* 接收下一条消息 */msgPtr = osal_msg_receive(Hal_TaskID);}// 清除 SYS_EVENT_MSG 事件标志,表示该事件已处理return events ^ SYS_EVENT_MSG;}#if (defined HAL_BUZZER) && (HAL_BUZZER == TRUE)// 检查是否有蜂鸣器事件if (events & HAL_BUZZER_EVENT){HalBuzzerStop();  // 停止蜂鸣器// 清除 HAL_BUZZER_EVENT 事件标志,表示该事件已处理return events ^ HAL_BUZZER_EVENT;}
#endif#ifdef CC2591_COMPRESSION_WORKAROUND// 检查是否有周期性 RSSI 重置事件if (events & PERIOD_RSSI_RESET_EVT){macRxResetRssi();  // 重置 RSSI// 清除 PERIOD_RSSI_RESET_EVT 事件标志,表示该事件已处理return (events ^ PERIOD_RSSI_RESET_EVT);}
#endif// 检查是否有 LED 闪烁事件if (events & HAL_LED_BLINK_EVENT){
#if (defined (BLINK_LEDS)) && (HAL_LED == TRUE)HalLedUpdate();  // 更新 LED 状态
#endif /* BLINK_LEDS && HAL_LED */// 清除 HAL_LED_BLINK_EVENT 事件标志,表示该事件已处理return events ^ HAL_LED_BLINK_EVENT;}// 检查是否有按键事件if (events & HAL_KEY_EVENT){
#if (defined HAL_KEY) && (HAL_KEY == TRUE)/* 检查按键状态 */HalKeyPoll();/* 如果中断已禁用,则安排下一次轮询 */if (!Hal_KeyIntEnable){osal_start_timerEx(Hal_TaskID, HAL_KEY_EVENT, 100);}
#endif// 清除 HAL_KEY_EVENT 事件标志,表示该事件已处理return events ^ HAL_KEY_EVENT;}#if defined POWER_SAVING// 检查是否有睡眠定时器事件if (events & HAL_SLEEP_TIMER_EVENT){halRestoreSleepLevel();  // 恢复睡眠级别// 清除 HAL_SLEEP_TIMER_EVENT 事件标志,表示该事件已处理return events ^ HAL_SLEEP_TIMER_EVENT;}// 检查是否有电源管理保持事件if (events & HAL_PWRMGR_HOLD_EVENT){(void)osal_pwrmgr_task_state(Hal_TaskID, PWRMGR_HOLD);(void)osal_stop_timerEx(Hal_TaskID, HAL_PWRMGR_CONSERVE_EVENT);(void)osal_clear_event(Hal_TaskID, HAL_PWRMGR_CONSERVE_EVENT);// 清除 HAL_PWRMGR_HOLD_EVENT 和 HAL_PWRMGR_CONSERVE_EVENT 事件标志return (events & ~(HAL_PWRMGR_HOLD_EVENT | HAL_PWRMGR_CONSERVE_EVENT));}// 检查是否有电源管理节能事件if (events & HAL_PWRMGR_CONSERVE_EVENT){(void)osal_pwrmgr_task_state(Hal_TaskID, PWRMGR_CONSERVE);// 清除 HAL_PWRMGR_CONSERVE_EVENT 事件标志,表示该事件已处理return events ^ HAL_PWRMGR_CONSERVE_EVENT;}
#endif// 如果没有处理任何事件,返回 0return 0;
}

HAL轮询:

  HAL的HAL轮询函数为位于hal_drivers.c文件中的Hal_ProcessPoll(),它的主要作用为轮询那些不支持中断或者需要定期检查状态的硬件模块,位置如下:

/*************************************************************************************************** @fn      Hal_ProcessPoll** @brief   该例程将被OSAL调用来轮询UART、TIMER等硬件模块的状态。*          主要用于轮询那些不支持中断或者需要定期检查状态的硬件模块。** @param   task_id - Hal TaskId(任务ID),用于标识HAL相关的任务。** @return  None**************************************************************************************************/
void Hal_ProcessPoll()
{
#if defined(POWER_SAVING)/* 允许在下一个OSAL事件循环之前进入睡眠模式 *//* 这个宏可能用于节能模式,允许系统在空闲时进入低功耗状态 */ALLOW_SLEEP_MODE();
#endif/* UART轮询 */
#if (defined HAL_UART) && (HAL_UART == TRUE)/* 如果定义了HAL_UART且其值为TRUE,则调用HalUARTPoll函数轮询UART状态 *//* UART轮询用于检查串口通信的状态,如是否有数据可读取或发送缓冲区是否为空 */HalUARTPoll();
#endif/* SPI轮询 */
#if (defined HAL_SPI) && (HAL_SPI == TRUE)/* 如果定义了HAL_SPI且其值为TRUE,则调用HalSpiPoll函数轮询SPI状态 *//* SPI轮询用于检查SPI通信的状态,如是否有数据传输完成或是否有错误发生 */HalSpiPoll();
#endif/* HID轮询 */
#if (defined HAL_HID) && (HAL_HID == TRUE)/* 如果定义了HAL_HID且其值为TRUE,则调用usbHidProcessEvents函数处理HID事件 *//* HID轮询用于处理人机接口设备(如键盘、鼠标等)的事件,如按键按下或移动事件 */usbHidProcessEvents();
#endif
}

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

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

相关文章

Linux如何判断磁盘是否已分区?

在 Linux 系统中,判断磁盘是否已分区可通过以下方法实现: 方法 1:使用 fdisk -l 命令 此命令会列出所有磁盘及其分区的详细信息: sudo fdisk -l输出解读: 若磁盘(如 /dev/sdb)下有类似 /dev/…

《熔化焊接与热切割作业》考试注意事项

考试前的准备 携带必要的证件和材料:考生需携带身份证、准考证等有效证件,以及考试所需的焊接工具、材料等。确保证件齐全,避免因证件问题影响考试。 提前检查焊接设备和工具:在考试前,考生应仔细检查焊接设备和工具是…

Matlab Hessian矩阵计算(LoG算子)

文章目录 一、简介二、实现代码三、实现效果参考资料一、简介 图像的Hessian矩阵用于描述图像灰度值的二阶导数,可以用来分析图像的局部曲率和变化。例如,在图像边缘检测、特征点检测等任务中,Hessian矩阵能帮助我们识别图像的结构。 Hessian矩阵定义 对于二维图像,Hessian…

selenium之处理弹框(alert、confirm、prompt)

弹框 WebDriver提供了一个API, 用于处理JavaScript提供的三种类型的原生弹窗消息. 这些弹窗由浏览器提供限定的样式.;分别为以下三种 alerts警告框confirm确认框prompt提示框 话不多说,开始实践下就知道怎么一回事了 alerts 警告框,显示…

Visual Studio 2019 Qt QML 项目环境搭建常见问题处理方法

在 Visual Studio 2019 运行 Qt/QML 项目比直接使用QtCreator环境麻烦,主要是有qmake 的一些配置项不能在 Visual Studio中设置。下面整理一些常见问题的处理方法,供参考: 搭建VS Qt 环境,在Visual Studios 2019下面安装 Qt Vis…

【Linux】POSIX信号量与基于环形队列的生产消费者模型

目录 一、POSIX信号量: 接口: 二、基于环形队列的生产消费者模型 环形队列: 单生产单消费实现代码: RingQueue.hpp: main.cc: 多生产多消费实现代码: RingQueue.hpp: main.…

RAG优化:python从零实现GraphRag 一场文档与知识的“恋爱”之旅

嘿,亲爱的算法工程师们,准备好迎接一场文档与知识的“恋爱”之旅了吗?今天我们要介绍的 Graph RAG,就像是一位“红娘”,帮助文档和知识在图的世界里找到彼此,擦出智慧的火花! 文章目录 为什么需要 Graph RAG?Graph RAG 的“恋爱秘籍”准备好了吗?让我们开始吧!环境设…

深入 SVG:矢量图形、滤镜与动态交互开发指南

1.SVG 详细介绍 SVG(Scalable Vector Graphics) 是一种基于 XML 的矢量图形格式,用于描述二维图形。 1. 命名空间 (Namespace) ★ 了解 命名空间 URI:http://www.w3.org/2000/svg 用途:在 XML 或 XHTML 中区分不同标…

HTTPS 加密过程详解

HTTPS 的核心组成是 HTTP 协议与 SSL/TLS 加密层的结合,通过加密传输、身份验证和完整性校验机制,确保数据安全。其加密过程通过以下方式保障数据的机密性、完整性和身份验证: 一、HTTPS 的核心组成 1. HTTP 协议 作为基础通信协议&#xf…

嵌入式硬件工程师从小白到入门-速通版(一)

嵌入式硬件工程师从小白到入门:知识点速通与实战指南 一、基础硬件知识体系 电子电路基础 基本概念:电流、电压、电阻、电容、电感等;电路分析:欧姆定律、基尔霍夫定律、戴维南定理;元器件特性:二极管、三极…

SpringBoot通过Map实现天然的策略模式

😊 作者: 一恍过去 💖 主页: https://blog.csdn.net/zhuocailing3390 🎊 社区: Java技术栈交流 🎉 主题: SpringBoot通过Map实现天然的策略模式 ⏱️ 创作时间: 202…

WordPress WooCommerce 本地文件包含漏洞(CVE-2025-1661)

免责声明 仅供网络安全研究与教育目的使用。任何人不得将本文提供的信息用于非法目的或未经授权的系统测试。作者不对任何由于使用本文信息而导致的直接或间接损害承担责任。如涉及侵权,请及时与我们联系,我们将尽快处理并删除相关内容。 一:产品介绍 HUSKY – WooCommer…

matlab近似计算联合密度分布

在 Matlab 中,当A和B是两个序列数据时,可以通过以下步骤来近似求出A大于B的概率分布:数据准备:确保序列A和B具有相同的长度。如果长度不同,需要进行相应的处理(例如截取或插值)。计算A大于B的逻…

可视化动态表单动态表单界的天花板--Formily(阿里开源)

文章目录 1、Formily表单介绍2、安装依赖2.1、安装内核库2.2、 安装 UI 桥接库2.3、Formily 支持多种 UI 组件生态: 3、表单设计器3.1、核心理念3.2、安装3.3、示例源码 4、场景案例-登录注册4.1、Markup Schema 案例4.2、JSON Schema 案例4.3、纯 JSX 案例 1、Form…

NAT 实验:多私网环境下 NAPT、Easy IP 配置及 FTP 服务公网映射

NAT基本概念 定义:网络地址转换(Network Address Translation,NAT)是一种将私有(保留)地址转化为合法公网 IP 地址的转换技术,它被广泛应用于各种类型 Internet 接入方式和各种类型的网络中。作…

C语言-桥接模式详解与实践

文章目录 C语言桥接模式详解与实践1. 什么是桥接模式?2. 为什么需要桥接模式?3. 实际应用场景4. 代码实现4.1 UML 关系图4.2 头文件 (display_bridge.h)4.3 实现文件 (display_bridge.c)4.4 使用示例 (main.c) 5. 代码分析5.1 关键设计点5.2 实现特点 6.…

el-table 合并单元格

vue2使用el-table合并单元格&#xff0c;包括合并行、合并列 <el-table:header-cell-style"handerMethod":span-method"arraySpanMethod"cell-click"handleCellClick":data"tableData"style"width: 100%"><el-tabl…

网络安全之vlan实验

在对vlan进行一定的学习之后我们来练习一个小实验来加深理解记忆 首先是对实验进行一个搭建 第一部分&#xff1a;给交换机配置vlan 首先是sw1 [Huawei]vlan batch 2 to 5 [Huawei]int g0/0/1 [Huawei-GigabitEthernet0/0/1]port hybrid tagged vlan 2 [Huawei-GigabitEthe…

STM32 - 在机器人、自动化领域,LL库相比HAL优势明显

在机器人控制器、电机控制器等领域的开发&#xff0c;需要高实时性、精细化控制或者对代码执行效率、占用空间有较高要求。所以&#xff0c;大家常用的HAL库明显不符合要求。再加上&#xff0c;我们学习一门技术&#xff0c;一定要学会掌握底层的原理。MCU开发的底层就是寄存器…

mysql中show命令的使用

在 MySQL 中&#xff0c;SHOW 命令是一个非常实用的工具&#xff0c;用于查询数据库元数据&#xff08;如数据库、表、列、索引等信息&#xff09;。以下是常见的 SHOW 命令及其用法&#xff1a; 1. 显示所有数据库 SHOW DATABASES;列出服务器上的所有数据库。 2. 显示当前数据…