STM32移植FreeRTOS操作系统

news2025/7/20 9:33:14

一、FreeRTOS源码下载

(1)移植钱得准备前菜对吧,我们先来去官网瞄一瞄

网址:https://freertos.org/zh-cn-cmn-s/

第一步:点击下载FreeRTOS

第二步:选择版本下载(我选择稳定版本)

注:我们下载的稳定版本不包含DEMO例程,可以自己下载上面的那个最新版本,有官方移植好的DEMO,那么最新版本下载过程如下图:

但是,这时候下载完成的压缩波其实并不包含FreeRTOS的子模块。所以,在该页面向下翻找。

第三步:回到我们下载稳定版本的路上,选择GitHub,复制网址可

到这里前菜算是准备完毕了。

二、添加内核文件

第一步:准备一个STM32工程,这里工程越简洁越好(可以参考之前写的创建工程理论与实践偏:

https://blog.csdn.net/qq_38295600/article/details/129372829

https://blog.csdn.net/qq_38295600/article/details/129372829)

第二步:准备好工程后,创建一个FreeRTOS文件夹

第三步:打开刚才下载好的稳定版本文件,路径:FreeRTOS-LTS\FreeRTOS\FreeRTOS-Kernel将里面内容复制出来

第四步:将内容粘贴到工程中得FreeRTOS文件中

为了简洁好看,我们在创建个source文件夹把这些.c文件放到这里面

外部这些文件有删除或者留着看自己

现在FreeRTOS源码被我们分成了三个目录,分别是①include目录;②portable目录;③source目录

这里 分析一下 FreeRTOS源码结构,①和③包含的是FreeRTOS核心功能源文件及头文件 .c和.h,这两部分的文件试用于各种编译器和处理器,是通用的,基本不需要修改,②为需要移植修改的目录,这与编译器和所使用的CPU有关,属于RTOS硬件接口层。

我们知道 FreeRTOS 是个系统,归根结底就是个纯软件的东西,它是怎么和硬件

联系在一起的呢?软件到硬件中间必须有一个桥梁,portable 文件夹里面的东西就是 FreeRTOS

系统和具体的硬件之间的连接桥梁!不同的编译环境,不同的 MCU,其桥梁应该是不同的,打

开 portable 文件夹,我们现在用的MDK,所以我们只需要

最终保留如下这三个文件

第五步:文件添加到工程

注:MemMang 是跟内存管理相关的,里面有 5 个 c 文件:heap_1.c、heap_2.c、heap_3.c、heap_4.c 和 heap_5.c。

这 5 个 c 文件是五种不同的内存管理方法,就像从北京到上海你可以坐火车、坐飞机,如果心情好的话也可以走路,反正有很多种方法,只要能到上海就行。这里也一样的,这 5 个文件都可以用来作为FreeRTOS 的内存管理文件,只是它们的实现原理不同,各有利弊。这里我们选择 heap_4.c,具体可以看看原子的讲解内存视频。

然后由于我用的是stm32f1内核是M3,所以选择如下

第六步:编译工程

直接编译(出现9个错误)这是因为缺少 FreeRTOSConfig.h 文件

FreeRTOS的裁剪主要依靠FreeRTOSConfig.h中的宏定义去完成,需要什么功能就打开对应的宏就可以了。

现在我们需要一个FreeRTOSConfig.h文件。但在源码FreeRTOS-Kernel目录下没有提供config文件。

那么哪里找呢?

我们打开最开始下载好的FreeRTOS文件(最开始下载我们下载了三个文件)

打开第一个FreeRTOS->路径:FreeRTOS\FreeRTOS\Demo

在demo目录下找到对应内核目录下的demo(可能是其它MCU,不要紧)拷贝一个FreeRTOSConfig.h文件到本地source\FreeRTOS\include目录内

重新编译没有错

三、修改工程

虽然没有错误了,但是我们的移植没有完成,还有一些小步骤需要完成,的确有些繁琐,好在逻辑性还是比较强的,理解起来相对容易。

第一步:

在FreeRTOSConfig.h中添加#define xPortPendSVHandler PendSV_Handler

在FreeRTOSConfig.h中添加#define vPortSVCHandler SVC_Handler

编译,还是报错,重复定义

第二步:处理错误: 进入对应的文件stm32f1xx_it.c屏蔽重复的3个函数

把SysTick_Handler也屏蔽起来是因为,等下我们要建立一个Bsp_SysTick.c,到时候这个中断函数也会放在这里面,所以我在这里也给他屏蔽了

重新编译

到这里,算移植成功了!!!,后面还需要做配置操作

四、滴答时钟配置

SysTick中断服务函数是一个非常重要的函数,FreeRTOS所有跟时间相关的事情都在里面处理,SysTick就是FreeRTOS的一个心跳时钟,驱动着FreeRTOS的运行,如果FreeRTOS没有了心跳,那么它就会卡死在某个地方,不能进行任务调度,不能运行任何的东西,因此我们需要实现一个FreeRTOS的心跳时钟

所以我们创建一个

BSP_SysTick.h 和一个BSP_SysTick.c

.c直接上代码块:

#include "BSP_SysTick.h"
#include "FreeRTOS.h"
#include "task.h"
static u8  fac_us=0;//us延时倍乘数   
static u16 fac_ms=0;//ms延时倍乘数,在ucos下,代表每个节拍的ms数
extern void xPortSysTickHandler(void);
//systick中断服务函数,使用ucos时用到
void SysTick_Handler(void)
{
    if(xTaskGetSchedulerState()!=taskSCHEDULER_NOT_STARTED)//系统已经运行
    {
       xPortSysTickHandler();
    }
}
   
//初始化延迟函数
//SYSTICK的时钟固定为AHB时钟,基础例程里面SYSTICK时钟频率为AHB/8
//这里为了兼容FreeRTOS,所以将SYSTICK的时钟频率改为AHB的频率!
//SYSCLK:系统时钟频率
void delay_init()
{
u32 reload;
SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK);//选择外部时钟  HCLK
fac_us=SystemCoreClock/1000000;//不论是否使用OS,fac_us都需要使用
reload=SystemCoreClock/1000000;//每秒钟的计数次数 单位为M  
reload*=1000000/configTICK_RATE_HZ;//根据configTICK_RATE_HZ设定溢出时间
//reload为24位寄存器,最大值:16777216,在72M下,约合0.233s左右
fac_ms=1000/configTICK_RATE_HZ;//代表OS可以延时的最少单位   
SysTick->CTRL|=SysTick_CTRL_TICKINT_Msk;   //开启SYSTICK中断
SysTick->LOAD=reload; //每1/configTICK_RATE_HZ秒中断一次
SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk;   //开启SYSTICK    
}

