TencentOS tiny 移植到STM32F103教程

news2024/9/25 1:22:56

一、移植前的准备工作

1. STM32的裸机工程模板

这个可以自己创建(创建过程参考之前的STM32裸机工程也有工程网盘在上面)

2.下载TencentOS tiny 源码

TencentOS tiny的源码可从TencentOS tiny GitHub仓库地址https://github.com/Tencent/TencentOS-tiny下载,如果GitHub下载慢,也可以通过腾讯工蜂开源仓下载,地址:https://git.code.tencent.com/Tencent_Open_Source/TencentOS-tiny

3.TencentOS tiny源码核心文件夹分析

打开TencentOS tiny源码文件,可以看见里面有12个文件夹,下面先来了解主要文件夹及其子文件夹的作用,然后将TencentOS tiny源码的核心文件提取出来,添加到工程根目录下的文件夹中,因为工程只需要有用的源码文件,而不是全部的TencentOS tiny源码,所以可以避免工程过于庞大。

一级目录

二 / 三级目录

说明

arch

arm

TencentOS tiny适配的IP核架构(含M核中断、调度、tick相关代码),对我们的移植很重要

arch

risc-v

TencentOS tiny适配的risc-v架构

board

TencentOS_tiny_EVB_MX

TencentOS tiny 定制开发板demo,包含AT适配框架、MQTT协议、安全组件等

component

connectivity / loraWAN

loRaWAN协议栈实现源码及适配层

connectivity / Eclipse-Paho-MQTT

MQTT协议栈实现源码及适配层

connectivity / TencentCloud_SDK

腾讯云C-SDK实现源码及适配层

fs

文件系统实现源码

security

mbedtls 安全协议源码

utils

包含json相关源码

devices

TencentOS tiny适配的一些外设驱动(如串口wifi gprs 驱动等)

doc

TencentOS tiny相关技术文档及开发指南(建议多看这部分)

examples

TencentOS tiny提供的功能示例

kernel

core

TencentOS tiny内核源码(这部分是最重要的)

hal

TencentOS tiny驱动抽象层

pm

TencentOS tiny低功耗模块源码

net

at

TencentOS tiny为串口类通信模组提供的AT框架实现层

lwip

TencentOS tiny为串口类LoraWAN模块提供的移植框架

sal_module_wrapper

Lwip协议实现源码及适配层

tencent_firmware_module_wrapper

TencentOS tiny为串口类网络模块(wifi gprs)提供的socket移植框架

tencent_firmware_module_wrapper

TencentOS tiny提供的腾讯定制模组移植框架

osal

cmsis_os

TencentOS tiny提供的cmsis os 适配

platform

hal

TencentOS tiny适配的部分芯片的驱动实现源码

vendor_bsp

芯片厂家提供的原厂bsp固件库,如STM32的HAL库

test

存放TencentOS tiny提供的一些测试代码,含内核及上层模块示例及测试代码

tools

存放TencentOS tiny提供的工具,小程序,配置工具等

简单提一下我们的重点文件夹:

*arch: TencentOS tiny是软件,单片机是硬件,为了使TencentOS tiny运行在单片机上面,TencentOS tiny和单片机必须关联在一起,那么如何关联呢?还是要通过代码来关联,这部分关联的文件叫接口文件,通常由汇编语言和C语言联合编写。这些接口文件都是跟硬件密切相关的,不同的硬件接口文件是不一样的,但都大同小异。

*TencentOS tiny在arch\arm\arm-v6m目录中存放了cortex m0内核的单片机的接口文件,在arch\arm\arm-v7m目录中存放了cortex m3、m4和m7内核的单片机的接口文件,以及一些通用的接口文件,基于这些内核的mcu都可以使用里面的接口文件。

*kernelkernel是TencentOS tiny内核核心源码,它的重要性我也不用多说,毕竟整个内核就是由这里面的文件组成,而其他文件夹都是基于内核的组件。

*config:board就是TencentOS tiny为一些常用开发板开发的demo文件夹,其内有各个工程的配置文件,选一个与移植芯片最相机的开发板,找到它的配置文件tos_config.h,比如我们可以选择:TencentOS-tiny\board\STM32F103_SIM800A\TOS-CONFIG

