FreeRTOS基础(六):中断管理

        在嵌入式系统开发中,中断管理是一个至关重要的概念。它允许我们的系统能够及时响应外部事件,而不需要通过轮询的方式来浪费宝贵的处理器资源。FreeRTOS作为一款广泛应用的实时操作系统,它提供了灵活且高效的中断管理机制,可以帮助我们更好地处理这些外部事件。

目录

一、什么是中断?

1.1 中断的概念       

1.2 中断执行机制

1.3 Cortex-M4的中断资源

         1.4 两个重要的内核中断

1.4.1 PendSV中断

1.4.2 Systick

二、中断优先级分组设置(熟悉)

2.1 外部中断

2.2 内部中断

2.3 中断优先级分组设置

 2.3.1 优先级分组概念    

 2.3.1 FreeRTOS优先级分组配置

 2.3.2 特点

三、中断相关寄存器(熟悉)

3.1 系统中断优先级配置寄存器

3.2 FreeRTOS如何配置PendSV和Systick中断优先级?

3.2 中断屏蔽寄存器

四、FreeRTOS中断管理实验(掌握)​编辑


一、什么是中断?

1.1 中断的概念       

        让CPU打断正常运行的程序,转而去处理紧急的事件(中断服务函数ISR),当中断事件处理完毕后,处理器可以恢复到中断前的状态,继续执行之前的程序,就叫中断。

1.2 中断执行机制

        中断执行机制,可简单概括为三步:

1.3 Cortex-M4的中断资源

        Cortex-M4内核支持256个中断,包含16个系统(内核)中断和240个外部中断。但是芯片厂商⼀般不会把内核的这些资源全部用完。经过裁剪得到自己厂家的芯片。内核中断如下所示:

经过裁剪,STM32F407具有82个可屏蔽中断通道。10个系统中断,如下图所示:

1.4 两个重要的内核中断

1.4.1 PendSV中断

        在FreeRTOS中,PendSV(Pended System Service Call)是一种专门的中断,用于任务切换。它是Cortex-M系列处理器(如ARM Cortex-M3、M4、M7等)提供的一种系统级中断,其优先级最低,以确保它只在所有其他中断处理完毕后才执行

PendSV的作用:

        PendSV的主要作用是实现上下文切换,即从一个任务切换到另一个任务。这是FreeRTOS实现多任务调度的核心机制之一。具体来说,当需要进行任务切换时,FreeRTOS会设置PendSV中断挂起(pend),以便在下一个合适的时间点执行任务切换。

PendSV的优点

  1. 优先级最低:由于PendSV中断的优先级最低,确保了它不会打断任何其他正在处理的中断,从而保证了系统的稳定性和中断处理的完整性。

  2. 简化任务切换:使用PendSV中断进行任务切换简化了操作系统内核的设计,因为任务切换逻辑被集中在一个统一的中断服务例程中。

  3. 效率高:PendSV中断通过硬件机制实现,效率高且开销小,适用于实时操作系统的需求。

1.4.2 Systick

        在FreeRTOS中,SysTick(系统定时器)是一种用于实现系统节拍(tick)的定时器。它是ARM Cortex-M系列处理器中的一个内置定时器,用于提供周期性中断,从而驱动操作系统的时钟节拍。这种周期性中断对操作系统的调度器至关重要,因为它决定了任务的时间片、延时操作和其他时间相关的功能。

SysTick的作用

  1. 生成系统节拍(tick)中断:SysTick定时器周期性地产生中断信号,每次中断称为一个"tick"。这个节拍频率通常被配置为1毫秒一次,但可以根据需要进行调整。

  2. 驱动调度器:每个tick中断都会触发FreeRTOS调度器的运行,检查是否有需要调度的任务。例如,如果一个任务的延时时间结束,调度器会将其状态从阻塞(blocked)变为就绪(ready)。

  3. 时间管理:SysTick中断用于实现FreeRTOS中的各种时间管理功能,如任务延时(vTaskDelay)、定时器服务(software timers)、和时间片轮转(time slicing)等。

