本文以通俗的语言阐述了Contiki的两个主要机制:事件驱动和protothread机制。

Contiki两个主要机制:事件驱动和protothread机制,前者是为了降低功耗,后者是为了节省内存。

1. 事件驱动

嵌入式系统常常被设计成响应周围环境的变化,而这些变化可以看成一个个事件。事件来了,操作系统处理之,没有事件到来,就跑去休眠了(降低功耗),这就是所谓的事件驱动,类似于中断。

2. Protothread机制

2.1 概述

传统的操作系统使用栈保存进程上下文,每个进程需要一个栈,这对于内存极度受限的传感器设备将难以忍受。protothread机制恰解决了这个问题,通过保存进程被阻塞处的行数(进程结构体的一个变量,unsiged short类型,只需两个字节),从而实现进程切换,当该进程下一次被调度时,通过switch(__LINE__)跳转到刚才保存的点,恢复执行。整个Contiki只用一个栈,当进程切换时清空,大大节省内存。

2.2 特点

Protothread(Lightweight, Stackless Threads in C)最大特点就是轻量级,每个protothread不需要自己的堆栈,所有的protothread使用同一个堆栈,而保存程序断点用两个字节保存被中断的行数即可。具体特点如下[1]:

  • Very small RAM overhead - only two bytes per protothread and no extra stacks
  • Highly portable - the protothreads library is 100% pure C and no architecture specific assembly code
  • Can be used with or without an OS
  • Provides blocking wait without full multi-threading or stack-switching
  • Freely available under a BSD-like open source license

protothread机制很早就有了,Contiki OS只要运用这种机制,protothread机制还可以用于以下情形[1]:

  • Memory constrained systems
  • Event-driven protocol stacks
  • Small embedded systems
  • Sensor network nodes
  • Portable C applications

2.3 编程提示

谨慎使用局部变量。当进程切换时,因protothread没有保存堆栈上下文(只使用两个字节保存被中断的行号),故局部变量得不到保存。这就要求使用局部变量要特别小心,一个好的解决方法,使用局部静态变量(加static修饰符),如此,该变量在整个生命周期都存在。

2.4 调度

直接看原文吧[2]。

A protothread is driven by repeated calls to the function in which the protothread is running. Each time the function is called, the protothread will run until it blocks or exits. Thus the scheduling of protothreads is done by the application that uses protothreads.

如果还想进一步了解protothread,可以到[3]下载源码,仔细研读。

参考资料:

[1] Protothreads - Lightweight, Stackless Threads in C

[2] About protothreads

[3] Protothread | SourceForge.net

本文系Spark & Shine原创,转载需注明出处本文最近一次修改时间 2022-03-20 15:29

results matching ""

    No results matching ""