这个配置文件很重要,后续在移植工程时,我们需要对这个配置文件进行修改,这样子可以裁剪TencentOS tiny的功能,得到最适合的工程配置。

这个congfig就是FreeRTOS一样,可以根据自己需求配置

所以我们需要以上分析的这三个文件

二、开始移植

第一步:创建文件夹TencentOS-tiny,将所有下载代码都添加进来

第二步:先创建文件夹TOS-CONFIG,用于存放TencentOS tiny的配置头文件,头文件后面在放

第三步:创建文件夹,添加文件
第四步:添加源码

(1)tos/kemel添加,从该路径TencentOS-tiny\kernel\core将源码添加进来

(2)添加arch平台代码

*1)从该路径TencentOS-tiny\arch\arm\arm-v7m\common将tos_cpu.c添加进来

tos_cpu.c是TencentOS tiny 的CPU适配文件,包括堆栈初始化,中断适配等,如果您的芯片是ARM Cortex M核,该文件可以不做改动,M0、M3 、M4、M7是通用的,其他IP核需要重新适配;

*2)从该路径TencentOS-tiny\arch\arm\arm-v7m\cortex-m3\armcc将port_c.c、port_s.S添加进来

port_s.S 文件是TencentOS tiny的任务调度汇编代码,主要做弹栈压栈等处理的,

port_c.c适配systick等

我们这边STM32F103是M3内核所以路径选择的是cortex-m3

这两个文件 每个IP核和编译器都是不一样的,如果您的芯片是ARM Cortex M核,我们都已经适配好

*3)从该路径TencentOS-tiny\board\TencentOS_Tiny_EVB_STM32WL\TOS_CONFIG将tos_config.h复制起来,这里随便选了一个例程的tos_config.h复制,我们把它复制到先前创建的TOS-CONFIG文件夹里面,后面在做修改。

因为这个配置文件很重要,后续在移植工程时,我们需要对这个配置文件进行修改,这样子可以裁剪TencentOS tiny的功能,得到最适合的工程配置

*4)从该路径TencentOS-tiny\osal\cmsis_os将cmsis_os.c添加进来

cmsis os是TencentOS tiny为了兼容cmsis标准而适配的OS抽象层,可以简化大家将业务从其他RTOS迁移到TencentOS tiny的工作量。

第五步:添加TencentOS tiny头文件目录

第六步:修改config.h

修改前:

#ifndef _TOS_CONFIG_H_
#define  _TOS_CONFIG_H_

#include "stm32wlxx.h"

#define TOS_CFG_TASK_PRIO_MAX     10u// 配置TencentOS tiny默认支持的最大优先级数量

#define TOS_CFG_ROUND_ROBIN_EN      0u// 配置TencentOS tiny的内核是否开启时间片轮转

#define TOS_CFG_OBJECT_VERIFY_EN   1u// 配置TencentOS tiny是否校验指针合法

#define TOS_CFG_TASK_DYNAMIC_CREATE_EN   0u// TencentOS tiny 动态任务创建功能宏

#define TOS_CFG_EVENT_EN        1u// TencentOS tiny 事件模块功能宏

#define TOS_CFG_MMBLK_EN        1u// 配置TencentOS tiny是否开启内存块管理模块

#define TOS_CFG_MMHEAP_EN       1u// 配置TencentOS tiny是否开启动态内存模块

#define TOS_CFG_MMHEAP_DEFAULT_POOL_EN     1u// TencentOS tiny 默认动态内存池功能宏

#define TOS_CFG_MMHEAP_DEFAULT_POOL_SIZE   0x8000// 配置TencentOS tiny默认动态内存池大小

#define TOS_CFG_MUTEX_EN      1u// 配置TencentOS tiny是否开启互斥锁模块


#define TOS_CFG_MESSAGE_QUEUE_EN        1u// 配置TencentOS tiny是否开启消息队列模块

#define TOS_CFG_MAIL_QUEUE_EN      1u// 配置TencentOS tiny是否开启消息邮箱模块

#define TOS_CFG_PRIORITY_MESSAGE_QUEUE_EN    1u// 配置TencentOS tiny是否开启优先级消息队列模块