.h代码块

#ifndef _BSP_SYSTICK_H
#define _BSP_SYSTICK_H
#include "stm32f10x.h"
#include "stdio.h"


//0,不支持os
//1,支持os
#define SYSTEM_SUPPORT_OS        1        //定义系统文件夹是否支持OS

void BSP_SysTickInit(void);

#endif

然后我们编译下:成功报错,说明还有问题

这里显示“xTaskGetSchedulerState”这个找不到,可是我们明明声明了头文件

#include "FreeRTOS.h"//FreeRTOS使用

#include "task.h"

这两个,还是报错,那么经过查找关键点在于“FreeRTOSCongfig.h”的配置

新增上这一句,编译就通过了

那么说明一个问题,我们的FreeRTOSCongfig.h配置不完善,得改良,早这里先引用原子的配置,我们先以这个配置进行更新,后面在专门写一篇关于FreeRTOSCongfig.h的功能介绍

更新“FreeRTOSCongfig.h”

/*
    FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd.
    All rights reserved

    VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.

    This file is part of the FreeRTOS distribution.

    FreeRTOS is free software; you can redistribute it and/or modify it under
    the terms of the GNU General Public License (version 2) as published by the
    Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception.

    ***************************************************************************
    >>!   NOTE: The modification to the GPL is included to allow you to     !<<
    >>!   distribute a combined work that includes FreeRTOS without being   !<<
    >>!   obliged to provide the source code for proprietary components     !<<
    >>!   outside of the FreeRTOS kernel.                                   !<<
    ***************************************************************************

    FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY
    WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
    FOR A PARTICULAR PURPOSE.  Full license text is available on the following
    link: http://www.freertos.org/a00114.html

    ***************************************************************************
     *                                                                       *
     *    FreeRTOS provides completely free yet professionally developed,    *
     *    robust, strictly quality controlled, supported, and cross          *
     *    platform software that is more than just the market leader, it     *
     *    is the industry's de facto standard.                               *
     *                                                                       *
     *    Help yourself get started quickly while simultaneously helping     *
     *    to support the FreeRTOS project by purchasing a FreeRTOS           *
     *    tutorial book, reference manual, or both:                          *
     *    http://www.FreeRTOS.org/Documentation                              *
     *                                                                       *
    ***************************************************************************

    http://www.FreeRTOS.org/FAQHelp.html - Having a problem?  Start by reading
    the FAQ page "My application does not run, what could be wrong?".  Have you
    defined configASSERT()?

    http://www.FreeRTOS.org/support - In return for receiving this top quality
    embedded software for free we request you assist our global community by
    participating in the support forum.

    http://www.FreeRTOS.org/training - Investing in training allows your team to
    be as productive as possible as early as possible.  Now you can receive
    FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers
    Ltd, and the world's leading authority on the world's leading RTOS.

    http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
    including FreeRTOS+Trace - an indispensable productivity tool, a DOS
    compatible FAT file system, and our tiny thread aware UDP/IP stack.

    http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.
    Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.

    http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High
    Integrity Systems ltd. to sell under the OpenRTOS brand.  Low cost OpenRTOS
    licenses offer ticketed support, indemnification and commercial middleware.

    http://www.SafeRTOS.com - High Integrity Systems also provide a safety
    engineered and independently SIL3 certified version for use in safety and
    mission critical applications that require provable dependability.

    1 tab == 4 spaces!
*/


