RT_Thread学习与STM32移值(二)

      该int rtthread_startup(void)函数完成了系统启动前的所有初始化动作,包括必要的硬件初始化、堆栈初始化,系统相关组件初始化、用户应用程序初始化,然后启动调度机制。

int rtthread_startup(void)
{
    rt_hw_interrupt_disable();

    /* board level initalization
     * NOTE: please initialize heap inside board initialization.
     */
    rt_hw_board_init();//初始化开发板硬件平台如LED,串口等

    /* show RT-Thread version打印版本信息 */
    rt_show_version();

    /* timer system initialization */
    rt_system_timer_init();

    /* scheduler system initialization */
    rt_system_scheduler_init();

#ifdef RT_USING_SIGNALS
    /* signal system initialization */
    rt_system_signal_init();
#endif

    /* create init_thread */
    rt_application_init();

    /* timer thread initialization */
    rt_system_timer_thread_init();/*初始化软件定时器*/

    /* idle thread initialization */
    rt_thread_idle_init(); /*初始化空线程*/

    /* start scheduler */
    rt_system_scheduler_start();

    /* never reach here */
    return 0;
}
#endif

1、 rt_hw_board_init()
完成中断向量表设置、系统滴答时钟设置,为系统提供串口初始化,将系统输入输出终端绑定到这个串口,后续系统运行信息就会从串口打印出来。
(void*)STM32_EXT_SRAM_END);内存管理设置好以后,应用程序就可以使用 rt_malloc、 rt_realloc、 re_free 等函数了。
2、 rt_application_init()
这个函数是为用户准备的,用户可以在这个函数里创建自己的应用线程。

什么是线程?

     从系统的角度看,线程是竞争系统资源的最小运行单元。 RT-Thread 是一个支持多线程的操作系统。通俗的讲,即把一个大问题分解成多个相对简单、比较容易解决的小问题,小问题逐个被解决了,大问题也就随之解决了。同样,在设计一个较为复杂的应用程序时,也通常把一个大型任务分解成多个小任务,然后通过运行这些小任务,最终达到完成大任务的目的。叫做线程

static void led1_thread_entry(void* parameter)
{	
	while (1)
	{
		GPIO_SetBits(GPIOB,GPIO_Pin_8);
		rt_thread_delay(500);   
		//rt_kprintf("led1_thread running,LED1_ON\r\n");
		GPIO_ResetBits(GPIOB,GPIO_Pin_8);  
		rt_thread_delay(500);   		 		
		//rt_kprintf("led1_thread running,LED1_OFF\r\n");
	}

上面即是一个典型的线程代码结构—无限死循环
 

其中线程控制块 rt_thread 结构体具体内容如下:

struct rt_thread
{
    /* rt object */
    char        name[RT_NAME_MAX];                      /**< the name of thread */
    rt_uint8_t  type;                                   /**< type of object */
    rt_uint8_t  flags;                                  /**< thread's flags */

#ifdef RT_USING_MODULE
    void       *module_id;                              /**< id of application module */
#endif

    rt_list_t   list;                                   /**< the object list */
    rt_list_t   tlist;                                  /**< the thread list */

    /* stack point and entry */
    void       *sp;                                     /**< stack point */
    void       *entry;                                  /**< entry */
    void       *parameter;                              /**< parameter */
    void       *stack_addr;                             /**< stack address */
    rt_uint32_t stack_size;                             /**< stack size */

    /* error code */
    rt_err_t    error;                                  /**< error code */

    rt_uint8_t  stat;                                   /**< thread status */

    /* priority */
    rt_uint8_t  current_priority;                       /**< current priority */
    rt_uint8_t  init_priority;                          /**< initialized priority */
#if RT_THREAD_PRIORITY_MAX > 32
    rt_uint8_t  number;
    rt_uint8_t  high_mask;
#endif
    rt_uint32_t number_mask;

#if defined(RT_USING_EVENT)
    /* thread event */
    rt_uint32_t event_set;
    rt_uint8_t  event_info;
#endif

#if defined(RT_USING_SIGNALS)
    rt_sigset_t     sig_pending;                        /**< the pending signals */
    rt_sigset_t     sig_mask;                           /**< the mask bits of signal */

    void            *sig_ret;                           /**< the return stack pointer from signal */
    rt_sighandler_t *sig_vectors;                       /**< vectors of signal handler */
    void            *si_list;                           /**< the signal infor list */
#endif

    rt_ubase_t  init_tick;                              /**< thread's initialized tick */
    rt_ubase_t  remaining_tick;                         /**< remaining tick */

    struct rt_timer thread_timer;                       /**< built-in thread timer */

    void (*cleanup)(struct rt_thread *tid);             /**< cleanup function when thread exit */

    rt_uint32_t user_data;                              /**< private user data beyond this thread */
};
typedef struct rt_thread *rt_thread_t;

    RT-Thread 中的线程分为静态线程—线程堆栈由编译器静态分配,使用 rt_thread_init()函数创建和动态线程—线程堆栈由系统动态分配,使用 rt_thread_create()函数创建。
       使用静态线程时,必须先定义静态的线程控制块,并且定义好堆栈空间,然后调用rt_thread_init()来完成线程的初始化工作。采用这种方式,线程控制块和堆栈占用的内存会放在 RW/ZI 段,这段空间在编译时就已经确定,它不是可以动态分配的,所以不能被释放,而只能使用 rt_thread_detach()函数将该线程控制块从对象管理器中脱离。
       使用动态定义方式 rt_thread_create()时, RT-Thread 会动态申请线程控制块和堆栈空间。在编译时,编译器是不会感知到这段空间的,只有在程序运行时, RT-Thread 才会从系统堆中申请分配这段内存空间,当不需要使用该线程时,调rt_thread_delete()函数就会将这段申请的内存空间重新释放到内存堆中。

        静态定义方式会占用 RW/ZI 空间,但是不需要动态分配内存,运行时效率较高,实时性较好。动态方式不会占用额外的 RW/ZI 空间,占用空间小,但是运行时需要动态分配内存,效率没有静态方式高。



 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Aaron-Suen

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值