RH850 中断嵌套功能说明
1 背景说明
RH850使用CS+配置自动生成的代码,在进入中断程序后,通过观察中断寄存器,发现PSW.DI置为1,即EI全局中断关闭,在EI中断程序运行的时候,低优先级中断程序的运行无法被打断,从而导致更高优先级的中断程序无法抢占执行。
2 原因梳理
在《RH850F1K Group User Manual Hardware.pdf》手册的7.2.9.4 Interrupt Suspended by CPU章节,其中描述在产生中断应答后,PSW.ID标志会自动置1,该位在置1后,PSW.ID = 1的时候,所有的EI中断将会被屏蔽,即在中断中,所有的中断程序将会无法被响应。
具体参数如下原文描述:
因此,如果要使用中断嵌套功能,需要在进入中断后手动的使能中断。
注:此部分仅描述中断嵌套,针对中断优先级抢占,调度部分不做详细描述。
3 应对策略
按照官方文档,我们可以在中断后,手动的调用指令来使用EI中断,除了手动的方式外,各个编译器针对RH850在中断使能提供了相关的方案。
3.1 CS+编译器
在CS+编译器中,其在#pragma中断中提供相关配置属性项,其中enable属性用于配置中断嵌套。(参见CS+for CC--CC-RH 使用手册.pdf P316)
其语法结构如下:
enable参数的说明如下:
当配置为true的时候,其会产生代码去输出ei/di,并保存和恢复eipc/eipsw。
示例:
#ifdef __CSP__
#pragma interrupt r_uart2_interrupt_receive(enable=true, channel=166, fpu=true, callt=false)
void r_uart2_interrupt_receive(void)
#endif /* __CSP__ */
3.2 GHS编译器
在GHS编译器中,#pragma ghs 中断指令可以有参数来指示编译器以不同的方式生成中断例程序言和尾声的代码。 (参见MULTI:Building Applications for Embedded V850 and RH850 v2021.1.chm Using the MULTI Compiler->Developing for V850 and RH850-> Other Topics -> Interrupt Routines -> Interrupt Pragma Directive Parameters.)
其语法结构如下:
#pragma ghs interrupt([parameter])
其通过增加parameter来针对中断函数的行为控制。其中,参数“enabled”用于配置进入中断后针对中断控制的行为。其原文描述如下:
enabled: Interrupts are already disabled when an interrupt routine is called, and are enabled immediately when it returns. The compiler does not normally insert code to enable interrupts; this is left to the implementation of the interrupt routine. To instruct the compiler to insert code that enables interrupts early on in the interrupt function's prologue, pass the enabled parameter to #pragma ghs interrupt
即在#pramga ghs interrupt后面追加enabled参数后,其在生成代码时候会生成相关中插入使能中断的代码。
示例:
#ifdef __GHS__
#pragma ghs interrupt(enabled)
void INTRLIN32UR1(void)
#endif /* __GHS__ */
上一篇: c 中的占位符数据填充
下一篇: R 中的管道 %>%
推荐阅读
-
RH850 中断嵌套功能说明
-
freeertos 中的 PendSV 中断服务功能说明。
-
@Validated和@Valid区别-1.分组 @Validated:提供了一个分组功能,可以在入参验证时,根据不同的分组采用不同的验证机制。没有添加分组属性时,默认验证没有分组的验证属性。 伪代码如下: public interface First{ } public interface Second{ } public class UserModel { @NotNull(message = "{id.empty}", groups = { First.class }) private int id; @NotNull(message = "{username.empty}", groups = { First.class, Second.class }) private String username; @NotNull(message = "{content.empty}", groups = { First.class, Second.class }) private String content; } public String save(@Validated( { Second.class }) UserModel userModel, BindingResult result) { if (result.hasErrors) { return "validate/error"; } return "redirect:/success"; } 对一个参数需要多种验证方式时,也可通过分配不同的组达到目的。例: @NotEmpty(groups = { First.class }) @Size(min = 3, max = 8, groups = { Second.class }) private String name; 分组还支持组序列 默认情况下,不同组别的约束验证是无序的,然而在某些情况下,约束验证的顺序却很重要,如下面两个例子:(1)第二个组中的约束验证依赖于一个稳定状态来运行,而这个稳定状态是由第一个组来进行验证的。(2)某个组的验证比较耗时,CPU 和内存的使用率相对比较大,最优的选择是将其放在最后进行验证。因此,在进行组验证的时候尚需提供一种有序的验证方式,这就提出了组序列的概念。 一个组可以定义为其他组的序列,使用它进行验证的时候必须符合该序列规定的顺序。在使用组序列验证的时候,如果序列前边的组验证失败,则后面的组将不再给予验证。 public interface GroupA { } public interface GroupB { } @GroupSequence( { GroupA.class, GroupB.class }) public interface Group { } public @ResponseBody String addPeople(@Validated({Group.class}) People p,BindingResult result) { if(result.hasErrors) { return "0"; } return "1"; } @Valid:作为标准JSR-303规范,还没有吸收分组的功能。 2.注解地方 @Validated:可以用在类型、方法和方法参数上。但是不能用在成员属性(字段)上 @Valid:可以用在方法、构造函数、方法参数和成员属性(字段)上 两者是否能用于成员属性(字段)上直接影响能否提供嵌套验证的功能。 3.嵌套验证 在比较两者嵌套验证时,先说明下什么叫做嵌套验证。 比如我们现在有个实体叫做Item: public class Item { @NotNull(message = "id不能为空") @Min(value = 1, message = "id必须为正整数") private Long id; @NotNull(message = "props不能为空") @Size(min = 1, message = "至少要有一个属性") private List<Prop> props; } Item带有很多属性,属性里面有:pid、vid、pidName和vidName,如下所示: public class Prop { @NotNull(message = "pid不能为空") @Min(value = 1, message = "pid必须为正整数") private Long pid; @NotNull(message = "vid不能为空") @Min(value = 1, message = "vid必须为正整数") private Long vid; @NotBlank(message = "pidName不能为空") private String pidName; @NotBlank(message = "vidName不能为空") private String vidName; } 属性这个实体也有自己的验证机制,比如pid和vid不能为空,pidName和vidName不能为空等。 现在我们有个ItemController接受一个Item的入参,想要对Item进行验证,如下所示: @RestController public class ItemController { @RequestMapping("/item/add") public void addItem(@Validated Item item, BindingResult bindingResult) { doSomething; } } 在上图中,如果Item实体的props属性不额外加注释,只有@NotNull和@Size,无论入参采用@Validated还是@Valid验证,Spring Validation框架只会对Item的id和props做非空和数量验证,不会对props字段里的Prop实体进行字段验证,也就是@Validated和@Valid加在方法参数前,都不会自动对参数进行嵌套验证。也就是说如果传的List中有Prop的pid为空或者是负数,入参验证不会检测出来。 为了能够进行嵌套验证,必须手动在Item实体的props字段上明确指出这个字段里面的实体也要进行验证。由于@Validated不能用在成员属性(字段)上,但是@Valid能加在成员属性(字段)上,而且@Valid类注解上也说明了它支持嵌套验证功能,那么我们能够推断出:@Valid加在方法参数时并不能够自动进行嵌套验证,而是用在需要嵌套验证类的相应字段上,来配合方法参数上@Validated或@Valid来进行嵌套验证。 我们修改Item类如下所示: public class Item { @NotNull(message = "id不能为空") @Min(value = 1, message = "id必须为正整数") private Long id; @Valid // 嵌套验证必须用@Valid @NotNull(message = "props不能为空") @Size(min = 1, message = "props至少要有一个自定义属性") private List<Prop> props; } 然后我们在ItemController的addItem函数上再使用@Validated或者@Valid,就能对Item的入参进行嵌套验证。此时Item里面的props如果含有Prop的相应字段为空的情况,Spring Validation框架就会检测出来,bindingResult就会记录相应的错误。 总结一下@Validated和@Valid在嵌套验证功能上的区别: