1. 程式人生 > >嵌入式系統資料結構

嵌入式系統資料結構

由於作業系統具有與普通軟體不同的任務, 因此它就有些不同的特點, 包括一些不同的資料結構, 常用資料結構如下

一. 程式控制塊

typedef struct tcb
{
	char* code_name;	//程式碼名稱
	int p;				//重要性級別
	int V_num;			//版本號
	void (*fun)(void);	//指向被管理程式碼的函式指標
}TCB;

為了把這個結構與被管理程式碼關聯起來, 該結構包含了一個指向被管理程式碼的指標(函式指標), 如下圖所示

例2-8程式碼:

/*
* @Author: FourLeafClover
* @Date:   2018-10-13 10:52:38
* @Last Modified by:   FourLeafClover
* @Last Modified time: 2018-10-13 11:48:56
*/

#include <stdio.h>
#include <string.h>

/*TCB結構體定義*/
typedef struct tcb
{
	char* code_name;	//程式碼名稱
	int p;				//重要性級別
	int V_num;			//版本號
	void (*fun)(void);	//指向被管理程式碼的函式指標
}TCB;

/*
 * @Fuction: fun1
 * @Description: 程式碼塊一服務函式
 * @param: 無
 * @return: 無
 */
void fun1(void)
{
	printf("I am fun1\n");
}

/*
 * @Fuction: fun2
 * @Description: 程式碼塊二服務函式
 * @param: 無
 * @return: 無
 */
void fun2(void)
{
	printf("I am fun2\n");
}

/*
 * @Fuction: fun3
 * @Description: 程式碼塊三服務函式
 * @param: 無
 * @return: 無
 */
void fun3(void)
{
	printf("I am fun3\n");
}

/*
 * @Fuction: TCB GreateTCB(char*name, int pp, int vnum, void(*f)(void))
 * @Description: 建立程式碼塊函式
 * @param name: 程式碼塊的名字
 * @param pp: 程式碼塊重要性
 * @param vnum: 程式碼塊版本號
 * @param f: 程式碼塊的執行函式
 * @return: tcb: 初始化的程式碼塊結構體
 */
TCB GreateTCB(char*name, int pp, int vnum, void(*f)(void))
{
	TCB tcb;			  //建立程式控制塊結構體
	tcb.code_name = name; //控制塊程式碼塊名字賦值
	tcb.p = pp;			  //重要性級別賦值
	tcb.V_num = vnum;	  //版本號賦值
	tcb.fun = f;		  //控制函式賦值

	return tcb;
}


int main(void)
{
	char code_name[3] = {0};//定義程式碼塊名字
	char i = 0;				
	char t = 0;				//定義查詢標誌
	TCB tcb[3];								//建立TCB結構體陣列
	tcb[0] = GreateTCB("F1", 2, 1, fun1);	//定義程式碼塊一的初始值
	tcb[1] = GreateTCB("F2", 3, 1, fun2);	//定義程式碼塊二的初始值
	tcb[2] = GreateTCB("F3", 4, 1, fun3);	//定義程式碼塊二的初始值

	/*使用者查詢需要的函式名, 並輸入*/
	printf("Please select fun_name:");
	scanf("%s", code_name);

	/*在tcb結構體中查詢使用者尋找的函式名*/
	for (i = 0; i < 3; i++)
	{
		/*對比結構體中的名字書否與使用者輸入的名字一樣*/
		if(strcmp(tcb[i].code_name, code_name) == 0)
		{
			tcb[i].fun();	//一樣則呼叫相應的函式
			t = 1;			//置標誌位為1
		}	
		/*沒有查詢相應的函式*/
		if((t == 0)&&(i == 2))
		{
			/*列印提示資訊*/
			printf("No code_name: %s\n", code_name);
		}	
	}
	return 0;
}

 

/*
* @Author: FourLeafClover
* @Date:   2018-10-13 10:52:38
* @Last Modified by:   FourLeafClover
* @Last Modified time: 2018-10-13 18:21:30
*/

#include <stdio.h>
#include <string.h>

/*TCB結構體定義*/
typedef struct tcb
{
	struct tcb *pre;	//指向前一個結構體的指標
	struct tcb *next;	//指向下一個結構體的指標
	char* code_name;	//程式碼名稱
	int p;				//重要性級別
	int V_num;			//版本號
	void (*fun)(void);	//指向被管理程式碼的函式指標
}TCB;

/*
 * @Fuction: fun1
 * @Description: 程式碼塊一服務函式
 * @param: 無
 * @return: 無
 */
void fun1(void)
{
	printf("I am fun1\n");
}

/*
 * @Fuction: fun2
 * @Description: 程式碼塊二服務函式
 * @param: 無
 * @return: 無
 */
void fun2(void)
{
	printf("I am fun2\n");
}

/*
 * @Fuction: fun3
 * @Description: 程式碼塊三服務函式
 * @param: 無
 * @return: 無
 */
void fun3(void)
{
	printf("I am fun3\n");
}

/*
 * @Fuction: TCB GreateTCB(char*name, int pp, int vnum, void(*f)(void))
 * @Description: 建立程式碼塊函式
 * @param pre: 前一個控制塊結構體地址
 * @param next: 後一個控制塊結構體地址
 * @param name: 程式碼塊的名字
 * @param pp: 程式碼塊重要性
 * @param vnum: 程式碼塊版本號
 * @param f: 程式碼塊的執行函式
 * @return: tcb: 初始化的程式碼塊結構體
 */
TCB GreateTCB(TCB *pre, TCB *next, char*name, int pp, int vnum, void(*f)(void))
{
	TCB tcb;			  //建立程式控制塊結構體
	tcb.pre = pre;		  //設定前一個控制塊的地址
	tcb.next = next;	  //設定後一個控制塊的地址
	tcb.code_name = name; //控制塊程式碼塊名字賦值
	tcb.p = pp;			  //重要性級別賦值
	tcb.V_num = vnum;	  //版本號賦值
	tcb.fun = f;		  //控制函式賦值

	return tcb;
}


int main(void)
{
	char str_number = 0;//定義程式碼塊名字
	char i = 0;				
	char t = 0;				//定義查詢標誌
	TCB tcb[3];								//建立TCB結構體陣列
	TCB *(tcb_array[3]) = {NULL};			//定義三個指標的指標陣列
	tcb[0] = GreateTCB(NULL, &tcb[1], "F1", 2, 1, fun1);	//定義程式碼塊一的初始值
	tcb[1] = GreateTCB(&tcb[0], &tcb[2], "F2", 3, 1, fun2);	//定義程式碼塊二的初始值
	tcb[2] = GreateTCB(&tcb[1], NULL, "F3", 4, 1, fun3);	//定義程式碼塊二的初始值

	/*給指標陣列賦值*/
	for (i = 0; i < 3; i++)
	{
		tcb_array[i] = &tcb[i];
	}

	/*使用者查詢需要的函式, 並輸入*/
	printf("Please select number struct:");
	scanf("%d", &str_number);

	/*查詢相應的結構體*/
	if(NULL == tcb_array[str_number]->pre)
		printf("the pre struct is NULL\n");	
	else
		(tcb_array[str_number] -> pre) -> fun();
	tcb_array[str_number] -> fun();

	if(NULL == tcb_array[str_number]->next)
		printf("the next struct is NULL\n");	
	else
		(tcb_array[str_number] -> next) -> fun();

	return 0;
}

 

三  點陣圖

看到點陣圖, 想起了做智慧的時候, 對影象進行二值化, 這個原理也差不多. 做個小實驗吧,  把上面的三個結構體控制塊分別設一個已經被佔用, 兩個個未被佔用,  讓程式找出未被佔用的控制塊.程式碼如下:

/*
* @Author: FourLeafClover
* @Date:   2018-10-13 10:52:38
* @Last Modified by:   FourLeafClover
* @Last Modified time: 2018-10-13 18:50:35
*/

#include <stdio.h>
#include <string.h>

/*TCB結構體定義*/
typedef struct tcb
{
	struct tcb *pre;	//指向前一個結構體的指標
	struct tcb *next;	//指向下一個結構體的指標
	char* code_name;	//程式碼名稱
	int p;				//重要性級別
	int V_num;			//版本號
	void (*fun)(void);	//指向被管理程式碼的函式指標
	char UsingFlag;		//定義是否正在使用, 0-未使用 1-正在使用
}TCB;

/*
 * @Fuction: fun1
 * @Description: 程式碼塊一服務函式
 * @param: 無
 * @return: 無
 */
void fun1(void)
{
	printf("I am fun1\n");
}

/*
 * @Fuction: fun2
 * @Description: 程式碼塊二服務函式
 * @param: 無
 * @return: 無
 */
void fun2(void)
{
	printf("I am fun2\n");
}

/*
 * @Fuction: fun3
 * @Description: 程式碼塊三服務函式
 * @param: 無
 * @return: 無
 */
void fun3(void)
{
	printf("I am fun3\n");
}

/*
 * @Fuction: TCB GreateTCB(char*name, int pp, int vnum, void(*f)(void))
 * @Description: 建立程式碼塊函式
 * @param pre: 前一個控制塊結構體地址
 * @param next: 後一個控制塊結構體地址
 * @param name: 程式碼塊的名字
 * @param pp: 程式碼塊重要性
 * @param vnum: 程式碼塊版本號
 * @param f: 程式碼塊的執行函式
 * @param UsingFlag: 是否使用標誌位
 * @return: tcb: 初始化的程式碼塊結構體
 */
TCB GreateTCB(TCB *pre, TCB *next, char*name, int pp, int vnum, void(*f)(void), char UsingFlag)
{
	TCB tcb;			  //建立程式控制塊結構體
	tcb.pre = pre;		  //設定前一個控制塊的地址
	tcb.next = next;	  //設定後一個控制塊的地址
	tcb.code_name = name; //控制塊程式碼塊名字賦值
	tcb.p = pp;			  //重要性級別賦值
	tcb.V_num = vnum;	  //版本號賦值
	tcb.fun = f;		  //控制函式賦值
	tcb.UsingFlag = UsingFlag;//對標誌位賦值

	return tcb;
}


int main(void)
{
	char str_number = 0;//定義程式碼塊名字
	char i = 0;				
	char t = 0;				//定義查詢標誌
	TCB tcb[3];								//建立TCB結構體陣列
	TCB *(tcb_array[3]) = {NULL};			//定義三個指標的指標陣列
	tcb[0] = GreateTCB(NULL, &tcb[1], "F1", 2, 1, fun1, 0);	//定義程式碼塊一的初始值
	tcb[1] = GreateTCB(&tcb[0], &tcb[2], "F2", 3, 1, fun2, 0);	//定義程式碼塊二的初始值
	tcb[2] = GreateTCB(&tcb[1], NULL, "F3", 4, 1, fun3, 0);	//定義程式碼塊二的初始值

	/*給指標陣列賦值*/
	for (i = 0; i < 3; i++)
	{
		tcb_array[i] = &tcb[i];
	}

	/*使用者查詢需要的函式, 並輸入*/
	printf("Please select Using tcb number:");
	scanf("%d", &str_number);

	/*置相應的控制塊為使用標誌*/
	tcb[str_number].UsingFlag = 1;
	/*查詢證被使用的控制塊*/
	for (i = 0; i < 3; i++)
	{
		if (1 == tcb[i].UsingFlag)
		{
			tcb[i].fun();
			break;
		}
	}

	if(3 == i)
	{
		printf("can not find!\n");
	}

	return 0;
}

完結!!!