SysTick的工作流程

  1. 初始化SysTick:在系统启动时,FreeRTOS会配置SysTick定时器的频率,使其以设定的周期产生中断。这个配置通常在FreeRTOS的初始化代码中完成。

  2. 产生中断:SysTick定时器按照设定的周期(例如,每1毫秒)产生中断信号。

  3. 中断处理:每次SysTick中断发生时,处理器会跳转到SysTick中断服务例程(ISR)。在FreeRTOS中,SysTick中断服务例程通常会调用xPortSysTickHandler()函数。

  4. 调度任务:在SysTick中断服务例程中,FreeRTOS的调度器会执行任务调度逻辑,包括检查延时任务、管理时间片、更新系统时钟等。如果有需要切换的任务,会通过PendSV中断来进行上下文切换。

       SysTick在FreeRTOS中扮演着关键角色,它通过周期性中断驱动操作系统的时钟节拍,使得任务调度、延时管理和时间片轮转等功能得以实现。利用Cortex-M系列处理器内置的SysTick定时器,FreeRTOS能够高效且准确地管理系统时间,确保实时操作系统的各项功能正常运行。 

二、中断优先级分组设置(熟悉)

2.1 外部中断

      Cortex-M处理器有多个用于管理中断的可编程寄存器。这些寄存器大多数在NVIC(嵌套向量中断控制器,每个中断通道都拥有16个可编程的优先等级,可对优先级进行分组。)和系统控制 块(SCB)中。

       IP [240](Interrupt Priority Registers):中断优先级控制寄存器组。由240个8bit的寄存器组成,每个可屏蔽中断占⽤8bit。由于我们只有82个可屏蔽中断通道,因此我们只⽤IP[81] - IP[0]这82个。并且,每个中断通道占用的 8bit并没有全部使用,而是只用了高4位。我们知道STM32的中断资源由NVIC来统⼀管理,而每个中断的优先级是由优先级寄存器IP 控制的,并且每⼀个8bit的寄存器对应⼀个中断。但是,只占用了高四位。 然后我们对这4位又进行了划分,分为高n位的抢占优先级和低4-n位的响应优先级。NVIC里面的中断优先级控制寄存器组IP可以对所有的外部中断进行优先级设置。

2.2 内部中断

       在ARM Cortex-M处理器中,系统处理优先级(System Handler Priority, SHP)寄存器用于设置系统异常/内核中断(如硬故障、SVCall、SysTick等)的优先级。SHP寄存器是ARM Cortex-M处理器内核的一部分,不是FreeRTOS特有的。它们用于配置特定系统异常/内部中断的优先级

2.3 中断优先级分组设置

 2.3.1 优先级分组概念    

       学过裸机开发,我们知道 ARM Cortex-M 使用了 8 位宽的寄存器来配置中断的优先等级(0-255),这个寄存器就是中断优先级配置寄存器IP,但STM32,只用了中断优先级配置寄存器的高4位 [7 : 4],所以STM32提供了最大16级的中断优先等级注意:中断优先级数值越小,优先级越高。

STM32 的中断优先级可以分为抢占优先级和响应优先级 :

  1. 抢占优先级: 抢占优先级高的中断可以打断正在执行但抢占优先级低的中断。
  2. 响应优先级:当同时发生具有相同抢占优先级的两个中断时,子优先级数值小的优先执行,如果两个相同抢占优先级的中断不是同时发生,那么是不会发生抢占的,等先发生中断的执行完,才会去执行后来的中断。

2.3.1 FreeRTOS优先级分组配置

           一共有 5 种分配方式,对应着中断优先级分组的 5 个组 :

2.3.2 特点

1低于configMAX_SYSCALL_INTERRUPT_PRIORITY优先级(也就是处于5-15优先级)的中断里才允许调用FreeRTOS 的API函数;FreeRTOS能管理的最高的优先级。

2、建议将所有优先级位指定为抢占优先级位,方便FreeRTOS管理。

(调用函数)
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);

3、中断优先级数值越小越优先,任务优先级数值越大越优先。

三、中断相关寄存器(熟悉)

3.1 系统中断优先级配置寄存器

     在系统控制块SCB结构体存在一个系统处理优先级(System Handler Priority, SHP)寄存器用于设置系统异常/内核中断(如硬故障、SVCall、SysTick等)的优先级。SHP寄存器是ARM Cortex-M处理器内核的一部分,不是FreeRTOS特有的。它们用于配置特定系统异常/内部中断的优先级。

       四个8位的寄存器组成⼀个32位的寄存器,所以,pendsv和systick的控制寄存器为:0XE000ED20 的次⾼8位和⾼8位。

3.2 FreeRTOS如何配置PendSV和Systick中断优先级?

  1. #define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY :此宏⽤来设置Free RTOS系 统可管理的最⼤优先级。⾼于此宏设置的优先级不受Free RTOS的管理。
  2. #define configKERNEL_INTERRUPT_PRIORITY⽤来设置内核中断优先级:PendSV 和 SYSTICK的中断优先级 (左移4位是因为:中断优先级IP只有⾼4位有效) 

      通过上述配置,将PendSV和SysTick设置中断优先级中的最低优先级,设置最低:保证系统任务切换不会阻塞系统其他中断的响应,为什么?中断是非常紧急的事情,也就是说中断可以打断任意的任务,而任务不可以打断中断,PendSV就是用来处理任务切换的,因此要把PendSV任务切换中断的优先级配置为最低优先级。

3.2 中断屏蔽寄存器

      三个中断屏蔽寄存器,分别为 PRIMASK、 FAULTMASK 和BASEPRI

      FreeRTOS所使用的中断管理就是利用的BASEPRI这个寄存器!!BASEPRI屏蔽优先级低于某一个阈值的中断。比如: BASEPRI设置为0x50,代表中断优先级在5~15内的均被屏蔽,0~4的中断优先级正常执行

BASEPRI:屏蔽优先级低于某一个阈值的中断,当设置为0时,则不关闭任何中断,也就是任何中断都可以响应。

关中断程序示例: 

中断优先级在5 ~ 15中断全部关闭,而中断优先级在0-4的中断不会受影响!

FreeRTOS中断管理就是利用BASEPRI寄存器实现的,屏蔽掉一定范围内的中断!

四、FreeRTOS中断管理实验(掌握)

定时器6和定时器7的初始化配置 

