FreeRTOS_系统配置

news2024/10/6 2:34:06

目录

1. FreeRTOSConfig.h 文件

2. "INCLUDE_" 开始的宏

2.1 INCLUDE_xSemaphoreGetMutexHolder

2.2 INCLUDE_xTaskAbortDelay

2.3 INCLUDE_vTaskDelay

2.4 INCLUDE_vTaskDelayUntil

2.5 INCLUDE_vTaskDelete

2.6 INCLUDE_xTaskGetCurrentTaskHandle

2.7 INCLUDE_xTaskGetHandle

2.8 INCLUDE_xTaskGetIdleTaskHandle

2.9 INCLUDE_xTaskGetSchedulerState

2.10 INCLUDE_uxTaskGetStackHighWaterMark

2.11 INCLUDE_uxTaskPriorityGet

2.12 INCLUDE_vTaskPrioritySet

2.13 INCLUDE_xTaskResumeFromISR

2.14 INCLUDE_eTaskGetState

2.15 INCLUDE_vTaskSuspend

2.16 INCLUDE_xTimerPendFunctionCall

3. "config" 开始的宏

3.1 configAPPLICATION_ALLOCATED_HEAP

3.2 configASSERT

3.3 configCHECK_FOR_STACK_OVERFLOW

3.4 configCPU_CLOCK_HZ

3.5 configSUPPORT_DYNAMIC_ALLOCATION

3.6 configENABLE_BACKWARD_COMPATIBILITY

3.7 configGENERATE_RUN_TIME_STATS

3.8 configIDLE_SHOULD_YIELD

3.9 configKERNEL_INTERRUPT_PRIORITY、configMAX_SYSCALL_INTERRUPT_PRIORITY、configMAX_API_CALL_INTERRUPT_PRIORITY

3.10 configMAX_CO_ROUTINE_PRIORITIES

3.11 configMAX_PRIORITIES

3.12 configMAX_TASK_NAME_LEN

3.13 configMINIMAL_STACK_SIZE

3.14 configNUM_THREAD_LOCAL_STORAGE_POINTERS        

3.15 configQUEUE_REGISTRY_SIZE

3.16 configSUPPORT_STATIC_ALLOCATION

3.17 configTICK_RATE_HZ

3.18 configTIMER_QUEUE_LENGTH

3.19 configTIMER_TASK_PRIORITY

3.20 configTIMER_TASK_STACK_DEPTH

3.21 configTOTAL_HEAP_SIZE

3.22 configUSE_16_BIT_TICKS

3.23 configUSE_APPLICATION_TASK_TAG

3.24 configUSE_CO_ROUTINES

3.25 configUSE_COUNTING_SEMAPHORES

3.26 configUSE_DAEMON_TASK_STARTUP_HOOK

3.27 configUSE_IDLE_HOOK

3.28 configUSE_MALLOC_FAILED_HOOK

3.29 configUSE_MUTEXES

3.30 configUSE_PORT_OPTIMISED_TASK_SELECTION

3.31 configUSE_PREEMPTION

3.32 configUSE_QUEUE_SETS

3.33 configUSE_RECURSIVE_MUTEXES

3.34 configUSE_STATS_FORMATTING_FUNCTIONS

3.35 configUSE_TASK_NOTIFICATIONS

3.36 configUSE_TICK_HOOK

3.37 configUSE_TICKLESS_IDLE

3.38 configUSE_TIMERS

3.39 configUSE_TIME_SLICING

3.40 configUSE_TRACE_FACILITY


        在实际使用 FreeRTOS 的时候我们时常需要根据自己的需求来配置 FreeRTOS,而且不同架构的 MCU 在使用的时候配置也不同。正点原子的 FreeRTOS 的系统配置文件为 FreeRTOSConfig.h,在此配置文件中可以完成 FreeRTOS 的裁剪和配置。

1. FreeRTOSConfig.h 文件

        FreeRTOS 的配置基本是通过在 FreeRTOSConfig.h 中使用 “#define” 这样的语句来定义宏定义实现的。在 FreeRTOS 的官方 demo 中,每个工程都有一个 FreeRTOSConfig.h 文件,我们在使用的时候可以参考这个文件,甚至直接复制粘贴使用。

2. "INCLUDE_" 开始的宏

        使用 "INCLUDE_" 开头的宏来表示使能或除能 FreeRTOS 中相应的 API 函数,作用就是用来配置 FreeRTOS 中的可选 API函数 的;比如说当宏 INCLUDE_vTaskPrioritySet 设置为 0 的时候表示不能使用函数 vTaskPrioritySet(),当设置为 1 的时候就表示可以使用函数 vTaskPrioritySet()。这个功能其实就是条件编译:

        从上图可以看出:INCLUDE_vTaskPrioritySet == 1 的时候,函数 vTaskPrioritySet() 才会被编译,注意,这里为了缩小篇幅将函数 vTaskPrioritySet() 的内容进行了折叠。FreeRTOS 中的裁剪和配置就是这种用条件编译的方法来实现的,不止是 FreeRTOS 这么干,很多的协议栈、RTOS系统和 GUI 库等都是使用条件编译的方法来完成配置和裁剪的。条件编译的好处就是节省空间,不需要的功能就不用编译,这样就可以根据实际需求来减少系统占用的 ROM 和 RAM 大小,根据自己所使用的 MCU 来调整系统消耗,降低成本。

什么是 API ?

        API 全称为 Application Programming Interface(应用程序编程接口):是一套明确定义的各种软件组件之间的通信方法

举个例子来看什么是 API?

有两个软件甲和乙,软件甲是已经开发测试完成的,软件乙是正在开发测试的,软件乙的某一部分功能想要调用软件甲来实现,但是又不想从头看一遍软件甲的源码,这个时候软件甲的工程师把软件乙想要调用的功能封装成一个函数;软件乙只需要把工程师封装好的这个函数放在软件乙里即可,就能直接用软件甲的功能了。

其中,API 就是软件甲说的那个封装好的函数。

更加通俗一点的说:就是别人写好的代码,或者编译好的程序,提供给你用,就叫做 API。

下面来看看 "INCLUDE_" 开始的都有哪些宏,它们的功能都是什么。

2.1 INCLUDE_xSemaphoreGetMutexHolder

如果要使用函数 xQueueGetMutexHolder()的话宏 INCLUDE_xSemaphoreGetMutexHolder 必须定义为 1 。

2.2 INCLUDE_xTaskAbortDelay

如果要使用函数 xTaskAbortDelay()的话将宏 INCLUDE_xTaskAbortDelay 定义为 1。

2.3 INCLUDE_vTaskDelay

如果要使用函数 vTaskDelay()的话需要将宏 INCLUDE_vTaskDelay 定义为 1。

2.4 INCLUDE_vTaskDelayUntil

如果要使用函数 vTaskDelayUntil()的话需要将宏 INCLUDE_vTaskDelayUntil 定义为 1。

2.5 INCLUDE_vTaskDelete

如果要使用函数 vTaskDelete()的话需要将宏 INCLUDE_vTaskDelete 定义为 1。

2.6 INCLUDE_xTaskGetCurrentTaskHandle

如果要使用函数 xTaskGetCurentTaskHandle() 的 话 需 要 将 宏INCLUDE_xTaskGetCurrentTaskHandle 定义为 1。

2.7 INCLUDE_xTaskGetHandle

如果要使用函数 xTaskGetHandle()的话需要将宏 INCLUDE_xTaskGetHandle 定义为 1。

2.8 INCLUDE_xTaskGetIdleTaskHandle

如果要使用函数 xTaskGetIdleTaskHandle() 的 话 需 要 将 宏INCLUDE_xTaskGetIdleTaskHandle 定义为 1。

2.9 INCLUDE_xTaskGetSchedulerState

如果要使用函数 xTaskGetSchedulerState()的话需要将宏 INCLUDE_xTaskGetSchedulerState 定义为 1。

2.10 INCLUDE_uxTaskGetStackHighWaterMark

如果要使用函数 uxTaskGetStackHighWaterMark() 的 话 需 要 将 宏INCLUDE_uxTaskGetStackHighWaterMark 定义为 1。

2.11 INCLUDE_uxTaskPriorityGet

如果要使用函数 uxTaskPriorityGet()的话需要将宏 INCLUDE_uxTaskPriorityGet 定义为 1。

2.12 INCLUDE_vTaskPrioritySet

如果要使用函数 vTaskPrioritySet()的话需要将宏 INCLUDE_vTaskPrioritySet 定义为 1。

2.13 INCLUDE_xTaskResumeFromISR

如果要使用函数 xTaskResumeFromISR()的话需要将宏 INCLUDE_xTaskResumeFromISR 和 INCLUDE_vTaskSuspend 都定义为 1。

2.14 INCLUDE_eTaskGetState

如果要使用函数 eTaskGetState()的话需要将宏 INCLUDE_eTaskGetState 定义为 1。

2.15 INCLUDE_vTaskSuspend

如果要使用函数 vTaskSuspend() 、 vTaskResume() 、 prvTaskIsTaskSuspended() 、xTaskResumeFromISR()的话宏 INCLUDE_vTaskSuspend 要定义为 1。

如果要使用函数 xTaskResumeFromISR() 的 话 宏 INCLUDE_xTaskResumeFromISR 和 INCLUDE_vTaskSuspend 都必须定义为 1。

2.16 INCLUDE_xTimerPendFunctionCall

如果要使用函数 xTimerPendFunctionCall()和 xTimerPendFunctionCallFromISR() 的话宏 INCLUDE_xTimerPendFunctionCall 和 configUSE_TIMERS 都必须定义为 1。

3. "config" 开始的宏

        "config" 开始的宏和 "INCLUDE_" 开始的宏一样,都是用来完成 FreeRTOS 的配置和裁剪的,接下来我们就看一下这些 "config" 开始的宏。

3.1 configAPPLICATION_ALLOCATED_HEAP

        默认情况下,FreeRTOS 的堆内存是由编译器来分配的,将宏 configAPPLICATION_ALLOCATED_HEAP 定义为 1 的话堆内存可以由用户自行设置,堆内存在 heap_1.c、heap_2.c、heap_3.c、heap_4.c 和 heap_5.c 中有定义,具体在哪个文件取决于用户选择哪种内存管理方式。

/* Allocate the memory for the heap. */
#if( configAPPLICATION_ALLOCATED_HEAP == 1 )
	/* The application writer has already defined the array used for the RTOS
	heap - probably so it can be placed in a special segment or address. */
	extern uint8_t ucHeap[ configTOTAL_HEAP_SIZE ];
#else
	static uint8_t ucHeap[ configTOTAL_HEAP_SIZE ];
#endif /* configAPPLICATION_ALLOCATED_HEAP */

/* Define the linked list structure.  This is used to link free blocks in order
of their memory address. */

        当宏 configAPPLICATION_ALLOCATED_HEAP 定义为 1 时,需要用户自行堆内存 ucHeap,否则的话就是编译器来分配的。

3.2 configASSERT

        断言,类似于 C 标准库中的 assert() 函数,调试代码的时候可以检查传入的参数是否合理,FreeRTOS 内核中的关键点都会调用 configASSERT(x),当 x 为 0 的时候说明有错误发生,使用断言的话会导致开销加大,一般在调试阶段使用。configASSERT() 需要在 FreeRTOSConfig.h 文件中定义,

#define configASSERT((x)) if((x)==0) vAssertCalled(__FILE_,__LINE__);

        注意:vAssertCalled() 函数需要用户自行去定义,可以是显示到 LCD 上的函数,也可以是通过串口打印出来的函数,本教程的所有例程采用如下的定义:

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

        当参数 x 错误的时候就通过串口打印出发生错误的文件名和错误所在的行号,调试代码可以使用断言,当调试完成以后尽量去掉断言,防止增加开销!

3.3 configCHECK_FOR_STACK_OVERFLOW

        设置堆栈溢出检测,每个任务都有一个任务堆栈,如果使用函数 xTaskCreate() 创建一个任务的话那么这个任务的堆栈是自动从 FreeRTOS 的堆(ucHeap) 中分配的,堆栈的大小是由函数 xTaskCreate() 的参数 usStackDepth 来决定的。如果使用函数 xTaskCreateStatic() 创建任务的话任务堆栈是由用户设置的,参数 pxStackBuffer 为任务堆栈,一般是一个数组。

        堆栈溢出是导致应用程序不稳定的主要因素,FreeRTOS 提供了两种可选的机制来帮助检测和调试堆栈溢出,不管使用哪种机制都要设置宏 configCHECK_FOR_STACK_OVERFLOW。如果使能了堆栈检测功能的话,即宏 configCHECK_FOR_STACK_OVERFLOW 不为 0,那么用户必须提供一个钩子函数(回调函数),当内核检测到堆栈溢出以后就会调用这个钩子函数,

void vApplicationStackOverflowHook( TaskHandle_t xTask, 
                                    char * pcTaskName );

        参数 xTask 是任务句柄,pcTaskName 是任务名字,要注意的是堆栈溢出太严重的话可能会 损毁这两个参数,如果发生这种情况的话可以直接查看变量 pxCurrentTCB 来确定哪个任务发 生了堆栈溢出。有些处理器可能在堆栈溢出的时候生成一个 fault 中断来提示这种错误,另外, 堆栈溢出检测会增加上下文切换的开销,建议在调试的时候使用。

        configCHECK_FOR_STACK_OVERFLOW==1,使用堆栈溢出检测方法 1。

        上下文切换的时候需要保存现场,现场是保存在堆栈中的,这个时候任务堆栈使用率很可 能达到最大值,方法一就是不断的检测任务堆栈指针是否指向有效空间,如果指向了无效空间 的话就会调用钩子函数。方法一的优点就是快!但是缺点就是不能检测所有的堆栈溢出。         

        configCHECK_FOR_STACK_OVERFLOW==2,使用堆栈溢出检测方法 2。

        使用方法二的话在创建任务的时候会向任务堆栈填充一个已知的标记值,方法二会一直检 测堆栈后面的几个 bytes(标记值)是否被改写,如果被改写的话就会调用堆栈溢出钩子函数,方 法二也会使用方法一中的机制!方法二比方法一要慢一些,但是对用户而言还是很快的!方法 二能检测到几乎所有的堆栈溢出,但是也有一些情况检测不到,比如溢出值和标记值相同的时 候。

3.4 configCPU_CLOCK_HZ

        设置 CPU 的频率。

3.5 configSUPPORT_DYNAMIC_ALLOCATION

        定义为 1 的话在创建 FreeRTOS 的内核对象的时候所需要的 RAM 就会从 FreeRTOS 的堆中 动态的获取内存,如果定义为 0 的话所需的 RAM 就需要用户自行提供,默认情况下宏

configSUPPORT_DYNAMIC_ALLOCATION 为 1。

3.6 configENABLE_BACKWARD_COMPATIBILITY

        FreeRTOS.h 中由一些列的 #define 宏定义,这些宏定义都是一些数据类型名字,

        默认情况下宏 configENABLE_BACKWARD_COMPATIBILITY 为 1。

3.7 configGENERATE_RUN_TIME_STATS

        设置为 1 开启时间统计功能,相应的 API 函数会被编译,为 0 时关闭时间统计功能。如果宏 configGENERATE_RUN_TIME_STATS 为 1 的话还需要定义以下两个宏。

portCONFIGURE_TIMER_FOR_RUN_TIME_STATS()
//此宏用来初始化一个外设来作为时钟统计的基准时钟

portGET_RUN_TIME_COUNTER_VALUE() 或
portALT_GET_RUN_TIME_COUNTER_VALUE(Time)
//此宏用来返回当前基准时钟的时钟值

