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

5.1原因

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

5.2 实现

5.2.1 定义空闲线程的栈

src中定义idle.c

#include 
#include 

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 
#include 
#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 
#include 

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

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);

	}
}		

你可能感兴趣的:(软件工程,#,嵌入式系统设计,c语言,嵌入式,笔记)