Rt-Thread 移植5--空闲线程和线程阻塞(KF32)

这篇具有很好参考价值的文章主要介绍了Rt-Thread 移植5--空闲线程和线程阻塞(KF32)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

5.1原因

线程延时是浪费CPU资源,受否可以考虑延时的时候放弃CPU使用权,这样就充分利用了CPU的资源。
如果线程进入阻塞状态,没有其他线程运行,是否可以运行一个空闲线程来做一些内存的清理等系统工作呢:

5.2 实现

5.2.1 定义空闲线程的栈

src中定义idle.c

#include <rtthread.h>
#include <rthw.h>

extern rt_list_t rt_thread_priority_table[RT_THREAD_PRIORITY_MAX];

#define IDLE_THREAD_STACK_SIZE			512

ALIGN(RT_ALIGN_SIZE)
static rt_uint8_t rt_thread_stack[IDLE_THREAD_STACK_SIZE];

5.2.2 定义空闲线程的线程控制块

struct rt_thread idle;

5.2.3 定义空闲线程函数


rt_ubase_t rt_idletask_ctr = 0;
void rt_thread_idle_entry(void *parameter)
{
	parameter = parameter;
	while(1)
	{
		rt_idletask_ctr++;
	}
}

5.2.4 空闲线程初始化

oid rt_thread_idle_init(void)
{

	rt_thread_init(&idle,"idle",rt_thread_idle_entry,RT_NULL,&rt_thread_stack[0],sizeof(rt_thread_stack),RT_THREAD_PRIORITY_MAX - 1);



	rt_list_insert_before(&(rt_thread_priority_table[RT_THREAD_PRIORITY_MAX-1]),&(idle.tlist));



}

5.3 实现阻塞延时

5.3.1 thread.c中

void rt_thread_delay(rt_tick_t tick)
{

	struct rt_thread *thread;
	thread = rt_current_thread;
	thread->remaining_tick = tick;
	rt_schedule();
}

5.3.2 struct thread中

添加	rt_ubase_t remaining_tick;成员

5.3.3 schedule.c

/* 系统调度 */
void rt_schedule(void)
{

	struct rt_thread *to_thread;
	struct rt_thread *from_thread;


	if(rt_current_thread == &idle)
	{
		if(rt_flag1_thread.remaining_tick == 0)
		{
			from_thread = rt_current_thread;
			to_thread = &rt_flag1_thread;
			rt_current_thread = to_thread;
		}
		else if(rt_flag2_thread.remaining_tick == 0)
		{
			from_thread = rt_current_thread;
			to_thread = &rt_flag2_thread;
			rt_current_thread = to_thread;
		}
		else
		{
			return ;
		}
	}
	else
	{
		if(rt_current_thread == &rt_flag1_thread)
		{
			if(rt_flag2_thread.remaining_tick == 0)
			{
				from_thread = rt_current_thread;
				to_thread = &rt_flag2_thread;
				rt_current_thread = to_thread;
			}
			else if(rt_current_thread->remaining_tick == 0)
			{
				from_thread = rt_current_thread;
				to_thread = &idle;
				rt_current_thread = to_thread;
			}
			else
			{
				return;
			}
		}
		else if(rt_current_thread == &rt_flag2_thread)
		{
			if(rt_flag1_thread.remaining_tick == 0)
			{
				from_thread = rt_current_thread;
				to_thread = &rt_flag1_thread;
				rt_current_thread = to_thread;
			}
			else if(rt_current_thread->remaining_tick == 0)
			{
				from_thread = rt_current_thread;
				to_thread = &idle;
				rt_current_thread = to_thread;
			}
			else
			{
				return;
			}
		}
	}

	rt_hw_context_switch((rt_uint32_t)&from_thread->sp,(rt_uint32_t)&to_thread->sp);



	/* 产生上下文切换 */

}


5.3.4 main.c中添加systick

void __attribute__((interrupt)) _SysTick_exception (void)
{
	rt_interrupt_enter();
	rt_tick_increase();
	rt_interrupt_leave();
}

void SysTick_Config(uint32_t Reload)
{
	SYSTICK_Cmd (FALSE);
	SYSTICK_Reload_Config(Reload);
	SYSTICK_Counter_Updata();                           //向ST_CV寄存器写任意值,以清零当前值寄存器
	SYSTICK_Clock_Config(SYSTICK_SYS_CLOCK_DIV_1);      //系统节拍定时器时钟源选择,SCLK作为时钟源
	SYSTICK_Systick_INT_Enable(TRUE);
	SYSTICK_Cmd(TRUE);
    INT_Interrupt_Enable(INT_SysTick,TRUE);				//使能SYSTICK中断
	INT_All_Enable (TRUE);
}

5.3.5 系统时基更新函数

clock.c

#include <rtthread.h>
#include <rthw.h>
#include "debug.h"

static rt_tick_t rt_tick = 0;
extern rt_list_t rt_thread_priority_table[RT_THREAD_PRIORITY_MAX];

void rt_tick_increase(void)
{
	rt_ubase_t i;
	struct rt_thread *thread;
	rt_tick++;
	for(i = 0;i < RT_THREAD_PRIORITY_MAX;i++)
	{
		thread = rt_list_entry(rt_thread_priority_table[i].next,struct rt_thread,tlist);
		if(thread->remaining_tick > 0)
		{
			thread->remaining_tick--;
		}
		rt_schedule();
	}

}

5.3.6 中断函数

irq.c

#include <rthw.h>
#include <rtthread.h>

volatile rt_uint8_t rt_interrupt_nest;
void rt_interrupt_enter(void)
{
    rt_base_t level;

   // RT_DEBUG_LOG(RT_DEBUG_IRQ, ("irq coming..., irq nest:%d\n",
                             //   rt_interrupt_nest));

    level = rt_hw_interrupt_disable();
    rt_interrupt_nest ++;
    //RT_OBJECT_HOOK_CALL(rt_interrupt_enter_hook,());
    rt_hw_interrupt_enable(level);
}


/**
 * This function will be invoked by BSP, when leave interrupt service routine
 *
 * @note please don't invoke this routine in application
 *
 * @see rt_interrupt_enter
 */
void rt_interrupt_leave(void)
{
    rt_base_t level;

   // RT_DEBUG_LOG(RT_DEBUG_IRQ, ("irq leave, irq nest:%d\n",
                              //  rt_interrupt_nest));

    level = rt_hw_interrupt_disable();
    rt_interrupt_nest --;
  //  RT_OBJECT_HOOK_CALL(rt_interrupt_leave_hook,());
    rt_hw_interrupt_enable(level);
}

5.4 案例

main.c文章来源地址https://www.toymoban.com/news/detail-735097.html

rt_hw_interrupt_disable();
SysTick_Config(SystemCoreClock/RT_TICK_PER_SECOND);
void flag1_thread_entry( void *p_arg )
{
	for( ;; )
	{
		P_DBG("flag1 thread\n");
		flag2 = 1;
		P_DBG("flag1 thread will dela1\n");
		rt_thread_delay(10);
		flag2 = 0;
		P_DBG("flag1 thread will dela2\n");
		rt_thread_delay(10);
	}
}

/* 线程2 */
void flag2_thread_entry( void *p_arg )
{
	for( ;; )
	{
		P_DBG("flag2 thread\n");

		flag2 = 1;
		rt_thread_delay(2);
		flag2 = 0;
		P_DBG("flag2 thread will dela1\n");
		rt_thread_delay(2);

	}
}		

到了这里,关于Rt-Thread 移植5--空闲线程和线程阻塞(KF32)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【STM32&RT-Thread零基础入门】 7. 线程创建应用(多线程运行机制)

    硬件:STM32F103ZET6、ST-LINK、usb转串口工具、4个LED灯、1个蜂鸣器、4个1k电阻、2个按键、面包板、杜邦线 本章进一步研究多线程的运行机制。要求实现功能如下:创建2个线程,线程名称分别为LED和BEEP。两个线程的任务是连续5次打印本线程的名字后退出线程(注意:线程不执行

    2024年02月03日
    浏览(27)
  • 【STM32&RT-Thread零基础入门】 6. 线程创建应用(线程挂起与恢复)

    硬件:STM32F103ZET6、ST-LINK、usb转串口工具、4个LED灯、1个蜂鸣器、4个1k电阻、2个按键、面包板、杜邦线 在上一个任务中,通过停止命令把线程删除后,线程在系统中就不存在了,也无法再使线程重新运行。例如输入stop_led_thread命令后,led停止闪烁,但也无法重新开启LED灯闪烁

    2024年02月11日
    浏览(25)
  • RT-Thread 内核移植

    内核移植就是指将RT-Thread内核在不同的芯片架构、不同的板卡上运行起来,能够具备线程管理和调度,内存管理,线程间同步和通信、定时器管理等功能。 移植可分为CPU架构移植和BSP(Board support package,板级支持包)移植两部分。 在嵌入式领域有多种不同CPU架构,例如Cort

    2024年01月23日
    浏览(34)
  • 【STM32&RT-Thread零基础入门】 5. 线程创建应用(线程创建、删除、初始化、脱离、启动、睡眠)

    硬件:STM32F103ZET6、ST-LINK、usb转串口工具、4个LED灯、1个蜂鸣器、4个1k电阻、2个按键、面包板、杜邦线 本章主要讲线程的工作机制和管理方法,通过实例讲解如何使用多线程完成多任务开发。 RT-Thread用线程控制块来描述和管理一个线程,一个线程对应一个线程控制块。线程控

    2024年02月12日
    浏览(43)
  • NUCLEO-F411RE RT-Thread 体验 (1) - GCC环境 RT-Thread 的移植

    a、用stm32cubemx新建一个工程。 时钟配置 st-link提供8M的mco输出,所以配置hse 8m,sysclk最高100M,设置如下: 配置LED 连接pa5,设置pa5为输出模式。 配置串口 st-link可以做虚拟串口用,这样可以省下一个usb转串口的模块。st-link连接f411的PA2 PA3,也就是uasrt2。 配置SWD 生成Makefile工程

    2024年02月09日
    浏览(33)
  • RT-Thread 线程间同步

    多个执行单元(线程、中断)同时执行临界区,操作临界资源,会导致竟态产生。 RTT使用信号量、互斥量、事件集来解决这种问题。 同步(按顺序)、互斥(排它)。 信号量是一种轻型的用于解决线程间同步问题的 内核对象 ,线程可以 获取或释放它 ,从而达到 同步或互

    2024年02月11日
    浏览(33)
  • 【STM32&RT-Thread零基础入门】 2. 新建RT-Thread项目

    硬件:STM32F103ZET6、ST-LINK、usb转串口工具 RT-Thread的全称是Real Time Thread,顾名思义,它是一个嵌入式实时多线程操作系统。相较于 Linux 操作系统,RT-Thread 体积小,成本低,功耗低、启动快速,除此之外 RT-Thread 还具有实时性高、占用资源小等特点,非常适用于各种资源受限(

    2024年02月13日
    浏览(33)
  • 使用RT-Thread Studio搭配STM32CubeMX新建RT-Thread项目

    STM32CubeMX下载 RT-Thread Studio下载 安装好RT-Thread Studio后,先打开RT-Thread SDK管理器确认有没有自己MCU需要的SDK包,直接安装好之后里面是有STM32F1系列的SDK包,其他的需要自己安装。 之后点击文件→新建→RT-Thread项目,根据自己需要配置好后点击完成就会生成RT-Thread项目。 新建项

    2024年02月11日
    浏览(34)
  • NUCLEO-F411RE RT-Thread 体验 (2) - GCC环境 Pin 驱动的移植

    前面控制LED的函数,其实还是调用的hal的函数,RT-Thread分离了驱动层与应用层,驱动层往下对接hal库,往上对接pin组件。 驱动层代码路径如图: pin组件代码位于 第一次编译 报错提示没有board.h,在Core/Inc目录新建一个board.h,内容如下: 第二次编译 无错误。 编译无报错。 添加

    2024年02月09日
    浏览(23)
  • NUCLEO-F411RE RT-Thread 体验 (9) - GCC环境 PWM的驱动移植以及简单使用

    驱动位于drv_pwm.c文件中,components层代码位于rt_drv_pwm.c中。 修改Makefile文件 修改配置文件rtconfig.h LED2链接PA5,而TIM2_CHANNEL1可从PA5输出PWM,所以我们需要配置TIM2,并使能TIM2_CH1. 修改RT-Thread-basic/Core/Src/stm32f4xx_hal_msp.c HAL_TIM_MspPostInit 函数在stm32_hw_pwm_init函数中被调用。主要配置

    2024年02月10日
    浏览(27)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包