3.8 configIDLE_SHOULD_YIELD

        此宏定义了与空闲任务 (idle Task) 处于同等优先级的其他用户任务的行为,当为 0 的时候空闲任务不会为其他处于同优先级的任务让出 CPU 使用权。当为 1 的时候空闲任务就会为处于同等优先级的用户任务让出 CPU 使用权,除非没有就绪的用户任务,这样花费在空闲任务上的时间就会很少,但是这种方法也带了副作用。

        上图中有三个用户任务:A、B、C,还有一个空闲任务 I ,用户任务和空闲任务处于同一优先级,任务切换发生在 T0~T7 时刻。T0~T1 之间的时间为一个时间片,从图中可以看出一 开始任务 B、C 都执行了一个完成的时间片,在 T2 时刻空闲任务 I 开始执行,I 任务运行了一段时间以后被 A 任务抢走了 CPU 使用权,A 任务运行到 T3 时刻发生任务切换,B 任务开始运行。可以看出其实任务 I 和任务 A 一起使用了一个时间片,所以任务 A 运行的时间就比其他任务少!

3.9 configKERNEL_INTERRUPT_PRIORITY、configMAX_SYSCALL_INTERRUPT_PRIORITY、configMAX_API_CALL_INTERRUPT_PRIORITY

        configKERNEL_INTERRUPT_PRIORITY、configMAX_SYSCALL_INTERRUPT_PRIORITY、configMAX_API_CALL_INTERRUPT_PRIORITY

        这三个宏和 FreeRTOS 的中断配置有关;

3.10 configMAX_CO_ROUTINE_PRIORITIES

        设置可以分配给协程的最大优先级,也就是协程的优先级数。设置好以后协程的优先级可以从 0 到 configMAX_CO_ROUTINE_PRIORITIES - 1,其中 0 是最低的优先级,configMAX_CO_ROUTINE_PRIORITIES - 1 为最高的优先级。

3.11 configMAX_PRIORITIES

        设置任务的优先级数量,设置好以后任务就可以使用从 0 到 configMAX_PRIORITIES - 1 的优先级,其中 0 是最低优先级,configMAX_PRIORITIES - 1 是最高优先级。注意:和 UCOS 的区别,UCOS 中 0 是最高优先级!

3.12 configMAX_TASK_NAME_LEN

        设置任务名的最大长度。

3.13 configMINIMAL_STACK_SIZE

        设置空闲任务的最小任务堆栈大小,以字为单位,不是字节。比如在 STM32 上设置为 100 的话,那么真正的堆栈大小就是 100 * 4 = 400 字节。

3.14 configNUM_THREAD_LOCAL_STORAGE_POINTERS        

        设置每个任务的本地存储指针数组大小,任务控制块中有本地存储数组指针,用户应用程序可以在这些本地存储中存入一些数据。

3.15 configQUEUE_REGISTRY_SIZE

        设置可以注册的队列和信号量的最大数量,在使用内核调试器查看信号量和队列的时候需要设置此宏,而且要先将消息队列和信号量进行注册,只有注册了的队列和信号量才会在内核调试器中看到,如果不使用内核调试器的话此宏设置为 0 即可。

3.16 configSUPPORT_STATIC_ALLOCATION

        当此宏定义为 1 ,在创建一些内核对象的时候需要用户指定的 RAM,当为 0 的时候就会自己使用 heap.c 中的动态内存管理函数来自动的申请 RAM。

3.17 configTICK_RATE_HZ

        设置 FreeRTOS 的系统时钟节拍频率,单位为 HZ ,此频率就是滴答定时器的中断频率,需要使用此宏来配置滴答定时器的中断。本教程中我们将此宏设置为 1000 ,周期就是 1ms。

3.18 configTIMER_QUEUE_LENGTH

        此宏是配置 FreeRTOS 软件定时器的,FreeRTOS 的软件定时器 API 函数会通过命令队列向软件定时器任务发送消息,此宏用来设置这个软件定时器的命令队列长度。

3.19 configTIMER_TASK_PRIORITY

        设置软件定时器任务的任务优先级。

3.20 configTIMER_TASK_STACK_DEPTH

        设置定时器服务任务的任务堆栈大小。

3.21 configTOTAL_HEAP_SIZE

        设置堆大小,如果使用了动态内存管理的话,FreeRTOS 在创建任务、信号量、队列等的时候就会使用 heap_x.c (x 为 1~5) 中的内存申请函数来申请内存。这些内存就是从堆 ucHeap[configTOTAL_HEAP_SIZE] 中申请的,堆的大小由 configTOTAL_HEAP_SIZE 来定义。

