3.FreeRTOS系统源码移植

news2024/12/30 2:44:22

目录

一、获取FreeRTOS源代码

二、FreeRTOS系统源码内容

三、FreeRTOS系统源码移植

一、获取FreeRTOS源代码

来FreeRTOS官方网站:https://www.freertos.org/

我这里主要提供的是例程为FreeRTOS的V10.4.6版本

1、进入官网,点击Download FreeRTOS

2、点击Download

二、FreeRTOS系统源码内容

 和我们密切相关的是FreeRTOS内核,我们打开freeRTOS系统内核文件夹

 每个文件夹的内容是

名称描述
DemoFreeRTOS演示例程
LicenseFreeRTOS相关许可
SourceFreeRTOS源码
Test公用以及移植层测试代码

Demo文件夹

        Demo文件夹里面就是FreeRTOS的演示例程,支持多种芯片架构,其中包括F1、F4、F7三种步如下所示,对于入门学习FreeRTOS是十分有帮助的,在FreeRTOS的过程中就可以参考这些演示工程。

Source文件夹 

        Source文件夹是源码的本尊

 接下来,我们看一下每个文件所对应的含义

名称描述
include包含了FreeRTOS的头文件
portable包含了FreeRTOS的移植文件
croytine.c协程相关文件
event_group.c事件相关文件
list.c列表相关文件
queue.c队列相关文件
stream_buffer.c流式缓冲区相关文件
tasks.c软件相关文件
timers.c软件定时器相关文件

红色加粗的是必须要添加进去的,其他可用可不用,根据自己的使用需求。

portable文件夹

        FreeRTOS操作系统归根到底是一个软件层面的东西,那FreeRTOS是如何跟硬件练习在一起的呢?

        portable文件夹里面的东西就是桥梁

由于我们使用MDK开发,因此这里重点介绍其中的部分移植文件。

名称描述
Keil指向RBDS文件夹
RVDS不同内核芯片的移植文件
MengMang内存管理文件

三、FreeRTOS系统源码移植

移植准备:

1、FreeRTOS源码

2、基础工程

移植步骤:

1、添加FreeRTOS源码(将FreeRTOS)源码添加至基础工程、头文件路径等

2、FreeRTOSConfig,添加FreeRTOSconfig.h配置文件

3、修改SYSTEM文件,修改SYSTEM文件中的sys.c、delay.c、usart.c

4、修改中断相关文件,修改Systick中断、SVC中断、PendSV中断。

5、添加应用程序,移植是否成功。

开始移植:

1、添加FreeRTOS 源码

        在基础工程的 Middlewares 文件夹中新建一个 FreeRTOS 子文件夹,如下图所示:

         接着就需要将 FreeRTOS 的源代码添加到刚刚新建的 FreeRTOS 子文件中了。将 FreeRTOS 内核源码的 Source 文件夹下的所有文件添加到工程的 FreeRTOS 文件夹中,如下图所示:

          其中,我们前边介绍到,portable,实际只用到三个文件,其他没用到的,我们可以删除掉

         而在MemMang是我们的内存管理算法,实际我们只用到算法4,即只用到heap_4.c,RVDS是一个软硬件连接桥梁,不同的内核,有不同的文件

2、将文件添加到工程

        打开工程,新建两个文件分组,分别为Middlewares/FreeRTOS_CORE和Middlewares/FreeRTOS_PORT,如下图所示:

        我们将内核的C源码添加到Middlewares/FreeRTOS_CORE,Middlewares/FreeRTOS_PORT分组用于存放FreeRTOS内核的移植文件,需要添加两个文件到这个分组,分别是heap_x.c和port.c。不同的开发板,所移植的port.c文件夹是不同的。

STM32系列开发板类型port.c所在文件夹
STM32F1ARM_CM3
STM32F4ARM_CM4F
STM32F7ARM_CM7/r0p1
STM32H7ARM_CM7/r0p1

        添加完以后如下图所示:

3、添加头文件路径

        我们总共需要添加两个头文件,一个是FreeRTOS系统的include的头文件,一个是硬件连接的头文件。添加完以后的路径如下图所示:

 4、添加FreeRTOSConfig.h文件

        FreeRTOSConfig.h是FreeRTOS操作系统的配置文件,FreeRTOS操作系统是可裁剪的,用户可以根据需求对FreeRTOS进行裁剪,裁剪掉不需要FreeRTOS功能,以此来节约MCU中内存资源。

5、修改SYSTEM文件

        我们分别修改sys.h,delay.h,usart.h

5.1、sys.h

        将#define SYS_SUPPORT_OS         1中的1修改成0

/**
 * SYS_SUPPORT_OS用于定义系统文件夹是否支持OS
 * 0,不支持OS
 * 1,支持OS
 */
#define SYS_SUPPORT_OS         1

5.2、usart.c

        usart.c 文件的修改也很简单,一共有两个地方需要修改,首先就是串口的中断服务函数, 原本在使用 µC/OS 的时候,进入和退出中断需要添加 OSIntEnter()和 OSIntExit()两个函数,这是µC/OS 对于中断的相关处理机制,而 FreeRTOS 中并没有这种机制,因此将这两行代码删除, 修改后串口的中断服务函数如下所示:

/**
 * @brief       串口1中断服务函数
 * @param       无
 * @retval      无
 */
void USART_UX_IRQHandler(void)
{ 
    uint32_t timeout = 0;
    uint32_t maxDelay = 0x1FFFF;
  
    HAL_UART_IRQHandler(&g_uart1_handle);       /* 调用HAL库中断处理公用函数 */

    timeout = 0;
    while (HAL_UART_GetState(&g_uart1_handle) != HAL_UART_STATE_READY) /* 等待就绪 */
    {
        timeout++;                              /* 超时处理 */
        if(timeout > maxDelay)
        {
            break;
        }
    }
     
    timeout=0;
    
    /* 一次处理完成之后,重新开启中断并设置RxXferCount为1 */
    while (HAL_UART_Receive_IT(&g_uart1_handle, (uint8_t *)g_rx_buffer, RXBUFFERSIZE) != HAL_OK)
    {
        timeout++;                              /* 超时处理 */
        if (timeout > maxDelay)
        {
            break;
        }
    }

}

#endif

        接下来 usart.c 要修改的第二个地方就是导入的头文件,因为在串口的中断服务函数当中已 经删除了 µC/OS 的相关代码,并且也没有使用到 FreeRTOS 的相关代码,因此将 usart.c 中包含 的关于 OS 的头文件删除,要删除的代码如下所示:

/* 如果使用os,则包括下面的头文件即可 */
#if SYS_SUPPORT_OS
#include "os.h"                               /* os 使用 */
#endif

5.3、delay.c

        接下来修改 SYSTEM 文件夹中的最后一个文件——delay.c,delay.c 文件需要改动的地方比 较多,大致可分为三个步骤:删除适用于 µC/OS 但不适用于 FreeRTOS 的相关代码、添加 FreeRTOS 的相关代码、修改部分内容。

(1) 删除适用于 µC/OS 但不适用于 FreeRTOS 的相关代码

        一共需要删除 1 个全局变量、6 个宏定义、3 个函数,这些要删除的代码在使用 µC/OS 的 时候会使用到,但是在使用 FreeRTOS 的时候无需使用,需要删除的代码如下所示:

static uint32_t g_fac_us = 0;       /* us延时倍乘数 */

/* 如果SYS_SUPPORT_OS定义了,说明要支持OS了(不限于UCOS) */
#if SYS_SUPPORT_OS

/* 添加公共头文件 ( ucos需要用到) */
#include "os.h"

/* 定义g_fac_ms变量, 表示ms延时的倍乘数, 代表每个节拍的ms数, (仅在使能os的时候,需要用到) */
static uint16_t g_fac_ms = 0;