#define TOS_CFG_PRIORITY_MAIL_QUEUE_EN        1u// 配置TencentOS tiny是否开启优先级消息邮箱模块

#define TOS_CFG_TIMER_EN             1u// 配置TencentOS tiny是否开启软件定时器模块

#define TOS_CFG_PWR_MGR_EN         0u// 配置TencentOS tiny是否开启外设电源管理模块

#define TOS_CFG_TICKLESS_EN       0u// 配置Tickless 低功耗模块开关

#define TOS_CFG_SEM_EN           1u// 配置TencentOS tiny是否开启信号量模块

#define TOS_CFG_TASK_STACK_DRAUGHT_DEPTH_DETACT_EN 1u// 配置TencentOS tiny是否开启任务栈深度检测

#define TOS_CFG_FAULT_BACKTRACE_EN     0u// 配置TencentOS tiny是否开启异常栈回溯功能

#define TOS_CFG_IDLE_TASK_STK_SIZE    128u// 配置TencentOS tiny空闲任务栈大小

#define TOS_CFG_CPU_TICK_PER_SECOND     1000u// 配置TencentOS tiny的tick频率

#define TOS_CFG_CPU_CLOCK   (SystemCoreClock)// 配置TencentOS tiny CPU频率

#define TOS_CFG_TIMER_AS_PROC      1u// 配置是否将TIMER配置成函数模式

#endif

修改后:

#ifndef _TOS_CONFIG_H_
#define  _TOS_CONFIG_H_

#include "stm32f10x.h"

#define TOS_CFG_TASK_PRIO_MAX     10u// 配置TencentOS tiny默认支持的最大优先级数量

#define TOS_CFG_ROUND_ROBIN_EN       1u// 配置TencentOS tiny的内核是否开启时间片轮转

#define TOS_CFG_OBJECT_VERIFY_EN     1u// 配置TencentOS tiny是否校验指针合法

#define TOS_CFG_TASK_DYNAMIC_CREATE_EN    1u// TencentOS tiny 动态任务创建功能宏

#define TOS_CFG_EVENT_EN           1u// TencentOS tiny 事件模块功能宏

#define TOS_CFG_MMBLK_EN            1u// 配置TencentOS tiny是否开启内存块管理模块

#define TOS_CFG_MMHEAP_EN      1u// 配置TencentOS tiny是否开启动态内存模块

#define TOS_CFG_MMHEAP_DEFAULT_POOL_EN    1u// TencentOS tiny 默认动态内存池功能宏

#define TOS_CFG_MMHEAP_DEFAULT_POOL_SIZE    0x200// 配置TencentOS tiny默认动态内存池大小

#define TOS_CFG_MUTEX_EN   1u// 配置TencentOS tiny是否开启互斥锁模块


#define TOS_CFG_MESSAGE_QUEUE_EN    1u// 配置TencentOS tiny是否开启消息队列模块

#define TOS_CFG_MAIL_QUEUE_EN    1u// 配置TencentOS tiny是否开启消息邮箱模块

#define TOS_CFG_PRIORITY_MESSAGE_QUEUE_EN    1u// 配置TencentOS tiny是否开启优先级消息队列模块

#define TOS_CFG_PRIORITY_MAIL_QUEUE_EN    1u// 配置TencentOS tiny是否开启优先级消息邮箱模块

#define TOS_CFG_TIMER_EN      1u// 配置TencentOS tiny是否开启软件定时器模块

#define TOS_CFG_PWR_MGR_EN      0u// 配置TencentOS tiny是否开启外设电源管理模块

#define TOS_CFG_TICKLESS_EN      0u// 配置Tickless 低功耗模块开关

#define TOS_CFG_SEM_EN    1u// 配置TencentOS tiny是否开启信号量模块

#define TOS_CFG_TASK_STACK_DRAUGHT_DEPTH_DETACT_EN  1u// 配置TencentOS tiny是否开启任务栈深度检测

#define TOS_CFG_FAULT_BACKTRACE_EN    0u// 配置TencentOS tiny是否开启异常栈回溯功能

#define TOS_CFG_IDLE_TASK_STK_SIZE    128u// 配置TencentOS tiny空闲任务栈大小

#define TOS_CFG_CPU_TICK_PER_SECOND    1000u// 配置TencentOS tiny的tick频率

#define TOS_CFG_CPU_CLOCK     (SystemCoreClock)// 配置TencentOS tiny CPU频率

#define TOS_CFG_TIMER_AS_PROC    1u// 配置是否将TIMER配置成函数模式

#endif

第七步:编译下

有重复定义的函数,注释PendSV_Handler()函数

鉴于TencentOS tiny已经处理好PendSV与SysTick中断了,就不需要用户自己去处理,所以要在中断相关的源文件(stm32f10x_it.c文件)中注释(或者删除PendSV_Handler()函数。

另外我们也把SysTick_Handler屏蔽掉,因为我们在另外建的BSP_SysTick_放置了SysTick_Handler

添加___weak关键字添加上去,变成弱定义即可

在编译下,编译通过!

第八步:编写SysTick_Handler()函数

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

在SysTick_Handler函数中添加TencentOS tiny的调度处理函数,然后在BSP_Systick.c文件中包含 tos_k.h 头文件

#include "BSP_SysTick.h"
#include "tos_k.h" 

//初始化延迟函数
//当使用OS的时候,此函数会初始化OS的时钟节拍
//SYSTICK的时钟固定为HCLK时钟的1/8
//SYSCLK:系统时钟
void BSP_SysTickInit()
{
    u32 reload;//装载次数
    /*滴答定时频率配置72MHZ,而心跳中断需要1ms中断一次,那么装载计数值->X = 0.0001s/(1/72000000) = 72000次  */
    SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK);//选择外部时钟  HCLK = SystemCoreClock = 72000000HZ
    reload=SystemCoreClock/1000000;                //reload = 72
    reload*=1000000/TOS_CFG_CPU_TICK_PER_SECOND;        //根据configTICK_RATE_HZ设定溢出时间 
                                                                                                    //reload为24位寄存器,最大值:16777216,在72M下,约合0.233s左右       
    SysTick->CTRL|=SysTick_CTRL_TICKINT_Msk;       //开启SYSTICK中断
    SysTick->LOAD=reload;                         //滴答定时频率72MHZ,72000*(1/72000000) = 1ms
    SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk;       //开启SYSTICK 
}

void SysTick_Handler(void)//1ms中断一次
{
     if (tos_knl_is_running())
  {
    tos_knl_irq_enter();
    tos_tick_handler();
    tos_knl_irq_leave();
  }
}

三、创建TencentOS tiny任务,测试移植结果

第一步:在mian.c 中添加TencentOS tiny 头文件,编写任务函数
#include "main.h"
#include "bsp_Stm32fx.h"
/* TencentOS头文件 */
#include "cmsis_os.h"

//task1
#define TASK1_STK_SIZE        256//任务栈大小
void task1(void *pdata);//任务函数
osThreadDef(task1, osPriorityNormal, 1, TASK1_STK_SIZE);//创建TASK1任务

//task2
#define TASK2_STK_SIZE        256//任务栈大小
void task2(void *pdata);//任务函数
osThreadDef(task2, osPriorityNormal, 1, TASK2_STK_SIZE);//创建TASK2任务



void BoardInit(void)
{
    //NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//裸机工程配置
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);//一旦一只哦操作系统需需要设置为中断分组4 
    BSP_SysTickInit();
    BSP_GpioInit();
    BSP_UartInit(115200);
}


int main(void)
{
    BoardInit();     BSP_SetLed0(0);     BSP_SetLed0(0);
    printf("Welcome to TencentOS tiny,CoreClock:%d\r\n",SystemCoreClock);  
    osKernelInitialize(); //TOS Tiny kernel initialize
  osThreadCreate(osThread(task1), NULL);// Create task1
  osThreadCreate(osThread(task2), NULL);// Create task2
  osKernelStart();//Start TOS Tiny
}


   void task1(void *pdata)
   {
       int count = 1;
       while(1)
       {
          printf("\r\nHello world!\r\n###This is task1 ,count is %d \r\n", count++);
               BSP_SetLed0(2);
           osDelay(2000);
       }
   }
   void task2(void *pdata)
   {
       int count = 1;
       while(1)
       {
           printf("\r\nHello TencentOS !\r\n***This is task2 ,count is %d \r\n", count++);
                    BSP_SetLed1(2);
           osDelay(1000);
       }
   }

// NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);切记,这个中断分组一定要设置成组4,设置成组4,总共变成了0-15级抢占优先级,就没有响应优先级了。

原来裸机工程默认将STM32的优先级分组配置为2,即4个抢占优先级、4个亚优先级。而freeRTOS的中断配置没有处理亚优先级这种情况,即要求全部为抢占优先级。所以STM32移植freeRTOS时,应将中断优先级配置为4,即16个抢占优先级。

第二步:编译工程

下载进去,查看现象

串口数据正常输出,证明两个任务都有跑,

但是确发现板载的LED灯没有闪烁运行,这个很奇怪

第三步:查找LED驱动问题

经过查找,我发现只有把 USE Micro LIB勾选起来,LED灯才会闪烁,很奇怪。

从理论上分析,USE Micro LIB勾选起来只是牺牲运行速度从而达到减小代码所占的空间跟这个GPIO没关系才对啊,我找不到答案。目前带线就是这个问题

附录:

针对第三步的问题,如果有小伙伴知道请评论区告诉我下,感谢,此次移植到此结束啦!

工程文件:

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

提取码:9ohw

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

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

相关文章

无人机动力测试台:150kg级-Flight Stand 150

“飞行汽车”被人们广泛视为下一代交通工具。从2022年初至今,eVTOL(电动垂直起降飞行器)产业乃至整个UAM(城市间空中交通)市场呈现爆发式增长——各国航空制造企业纷纷入局,不断有新产品问世、试飞或试运行…

吐血整理,web自动化测试,POM模式搭建自动化测试框架(超级详细)

目录:导读前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结(尾部小惊喜)前言 POM设计模式 主要是…

IO多路复用(select、poll、epoll网络编程)

目录一、高级IO相关1.1 同步通信和异步通信1.2 阻塞与非阻塞1.3 fcntl 函数二、五种IO模型2.1 阻塞式IO模型2.2 非阻塞式IO模型2.3 多路复用IO模型2.4 信号驱动式IO模型2.5 异步IO模型三、认识IO多路复用四、select4.1 认识select函数4.2 select函数原型4.3 select网络编程4.4 …

脂肪毒性的新兴调节剂——肠道微生物组

谷禾健康 肠道微生物组与脂质代谢:超越关联 脂质在细胞信号转导中起着至关重要的作用,有助于细胞膜的结构完整性,并调节能量代谢。 肠道微生物组通过从头生物合成和对宿主和膳食底物的修饰产生了大量的小分子。 最近的研究表明,由…

[计算机操作系统(第四版 汤小丹 汤子瀛)]第一章 操作系统引论(学习复习笔记)

操作系统(Operating System,OS)是配置在计算机硬件上的第一层软件,是对硬件系统的首次扩充。操作系统的主要作用: 管理硬件设备,提高他们的利用率和系统吞吐量 利用率:使硬件充分忙碌系统吞吐量…

MQTT协议-心跳请求和心跳响应

MQTT协议-心跳请求和心跳响应 心跳请求是客户端发送给服务器的,心跳响应是服务器回应给客户端的 作用是保持客户端与服务器之间的连接 CONNECT报文的可变报头是由协议名(Procotol Name)协议级别(Procotol Level)连接…

冰刃杀毒工具使用实验(29)

实验目的 (1)学习冰刃的基本功能; (2)掌握冰刃的基本使用方法;预备知识 windows操作系统的基本知识,例如:进程、网络、服务和文件等的了解。 冰刃是一款广受好评的ARK工…

MYSQL 中 ROW_NUMBER 的实现

由于mysql没有 row_number函数实现,然后我们后台表里没给可以排序的字段,考虑用mysql实现一个row_number, 由于想使用视图进行实时展示,但是row_number在视图中不生效,所有我们最后还是找了后台程序伙伴沟通加了排序字段。 row_nu…

MySQL的图形化界面开发工具DataGrip的下载安装