3.22 configUSE_16_BIT_TICKS

        设置系统节拍计数器变量数据类型,系统节拍计数器变量类型为 TickType_t,当 configUSE_16_BIT_TICK 为 1 的时候 TickType_t 就是 16 位的,当 configUSE_16_BIT_TICKS 为 0 的话 TickType_t 就是 32 位的。

3.23 configUSE_APPLICATION_TASK_TAG

        此宏设置为 1 的话函数 configUSE_APPLICATION_TASK_TAGF() 和 xTaskCallApplicationTaskHook() 就会被编译。

3.24 configUSE_CO_ROUTINES

        此宏为 1 的时候启动协程,协程可以节省开销,但是功能有限。

3.25 configUSE_COUNTING_SEMAPHORES

        设置为 1 的时候启用计数型信号量,相关的 API 函数会被编译。

3.26 configUSE_DAEMON_TASK_STARTUP_HOOK

        当宏 configUSE_TIMERS 和 configUSE_DAEMON_TASK_STARTUP_HOOK 都为 1 的时需要定义函数 vApplicationDaemonTaskStartupHook(),函数原型如下:

void vApplicationDaemonTaskStartupHook(void);

3.27 configUSE_IDLE_HOOK

        为 1 时使用空闲任务钩子函数,用户需要实现空闲任务钩子函数,函数的原型如下:

void vApplicationIdleHook(void);

3.28 configUSE_MALLOC_FAILED_HOOK

        为 1 时使用内存分配失败钩子函数,用户需要实现内存分配失败钩子函数,函数原型如下:

void vApplicationMallocFailedHook(void);

3.29 configUSE_MUTEXES

        为 1 时使用互斥信号量,相关的 API 函数会被编译。

3.30 configUSE_PORT_OPTIMISED_TASK_SELECTION

        FreeRTOS 有两种方法来选择下一个要运行的任务,一个是通用的方法,另外一个是特殊的方法,也就是硬件方法,使用 MCU 自带的硬件指令来实现

通用方法:

        当宏 configUSE_PORT_OPTIMISED_TASK_SELECTION 为0,或者硬件不支持的时候。

        希望所有硬件通用的时候。

        全部用 C 语言来实现,但是效率比特殊方法低。

        不限制最大优先级数目的时候。

特殊方法:

        不是所有的硬件都支持。

        当宏 configUSE_PORT_OPTIMISED_TASK_SELECTION 为 1 的时候。

        硬件拥有特殊的指令,比如计算前导零(CLZ)指令。

        比通用方法效率高。

        会限制优先级数目,一般是 32 个。

3.31 configUSE_PREEMPTION

        为 1 时使用抢占式调度器,为 0 时使用协程。如果使用抢占式调度器的话内核会在每个时钟节拍中断中进行任务切换,当使用协程的话会在如下地方进行任务切换:

  •         一个任务调用了函数 taskYIELD()。
  •         一个任务调用了可以使任务进入阻塞态的 API 函数。
  •         应用程序明确定义了在中断中执行上下文切换。

3.32 configUSE_QUEUE_SETS

        为 1 时启用队列集功能。

3.33 configUSE_RECURSIVE_MUTEXES

        为 1 时使用递归互斥信号量,相关的 API 函数会被编译。

3.34 configUSE_STATS_FORMATTING_FUNCTIONS

        宏 configUSE_TRACE_FACILITY 和 configUSE_STATS_FORMATTING_FUNCTIONS 都为 1 的时候函数 vTaskList() 和 vTaskGetRunTimeStats() 会被编译。

3.35 configUSE_TASK_NOTIFICATIONS

        为 1 的时候使用任务通知功能,相关的 API 函数会被编译,开启了此功能的话每个任务会多消耗 8 个字节。

3.36 configUSE_TICK_HOOK

        为 1 时使能时间片钩子函数,用户需要实现时间片钩子函数,函数的原型如下:

void vApplicationTickHook(void);

3.37 configUSE_TICKLESS_IDLE

        为 1 时使能低功耗 tickless 模式。