#ifndef FREERTOS_CONFIG_H
#define FREERTOS_CONFIG_H

#include "BSP_Uart.h"      
//针对不同的编译器调用不同的stdint.h文件
#if defined(__ICCARM__) || defined(__CC_ARM) || defined(__GNUC__)
    #include <stdint.h>
    extern uint32_t SystemCoreClock;
#endif

//断言
#define vAssertCalled(char,int) printf("Error:%s,%d\r\n",char,int)
#define configASSERT(x) if((x)==0) vAssertCalled(__FILE__,__LINE__)

/***************************************************************************************************************/
/*                                        FreeRTOS基础配置配置选项                                              */
/***************************************************************************************************************/
#define configUSE_PREEMPTION                    1                       //1使用抢占式内核,0使用协程
#define configUSE_TIME_SLICING                    1                        //1使能时间片调度(默认式使能的)
#define configUSE_PORT_OPTIMISED_TASK_SELECTION    1                       //1启用特殊方法来选择下一个要运行的任务
                                                                        //一般是硬件计算前导零指令,如果所使用的
                                                                        //MCU没有这些硬件指令的话此宏应该设置为0!
#define configUSE_TICKLESS_IDLE                    0                       //1启用低功耗tickless模式
#define configUSE_QUEUE_SETS                    1                       //为1时启用队列
#define configCPU_CLOCK_HZ                        (SystemCoreClock)       //CPU频率
#define configTICK_RATE_HZ                        (1000)                  //时钟节拍频率,这里设置为1000,周期就是1ms
#define configMAX_PRIORITIES                    (32)                    //可使用的最大优先级
#define configMINIMAL_STACK_SIZE                ((unsigned short)130)   //空闲任务使用的堆栈大小
#define configMAX_TASK_NAME_LEN                    (16)                    //任务名字字符串长度

#define configUSE_16_BIT_TICKS                    0                       //系统节拍计数器变量数据类型,
                                                                        //1表示为16位无符号整形,0表示为32位无符号整形
#define configIDLE_SHOULD_YIELD                    1                       //为1时空闲任务放弃CPU使用权给其他同优先级的用户任务
#define configUSE_TASK_NOTIFICATIONS            1                       //为1时开启任务通知功能,默认开启
#define configUSE_MUTEXES                        1                       //为1时使用互斥信号量
#define configQUEUE_REGISTRY_SIZE                8                       //不为0时表示启用队列记录,具体的值是可以
                                                                        //记录的队列和信号量最大数目。
#define configCHECK_FOR_STACK_OVERFLOW            0                       //大于0时启用堆栈溢出检测功能,如果使用此功能
                                                                        //用户必须提供一个栈溢出钩子函数,如果使用的话
                                                                        //此值可以为1或者2,因为有两种栈溢出检测方法。
#define configUSE_RECURSIVE_MUTEXES                1                       //为1时使用递归互斥信号量
#define configUSE_MALLOC_FAILED_HOOK            0                       //1使用内存申请失败钩子函数
#define configUSE_APPLICATION_TASK_TAG            0                       
#define configUSE_COUNTING_SEMAPHORES            1                       //为1时使用计数信号量

/***************************************************************************************************************/
/*                                FreeRTOS与内存申请有关配置选项                                                */
/***************************************************************************************************************/
#define configSUPPORT_DYNAMIC_ALLOCATION        1                       //支持动态内存申请
#define configTOTAL_HEAP_SIZE                    ((size_t)(20*1024))     //系统所有总的堆大小

/***************************************************************************************************************/
/*                                FreeRTOS与钩子函数有关的配置选项                                              */
/***************************************************************************************************************/
#define configUSE_IDLE_HOOK                        0                       //1,使用空闲钩子;0,不使用
#define configUSE_TICK_HOOK                        0                       //1,使用时间片钩子;0,不使用

/***************************************************************************************************************/
/*                                FreeRTOS与运行时间和任务状态收集有关的配置选项                                 */
/***************************************************************************************************************/
#define configGENERATE_RUN_TIME_STATS            0                       //为1时启用运行时间统计功能
#define configUSE_TRACE_FACILITY                1                       //为1启用可视化跟踪调试
#define configUSE_STATS_FORMATTING_FUNCTIONS    1                       //与宏configUSE_TRACE_FACILITY同时为1时会编译下面3个函数
                                                                        //prvWriteNameToBuffer(),vTaskList(),
                                                                        //vTaskGetRunTimeStats()
                                                                        
/***************************************************************************************************************/
/*                                FreeRTOS与协程有关的配置选项                                                  */
/***************************************************************************************************************/
#define configUSE_CO_ROUTINES                     0                       //为1时启用协程,启用协程以后必须添加文件croutine.c
#define configMAX_CO_ROUTINE_PRIORITIES         ( 2 )                   //协程的有效优先级数目

/***************************************************************************************************************/
/*                                FreeRTOS与软件定时器有关的配置选项                                            */
/***************************************************************************************************************/
#define configUSE_TIMERS                        1                               //为1时启用软件定时器
#define configTIMER_TASK_PRIORITY                (configMAX_PRIORITIES-1)        //软件定时器优先级
#define configTIMER_QUEUE_LENGTH                5                               //软件定时器队列长度
#define configTIMER_TASK_STACK_DEPTH            (configMINIMAL_STACK_SIZE*2)    //软件定时器任务堆栈大小

/***************************************************************************************************************/
/*                                FreeRTOS可选函数配置选项                                                      */
/***************************************************************************************************************/
#define INCLUDE_xTaskGetSchedulerState          1                       
#define INCLUDE_vTaskPrioritySet                1
#define INCLUDE_uxTaskPriorityGet                1
#define INCLUDE_vTaskDelete                        1
#define INCLUDE_vTaskCleanUpResources            1
#define INCLUDE_vTaskSuspend                    1
#define INCLUDE_vTaskDelayUntil                    1
#define INCLUDE_vTaskDelay                        1
#define INCLUDE_eTaskGetState                    1
#define INCLUDE_xTimerPendFunctionCall            1

/***************************************************************************************************************/
/*                                FreeRTOS与中断有关的配置选项                                                  */
/***************************************************************************************************************/
#ifdef __NVIC_PRIO_BITS
    #define configPRIO_BITS               __NVIC_PRIO_BITS
#else
    #define configPRIO_BITS               4                  
#endif

