RT-Thread入門(三)タイマー

13574 ワード

RT-thread入門のタイマー
        前回はRT-Threadのスレッド関連関数の構築について学習しましたが,今回はシステムにおける重要な機能であるタイマについて学習します.システムが提供するソフトウェアタイマは、無限のタイマを提供することができますが、タイミング時間はシステムのビートの整数倍でなければなりません.RT-Threadでは、クロックビートの長さは、RT_TICK_PER_SECONDの定義を調整して、私たちが使用している工事の設定は100で、ここでは彼のデフォルトの設定を使用しているので、私たちが設定できるタイミングは10 msの整数倍しかありません.
一、HARD/SOFT_TIMERの違い
        HARD_TIMERモードのタイマタイムアウト関数は、割り込みコンテキスト環境で実行され、割り込みコンテキスト環境で実行される場合、タイムアウト関数に対する要求は割り込みサービスルーチンの要求と同じである:実行時間はできるだけ短く、実行時に現在のコンテキストが一時停止したり、待機したりすることはない.        SOFT_TIMERモードは構成可能で、マクロによってRT_を定義するUSING_TIMER_SOFTは、rtconfigs.hで定義され、デフォルトでは使用されないモードを有効にするかどうかを決定します.このモードを有効にすると、初期化時にtimerスレッドが作成され、SOFT_TIMERモードのタイマタイムアウト関数は、いずれもtimerスレッドのコンテキスト環境で実行されます.       まとめるとhard_timer割り込みサービスプログラムを中断することはできません.soft_timer割り込みサービスプログラムは、スレッドと同様にタスクのスケジューリングに参加します.       このほか、タイマにはダイナミックモードと静的モードの2つの作成方法があります.ええと、ほとんどの時間はダイナミック方式を使えばいいと思います.彼らの違いはプロセスと似ています.コード空間の割り当て方式は違います.この文章は主にダイナミック方式を使って実験を行います.
二、関連関数の紹介
1.rt_timer_createこの関数により、タイマのタイミング、タイムアウト関数のエントリ、タイマモードなどのパラメータを設定できます.
rt_timer_t rt_timer_create(const char* name,
							void (*timeout)(void* parameter),
							void* parameter,
							rt_tick_t time,
							rt_uint8_t flag);

2.rt_timer_start設定タイマのパラメータが完了すると、タイマはすぐに起動せず、rt_のみが呼び出されます.timer_start関数の後、タイマが計時を開始します.
rt_err_t rt_timer_start(rt_timer_t timer);

3.rt_timer_stopがタイマを起動した後、停止させるには、次の関数インタフェースを使用します.
rt_err_t rt_timer_stop(rt_timer_t timer);

4.rt_timer_コントローラは、上述したいくつかのプログラミングインターフェースに加えて、RT−Threadは、タイマ制御関数インターフェースを追加して、より多くのタイマの情報を取得または設定する.制御タイマ関数インタフェースは次のとおりです.
rt_err_t rt_timer_control(rt_timer_t timer, rt_uint8_t cmd, void* arg);

ここでcmdはタイマを制御するコマンドに用いられ、現在は4つのコマンドをサポートしており、それぞれタイミング時間を設定し、タイミング時間を表示し、単一トリガを設定し、周期トリガを設定する.argはタイマを制御するコマンドで、現在は4つのコマンドをサポートしています.それぞれ、タイミング時間の設定、タイミング時間の表示、単一トリガの設定、周期トリガの設定です.関数パラメータcmdでサポートされるコマンドは次のとおりです.
#define RT_TIMER_CTRL_SET_TIME 0x0 		/*                   */
#define RT_TIMER_CTRL_GET_TIME 0x1 		/*                   */
#define RT_TIMER_CTRL_SET_ONESHOT 0x2 	/*                       */
#define RT_TIMER_CTRL_SET_PERIODIC 0x3 	/*                         */

三、プログラミングの練習
ここでは以下の機能を実現する:1.2つのタイマtimer 1とtimer 2を作成し、timer 1は周期ソフト甲タイマであり、設定タイミング時間は500 msであり、毎回時間が来たらシリアルポートを通じてtimer 1の実行回数を出力する.timer 2は、1回のハードウェアタイマであり、設定タイミング時間は5 sであり、タイミングが達した後にタイマ1を停止する.2.タイマ1を5回実行した後、自身のタイミング長を250 msに変更する.プログラムコードは次のとおりです.
ソフトウェアタイマを使用しているので、まずrtconfig.hでdefine RT_を定義します.USING_TIMER_SOFT.(しかし、これは定義されていないプログラムでも実行できるようですが、プログラミングガイドでは定義すると定義されています.)プログラミングマニュアルでは初期化にrt_を加えると言っています.system_timer_init(void);またはrt_system_timer_thread_Init(void)ですが、ネット上のチュートリアルを見てみると、この2つの関数はシステムの初期化時に初期化されているので、この2つの関数を追加しません.
#include 
#include "LED.h"

//LED_thread 
#define LED_priority 5
#define LED_timeslices 5 
#define LED_SIZE	1024
static rt_thread_t LED_thread = RT_NULL;
static void LED_enter(void *parameter);

//timer1_thread
static rt_timer_t timer1;
static void timeout1(void *parameter);

//timer2_thread
static rt_timer_t timer2;
static void timeout2(void *parameter);


int main(void)
{

		//  USART  
		LED_thread=rt_thread_create("LED_thread",
									LED_enter,
									RT_NULL,
									LED_SIZE,
									LED_priority,
									LED_timeslices);
									 
		if(LED_thread != RT_NULL) rt_thread_startup(LED_thread);
								 
    timer1 = rt_timer_create("timer1",timeout1,RT_NULL,50,RT_TIMER_FLAG_PERIODIC|RT_TIMER_FLAG_SOFT_TIMER);
		/*           1 */
		if (timer1 != RT_NULL) rt_timer_start(timer1);
		
		timer2 = rt_timer_create("timer2",timeout2,RT_NULL,500,RT_TIMER_FLAG_ONE_SHOT);
		/*           2 */
		if (timer2 != RT_NULL) rt_timer_start(timer2);
		
}

static void LED_enter(void *parameter)
{
    while (1)
    {
				rt_thread_mdelay(500);
				LED0=~LED0;
    }
}

	rt_uint16_t count = 0;
static void timeout1(void *parameter)
{
	int arg=25;
	if(count==4) rt_timer_control(timer1 , RT_TIMER_CTRL_SET_TIME ,&arg);
	rt_kprintf("thread timer1 count: %d\r
"
, count++); } static void timeout2(void *parameter) { rt_timer_stop(timer1); rt_kprintf("timer1 was stopped!
"
); }

四、まとめ
       最初はどこに問題があったのか分からなかったが、プログラムは実行されず、シリアルポートにはバージョン情報もなかったが、そこを変更したらよかったとは知らなかった.       プログラミングマニュアルを見て、ソフトウェアタイマーのタイムアウト関数がコンテキストで実行できると言っていたので、タイムアウト関数に遅延とタスクスケジューリング関数を入れたいと思っていましたが、その後もだめのようです.後で調べてみると、ソフトウェアタイムアウト関数でも長時間実行したり、ブロックしたり、タスクを保留したりすることはできないという人もいます.大神さんが教えてくれませんか.