/*
 *  当delay_us/delay_ms需要支持OS的时候需要三个与OS相关的宏定义和函数来支持
 *  首先是3个宏定义:
 *      delay_osrunning    :用于表示OS当前是否正在运行,以决定是否可以使用相关函数
 *      delay_ostickspersec:用于表示OS设定的时钟节拍,delay_init将根据这个参数来初始化systick
 *      delay_osintnesting :用于表示OS中断嵌套级别,因为中断里面不可以调度,delay_ms使用该参数来决定如何运行
 *  然后是3个函数:
 *      delay_osschedlock  :用于锁定OS任务调度,禁止调度
 *      delay_osschedunlock:用于解锁OS任务调度,重新开启调度
 *      delay_ostimedly    :用于OS延时,可以引起任务调度.
 *
 *  本例程仅作UCOSII的支持,其他OS,请自行参考着移植
 */

/* 支持UCOSII */
#define delay_osrunning     OSRunning           /* OS是否运行标记,0,不运行;1,在运行 */
#define delay_ostickspersec OS_TICKS_PER_SEC    /* OS时钟节拍,即每秒调度次数 */
#define delay_osintnesting  OSIntNesting        /* 中断嵌套级别,即中断嵌套次数 */


/**
 * @brief     us级延时时,关闭任务调度(防止打断us级延迟)
 * @param     无
 * @retval    无
 */
void delay_osschedlock(void)
{
    OSSchedLock();                      /* UCOSII的方式,禁止调度,防止打断us延时 */
}

/**
 * @brief     us级延时时,恢复任务调度
 * @param     无
 * @retval    无
 */
void delay_osschedunlock(void)
{
    OSSchedUnlock();                    /* UCOSII的方式,恢复调度 */
}

/**
 * @brief     us级延时时,恢复任务调度
 * @param     ticks: 延时的节拍数
 * @retval    无
 */
void delay_ostimedly(uint32_t ticks)
{
    OSTimeDly(ticks);                               /* UCOSII延时 */
}

/**
 * @brief     systick中断服务函数,使用OS时用到
 * @param     ticks : 延时的节拍数  
 * @retval    无
 */  
void SysTick_Handler(void)
{
    /* OS 开始跑了,才执行正常的调度处理 */
    if (delay_osrunning == OS_TRUE)
    {
        /* 调用 uC/OS-II 的 SysTick 中断服务函数 */
        OS_CPU_SysTickHandler();
    }
    HAL_IncTick();
}
#endif

(2) 添加 FreeRTOS 的相关代码

        只 需 要 在 delay.c 文 件 中 使 用 extern 关 键 字 导 入 一 个 FreeRTOS 函 数 — — xPortSysTickHandler()即可,这个函数是用于处理 FreeRTOS 系统时钟节拍的,本教程是使用 SysTick作为FreeRTOS操作系统的心跳,因此需要在SysTick的中断服务函数中调用这个函数, 因此将代码添加到 SysTick 中断服务函数之前,代码修改如下:

void SysTick_Handler(void)
{
   代码省略
}
#endif

(3) 修改部分内容

        最后要修改的内容包括两个,分别是包含头文件和 4 个函数。 首先来看需要修改的 4 个函数,分别是 SysTick_Handler()、delay_init()、delay_us()和 delay_ms()。

(a) SysTick_Handler()

        这个函数是 SysTick 的中断服务函数,需要在这个函数中重复调用上个步骤中导入的函数 xPortSysTickHandler(),代码修改后如下所示:

/**
 * @brief     systick中断服务函数,使用OS时用到
 * @param     ticks: 延时的节拍数
 * @retval    无
 */  
void SysTick_Handler(void)
{
    HAL_IncTick();
    if (xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED) /* OS开始跑了,才执行正常的调度处理 */
    {
        xPortSysTickHandler();
    }
}

 (b) delay_init()

         函 数 delay_init() 主要用于初始化 SysTick 。 这 里 要 说 明 的 是 , 在 后 续 调 用 函 数 vTaskStartScheduler()(这个函数在下文中讲解到 FreeRTOS 任务调度器的时候会具体分析)的 时候,FreeRTOS 会按照 FreeRTOSConfig.h 文件的配置对 SysTick 进行初始化,因此 delay_init() 函数初始化的 SysTick 主要使用在 FreeRTOS 开始任务调度之前。函数 delay_init()要修改的部分主要为 SysTick 的重装载值以及删除不用的代码,代码修改如下:

void delay_init(uint16_t sysclk)
{
#if SYS_SUPPORT_OS                                      /* 如果需要支持OS */
    uint32_t reload;
#endif
    HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);/* SYSTICK使用内核时钟源,同CPU同频率 */
    g_fac_us = sysclk;                                  /* 不论是否使用OS,g_fac_us都需要使用 */
#if SYS_SUPPORT_OS                                      /* 如果需要支持OS. */
    reload = sysclk;                                    /* 每秒钟的计数次数 单位为M */
    reload *= 1000000 / configTICK_RATE_HZ;             /* 根据delay_ostickspersec设定溢出时间,reload为24位
                                                           寄存器,最大值:16777216,在168M下,约合0.099s左右 */
    SysTick->CTRL |= SysTick_CTRL_TICKINT_Msk;          /* 开启SYSTICK中断 */
    SysTick->LOAD = reload;                             /* 每1/delay_ostickspersec秒中断一次 */
    SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk;           /* 开启SYSTICK */
#endif 
}

(c) delay_us()

        函数 delay_us()用于微秒级的 CPU 忙延时,原本的函数 delay_us()延时的前后加入了自定义 函数 delay_osschedlock()和 delay_osschedunlock()用于锁定和解锁 µC/OS 的任务调度器,以此来 让延时更加准确。在 FreeRTOS 中可以不用加入这两个函数,但是要注意的是,这会让函数 delay_us()的微秒级延时的精度有所下降,函数 delay_us()修改后的代码如下所示:

void delay_us(uint32_t nus)
{
    uint32_t ticks;
    uint32_t told, tnow, tcnt = 0;
    uint32_t reload = SysTick->LOAD;        /* LOAD的值 */
    
    ticks = nus * g_fac_us;                 /* 需要的节拍数 */
    told = SysTick->VAL;                    /* 刚进入时的计数器值 */
    while (1)
    {
        tnow = SysTick->VAL;
        if (tnow != told)
        {
            if (tnow < told)
            {
                tcnt += told - tnow;        /* 这里注意一下SYSTICK是一个递减的计数器就可以了 */
            }
            else
            {
                tcnt += reload - tnow + told;
            }
            told = tnow;
            if (tcnt >= ticks) 
            {
                break;                      /* 时间超过/等于要延迟的时间,则退出 */
            }
        }
    }
} 

 (d) delay_ms()

        函数 delay_ms()用于毫秒级的 CPU 忙延时,原本的函数 delay_ms()会判断 µC/OS 是否运 行,如果 µC/OS 正在运行的话,就使用 µC/OS 的 OS 延时进行毫秒级的延时,否则就调用函数 delay_us()进行毫秒级的 CPU 忙延时。在 FreeRTOS 中,可以将函数 delay_ms()定义为只进行 CPU 忙延时,当需要 OS 延时的时候,调用 FreeRTOS 提供的 OS 延时函数 vTaskDelay()(在下 文讲解 FreeRTOS 时间管理的时候会对此函数进行分析)进行系统节拍级延时,函数 delay_ms() 修改后的代码如下所示:

void delay_ms(uint16_t nms)
{
    uint32_t i;

    for (i=0; i<nms; i++)
    {
        delay_us(1000);
    }
}

(e) 包含头文

        根据上述步骤的修改,delay.c 文件中使用到了 FreeRTOS 的相关函数,因此就需要在 delay.c 文件中包含 FreeRTOS 的相关头文件,并且移除掉原本存在的 µC/OS 相关头文件。先看一下修 改前 delay.c 文件中包含的 µC/OS 相关的头文件:

/* 添加公共头文件 (FreeRTOS 需要用到) */
#include "FreeRTOS.h"
#include "task.h"