#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY            15                      //中断最低优先级
#define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY    5                       //系统可管理的最高中断优先级
#define configKERNEL_INTERRUPT_PRIORITY         ( configLIBRARY_LOWEST_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )
#define configMAX_SYSCALL_INTERRUPT_PRIORITY     ( configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )

/***************************************************************************************************************/
/*                            移植添加的,FreeRTOS与中断服务函数有关的配置选项                                  */
/***************************************************************************************************************/
#define xPortPendSVHandler     PendSV_Handler
#define vPortSVCHandler     SVC_Handler

#endif /* FREERTOS_CONFIG_H */



到这里我们总体的移植算是完成了!

五、创建任务,点灯实验启动

上代码块:

#include "main.h"
#include "BSP_SysTick.h"    
#include "BSP_Gpio.h"
#include "BSP_Uart.h"     
/* FreeRTOS头文件 */
#include "FreeRTOS.h"
#include "task.h"


#define START_TASK_PRIO        1                    //任务优先级
#define START_STK_SIZE         128              //任务栈大小    
TaskHandle_t StartTask_Handler;            //任务句柄
void start_task(void *pvParameters);//任务函数

#define LED0_TASK_PRIO        2                    //任务优先级
#define LED0_STK_SIZE         50              //任务栈大小    
TaskHandle_t LED0Task_Handler;            //任务句柄
void led0_task(void *pvParameters);    //任务函数

#define LED1_TASK_PRIO        3                    //任务优先级
#define LED1_STK_SIZE         50              //任务栈大小    
TaskHandle_t LED1Task_Handler;            //任务句柄
void led1_task(void *pvParameters);    //任务函数



void BoardInit(void)
{
    BSP_SysTickInit();
    BSP_GpioInit();
    BSP_UartInit(115200);
}


//开始任务任务函数
void start_task(void *pvParameters)
{
    taskENTER_CRITICAL();           //进入临界区
    //创建LED0任务
    xTaskCreate((TaskFunction_t )led0_task,         
                (const char*    )"led0_task",       
                (uint16_t       )LED0_STK_SIZE, 
                (void*          )NULL,                
                (UBaseType_t    )LED0_TASK_PRIO,    
                (TaskHandle_t*  )&LED0Task_Handler);   
    //创建LED1任务
    xTaskCreate((TaskFunction_t )led1_task,     
                (const char*    )"led1_task",   
                (uint16_t       )LED1_STK_SIZE, 
                (void*          )NULL,
                (UBaseType_t    )LED1_TASK_PRIO,
                (TaskHandle_t*  )&LED1Task_Handler);         
    vTaskDelete(StartTask_Handler); //删除开始任务
    taskEXIT_CRITICAL();            //退出临界区
}


int main(void)
{    
//  BaseType_t xReturn = pdPASS;/* 定义一个创建信息返回值,默认为pdPASS */
    BoardInit();
    printf("Welcome to FreeRTOS,CoreClock:%d\r\n",SystemCoreClock);
     
    //创建开始任务
    xTaskCreate((TaskFunction_t )start_task,            //任务函数
                (const char*    )"start_task",          //任务名称
                (uint16_t       )START_STK_SIZE,        //任务堆栈大小
                (void*          )NULL,                  //传递给任务函数的参数
                (UBaseType_t    )START_TASK_PRIO,       //任务优先级
                (TaskHandle_t*  )&StartTask_Handler);   //任务句柄              
    vTaskStartScheduler();                                                     //开启任务调度   
}

//LED0任务函数 
void led0_task(void *pvParameters)
{
    while(1)
    {
        BSP_SetLed0(2);
        vTaskDelay(500);
    }
}   

//LED1任务函数
void led1_task(void *pvParameters)
{
    while(1)
    {
        BSP_SetLed1(2);
        vTaskDelay(800);
    }
}




编译完成

可以看到输出信息正常,同时开发板指示灯在循环闪烁

到此整个FreeRTOS移植完成!!!

六、附录:完整的工程代码

链接:https://pan.baidu.com/s/1UCta6zUQuRgVwoMYRJ1CMg

提取码:v5t7

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

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

相关文章

git 双因子身份登录遇到的问题及解决方法