在日常的开发中,会借助于MySQL的图形化界面,来简化开发,提高开发效率。目前mysql主流的图形化界面工具,有Navicat、SQLyog、DataGrip等,最后一种DataGrip,这种图形化界面工具,功能更加强大&…

Android Framework-管理Activity和组件运行状态的系统进程—— ActivityManagerService(AMS)

ActivityManagerService(AMS)是Android提供的一个用于管理Activity(和其他组件)运行状态的系统进程 AMS功能概述 和WMS一样,AMS也是寄存于systemServer中的。它会在系统启动时,创建一个线程来循环处理客户…

uni-app中使用vue3语法详解

全局创建 app.use(createPina()).mount 全局方法 通过app.config.globalProperties.xxx可以创建 这里我们写了一个字符串翻转的全局方法 main.js里面添加一个全局方法 不要忘了加$ 否则会报错 // #ifdef VUE3 //导入创建app import { createSSRApp } from vue //导入创建ap…

数据结构刷题(二十一):131分割回文串、78子集

1.分割回文串题目链接思路:回溯算法的组合方法(分割问题类似组合问题)。流程图:红色竖杠就是startIndex。 for循环是横向走,递归是纵向走。回溯三部曲:递归函数参数:字符串s和startIndex&#…

Vue(10-20)

1Vue赋值方式 Object.defineProperty <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta http-equiv"X-UA-Compatible" content"IEedge"><meta name"viewport" conten…

如何从Outlook向Teams共享电子邮件

从 Outlook 或 web 上的 Outlook,你可以将电子邮件共享到Teams中的聊天和频道。 注意: 你必须具有“共享到Teams”的Outlook”加载项。它为Teams用户自动安装。此外,移动设备当前不支持该功能。外接程序当前不支持共享邮箱。如果你安装了Teams桌面客户端,并且使用的是Outl…

精、稳、敏、融,步入人民金融时代 | 易观银行业数字化转型年度趋势报告

易观分析&#xff1a;2022年&#xff0c;在深化金融供给侧结构性改革和高质量增长要求的指引下&#xff0c;赋能实体、公平普惠、审慎经营成为银行业转型发展的关键词。一方面面临内外部复杂的经济环境和不确定性风险&#xff0c;银行主打稳健策略&#xff0c;数字化转型仍在持…

软件测试用例篇(5)

测试是否运行代码去划分&#xff1f; 1)静态测试: 不运行代码&#xff0c;检查代码的风格&#xff0c;格式是否符合公司的标准规范&#xff0c;检查代码的逻辑结构是否满足需求要实现的功能 看代码&#xff0c;不运行代码&#xff0c;通过静态分析代码的语法&#xff0c;编写规…

谷歌Google Pixel6Pro/7pro手机刷入ROOT权限-开通Volte+破解5G网络高速刷机教程

谷歌pixel6和pixel7系列&#xff0c;出厂并不带volte功能&#xff0c;也不支持完美的5G效果&#xff0c;对于我们这种身处大陆&#xff0c;又想体验高清通话的小伙伴来说&#xff0c;并不友好&#xff0c;所以第三方破解实现就显得非常重要了。通过实际测试&#xff0c;两款机型…

Java 文件上传 MultipartFile RequestPart 方式上传 HttpClient

Java springboot/springCloud项目&#xff0c;后端接口是用RequestPart 注解MultipartFile类型和实体类型的参数&#xff0c;目的是同时提交文件和表单参数。前端调用方式&#xff1a;需要使用表单&#xff08;form-data&#xff09;方式进行提交&#xff0c;content-type设置为…

Hive排序,窗口函数

数据排序1&#xff0c;全局排序&#xff08;order by&#xff09;&#xff1a;类似于标准SQL&#xff0c;只使用一个Reducer执行全局数据排序&#xff1b;速度慢,应提前做好数据过滤 &#xff1b;支持使用case when或表达式&#xff1b;支持按位置编号排序desc升序&#xff0c;…

拉链表

每日的用户更新表获取的三种方式&#xff1a;一是监听mysql库数据的变化&#xff0c;比如用canal合并每日的变化&#xff0c;获取到最后的一个状态二是每天获得一份切片数据&#xff0c;可以通过去两天切片数据的不同来作为每日更新表&#xff0c;可以对所有字段先进性concat&a…