5.5、修改中断定时器函数

        在 FreeRTOS 的移植过程中会这几到三个重要的中断,分别是 FreeRTOS 系统时基定时器 的中断(SysTick 中断)、SVC 中断、PendSV 中断(SVC 中断和 PendSV 中断在下文讲解 FreeRTOS 中断和 FreeRTOS 任务切换的时候会具体分析),这三个中断的中断服务函数在 HAL 库提供的 文件中都有定义,对于正点原子不同的 STM32 开发板,对应了不同的文件,具体对应关系如下 表所示:

正点原子的 STM32 系列开发板类型中断服务函数所在文件
STM32F1stm32f1xx_it.c
STM32F4stm32f4xx_it.c
STM32F7stm32f7xx_it.c
STM32H7stm32h7xx_it.c

        其中,SysTick 的中断服务函数在 delay.c 文件中已经定义了,并且 FreeRTOS 也提供了 SVC 和 PendSV 的中断服务函数,因此需要将 HAL 库提供的这三个中断服务函数注释掉,这里采用 宏开关的方式让 HAL 库中的这三个中断服务函数不加入编译,使用的宏在 sys.h 中定义,因此 还需要导入 sys.h 头文件,参照上表进行找到对应的文件进行修改,修改后的代码如下所示:

/*导入sys.h头文件*/
#include "./SYSTEM/SYS/sys.h"

#if(!SYS_SUPPORT_OS)
void SVC_Handler(void)
{
}
#endif


#if(!SYS_SUPPORT_OS)
void PendSV_Handler(void)
{
}
#endif

#if(!SYS_SUPPORT_OS)
void SysTick_Handler(void)
{
  HAL_IncTick();
}
#endif

        最后,也是移植 FreeRTOS 要修改的最后一个地方,FreeRTOSConfig.h 文件中有如下定义: #define configPRIO_BITS __NVIC_PRIO_BITS

        我们需要将

#define __NVIC_PRIO_BITS 4U

        修改成

#define __NVIC_PRIO_BITS 4

5.6、可选步骤

        这个步骤是可选的,但是笔者强烈建议读者完成,因为在后续实验中会使用到,并且规范 工程。本小节可分为 3 个小部分,分别为修改工程目标名、移除 USMART 调试组件、添加定时 器驱动。

1、修改工程目标名称

        将之前的基础工程名称修改成FreeRTOS

 2、移除 USMART 调试组件

 

 3、添加定时器驱动

        由于在后续的实验中需要使用到 STM32 的基本定时器外设,因此需要向工程中添加定时 器的相关驱动文件。

5.7、添加应用程序

        移植好 FreeRTOS 之后,当然要测试一下移植是否成功。在本步骤中,一共需要修改 1 个 文件并添加 2 个文件,修改的 1 个文件为 main.c,添加的 2 个文件为 freertos_demo.c 和 freertos_demo.h。对于 main.c 主要是在 main()函数中完成一些硬件的初始化,最后调用 freertos_demo.c 文件中的 freertos_demo()函数。而 freertos_demo.c 则是用于编写 FreeRTOS 的相 关应用程序代码。

#include "./SYSTEM/sys/sys.h"
#include "./SYSTEM/usart/usart.h"
#include "./SYSTEM/delay/delay.h"
#include "./BSP/LED/led.h"
#include "./BSP/LCD/lcd.h"
#include "./BSP/KEY/key.h"
#include "./BSP/SRAM/sram.h"
#include "./MALLOC/malloc.h"
#include "freertos_demo.h"
int main(void)
{
 HAL_Init(); /* 初始化 HAL 库 */
 sys_stm32_clock_init(RCC_PLL_MUL9); /* 设置时钟, 72Mhz */
 delay_init(72); /* 延时初始化 */
 usart_init(115200); /* 串口初始化为 115200 */
 led_init(); /* 初始化 LED */
 lcd_init(); /* 初始化 LCD */
 key_init(); /* 初始化按键 */
 sram_init(); /* SRAM 初始化 */
 my_mem_init(SRAMIN); /* 初始化内部 SRAM 内存池 */
 my_mem_init(SRAMEX); /* 初始化外部 SRAM 内存池 */
 
 freertos_demo(); /* 运行 FreeRTOS 例程 */
}

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

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

