STM32F103 移植 FreeRTOS シリーズ 12: リスト項目の挿入と削除の実験 (記事の最後にコードを添付)

この実験は stm32f103rct6 と時間厳守のアトム ソース コードに基づいています

12.1 実験プログラムの設計

1. 実験の目的: FreeRTOS リストとそれに対応するリスト項目の演算関数の使い方を学び、これらの演算関数の演算結果が理論的分析と一致するかどうかを観察します。

2. 実験設計 この実験では、start_task、task1_task、list_task の 3 つのタスクを設計しており、これら 3 つのタスクのタスク関数は次のとおりです。

start_task: 他の 2 つのタスクを作成するために使用されます。

task1_task: アプリケーション タスク 1、制御 LED0 の点滅。システムの実行を促すために使用されます。

task2_task: リストおよびリスト項目の操作タスク。リストおよびリスト項目に関連する API 関数を呼び出し、シリアル ポートを介して対応する情報を出力して、これらの API 関数の実行プロセスを監視します。実験では、KEY_UP ボタン (PA0) を使用してタスクの操作を制御する必要があります。

実際、コードとアトムの違いは大きくなく、対応する .c ファイルと .h ファイルを変更するだけです。例えばkey.cやled.cなどはここで見れば気軽に扱えるはずです。

ここでは実験結果を簡単に記録します。

 最初のステップと第 2 ステップ

	//第一步:初始化列表和列表项
	vListInitialise(&TestList);
	vListInitialiseItem(&ListItem1);
	vListInitialiseItem(&ListItem2);
	vListInitialiseItem(&ListItem3);
	
	ListItem1.xItemValue=40;			//ListItem1列表项值为40
	ListItem2.xItemValue=60;			//ListItem2列表项值为60
	ListItem3.xItemValue=50;			//ListItem3列表项值为50
	
	//第二步:打印列表和其他列表项的地址
	printf("/*******************列表和列表项地址*******************/\r\n");
	printf("项目                              地址				    \r\n");
	printf("TestList                          %#x					\r\n",(int)&TestList);
	printf("TestList->pxIndex                 %#x					\r\n",(int)TestList.pxIndex);
	printf("TestList->xListEnd                %#x					\r\n",(int)(&TestList.xListEnd));
	printf("ListItem1                         %#x					\r\n",(int)&ListItem1);
	printf("ListItem2                         %#x					\r\n",(int)&ListItem2);
	printf("ListItem3                         %#x					\r\n",(int)&ListItem3);
	printf("/************************结束**************************/\r\n");
	printf("按下KEY_UP键继续!\r\n\r\n\r\n");

最初と 2 番目のステップは、リストとリスト項目を初期化し、シリアル ポートを介してリストとリスト項目のアドレスを出力するために使用されます。このステップは、開発ボードがリセットされた後にデフォルトで実行されます。シリアル ポート デバッグの情報アシスタントは以下の通りです。

これらのリストとリスト項目のアドレスの最初の 6 ビットはすべて 0X200000 であり、異なるのは下位 2 ビットだけであるため、これらのリストとリスト項目のアドレスを表すために下位 2 ビットを使用します知らせ!リストとリスト項目のアドレスは、ハードウェア プラットフォームやコンパイルされたソフトウェアによって異なります。実際の実験結果を参照してください。図 7.7.2.1 を分析するだけで、次の情報が得られます。

1. リスト TestList のアドレスは bc です。

2. リスト項目 ListItem1、ListItem2、ListItem3 のアドレスはそれぞれ d0、e4、f8 です。

3. リスト TestList の xListEnd アドレスは bc です。4. リスト TestList の pxIndex はアドレス bc を指し、このアドレスはまさにミニリスト項目 xListEnd であり、pxIndex が xListEnd を指すことを示します。これは、リスト初期化関数 vListInitialise() を分析したときに得られる結果と一致しています。 。

第三段階

	while(KEY_Scan(0)!=WKUP_PRES) delay_ms(10);					//等待KEY_UP键按下
	
	//第三步:向列表TestList添加列表项ListItem1,并通过串口打印所有
	//列表项中成员变量pxNext和pxPrevious的值,通过这两个值观察列表
	//项在列表中的连接情况。
	vListInsert(&TestList,&ListItem1);		//插入列表项ListItem1
	printf("/******************添加列表项ListItem1*****************/\r\n");
	printf("项目                              地址				    \r\n");
	printf("TestList->xListEnd->pxNext        %#x					\r\n",(int)(TestList.xListEnd.pxNext));
	printf("ListItem1->pxNext                 %#x					\r\n",(int)(ListItem1.pxNext));
	printf("/*******************前后向连接分割线********************/\r\n");
	printf("TestList->xListEnd->pxPrevious    %#x					\r\n",(int)(TestList.xListEnd.pxPrevious));
	printf("ListItem1->pxPrevious             %#x					\r\n",(int)(ListItem1.pxPrevious));
	printf("/************************结束**************************/\r\n");
	printf("按下KEY_UP键继续!\r\n\r\n\r\n");
	while(KEY_Scan(0)!=WKUP_PRES) delay_ms(10);					//等待KEY_UP键按下

 1. xListEnd の pxNext はアドレス d0 を指し、d0 は ListItem1 のアドレスです。つまり、xListEnd の pxNext は ListItem1 を指します。(指輪)

2. ListItem1 の pxNext はアドレス c4 を指し、c4 は xListEnd のアドレスです。つまり、ListItem1 の pxNext は xListEnd を指します。

3. xListEnd の pxPrevious はアドレス d0 を指し、d0 は ListItem1 のアドレスです。つまり、xListEnd の pxPrevious は ListItem2 を指します。

4. ListItem1 の pxPrevious はアドレス c4 を指し、c4 は xListEnd のアドレスです。これは、ListItem1 の pxPrevious が xListEnd を指すことを示します。

4番目のステップ

 1. xListEnd の pxNext は ListItem1 を指します。

2. ListItem1 の pxNext は ListItem2 を指します。

3. ListItem2 の pxNext は xListEnd を指します。

4. リスト項目の pxPrevious 分析プロセスも同様であり、次の手順では分析は行われません。

 5番目のステップ

 1. xListEnd の pxNext は ListItem1 を指します。

2. ListItem1 の pxNext は ListItem3 を指します。

3. ListItem3 の pxNext は ListItem2 を指します。

4. ListItem2 の pxNext は xListEnd を指します。

ステップ 6 と 7

これら 2 つの手順は、関数 uxListRemove() および vListInsertEnd() の実行プロセスを観察することです。

ここでは7 番目のステップのみを分析します

 この文は、TestList.pxIndex が指す位置を変更します。デフォルトでは、リストの末尾を指します。ここでは、リスト 1 を指します。

それでランク付けしてください

この挿入関数は TestList.pxIndex が指す位置の前に 1 ビットを挿入するため、132 は 213 になります。

 1. xListEnd の pxNext は ListItem2 を指します。

2. ListItem1 の pxNext は ListItem3 を指します。

3. ListItem3 の pxNext は xListEnd を指します。

4. ListItem2 の pxNext は ListItem1 を指します。

シリアル ポート デバッグ アシスタントによって出力された情報に基づいて、独自の分析を行うことができます。

リンク: https://pan.baidu.com/s/1ZHX16Nuim6pWLH-y2XM7zQ?pwd=rtos 
抽出コード: rtos

 

おすすめ

転載: blog.csdn.net/qq_51519091/article/details/131604382