RTThread学习笔记——对线程的我的了解

线程?它是啥?编程

  在咱们刚开始进入嵌入式软件的编程领域时,每次都会接触到一个函数——main函数,在裸机的编程中,程序的执行流程就是在main函数中进行的,main函数也能够理解为一个线程,它也有它的栈空间来存储变量。可是,若是有许多线程呢,怎样来区分它们?又怎样来分配存储空间?数组

  对于这个问题,RTThread有它的解决办法。多线程


 

首先是线程栈app

  栈,是一种经典的储存结构,RTThread为每一个线程都分配了栈空间,来看看它是怎样定义的。函数

ALIGN(RT_ALIGN_SIZE)  //线程栈对齐
static rt_uint8_t rt_led1_thread_stack[1024];  //定义线程栈

  这是一个rt_uint8_t(RTThread中的宏定义,无符号8位)类型的全局数组,第一句话是为了栈空间对齐,使得CPU对数据的访问更加高效,第二句就是线程的具体定义了,这里定义1024的长度。ui


 

而后是线程的ID卡——线程控制块this

  在操做系统中,经常有许多的线程在运行,面对着这么多的的线程,天然须要一个身份块来标识每一个线程,使得系统便于管理。而这个身份,就是线程控制块。spa

  具体定义以下:操作系统

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 */

    /* light weight process if present */
#ifdef RT_USING_LWP
    void        *lwp;
#endif

    rt_uint32_t user_data;                             /**< private user data beyond this thread */
};

  看起来线程控制块的定义很是复杂,实际上,线程控制块的主要包含信息有对象成员相关(RTT(hread)经过对象来进行管理),线程链表相关(RTT经过线程链表实现调度,也被称为优先级表/就绪链表),线程栈相关和线程自己的相关地址。使用时,须要经过static struct定义一个控制块结构体线程


 

初始化:

  线程初始化定义以下:

rt_err_t rt_thread_init(struct rt_thread *thread,
                        const char       *name,
                        void (*entry)(void *parameter),
                        void             *parameter,
                        void             *stack_start,
                        rt_uint32_t       stack_size,
                        rt_uint8_t        priority,
                        rt_uint32_t       tick)

  初始化的须要的参数有(从上到下):线程控制块地址,线程名称,入口函数地址,入口函数参数,栈起始地址,线程优先级和线程时间片。使用时,需引入具体参数。


 

具体定义:

  线程的具体定义,给出一个荔枝(这里部分参考了野火哥的例程):

static void led_thread_entry(void *parameter)
{
    while(1)
    {
        LED_ON;
        rt_thread_mdelay(1000);
        LED_OFF;
        rt_thread_mdelay(1000);
    }
}        

  须要特别注意的是,这里必定要用RTT系统的延时,不然线程不会让出CPU供其余线程使用,这就不是一个RTOS系统了。


 

启动线程,开始调度:

  万事俱备,只欠东风,只须要启动线程(参数为线程控制块地址):

rt_thread_startup(&ABCDEFG);

  便可纵享RTOS系统的魅力。

 

(因为我的水平有限,可能会出现理解,语句错误,请注意~:)

相关文章
相关标签/搜索