#include "stm32f4xx.h"                  // Device header
#include "mytim.h"
#include "stdio.h"/************配置基本定时器6和基本定时器7**************/
void Interrupt_Init(void)
{//1.开启TIM时钟 RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM6,ENABLE); //开启时钟使能RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM7,ENABLE); //开启时钟使能//设置中断优先级分组(FreeRTOS利用的是抢占式调度)NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);//2.配置中断,配置NVICNVIC_InitTypeDef Struct;Struct.NVIC_IRQChannel = TIM6_DAC_IRQn;Struct.NVIC_IRQChannelCmd =ENABLE;Struct.NVIC_IRQChannelPreemptionPriority = 6;   //基本定时器6抢占优先级6Struct.NVIC_IRQChannelSubPriority = 0;           //基本定时器6响应优先级0NVIC_Init(&Struct); NVIC_InitTypeDef Struct1;Struct1.NVIC_IRQChannel = TIM7_IRQn;Struct1.NVIC_IRQChannelCmd =ENABLE;Struct1.NVIC_IRQChannelPreemptionPriority = 4; //基本定时器7抢占优先级4Struct1.NVIC_IRQChannelSubPriority = 0;       //基本定时器7响应优先级0NVIC_Init(&Struct1); //3.配置TIM(时基单元)TIM_TimeBaseInitTypeDef Struct2;Struct2.TIM_Period = 9999;        //自动重载寄存器ARR:定时1秒Struct2.TIM_Prescaler = 8399;      //预分频器PSCTIM_TimeBaseInit(TIM6,&Struct2);  //初始化时基单元TIM_TimeBaseInitTypeDef Struct3;Struct3.TIM_Period = 9999;        //自动重载寄存器ARR:定时1秒Struct3.TIM_Prescaler = 8399;      //预分频器PSCTIM_TimeBaseInit(TIM7,&Struct3);  //初始化时基单元TIM_ITConfig(TIM6,TIM_IT_Update,ENABLE); //定时中断配置 TIM_Cmd(TIM6,ENABLE);                  //使能定时器TIM_ITConfig(TIM7,TIM_IT_Update,ENABLE); //定时中断配置 TIM_Cmd(TIM7,ENABLE);                  //使能定时器
}//4.重写定时器6中断服务函数
void TIM6_DAC_IRQHandler(void) 
{if(TIM_GetITStatus(TIM6,TIM_IT_Update) == SET){//具体实现printf("TIM6优先级为6的定时器正在运行!\n");TIM_ClearITPendingBit(TIM6,TIM_IT_Update);  //清除中断标志位} 
}//4.重写定时器7中断服务函数
void TIM7_IRQHandler(void) 
{if(TIM_GetITStatus(TIM6,TIM_IT_Update) == SET){//具体实现printf("TIM7优先级为4的定时器正在运行!!!!\n");TIM_ClearITPendingBit(TIM7,TIM_IT_Update);  //清除中断标志位} 
}

创建任务及实现任务函数:

#include "stm32f4xx.h"                  // Device header
#include "stdio.h"
#include "FreeRTOS.h"
#include "task.h"
#include "dynamic.h"
#include "mydelay.h"/**********************START_TASK任务配置******************************/
/***********包括任务堆栈大小、任务优先级、任务句柄、创建任务***********/#define        START_TASK_STACK_SIZE  128   //定义堆栈大小为128字(1字等于4字节)
#define        START_TASK_PRIO         1    //定义任务优先级,0-31根据任务需求
TaskHandle_t   start_task_handler;    //定义任务句柄(结构体指针)
void start_task(void* args);/**********************TASK1任务配置******************************/
/***********包括任务堆栈大小、任务优先级、任务句柄、创建任务***********/
#define  TASK1_STACK_SIZE  128            //定义堆栈大小为128字(1字等于4字节)
#define  TASK1_PRIO         2             //定义任务优先级,0-31根据任务需求
TaskHandle_t   task1_handler;           //定义任务句柄(结构体指针)
void task1(void* args);/*********开始任务用来创建一个任务,只创建一次,不能是死循环,创建完这个任务后删除开始任务本身***********/
void start_task(void* args)
{taskENTER_CRITICAL();        /*进入临界区*/xTaskCreate( (TaskFunction_t)         task1,(char *)     "task1",  ( configSTACK_DEPTH_TYPE)   TASK1_STACK_SIZE,(void *)      NULL,(UBaseType_t) TASK1_PRIO ,(TaskHandle_t *)  &task1_handler );vTaskDelete(NULL);    //删除开始任务自身,传参NULLtaskEXIT_CRITICAL();   /*退出临界区*///临界区内不会进行任务的调度切换,出了临界区才会进行任务调度,抢占式						
}/********任务1的任务函数,无返回值且是死循环***********//***任务1:实现LED0每500ms翻转一次*******/
void task1(void* args)
{uint8_t task1_num=0;while(1){if(++task1_num==5){task1_num=0;printf("关中断!\n");portDISABLE_INTERRUPTS();   //将BASEPRI寄存器设置为5My_Delay_s(5);         // 这里不能调用vTaskDelay(5000); 因为:这个函数内部调用的是临界区保护,将将BASEPRI寄存器设置为0,也就是打开中断,关了又开无法看到实验效果printf("开中断!!!\n");portENABLE_INTERRUPTS();  //将BASEPRI寄存器设置为0,打开中断}vTaskDelay(1000);       //FreeRTOS自带的延时函数,延时1秒}}//FreeRTO入口例程函数,无参数,无返回值
void freertos_demo(void)
{xTaskCreate( (TaskFunction_t)     start_task,(char *)     "start_task",  ( configSTACK_DEPTH_TYPE)   START_TASK_STACK_SIZE,(void *)      NULL,(UBaseType_t) START_TASK_PRIO ,(TaskHandle_t *)  &start_task_handler );vTaskStartScheduler();  //开启任务调度器}

主函数调用入口函数,操作系统开始进行任务的切换和调度

#include "stm32f4xx.h"                  // Device header
#include "stdio.h"
#include "myled.h"
#include "mykey.h"
#include "myusart.h"
#include "mytim.h"#include "FreeRTOS.h"
#include "task.h"
#include "dynamic.h"extern TaskHandle_t Start_Handle;int main(void)
{//硬件初始化My_UsartInit();LED_Init();KEY_Init();Interrupt_Init();//调用入口函数freertos_demo();}

       本实验创建了两个定时器中断,每隔1秒打印字符串,并且一个定时器中断的优先级在FreeRTOS的管理范围之内,另一个不在FreeRTOS的管理范围之内,这样就可以验证中断管理函数的作用!一开始,两个定时器每隔1秒打印相应的字符串,各自运行5次后,关闭中断,那么定时器6中断就会被屏蔽,因此它不会打印,但定时器7不会受影响,定时器7打印5次后,再打开中断,这时那么定时器6中断就会被打开,两个定时器每隔1秒打印相应的字符串,依次循环往复运行!

至此,中断管理就已经讲解完毕!初次学习,循序渐进,一步步掌握即可!以上就是全部内容!请务必掌握,创作不易,欢迎大家点赞加关注评论,您的支持是我前进最大的动力!下期再见!

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

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

相关文章

搭建基于Django的博客系统增加广告轮播图(三)

上一篇:ChatGPT搭建博客Django的web网页添加用户系统(二) 下一篇:搭建基于Django的博客系统数据库迁移从Sqlite3到MySQL(四) 功能概述 增加轮播图显示广告信息。 需求详细描述 1. 增加轮播图显示广告信…

STM32(九):USART串口通信 (标准库函数)

前言 上一篇文章已经介绍了如何用STM32单片机中独立看门狗来实现检测按键点灯的程序。这篇文章我们来介绍一下如何用STM32单片机中USART通信协议来串口通信,并向XCOM发送信息。 一、实验原理 1.通信的介绍 首先,我们先介绍一下通信,何为通…

嵌入式linux系统中图片处理详解

大家好,今天给大家分享一下,嵌入式中如何进行图像处理,常见的处理方式有哪几种?这次将详细分析一下 第一:BMP图形处理方式 图形的基本特点,所有的图像文件,都是一种二进制格式文件,每一个图像文件,都可以通过解析文件中的每一组二进制数的含义来获得文件中的各种信息…

DataCube 漏洞小结

在这里分享一下通过拖取 DataCube 代码审计后发现的一些漏洞,包括前台的文件上传,信息泄露出账号密码,后台的文件上传。当然还有部分 SQL 注入漏洞,因为 DataCube 采用的是 SQLite 的数据库,所以SQL 注入相对来说显得就…

海外高清短视频:四川京之华锦信息技术公司

海外高清短视频:探索世界的新窗口 在数字化时代的浪潮下,海外高清短视频成为了人们探索世界、了解异国风情的新窗口。四川京之华锦信息技术公司这些短视频以其独特的视角、丰富的内容和高清的画质,吸引了无数观众的目光,让人们足…

关于前端代码移动端的适配方案

为什么需要适配? 由于PC端和移动端的分辨率不同,前端展示的页面在两端设备如果原模原样的搬运则会导致PC端或移动端看到的画面相对于其设备的分辨率及其的不合理。 最为常见的是PC端正常浏览的网页没有做移动端适配,由于移动端分辨率普遍低于…

ChaosBlade混沌测试实践

ChaosBlade: 一个简单易用且功能强大的混沌实验实施工具 官方仓库:https://github.com/chaosblade-io/chaosblade 1. 项目介绍 ChaosBlade 是阿里巴巴开源的一款遵循混沌工程原理和混沌实验模型的实验注入工具,帮助企业提升分布式系统的容错能力&…

【CVE-2021-3156】——漏洞复现、原理分析以及漏洞修复

文章目录 前言1、漏洞概述2、漏洞复现2.1、漏洞复现测试环境2.2、漏洞复现具体步骤 3、漏洞原理3.1、前置知识3.1.1、sudo3.1.2、sudoedit3.1.3、转义字符 3.2、漏洞分析 4、漏洞修复5、参考文献总结 前言 2021年01月27日,RedHat官方发布了Sudo缓冲区/栈溢出漏洞的风…

基于SSM前后端分离版本的论坛系统-自动化测试

目录 前言 一、测试环境 二、环境部署 三、测试用例 四、执行测试 4.1、公共类设计 创建浏览器驱动对象 测试套件 释放驱动类 4.2、功能测试 注册页面 登录页面 版块 帖子 用户个人中心页 站内信 4.3、界面测试 注册页面 登录页面 版块 帖子 用户个人中心页…

【Qt秘籍】[005]-Qt的首次邂逅-创建

一、如何创建文件? 当我们打开Qt Creator,你会发现整个界面类目繁多。现在,让我们直接开始新建一个项目。 1.点击左上角的“文件”>点击“新建文件或项目” 2.如图,选择“Application”>“Qt Wifgets application”> “…

奇偶校验位

描述 题目描述: 现在需要对输入的32位数据进行奇偶校验,根据sel输出校验结果(1输出奇校验,0输出偶校验) 信号示意图: 波形示意图: 输入描述: 输入信号 bus sel 类型 wi…

rust安装

目录 一、安装1.1 在Windows上安装1.2 在Linux下安装 二、包管理工具三、Hello World3.1 安装IDE3.2 输出Hello World 一、安装 1.1 在Windows上安装 点击页面 安装 Rust - Rust 程序设计语言 (rust-lang.org),选择"下载RUSTUP-INIT.EXE(64位)&qu…

2021JSP普及组第三题:插入排序

2021JSP普及组第三题 题目: 思路: 题目要求排序后根据操作进行对应操作。 操作一需要显示某位置数据排序后的位置,所以需要定义结构体数组储存原数据的位置和数据本身排序后所得数据要根据原位置输出排序后的位置,所以建立一个新…

Linux网络编程:应用层协议|HTTPS

目录 1.预备知识 1.1.加密和解密 1.2.常见加密方式 1.2.1.对称加密 1.2.2.非对称加密 ​编辑 1.3.数据摘要(数据指纹)和数据签名 1.4.证书 1.4.1.CA认证 1.4.2.证书和数字签名 2.HTTPS协议 2.1.自行设计HTTPS加密方案 2.1.1.只使用对称加密 …

构建企业级AI私有知识库

一、引言 在当今竞争激烈的市场环境中,企业为了保持竞争优势,需要高效地管理和利用内部知识资源。构建一个企业级AI私有知识库,不仅可以集中存储和管理企业知识,还能通过人工智能技术实现知识的智能化处理和利用。本文将详细介绍…

软考系统集成项目管理工程师第7章思维导图发布

2024年开年,软考系统集成项目管理工程师官方教程,迎来了阔别7年的大改版,改版之后的软考中项考试,离同宗兄弟高项考试渐行渐远。 中项第3版教程,仅仅从教程来看,其难度已经不亚于高级的信息系统项目管理师&…

WebGL开发三维家装设计

使用WebGL开发三维家装设计软件是一项复杂而有趣的任务,涉及3D建模、渲染、用户交互等多个方面。以下是详细的开发步骤和技术要点。北京木奇移动技术有限公司,专业的软件外包开发公司,欢迎交流合作。 1. 需求分析 目标用户 家装设计师家装公…

AVL树(C++)

文章目录 1. 键值对2. AVL树2.1 AVL树的概念2.2 AVL树节点的定义2.3 AVL树的插入2.3.1 按照二叉搜索树的方式插入新节点2.3.2 调整节点的平衡因子 2.4 AVL树的旋转2.4.1 右单旋2.4.2 左单旋2.4.3 左右双旋2.4.4 右左双旋 3. AVL树的删除4. AVL树的验证4. 源码 1. 键值对 键值对…

用follow.it为您的网站添加邮箱订阅功能(附2024版教程)

多数情况下网站用户浏览一次就不会来了(即使用户已收藏您的网站),因为用户很可能已把您的网站忘了。那么怎么样才能抓住网站回头客,让用户再次回到您的网站呢?除了提供更优质的原创内容外,比较好的方法是给…

笔试强训week7

day1 Q1 难度⭐⭐ 旋转字符串_牛客题霸_牛客网 (nowcoder.com) 题目: 字符串旋转: 给定两字符串A和B,如果能将A从中间某个位置分割为左右两部分字符串(可以为空串),并将左边的字符串移动到右边字符串后面组成新的…