0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

从裸机到rtt任务切换有感

冬至子 来源:陈再松 作者:陈再松 2023-10-13 11:31 次阅读

闲来无事,作为第一次使用实时操作系统的小白想看看rtthread的调度方式。

总结:

主要调度使用scheduler.c和context——gcc.s。

void rt_system_scheduler_start(void)
{
register struct rt_thread *to_thread;
rt_ubase_t highest_ready_priority;
to_thread = _get_highest_priority_thread(&highest_ready_priority);
rt_current_thread = to_thread;
rt_schedule_remove_thread(to_thread);
to_thread->stat = RT_THREAD_RUNNING;
rt_hw_context_switch_to((rt_ubase_t)&to_thread->sp);//跳转至.s文件执行
}

第一次会调用此函数用来执行一个.s文件

c
rt_hw_context_switch_to:
LDR r1, =rt_interrupt_to_thread
STR r0, [r1] / 将rt_interrupt_to_thread写入一个sp指针待会会用到 /
/* set interrupt flag to 1 /
LDR r1, =rt_thread_switch_interrupt_flag
MOV r0, #1
STR r0, [r1]
...
LDR r0, =NVIC_INT_CTRL /
trigger the PendSV exception (causes context switch) /
LDR r1, =NVIC_PENDSVSET
STR r1, [r0] / NVIC_INT_CTRL为ICSR寄存器将28位置1会导致一个sv异常,任务切 换也在sv中进行 /
/
restore MSP */
LDR r0, =SCB_VTOR / VTOR保存着内存地址偏移,取出偏移值赋值给msp寄存器 /
LDR r0, [r0]
LDR r0, [r0]
NOP
MSR msp, r0
...
第一次触发的sv异常

PendSV_Handler:
/* disable interrupt to protect context switch /
MRS r2, PRIMASK
CPSID I
/
get rt_thread_switch_interrupt_flag /
LDR r0, =rt_thread_switch_interrupt_flag
LDR r1, [r0]
CBZ r1, pendsv_exit /
pendsv already handled /
/
clear rt_thread_switch_interrupt_flag to 0 /
MOV r1, #0x00
STR r1, [r0]
LDR r0, =rt_interrupt_from_thread /
第一次执行所以此函数我们并没有赋值所以会执行跳转 /
LDR r1, [r0]
CBZ r1, switch_to_thread /
skip register save at the first time /
MRS r1, psp /
get from thread stack pointer /
STMFD r1!, {r4 - r11} /
push r4 - r11 register /
LDR r0, [r0]
STR r1, [r0] /
update from thread stack pointer /
switch_to_thread:
LDR r1, =rt_interrupt_to_thread /
获取需要切换的任务的sp指针 /
LDR r1, [r1]
LDR r1, [r1] /
load thread stack pointer /
LDMFD r1!, {r4 - r11} /
pop r4 - r11 register /
MSR psp, r1 /
update stack pointer /
/
此时psp寄存器已指向我们目标任务的sp /
pendsv_exit:
/
restore interrupt */
MSR PRIMASK, r2
ORR lr, lr, #0x04
BX lr

在后续的轮转中我们会调用

void rt_schedule(void)
{
rt_base_t level;
struct rt_thread to_thread;
struct rt_thread from_thread;
/
disable interrupt /
level = rt_hw_interrupt_disable();
/
check the scheduler is enabled or not /
if (rt_scheduler_lock_nest == 0)
{
rt_ubase_t highest_ready_priority;
if (rt_thread_ready_priority_group != 0)
{
/
need_insert_from_thread: need to insert from_thread to ready queue /
int need_insert_from_thread = 0;
/ 获取任务列表中优先级最高的我们假设有比当前任务更高的优先级执行39行,此时目标任务为高优先级任务 /
to_thread = _get_highest_priority_thread(&highest_ready_priority);
...
if (to_thread != rt_current_thread)
{
/
if the destination thread is not the same as current thread /
/
开始进行转换,首先将源任务设置为当前任务,再将当前任务设置为目标任务 /
rt_current_priority = (rt_uint8_t)highest_ready_priority;
from_thread = rt_current_thread;
rt_current_thread = to_thread;
...
#ifdef RT_USING_OVERFLOW_CHECK
_rt_scheduler_stack_check(to_thread);
#endif
if (rt_interrupt_nest == 0)
{
extern void rt_thread_handle_sig(rt_bool_t clean_state);
/
这句进行任务切换 /
rt_hw_context_switch((rt_ubase_t)&from_thread->sp,
(rt_ubase_t)&to_thread->sp);
/
enable interrupt /
rt_hw_interrupt_enable(level);
goto __exit;
}
else
{
RT_DEBUG_LOG(RT_DEBUG_SCHEDULER, ("switch in interruptn"));
rt_hw_context_switch_interrupt((rt_ubase_t)&from_thread->sp,
(rt_ubase_t)&to_thread->sp);
}
}
else
{
rt_schedule_remove_thread(rt_current_thread);
rt_current_thread->stat = RT_THREAD_RUNNING | (rt_current_thread->stat & ~RT_THREAD_STAT_MASK);
}
}
}
/
enable interrupt /
rt_hw_interrupt_enable(level);
__exit:
return;
}
rt_hw_context_switch:
/
set rt_thread_switch_interrupt_flag to 1 /
LDR r2, =rt_thread_switch_interrupt_flag
LDR r3, [r2]
CMP r3, #1
/
没有设置interrupt_flag跳过执行 /
BEQ _reswitch
/
再次置1用于sv异常 /
MOV r3, #1
STR r3, [r2]
/
将源任务sp赋值给rt_interrupt_from_thread,此时from是有值的
/
LDR r2, =rt_interrupt_from_thread /* set rt_interrupt_from_thread /
STR r0, [r2]
_reswitch:
/
将目标任务sp赋值给rt_interrupt_to_thread*/
LDR r2, =rt_interrupt_to_thread /* set rt_interrupt_to_thread /
STR r1, [r2]
/
再次进入sv异常处理 /
LDR r0, =NVIC_INT_CTRL /
trigger the PendSV exception (causes context switch) */
LDR r1, =NVIC_PENDSVSET
STR r1, [r0]
BX LR

此时sv处理与上次相比多了一个源任务的r4-r11的压栈处理其他相同。

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 寄存器
    +关注

    关注

    30

    文章

    5028

    浏览量

    117723
  • 裸机
    +关注

    关注

    0

    文章

    37

    浏览量

    6154
  • LDR
    LDR
    +关注

    关注

    0

    文章

    92

    浏览量

    7437
  • gcc编译器
    +关注

    关注

    0

    文章

    77

    浏览量

    3233
  • RTThread
    +关注

    关注

    7

    文章

    129

    浏览量

    40519
收藏 人收藏

    评论

    相关推荐

    ATmega128两个任务切换不成功的问题

    写了两个任务, 手动切换两个任务的执行。 但是切换有问题。高手帮忙看看。
    发表于 02-08 16:21

    请问uc/os任务切换问题该怎么解决?

    切换的时候,任务1的寄存器以及PC压栈自己的任务堆栈,然后把任务2的任务堆栈内容填写到系统堆栈
    发表于 06-12 04:35

    请问ucos任务切换时先寻找优先级高的任务任务切换有影响吗?

    任务切换函数的本意是将正在运行的任务的cpu寄存器内容压入堆栈,将优先级高的任务堆栈的内容存入cpu,但切换时要先寻找优先级高的
    发表于 09-05 02:20

    请问UCOSIII中的任务调度和任务切换有什么区别?

    的现场当前任务的堆栈中,主要是CPU寄存器值,然后恢复新的现场并且执行新的任务,这个过程就是任务切换。问题:1.他们的区别是
    发表于 05-25 07:27

    RTOS中的多任务切换的相关资料分享

    函数四.总流程五.结果六.后记(含代码链接)一. 简介  RTOS中的多任务切换是操作系统与裸机编程的一个非常大的区别,一般逻辑变成运行在一个循环内,裸机编程很难实现两个事件的并行(这
    发表于 12-06 07:08

    任务裸机系统与多任务系统的区别在哪

    总体概述与任务裸机系统与多任务系统的区别任务的定义与切换裸机系统与多
    发表于 02-18 07:03

    UCosIII STM32F429任务的定义与任务切换的实现相关资料下载

    ,图任务轮流切换波形图 的波形图的效果,并不是真正的多任务系统中任务切换的效果图,这个效果其实可以完全由
    发表于 02-18 06:34

    uCOS-III任务切换的实现

    uCOS-III任务切换的实现学习目的:熟悉uCOS-III任务切换实现原理在使用单片机做一些复杂的产品开发时,单纯的裸机系统通常不能很
    发表于 02-18 06:16

    介绍一种嵌入式裸机任务切换方法

    一种嵌入式裸机任务切换方法有时候为了实现一些简单的、对实时性要求不高的任务,采用操作系统不仅增加了程序的复杂性,对低性能单片机的资源占用也是值得考虑的问题。这时候操作系统可能不是必要
    发表于 02-28 13:27

    RTT切换极限是1ms吗?

    有一个任务每秒需要运行两千次,应该怎么写程序。RTT切换极限是1ms吗?
    发表于 01-16 17:24

    RTT任务切换机制是如何实现的?

    RTT中如何实现任务切换机制
    发表于 11-02 06:28

    什么是CDMA软切换?它与硬切换有什么分别?

    什么是CDMA软切换?它与硬切换有什么分别? 移动通讯是建立在移动之中的。有了频率的复用,必然带来移动中的频率切换问题,一个网络质量的
    发表于 06-01 20:27 843次阅读

    什么是CDMA软切换?它与硬切换有什么分别

    什么是CDMA软切换?它与硬切换有什么分别 移动通讯是建立在移动之中的。有了频率的复用,必然带来移动中的频率切换问题,一个网络质
    发表于 06-15 09:42 1231次阅读

    浅谈RTOS中的多任务切换(基于UC/OS iii)

    函数四.总流程五.结果六.后记(含代码链接)一. 简介  RTOS中的多任务切换是操作系统与裸机编程的一个非常大的区别,一般逻辑变成运行在一个循环内,裸机编程很难实现两个事件的并行(这
    发表于 11-23 18:06 25次下载
    浅谈RTOS中的多<b class='flag-5'>任务</b><b class='flag-5'>切换</b>(基于UC/OS iii)

    ucosiii 任务切换

    uCOS-III任务切换的实现学习目的:熟悉uCOS-III任务切换实现原理在使用单片机做一些复杂的产品开发时,单纯的裸机系统通常不能很
    发表于 12-23 20:02 1次下载
    ucosiii <b class='flag-5'>任务</b><b class='flag-5'>切换</b>