相关文章

数分面试题-SQL高频考点

目录标题 1、SQL语言分类2、join连接3、列转换3.1 列转行3.2 行转列 4、分页查询5、字符串处理函数5.1 字符函数5.2 数学函数5.3 日期函数 6、索引6.1 什么是索引6.2 建立索引的优缺点6.3 索引有哪些6.4 索引为什么快6.5 什么情况下加索引6.6 怎么知道索引用没用上6.7 用过组合…

Axure教程—中继器删除与批量删除

本文介绍的是用Axure中的中继器实现删除与批量删除效果 效果 功能 1、选中某项数据删除&#xff0c;删除后提示“删除成功” 2、选择多项数据删除&#xff0c;删除后提示“删除成功”&#xff0c;如果不选取数据&#xff0c;点击”批量删除“按钮&#xff0c;提示”请至少选择…

SNMP 计算机网络管理 一文理清-管理信息库,OID,MIB结构树,SNMP协议体系结构

⬜⬜⬜ &#x1f430;&#x1f7e7;&#x1f7e8;&#x1f7e9;&#x1f7e6;&#x1f7ea;(*^▽^*)欢迎光临 &#x1f7e7;&#x1f7e8;&#x1f7e9;&#x1f7e6;&#x1f7ea;&#x1f430;⬜⬜⬜ ✏️write in front✏️ &#x1f4dd;个人主页&#xff1a;陈丹宇jmu &am…

Java接口详解

目录 接口方法 接口的属性 接口方法 在Java设计的时候, 我们所说的接口,不同于类,我们尝尝希望一个类能满足某个特定的功能,或者需求. 我们在使用Arrays类中的sort方法对对象数组进行排序,但是对象所属的类必须实现Comparable接口: 可以看到里面只有一个方法: public inter…

【动态规划算法】第二题:⾯试题08.01.三步问题

&#x1f496;作者&#xff1a;小树苗渴望变成参天大树 &#x1f389;作者宣言&#xff1a;认真写好每一篇博客 &#x1f38a;作者gitee:gitee 如 果 你 喜 欢 作 者 的 文 章 &#xff0c;就 给 作 者 点 点 关 注 吧&#xff01; 文章目录 前言 前言 今天我们开始讲解动态规…

MySQL数据库总结 之 约束(restraint) 外键约束

前三篇关于MySQL的博客&#xff0c;地址如下&#xff1a; 1. MySQL数据库 && SQL语言命令总结 && 数据类型、运算符和聚合函数汇总_Flying Bulldog的博客-CSDN博客 2. 从0到1 && 关于MySQL的数据库和表_Flying Bulldog的博客-CSDN博客 3. MySQL数据…

Protobuf实现序列化和反序列化详细步骤

步骤1&#xff1a;添加对应的依赖 <dependency><groupId>com.google.protobuf</groupId><artifactId>protobuf-java</artifactId><version>3.7.1</version> </dependency>步骤2&#xff1a;编写bulid.bat文件执行&#xff0c…

react组件--npm发包总过程(超全教程!建议收藏!)

npm发包总过程 npm账号登录注册&#xff08;已有账号可跳过&#xff09;登录验证是否登录成功创建组件项目目录图新建文件夹&#xff0c;并初始化安装依赖/src/index.js --打包入口文件src/components/button/index.js --组件逻辑代码src/components/button/index.css --组件逻…

10 次面试 9 次被刷?吃透这 500 道大厂 Java 高频面试题后,怒斩 offer

很多 Java 工程师的技术不错&#xff0c;但是一面试就头疼&#xff0c;10 次面试 9 次都是被刷&#xff0c;过的那次还是去了家不知名的小公司。 问题就在于&#xff1a;面试有技巧&#xff0c;而你不会把自己的能力表达给面试官。 应届生&#xff1a;你该如何准备简历&#x…

verilog HDL -生成块 - generate——endgenerate