git 双因子身份登录描述&#xff1a; 一般我们登录账号和密码的时候都是通过git的账号和密码直接登录即可&#xff0c;但是如果我们用双因子身份进行登录的时候发现用账号和密码登录一直登录不了&#xff0c;&#xff0c;&#xff0c;&#xff0c;有点emo了。。 git 双因子身份…

CentOS8基础篇13:yum与dnf软件包管理器

一、YUM工具的使用 yum可以说是一个管理rpm软件包的前端工具&#xff0c;其基于rpm软件包进行管理&#xff0c;能够从指定服务器自动下载rpm软件包并进行安装&#xff0c;可以自动处理依赖关系&#xff0c;并一次安装所有需要的软件包。在RHEL本地操作系统中设置相应的软件仓库…

SAP smartforms打印图片

注意&#xff1a;SAP只能上传打印bmp格式图片 1.标准程序上传 T-CODE:SE78 2.程序代码上传 DATA: P_FILENAME TYPE RLGRAP-FILENAME,P_NAME TYPE STXBITMAPS-TDNAME,P_TITLE LIKE BAPISIGNAT-PROP_VALUE,P_DOCID TYPE STXBITMAPS-DOCID,P_RESOLUTION TYPE …

案例分析之——理由Mybatis动态SQL实现复用

无复用思想的做法&#xff1a; 在没有复用思想的时候&#xff0c;就只顾着实现功能。比如开发过程中涉及到两个表的更新功能&#xff0c;每需要更新一处&#xff0c;就写一个接口&#xff0c;结果出现了写了11个接口的情况。 这样虽然功能实现了&#xff0c;可是可能自…

express+websocket实现线上聊天

1.webSocket简介 WebSocket是一种通信协议&#xff0c;可在单个TCP连接上进行全双工通信。WebSocket使得客户端和服务器之间的数据交换变得更加简单&#xff0c;允许服务端主动向客户端推送数据。在WebSocket API中&#xff0c;浏览器和服务器只需要完成一次握手&#xff0c;两…

SpringCloud之 Hystrix服务熔断

文章目录一、Hystrix 服务熔断 (已过时)&#x1f349;1.1 服务降级&#x1f349;1.2 服务熔断&#x1f349;1.3 OpenFeign 实现降级二、hystrix-dashboard 监控&#x1f34b;2.1 监控页面部署&#x1f34b;2.2 观察现象提示&#xff1a;以下是本篇文章正文内容&#xff0c;Spri…

【PySide6】信号(signal)和槽函数(slot),以及事件过滤器

说明 在PYQT中&#xff0c;父控件可以通过两种方式响应子控件的事件&#xff1a; 通过信号(signal)和槽函数(slot)机制连接子控件和父控件父控件可以通过设置eventFilter()方法来监听响应子控件的事件 一、信号(signal)和槽函数(slot) 示例 在PYQT中&#xff0c;每个组件都…

传输线的物理基础(三):传输线的瞬时阻抗

每个信号都有一个上升时间 RT&#xff0c;通常是从 10% 到 90% 的电压电平测量的。当信号沿传输线向下移动时&#xff0c;前沿在传输线上展开并具有空间范围。如果我们可以冻结时间并观察电压分布向外移动时的大小&#xff0c;我们会发现类似下图的东西。传输线上上升时间的长度…

Python中的三器一闭(详细版)

python中的三器一闭迭代器什么是迭代什么是可迭代对象判断数据是否可迭代什么是迭代器迭代器的本质使用迭代器取数据自定义迭代器生成器创建生产器的方法关键字yieldnext和send装饰器装饰器的功能定义装饰器闭包什么是闭包函数、匿名函数、闭包、对象 当做实参时的区别迭代器 …

Blazor_WASM之3:项目结构

Blazor_WASM之3&#xff1a;项目结构 Blazor WebAssembly项目模板可选两种&#xff0c;Blazor WebAssemblyAPP及Blazor WebAssemblyAPP-Empty 如果使用Blazor WebAssemblyAPP模板&#xff0c;则应用将填充以下内容&#xff1a; 一个 FetchData 组件的演示代码&#xff0c;该…

蓝桥杯-最优清零方案(2022省赛)

蓝桥杯-最优清零方案1、问题描述2、解题思路3、代码实现1、问题描述 给定一个长度为 N 的数列 1,2,⋯,A1,A2,...,ANA_1,A_2,...,A_NA1​,A2​,...,AN​ 。现在小蓝想通过若干次操作将 这个数列中每个数字清零。 每次操作小蓝可以选择以下两种之一: 1. 选择一个大于 0 的整数, 将…

杂记——18.VSCode的下载及使用

这篇文章&#xff0c;我们来讲一下VSCode&#xff0c;讲一下如何下载及使用VSCode 目录 1.VSCode的下载 1.1VSCode的简介 1.2VSCode的下载与安装 1.2.1下载 1.2.2安装 2.VSCode的使用 2.1界面 2.2基础设置 2.3禁用自动更新 2.3自动保存设置 2.4Vscode更换主题 2.5…

Hive面试题-HQL转换MapReduce底层核心逻辑剖析

视频可查看&#xff1a;https://www.bilibili.com/video/BV1RV41147Tb/?spm_id_from333.999.0.0&vd_source3ba3c3ba31427f60d734ede7a948de4a 原文地址&#xff1a;Hive学习之路 &#xff08;二十&#xff09;Hive 执行过程实例分析 - 扎心了&#xff0c;老铁 - 博客园 (c…

K_A14_012基于STM32等单片机驱动GY-25倾斜度角度模块 串口与OLED0.96双显示

K_A14_012基于STM32等单片机驱动GY-25倾斜度角度模块 串口与OLED0.96双显示一、资源说明二、基本参数参数引脚说明三、驱动说明对应程序:四、部分代码说明1、接线引脚定义1.1、STC89C52RCGY-25倾斜度角度模块1.2、STM32F103C8T6GY-25倾斜度角度模块五、基础知识学习与相关资料下…

测试按方向的分类

按方向分(都是在系统测试阶段测试的) 功能测试&#xff1a;举例说明什么是功能 性能测试 ①压力测试&#xff1a;不断地增加压力&#xff0c;从而找到系统的极限 ②负载测试&#xff1a;系统在极限工作条件下&#xff0c;最多能持续多久——可能发生内存泄漏/溢出&#xff0c;导…

angular技术(持续更新)

css类绑定[class.color-blue]"isBlue()" 如果isBlue()返回为true 这里使用color-blue的class样式style样式绑定[style.background-color]"canclick ? blue: red" 组件与模块模块的元数据*declarations: 用于指定属于这个模块的视图类&#xff08;View Cla…

CM6.3.2启用Kerberos(附问题解决)

基础准备支持JCE的jdk重新安装JCE的jdk(已正确配置跳过)删除/usr/java/下面的jdk,然后通过CM->管理->安全->安装Java无限制...重新安装后,配置Java(可选)主机->主机配置->搜java->Java主目录 配置路径主机->所有主机->设置->高级:Java配置Kerberos安…

[算法]插入排序

参考&#xff1a;《漫画算法-小灰的算法之旅》 目录 1、排序算法的思想 2、具体步骤 3、插入排序的优化 4、时间复杂度和空间复杂度 5、代码 1、排序算法的思想 维护一个有序区&#xff0c;把元素一个个插入有序区的适当位置&#xff0c;直到所有元素都有序为止。 2、具体…

多线程面试题

1. Sychronized的锁升级过程是怎样的&#xff1f; 2. Tomcat 中为什么要使用自定义类加载器&#xff1f; 3. 说说对线程安全的理解 4. 对守护线程的理解 5. 并发、并行、串行之间的区别 6. Java死锁如何避免&#xff1f; 7. 谈谈你对AQS的理解&#xff0c;AQS如何实现可重入锁&…

华为机试题:HJ107 求解立方根(python)

文章目录&#xff08;1&#xff09;题目描述&#xff08;2&#xff09;Python3实现&#xff08;3&#xff09;知识点详解1、input()&#xff1a;获取控制台&#xff08;任意形式&#xff09;的输入。输出均为字符串类型。1.1、input() 与 list(input()) 的区别、及其相互转换方…