发 帖  
原厂入驻New
【MiCOKit试用体验】庆科MiCO系统篇(1)MiCO RTOS线程
2015-10-24 16:26:04  4532 无线网络
分享
本帖最后由 gjianw217 于 2015-10-25 15:34 编辑

      在本帖子中,主要分析一下庆科MiCO RTOS的线程,具体包括:
      操作系统中的线程
      MiCO操作系统简述
      MiCO线程关键API
      MiCO线程示例
      MiCO效果


一、操作系统中的线程
       一般通用的操作系统中,进程和线程是重要的概念,现对其作一简单介绍:以下转自:进程与线程的一个简单解释
       计算机的核心是CPU,它承担了所有的计算任务。它就像一座工厂,时刻在运行。假定工厂的电力有限,一次只能供给一个车间使用。也就是说,一个车间开工的时候,其他车间都必须停工。背后的含义就是,单个CPU一次只能运行一个任务。进程就好比工厂的车间,它代表CPU所能处理的单个任务。任一时刻,CPU总是运行一个进程,其他进程处于非运行状态。
       一个车间里,可以有很多工人。他们协同完成一个任务。线程就好比车间里的工人。一个进程可以包括多个线程。
       车间的空间是工人们共享的,比如许多房间是每个工人都可以进出的。这象征一个进程的内存空间是共享的,每个线程都可以使用这些共享内存。可是,每间房间的大小不同,有些房间最多只能容纳一个人,比如厕所。里面有人的时候,其他人就不能进去了。这代表一个线程使用某些共享内存时,其他线程必须等它结束,才能使用这一块内存。一个防止他人进入的简单方法,就是门口加一把锁。先到的人锁上门,后到的人看到上锁,就在门口排队,等锁打开再进去。这就叫"互斥锁"(Mutual exclusion,缩写 Mutex),防止多个线程同时读写某一块内存区域。
       还有些房间,可以同时容纳n个人,比如厨房。也就是说,如果人数大于n,多出来的人只能在外面等着。这好比某些内存区域,只能供给固定数目的线程使用。这时的解决方法,就是在门口挂n把钥匙。进去的人就取一把钥匙,出来时再把钥匙挂回原处。后到的人发现钥匙架空了,就知道必须在门口排队等着了。这种做法叫做"信号量"(Semaphore),用来保证多个线程不会互相冲突。不难看出,mutex是semaphore的一种特殊情况(n=1时)。也就是说,完全可以用后者替代前者。但是,因为mutex较为简单,且效率高,所以在必须保证资源独占的情况下,还是采用这种设计。
       操作系统的设计,如果以多线程形式运行,必须允许单个任务分成不同的部分运行;而且要提供协调机制,一方面防止进程之间和线程之间产生冲突,另一方面允许进程之间和线程之间共享资源。

二、MiCO操作系统简述

     MICO全 称为:micro-controllerbased Internet Connectivity Operatingsystem,即基于微控制器的互联网接入操作系统,它是一个面向智能硬件设计、运行在微控制器(MCU)上的高可靠、可移植的操作系统和中间件开发平台。MICOTM作为针对微控制器(MCU)的物联网应用OS,并不是一个简单的RTOS,而是一个包含大量中间件的软件组件包,它可支持广泛的MCU,加上上海庆科拥有的完整Wi-Fi连接解决方案,可通过内建的云端接入协议、以及丰富的中间件和调试工具,快速开发智能硬件产品。该系统包括了底层的芯片驱动、无线网络协议、射频控制技术、安全、应用框架等模块,同时提供阿里物联平台、移动APP支持、以及生产测试等一系列解决方案和SDK。这使得“软制造”创业者可以简化底层的投入,真正实现产品的网络化和智能化并快速量产。
      在庆科的MiCO系统中,通过MiCO RTOS线程控制API可以在系统中定义,创建,控制和销毁线程。
  • 线程的优先级分为10级,从0-9,级数越低,优先级越高。
  • 高优先级的线程可以抢占低优先级线程,如果高优先级线程不能挂起,会导致低优先级的线程无法得到时间去运行。
  • 相同优先级的各个线程通过时间片轮转的方式分时运行,使得这些线程看起来是同时运行的。
      在MiCO系统初始化时,会创建一个以函数int application_start(void)为主执行体的线程,该线程的优先级是 7(MICO_APPLICATION_PRIORITY)。
一个线程可以处于以下几种状态:
  • RUNNING,运行: 线程正在运行中,在同一个时间,MiCO RTOS中之可能有一个线程处于运行状态。
  • Ready,就绪: 线程已经就绪并且等待运行。一旦当前的运行线程被终止,或者挂起,所有就绪的线程中优先级最高的线程将会变成运行状态。
  • Suspend,挂起: 线程正在等待事件(一段时间,信号量,互斥锁,消息队列)发生后,转换成就绪状态。
  • Terminate,终止: 线程处于非活动状态,在MiCO系统的IDLE线程中,所有的非活动状态的线程所拥有的私有资源将会被自动销毁。
  • 共享资源(如通过malloc创建的内存区块)需要通过人工进行销毁。

三、MiCO线程关键API
对于线程的定义,位于SDK_MiCOKit_v2.3.0.2\include\mico_rtos.h中,主要有以下函数
序号函数名功能描述
1mico_rtos_create_thread创建并启动一个新的线程
2mico_rtos_delete_thread删除进程,使之进入终止状态,并在IDLE线程中清除资源
3mico_rtos_suspend_thread挂起一个线程
4mico_rtos_suspend_all_thread挂起其它所有线程,始终执行当前线程,并中断OS调度
5mico_rtos_resume_all_thread恢复OS调度
6mico_rtos_thread_join使当前线程挂起,等待另一个线程终止
7mico_rtos_thread_force_awake强制唤醒一个挂起的线程
8mico_rtos_is_current_thread查询一个线程当前是否正在运行
9mico_thread_sleep使一个线程挂起一段时间,时间单位是:秒
10mico_thread_msleep使一个线程挂起一段时间,时间单位是:毫秒

      其中,常用的有:
(1)创建并启动一个新线程
OSStatus mico_rtos_create_thread(mico_thread_t* thread, uint8_t priority, const char* name, mico_thread_function_tfunction, uint32_t stack_size, void* arg );
参数1为mico_thread_t(typedef void* mico_thread_t)类型的指针,代表创建的线程句柄;
参数2为代表该线程的优先级,在MiCO中,定义了4种优先级:
#define MICO_NETWORK_WORKER_PRIORITY      (3)
#define MICO_DEFAULT_WORKER_PRIORITY      (5)
#define MICO_DEFAULT_LIBRARY_PRIORITY     (5)
#define MICO_APPLICATION_PRIORITY         (7)
参数3为线程的名字,可任意取,一般定义为一个见名知义的字符串;
参数4为该线程的回调函数,mico_thread_function_t(typedef void (*mico_thread_function_t)( void* arg ))为一函数指针;
参数5为该线程分配的堆栈大小;
参数6为线程向回调函数传递的参数;
(2)删除一个线程
OSStatus mico_rtos_delete_thread(mico_thread_t* thread );
参数代表将要删除的线程句柄,NULL表示当前线程
(3)等待(阻塞)一个线程结束
OSStatus mico_rtos_thread_join(mico_thread_t* thread );
该函数的作用是使当前线程进入睡眠状态,直到指定的线程(输入参数)终止,当前线程才能退出。

四、MiCO线程示例
示例代码参数了官方提供的demo程序,即:
(1)首先宏定义了串口函数,用以输入线程的工作状态
(2)然后创建了两个参数为void *类型,返回类型为void的回调函数,
(3)最后在测试函数中,分别创建了两个线程,分别来响应定义的回调函数
(4)具体代码如下:
  1. #define mico_os_log(M, ...) custom_log("OS", M, ##__VA_ARGS__)

  2. void thread_1(void *arg)
  3. {
  4.   UNUSED_PARAMETER(arg);
  5.   while(1){
  6.     mico_os_log( "This is thread 1" );
  7.     mico_thread_sleep( 2 );
  8.   }
  9. }

  10. void thread_2(void *arg)
  11. {
  12.   UNUSED_PARAMETER(arg);
  13.   mico_os_log( "This is thread 2" );
  14.   mico_thread_sleep( 4 );
  15.   /* Make with terminiate state and IDLE thread will clean resources */
  16.   mico_rtos_delete_thread(NULL);
  17. }


  18. void TestMiCOThread(void)//由application_start( )调用
  19. {
  20.   OSStatus err = kNoErr;
  21.   mico_thread_t t_handler = NULL;
  22.   
  23.   /* Create a new thread */
  24.   err = mico_rtos_create_thread( NULL, MICO_APPLICATION_PRIORITY, "Thread 1", thread_1, 500, NULL );
  25.   require_noerr_string( err, exit, "ERROR: Unable to start the thread 1." );
  26.   
  27.   while(1){
  28.     /* Create a new thread, and this thread will delete its self and clean its resource */
  29.     err = mico_rtos_create_thread( &t_handler, MICO_APPLICATION_PRIORITY, "Thread 2", thread_2, 500, NULL );
  30.     require_noerr_string( err, exit, "ERROR: Unable to start the thread 2." );
  31.     mico_rtos_thread_join( &t_handler );
  32.   }
  33.   
  34. exit:
  35.   IF( err != kNoErr )
  36.     mico_os_log( "Thread exit with err: %d", err );
  37.   
  38.   mico_rtos_delete_thread(NULL);
  39.   return ;
  40. }
复制代码

五、运行MiCO效果
QQ截图20151025012503.png


0
2015-10-24 16:26:04   评论 分享淘帖
3 个讨论
您好,请问怎么创建多个线程进行调度啊?比如再创建两线程
2015-11-4 22:14:41 评论

举报

ICHLIEBEDICH13 发表于 2015-11-4 22:14
您好,请问怎么创建多个线程进行调度啊?比如再创建两线程

mico_rtos_create_thread它主是创建线程的
2015-11-5 08:54:59 评论

举报

gjianw217 发表于 2015-11-5 08:54
mico_rtos_create_thread它主是创建线程的

创建线程之后在哪里调度啊,什么时候进入睡眠状态,什么情况下唤醒。有点不明白
2015-11-5 20:59:32 评论

举报

只有小组成员才能发言,加入小组>>

64个成员聚集在这个小组

加入小组

创建小组步骤

关闭

站长推荐 上一条 /10 下一条

快速回复 返回顶部 返回列表