3.38 configUSE_TIMERS

        为 1 时使用软件定时器,相关的 API 函数会被编译,当宏 configUSE_TIMERS 为 1 的话,那么宏 configTIMER_TASK_PRIORITY、configTIMER_QUEUE_LENGTH 和 configTIMER_TASK_STACK_DEPTH 必须定义。

3.39 configUSE_TIME_SLICING

        默认情况下,FreeRTOS 使用抢占式调度器,这意味着调度器永远都在执行已经就绪了的最高优先级任务,优先级相同的任务在时钟节拍中断中进行切换,当宏 configUSE_TIME_SLICING 为 0 的时候不会在时钟节拍中断中执行相同优先级任务的任务切换,默认情况下宏 configUSE_TIME_SLICING 为1。

3.40 configUSE_TRACE_FACILITY

         为 1 启用可视化跟踪调试,会增加一些结构体成员和 API 函数。

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

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

相关文章

数据结构与算法(二)

一、数组 什么是数组? 数组:在内存中用一串连续的区域来存放一些值。数组是相同类型数据元素的有序集合 数组是由相同类型的元素的集合组成的数据结构 连续内存:JS的数组元素可以是任意类型,JS中的内存地址是不连续的 数组的…

工业互联网的新应用:高端装备的故障预测和健康管理

高端装备制造行业作为我国战略性新兴产业的重要组成部分,面临着产品复杂和生命周期长的挑战。为了提高装备的可靠性、可用性和维护效率,工业互联网技术在高端装备的故障预测和健康管理方面发挥了重要作用。 本文将探讨工业互联网在高端装备中故障预测和…

如何应用金字塔模型提高结构化表达能力

看一下结构化表达的定义: 结构化表达:是基于结构化思维,理清事物整理与部分之间关系、换位思考后,进行简洁、清晰和有信服力的表达,是一种让受众听得明白、记得清楚、产生认同的精益沟通方式。 结构化表达的基本原则是…

度娘教我influxdb,先搞一波在补理论

InfluxDb中的数据查询语法where子句 公司用的时序性数据库是influxdb,但是确实接触有点少。 心里话: 就是没接触过,度娘教教我。。。。 我咋回呢,现学吧,都是数据库,天下乌鸦一般黑然后就哟了以下&#xf…

Mac 更换.gradle文件目录

用mac开发最大滑铁卢居然是存储空间不足......于是加了一个外置的存储器。于是需要把android开发中最大的一个缓存目录移到外置存储器... 一开始对android studio的进行了如下设置 于是乎...Mac用户下的.gradle全删了...这个时候用android studio打包运行都没问题了。 如果你…

AI在视频教学方面会有哪些有意思应用?

阿酷TONY / 原创 / 2023-5-17 / 长沙 来,我们一起来探索未来式的学习体验,AI视频,AI与视频的应用将为你带来前所未有的教学体验。AI在视频教学方面的应用,主要会体现在如下几个方面: 1. AI 课程知识点梳理 2. AI 学…

前段时间公司招人,面了一个要23K的,一问自动化只会点皮毛···

前段时间公司要招2个自动化测试,同事面了几十个候选人,发现了一个很奇怪的现象,面试的时候,如果问的是框架api、脚本编写这些问题,基本上个个都能对答如流,等问到实际项目的时候,类似“怎么从0开…

OPPO关停哲库业务,工程师造芯何去何从?

5月12日(上周五),新浪科技从OPPO处了解到,OPPO将终止ZEKU业务。3000多人团队突然原地解散,网上唏嘘声一片! ZEKU最初成立于2019年,是OPPO的全资子公司,欧加集团百分之百注资成立。总…

提高合规性与安全性:ADAudit Plus助力企业数据审计

简介:在现代数字化时代,企业面临着日益增长的数据安全威胁和法规合规要求。为了应对这些挑战,企业需要强大的数据审计解决方案来监控和保护其敏感数据。ADAudit Plus是一款功能强大的工具,旨在帮助企业提高合规性,并提…

dll注入技术

一、dll注入的概念 当一个进程运行时,它会加载并使用一些动态链接库(DLL)来提供额外的功能和资源。这些DLL可以被多个进程共享,使得代码重用和资源共享变得更加高效。DLL注入技术利用了这种共享机制。它允许向正在运行的进程中注…

厦大凭什么和清北复一起入选首批国家集成电路产教融合创新平台?对台区位优势吗

最近,有网友提出这样一个问题,众所周知,中国集成电路研究主要集中在北京和上海,清北可以和北京合作,复旦可以和上海合作,那么厦大和谁合作,厦大又凭什么和清北复一起入选了首批国家集成电路产教…

RecyclerView 分层级展示(抽屉) TreeView

先看效果 难点: 数据层级的划分;理清楚层级关系, 剩下的就简单明了了; 1. 第一步 new Adapter, and setAdapter; (不需要setLayoutManager, Adapter里有set); mAdapter new TreeViewAdapter(getContext(),mRecyclerView); mRecyclerView.setAdapter(mAdapter); 2. 第二步, …

素雅的登录界面,简单而优雅

先上效果图&#xff1a; 再上代码&#xff1a; <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>Title</title><style>*, *::after, *::before {margin: 0;padding: 0;box-sizing: bord…

本地服务器与云服务器哪个好?

本地服务器和云服务器是企业可以使用的两种不同的服务器设置。主要区别在于本地服务器托管&#xff0c;第三方提供商托管云服务器。那么&#xff0c;本地服务器和云服务器哪个更好呢&#xff1f; 接下来&#xff0c;将带大家讨论本地服务器和云服务器的优缺点&#xff0c;并帮…

Golang笔记:使用embed包将静态资源嵌入到程序中

文章目录 目的使用演示//go:embed 指令在WebServer中应用总结 目的 Golang编译程序默认是静态编译&#xff0c;会把相关的库都打包到一起&#xff0c;这在分发部署使用时非常方便。不过如果项目中用到的外部的静态资源文件&#xff0c;通常就需要将这些资源和程序一起拷贝分发…

软件测试面试大全(涵盖了软件测试的全部核心技术点),应对技术面妥妥的

软件测试面试题&#xff1a;项目 1、简单介绍下最近做过的项目 根据自己的项目整理完成&#xff0c;要点&#xff1a; 1&#xff09;项目背景、业务、需求、核心业务的流程 2&#xff09;项目架构&#xff0c;B/S 还是 C/5&#xff0c;数据库用的什么? 中间件用的什么&…

[开源工具] [Unity实战]Jenkins如何配置拉取Git/Jenkins使用Unity一键打包[windows][android]

[开源工具]Jenkins如何配置拉取Git/Jenkins使用Unity一键打包[windows][android] 1.背景介绍1.1Jenkins是什么?1.2用JenkinsUnity的好处? 2.Jenkins安装&使用2.1Java112.2 下载jenkins.war(我用tomcat所以需要,可以用jenkins安装版本)2.3 使用Tomcat92.4将tomcat9解压后,…

1.高级面试-MySQL、Redis、特殊场景、Java

本文目录如下&#xff1a; 高级面试一、MySQLB树有什么优点&#xff1f; image.pngInnoDB 和 MyISAM 的索引结构有什么区别 (聚簇索引-非聚簇索引)&#xff1f; 二、RedisRedis 如何保证存储的都是 热点数据&#xff1f;大量 key 为同一过期时间怎么办&#xff1f;缓存一致性的…

TS构建微信小程序后使用vant weapp框架配置

1.npm 安装 # 通过 npm 安装 npm i vant/weapp -S --production 2.配置app.json 将 app.json 中的 "style": "v2" 去除&#xff0c;小程序的新版基础组件强行加上了许多样式&#xff0c;难以覆盖&#xff0c;不关闭将造成部分组件样式混乱。 3.修改 pr…

ubuntu20 kvm显卡直通实验-a4000

一、环境&#xff1a; 显卡&#xff1a;NVIDIA RTX A4000 系统&#xff1a;Ubuntu20.04 CPU&#xff1a;intel二、安装kvm sudo apt install qemu-kvm libvirt-daemon-system libvirt-clients bridge-utils virtinst virt-manager ovmf添加用户到“libvirt”和“kvm”组 s…