参考&#xff1a;vrilog数字系统设计 夏宇闻 【第3版】 5.7 生成块理解 生成语句可以动态的生成verilog代码&#xff0c;方便参数化模块的生成&#xff0c;大大的简化程序的编写过程,常用于以下情况&#xff1a; 对矢量中的多个位进行重复操作进行多个模块的实例引用的重复操…

Anacoda3中成功配置Tesseract-OCR超详细教程!!(win7、win10)

Anacoda3中成功配置Tesseract-OCR Tesseract-OCR简介安装及配置环境步骤1、在Anaconda虚拟环境中安装pytesseract第三方库2、下载tesseract-ocr安装包并安装3、环境配置检验是否安装成功修改pytesseract.py文件&#xff08;很重要&#xff01;&#xff09; Tesseract-OCR简介 …

C语言常用的数据转换函数

编程时&#xff0c;经常用到进制转换、字符转换。现整理记录如下&#xff1a; 一、字符串转十六进制 void StrToHex(char *pbDest, char *pbSrc, int nLen) {char h1,h2;char s1,s2;int i;for (i0; i<nLen/2; i){h1 pbSrc[2*i];h2 pbSrc[2*i1];s1 toupper(h1) - 0x30; …

ASP.NET Core MVC -- 控制器

添加控制器 访问测试 默认控制器访问index public string Index() {return "This is my default action..."; }特定访问路径 public string Welcome() {return "This is the Welcome action method..."; } 特定路径访问&#xff0c;带参数 public str…

查询Oracle当前用户下,所有数据表的总条数

需求&#xff1a;查询Oracle当前用户下&#xff0c;所有数据表的总条数 方法&#xff1a;存储过程 右键点击Procedures&#xff0c;点击New 点击OK 把存储过程写进去&#xff0c;然后点击编译运行&#xff1a; create or replace procedure tables_count ist_count numbe…

dolphinscheduler的switch组件

目录 一、背景 switch组件官方文档 Switch简介 创建任务 任务参数 二、实操DEMO SQL任务switch判断DEMO 第一步&#xff1a;新建SQL任务&#xff0c;配置好参数 第二步&#xff1a; 定义SWITCH节点 三、参考资料 默认任务参数 一、背景 Apache DolphinScheduler 是…

B站广告投放,B站有哪些投放广告的方式比较靠谱?

随着各视频平台发展&#xff0c;B站也逐渐壮大&#xff0c;成为当下最受年轻人喜爱的社交媒体平台之一&#xff0c;B站根据年轻人的喜好提供了多样化的产品和服务&#xff0c;如视频、直播、游戏、漫画、影业、演出活动、专栏等。形成了自己独特的up主文化。B站拥有着高黏性和高…

如何保证消息的可靠性传输?或者说,如何处理消息丢失的问题?

这个是肯定的&#xff0c;用 MQ 有个基本原则&#xff0c;就是数据不能多一条&#xff0c;也不能少一条&#xff0c;不能多&#xff0c;就是 前面说的重复消费和幂等性问题。不能少&#xff0c;就是说这数据别搞丢了。那这个问题你必须得考 虑一下。 如果说你这个是用 MQ 来传…

基于单片机心率脉搏心率血压体温血氧检测系统的设计与实现

功能介绍 本次设计通过32系列单片机STM32进行数据处理&#xff0c;配置引脚和JFC103传感器以及温度传感器进行数据通信。采用防水DS18B20进行腋下温度采集&#xff0c;通过单总线方式进行数据传输。心率血氧血压模块通过串口通信方式把采集到的数据发送给单片机&#xff0c;所有…

mac版本的xshell远程ssh工具

官网下载地址&#xff1a; https://www.royalapps.com/ts/win/download 注意&#xff1a;一定要保存(下载安装之后记得一定要点击&#xff1a;Apply & Close&#xff0c;保存设置) 使用

Transactional outbox pattern

文章目录 Transactional outbox pattern事件驱动架构(Event Driven Architecture, EDA)数据库事务和消息发布的一致性问题Transactional outbox如何解决数据事务和消息发布之间的一致性问题如何实现Transactional outbox pattern消息幂等性问题Transactional outbox pattern能保…