📄 example.c
字号:
/*包含必要的Nucleus PLUS 文件*/
#include <nucleus.h>
/*定义应用程序数据结构*/
NU_TASK Task_0;
NU_TASK Task_1;
NU_TASK Task_2;
NU_TASK Task_4;
NU_TASK Task_5;
NU_QUEUE Queue_0;
NU_SEMAPHORE Semaphore_0;
NU_EVENT_GROUP Event_Group_0;
NU_MEMORY_POOL System_Memory;
/*分配全局计数器*/
unsigned Task_Time;
UNSIGNED Task_2_message_received;
UNSIGNED Task_2_ invalid_messages;
UNSIGNED Task_1_messages_sent;
NU_TASK *Who_has_the_resource;
UNSIGNED Event_Detections;
/*定义引用函数的原型*/
void task_0(UNSIGNED argc,VOID *argv);
void task_1(UNSIGNED argc,VOID *argv);
void task_2(UNSIGNED argc,VOID *argv);
void task3_and_4(UNSIGNED argc,VOID *argv);
void task_5(UNSIGNED argc,VOID *argv);
void main(void)
{
/*这是一个汇编函数,处理底层的和目标板相关的初始化。当这个函数完成后,就调用Inc_Initialize */
/*Inc_Initialize是系统初始化函数,所有的组件都被该函数初始化,之后再调用Application_Initialize */
Int_Initialize();/*-->Inc_Initialize(VOID *first_available_memory)-->Application_Initialize() */
/*任务调度函数:该函数等待一个变成就绪的线程,当一个线程就绪时,该函数就开始将控制权转移给该线程*/
TCT_Schedule();
}
/*************************************************************************
*定义应用程序初始化子程序,初始化子程序决定初始化Nucleus PLUS 应用程序环境
*************************************************************************/
void Application_Initialize(void *first_available_memeory)
{
VOID *pointer;
/*创建一个系统内存池将用于分配任务堆栈,队列区域等*/
NU_Create_Memory_Pool(&System_Memory,”SYSTEM”, first_available_memory,20000,50,NU_FIFO);
/*创建系统中的每个任务*/
/*创建任务0*/
NU_Allocate_Memory(&System_Memory,&pointer,1333, NU_NO_SUSPEND);
NU_Create_Task(&Task_0,TASK_0,task_0,0,NU_NULL,pointer,1000,1,20,NU_PREEMPT,NU_START);
/*创建任务1*/
NU_Allocate_Memory(&System_Memory,&pointer,1000, NU_NO_SUSPEND);
NU_create_Task(&Task_1,TASK_1,task_1,3,NU_NULL,pointer,1000,10,5,NU_PREEMPT,NU_START);
/*创建任务2*/
NU_Allocate_Memory(&System_Memory,&pointer,1333, NU_NO_SUSPEND);
NU_Create_Task(&Task_2,TASK_2,task_2,0,NU_NULL,pointer,1000,13,5,NU_PREEMPT,NU_START);
/*创建任务3。注意任务4 用的同一个指令区*/
NU_Allocate_Memory(&System_Memory,&pointer,1000, NU_NO_SUSPEND);
NU_Create_Task(&Task_3,TASK_3,task3_and_4,0,NU_NULL, pointer,1000,5,0,NU_PREEMPT,NU_START);
/*创建任务4。注意任务3 使用同样的指令区*/
NU_Allocate_Memory(&System_Memory,&pointer,1000, NU_NO_SUSPEND);
NU_Create_Task(&Task_4,TASK_4,task_4,3,NU_NULL,pointer,1000,5,0,NU_PREEMPT,NU_START);
/*创建任务5*/
NU_Allocate_Memory(&System_Memory,&pointer,1000, NU_NO_SUSPEND);
NU_Create_Task(&Task_5,TASK_5,task_5,0,NU_NULL,pointer,1000,7,0,NU_PREEMPT,NU_START);
/*创建通信队列*/
NU_Allocate_Memory(&System_Memory,&pointer,100*sizeof(UNSIGNED),NU_NO_SUSPEND);
NU_Create_Queue(&Queue_0,QUEUE_0,pointer,100,NU_FIXED_SIZE,1,NU_FIFO);
/*创建同步信号量*/
NU_Create_Semaphore(&Semaphore_0,SEM_0,1,NU_FIFO);
/*创建事件标志集*/
NU_Create_Event_Group(&Event_Group_0,EVGROUP0);
}
/*****************************************************************
*定义任务0。任务0 每18 个时钟节拍递增一次Task_Time 变量。另外,
*任务0置位任务5 正在等待的事件标志集,每个循环一次反复
*任务0 无限循环的处理包括连续调用NU_Sleep 和NU_Set_Events。
*因为NU_Sleep 的调用,任务0 循环每18 个定时器节拍运行一次。
*****************************************************************/
void task_0(UNSIGNED argc,VOID *argv)
{
STATUS status;
/*访问argc 和argv 只是为了避免编辑警告*/
status = (STATUS) argc + (STATUS)argv;
/*设置时钟为0。这个时钟每18 个系统定时器节拍为一拍。*/
Task_Time = 0;
while(1)
{
/*休眠18 个定时器节拍。在IND.ASM 中时钟节拍值可编程,且与目标系统的速度有关*/
NU_Sleep(18);
/*递增次数*/
Task_Time++;
/*设置事件标志来消除任务5 的挂起*/
/*任务5优先级低于任务0,在任务0再次运行NU_Sleep调用之前,任务5不会运行*/
NU_Set_Events(&Event_Group_0,1,NU_OR);
}
}
/*****************************************************************
*定义队列发送任务。对列满条件和配置文件指定的时间片导致任务挂起。
*任务1 连续发送单个32 位消息到队列0。当管道充满时,任务1挂起,
*直到队列0空间有效(有可用空间)。任务1的挂起允许任务2 恢复运行。
*****************************************************************/
void task_1(UNSIGNED argc,void *argv)
{
STATUS status;
UNSIGNED Send_Message;
/*访问argc 和argv 只是为了避免编辑警告*/
status = (STATUS)argc + (STATUS)argv;
/*初始化消息计数器*/
Task_1_messages_send = 0;
/*初始化消息内容。接收器将检查消息内容是否错误。*/
Send_Message = 0;
while(1)
{
/*发送消息到Queue_0,任务2 从里面读。注意如果目标队列充满,这个任务挂
起直到空间有效*/
status = NU_Send_To_Queue(&Queue_0,&Send_Message,1,
NU_SUSPEND);
/*确定消息是否发送成功*/
if (status == NU_SUCCESS){
Task_1_message_sent++;
}
/*修改下一个发送消息的内容*/
Send_Message++;
}
}
/*****************************************************************
*定义队列接收任务。注意队列空条件和配置文件指定的时间片导致任务挂起
*任务2 连续从队列0接收单个32 位消息。当队列为空时,任务挂起,直到队
*列0空间有效(有可用消息)。任务1 的挂起允许任务2 恢复运行。
*****************************************************************/
void task_2(UNSIGNED argc,VOID *argv)
{
STATUS status;
UNSIGNED Receive_Message;
UNSIGNED received_size;
UNSIGNED message_expected;
/*访问argc 和argv 只是为了避免编辑警告*/
status = (STATUS)argc + (STATUS)argv;
/*初始化消息计数器*/
Task_2_message_received = 0;
/*初始化消息错误计数器*/
Task_2_invalid_messages = 0;
/*初始化消息内容为期望值*/
message_expected = 0;
while(1)
{
/*从Queue_0 重新获得任务1 写入的消息,注意如果源队列为空,这个任务挂
起知道有东西可用*/
status = NU_Receive_From_Queue(&Queue_0,&Receive_Message,1,&received_size,NU_SUSPEND);
/*确定消息是否接收正确*/
if (status == NU_SUCCESS){
Task_2_message_received++;
}
/*检测消息内容是否与任务期望一致*/
if ((received_size !=) || (Receive_Message != message_expected)){
Task_2_invalid_messages++;
}
message_expected++;
}
}
/*****************************************************************
*Task_3_and_4 只想要单个资源。一旦其中一个任务获得资源,它将在释放
*它之前保持33 个时钟节拍。在这期间,其他任务挂起等待这个资源。注意
*任务3和4都使用同样的代码区但是堆栈不一样。
*****************************************************************/
void task_3_and_4(UNSIGNED argc,VOID *argv)
{
STATUS status;
/*访问argc 和argv 只是为了避免编辑警告*/
status = (STATUS)argc + (STATUS)argv;
/*循环分配和收回资源*/
while(1)
{
/*分配资源。挂起知道它变得有效*/
status = NU_Obtain_Semaphore(&Semaphore_0,NU_NU_SUSPEND);
/*如果status 为成功,显示这个任务拥有资源*/
if (status == NU_SUCCESS)
{
Who_has_the_resource = NU_Create_Task_Pointer();
/*休眠100 个时钟节拍导致其他任务挂起等待资源*/
NU_Sleep(100);
/*释放信号量*/
NU_Release_Semaphore(&Semaphore_0);
}
}
}
/*****************************************************************
*定义等待任务0 设置事件的任务
*此任务在一个死循环中等待事件标志被置位。被等待的事件标
*志被任务0 置位。因此,任务5 和任务0 以同样的频率运行
*****************************************************************/
void task_5(UNSIGNED argc,VOID *argv)
{
STATUS status;
UNSIGNED event_group;
/*访问argc 和argv 只是为了避免编辑警告*/
status = (STATUS)argc + (STATUS)argv;
/*初始化事件跟踪计数器*/
Event_Detections = 0;
/*永远继续这个处理*/
while(1)
{
/*等待一个事件且消耗它*/
status = NU_Retrieve_Events(&Event_Group_0,1,NU_OR_CONSUME,&event_group,NU_SUSPEND);
/*如果status 成功,递增计数器*/
if (status == NU_SUCCESS){
Event_Detections++;
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -