⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 nucleus_task_dispatch.c

📁 Nucleus任务调度算法原理及Nucleus优先级查找表的原理(有详细的文档及演示代码)。
💻 C
字号:
/********************************************************************************					
*        When nucleus task dispatching, how it get a highest priority
*
*    File : Nucleus_priority_diapatch.c
*    BY :
*    Version :
*    Date :  
********************************************************************************/

#include <stdio.h>

typedef unsigned char DATA_ELEMENT;
typedef unsigned long UNSIGNED;
typedef unsigned char UNSIGNED_CHAR;
typedef int INT;

#define TC_PRIORITIES 256
#define TC_MAX_GROUPS (TC_PRIORITIES/8)

#define TC_HIGHEST_MASK 0x000000FFUL
#define TC_NEXT_HIGHEST_MASK 0x0000FF00UL
#define TC_NEXT_LOWEST_MASK 0x00FF0000UL
#define TC_LOWEST_MASK 0xFF000000UL

typedef struct nu_tcb
{
	UNSIGNED        tc_priority_group;     /* Priority group mask bit*/
	DATA_ELEMENT	tc_priority;           /* Task priority */
	DATA_ELEMENT	*tc_sub_priority_ptr;  /* Pointer to sub-group   */
	DATA_ELEMENT	tc_sub_priority;       /* Mask of sub-group bit  */	
	DATA_ELEMENT 	reserved;
}NU_TCB, *P_NU_TCB;

/********************************************************************************
*	TCD_Priority_Groups is a 32-bit unsigned integer that is used as a bit map.  
*	Each bit corresponds to an 8-priority group.  For example, if bit 0 is set, 
*	at least one task of priority 0 through 8 is ready for execution. 
********************************************************************************/
UNSIGNED TCD_Priority_Groups;

/********************************************************************************
* TCD_Sub_Priority_Groups is an array of sub-priority groups.  These are 
*   also used as bit maps.  Index 0 of this array corresponds to priorities 
*   0 through 8.  Bit 0 of this element represents priority 0, while bit 7 
*   represents priority 7. 
********************************************************************************/
DATA_ELEMENT TCD_Sub_Priority_Groups[TC_MAX_GROUPS];

/********************************************************************************
*	TCD_Highest_Priority contains the highest priority task ready for execution.
*	Note that this does not necessarily represent the priority of the currently 
*	executing task.  This is true if the currently executing task has preemption
*	disabled.  If no tasks are executing, this variable is set to the maximum
*	priority.
********************************************************************************/
INT TCD_Highest_Priority = TC_PRIORITIES;

/********************************************************************************
*	TCD_Lowest_Set_Bit is nothing more than a standard lookup table.  The 
*	table is indexed by values ranging from 1 to 255.  The value at that 
*	position in the table indicates the number of the lowest set bit.  This is 
*	used to determine the highest priority task represented in the previously 
*	defined bit maps.  
********************************************************************************/
UNSIGNED_CHAR TCD_Lowest_Set_Bit[] = 
{/*	1  2  3  4  5  6  7  8  9  10 11 12 13 14 15 16*/
	0, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, //1
	4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, //2
	5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, //3
	4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, //4
	6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, //5
	4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, //6
	5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, //7
	4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, //8
	7, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, //9
	4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, //10
	5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, //11
	4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, //12
	6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, //13
	4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, //14
	5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, //15
	4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, //16
};

static void nu_printf_highest_priority()
{
	printf("Now, The highest priority is : %d\n", TCD_Highest_Priority);
}

static void nu_create_task(NU_TCB *task_tcb, DATA_ELEMENT task_prio)
{
	task_tcb->tc_priority = task_prio;
    task_tcb->tc_sub_priority = (DATA_ELEMENT)(1<<(task_prio&7));
    task_prio >>= 3;
    task_tcb->tc_priority_group = ((UNSIGNED)1)<<task_prio; 
    task_tcb->tc_sub_priority_ptr = &(TCD_Sub_Priority_Groups[task_prio]);
}

static void nu_start_task(NU_TCB *task_tcb)
{
    TCD_Priority_Groups |= task_tcb->tc_priority_group;
    *(task_tcb->tc_sub_priority_ptr) |= task_tcb->tc_sub_priority;

    if((INT)(task_tcb->tc_priority) < TCD_Highest_Priority)
        TCD_Highest_Priority = (INT)task_tcb->tc_priority;
}

static void nu_find_highest_prio()
{
	UNSIGNED_CHAR index, temp;
	if(TCD_Priority_Groups & TC_HIGHEST_MASK)/* Base of sub-group is 0. */
		index =  0;
	else if (TCD_Priority_Groups & TC_NEXT_HIGHEST_MASK)/* Base of sub-group is 8. */
		index =  8;
	else if (TCD_Priority_Groups & TC_NEXT_LOWEST_MASK)	/* Base of sub-group is 16.  */
		index =  16;
	else/* Base of sub-group is 24. */
		index =  24;
	index +=  TCD_Lowest_Set_Bit[(INT)((TCD_Priority_Groups >> index) & TC_HIGHEST_MASK)];
	temp =  TCD_Sub_Priority_Groups[index];
	TCD_Highest_Priority = (index << 3) + TCD_Lowest_Set_Bit[temp];
}

static void get_a_priority(INT *prio)
{
reinput:
	printf("Please input a priority : ");
	scanf("%d", prio);
	if(*prio > 255 || *prio < 0)
	{
		printf("Unlogical priority!\n");
		goto reinput;
	}
	printf("\n");
	printf("The 1st priority you input is : %d\n", *prio);	
}

static void execute_priority_test_routine(INT priority)
{
	NU_TCB tcb;

	nu_create_task(&tcb, priority);
	nu_start_task(&tcb);
	nu_find_highest_prio();
	
	nu_printf_highest_priority();
}

int main(int argc, char *argv[])
{	
	NU_TCB my_tcb;
	INT i, my_prio;

	for(i=0;i<5;i++)
	{
		get_a_priority(&my_prio);	
		execute_priority_test_routine((UNSIGNED_CHAR)my_prio);
	}
	system("pause");

	return 0;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -