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

📄 demoreference.c

📁 基于OMAP1510的Nucleus移植代码
💻 C
字号:
/*The  example  system  described  in  this  chapter  is  comprised  of  an 
Application_Initialize function  and  six  tasks. All  of  the  tasks  are  created  during 
initialization.  In  addition  to  task  execution,  task  communication  and  synchronization  are 
demonstrated in this example. 
In  the  example  system  listing,  the  data  structures  are  defined  between  lines  3  and  20. 
Nucleus PLUS control structures are defined between lines 3 and 13. 
Application_Initialize starts  at  line  30,  and  ends  at  line  71.    In  this  example,  all 
system  objects  (tasks,  queues,  semaphores,  and  event  flag  groups)  are  created  during 
initialization.    The  example  system  tasks  are  created  between  lines  38  and  61.    The 
communication queue  is  created  at  line  64.    The  system  semaphore  is  created  at line 68.  
Finally, the system event flag group is created at line 70.   
NOTE:  A  20,000  byte  memory  pool,  starting  at  the  address  specified  by  the 
first_available_memory parameter is created first, at line 35.  This memory 
pool is used to allocate all of the task stacks and the actual queue area.  
Task  0  is  the  first  task  to  execute  when  the  system  starts.    This  is  because  task  0  is  the 
highest priority task in the system (priority 1).  Task 3  executes  after  task  0  suspends 
(priority 5).  Task 4 executes after task 3 suspends.  It is important to realize why task 3 
executes before task 4 although they both have the same priority.  The reason for this is 
that task 3 was created and started first (see Application_Initialize).  Tasks of the 
same priority execute in the order they become ready for execution. After task 4 suspends, 
task 5 executes (priority 7).  After task 5 suspends, task 1 executes (priority 10).  Finally, 
task 2 executes (priority 10) after task 1 suspends on a queue full condition. 
Task 0 is defined between lines 76 and 92.  Like all of the tasks in this example system, 
task  0  does  some  preliminary  initialization  and  then  starts  execution  of  an  endless  loop.  
Processing  inside  of  task  0.s  endless  loop  includes  successive  calls  to NU_Sleep and  
NU_Set_Events. Because of the call to NU_Sleep, task 0.s loop is executed once every 
18 timer ticks.   
NOTE: Task 5 is made ready on each call to NU_Set_Events. Since task 5 has 
a lower priority than task 0, it does not execute until task 0  executes  the
NU_Sleep call again. 
Task  1  is  defined  between  lines  96  and  121.    Task  1  continually  sends  a  single  32-bit 
message  to  queue  0.  When  the  capacity  of  the  queue  is  reached,  task  1  suspends,  until 
room is available in queue 0.  The suspension of task 1 allows task 2 to resume execution. 
Task  2  is  defined  between  lines  124 and  156.    Task 2 continually  retrieves  single  32-bit 
messages  from  queue  0.    When  the  queue  becomes  empty,  task  2  suspends.    The 
suspension of task 2 allows task 1 to resume execution. 
Tasks  3  and  4  share  the  same  instruction  code.    However,  each  task has  its own unique 
stack.    Tasks  3  and  4  are  defined  between  lines 162 and  184.   Each task competes for a 
binary  semaphore.    Once  the  semaphore  is  obtained,  the  task  sleeps  for 100 ticks  before 
releasing the semaphore again.   
This  action  allows  the  other  task  to  execute  and  suspend  attempting  to  obtain  the  same 
semaphore.  When the semaphore is released, suspension is lifted on the task waiting for 
the semaphore. 
Task 5 is defined between lines 186 and 204.  This task is in an endless loop waiting for an 
event flag to be set.  The desired event flag is set by task 0.  Therefore, task 5 executes at 
the same frequency as task 0. 
Example System  
The following is a source file listing of the example system.   
NOTE:  The  line  number  on  the  left  is  not  part  of  the  actual  file,  it  is  there  for 
reference purposes only. 
*/

1 /* Include necessary Nucleus PLUS files. */
2 #include "inucleus.h”
3 /* Define Application data structures. */
4 NU_TASK Task_0;
5 NU_TASK Task_1;
6 NU_TASK Task_2;
7 NU_TASK Task_3;
8 NU_TASK Task_4;
9 NU_TASK Task_5;
10 NU_QUEUE Queue_0;
11 NU_SEMAPHORE Semaphore_0;
12 NU_EVENT_GROUP Event_Group_0;
13 NU_MEMORY_POOL System_Memory;
14 /* Allocate global counters. */
15 UNSIGNED Task_Time;
16 UNSIGNED Task_2_messages_received;
17 UNSIGNED Task_2_invalid_messages;
18 UNSIGNED Task_1_messages_sent;
19 NU_TASK * Who_has_the_resource;
20 UNSIGNED Event_Detections;
21 /* Define prototypes for function references. */
22 void task_0(UNSIGNED argc, VOID *argv);
23 void task_1(UNSIGNED argc, VOID *argv);
24 void task_2(UNSIGNED argc, VOID *argv);
25 void task_3_and_4(UNSIGNED argc, VOID *argv);
26 void task_5(UNSIGNED argc, VOID *argv);
/*27  Define the Application_Initialize routine that determines the initial
  28 Nucleus PLUS application environment. */
29
30 void Application_Initialize(void *first_available_memory)
31 {
32 VOID *pointer;
/*33  Create a system memory pool that will be used to allocate task
  34  stacks, queue areas, etc. */
35 NU_Create_Memory_Pool(&System_Memory, "SYSMEM”, first_available_memory,
36 20000, 50, NU_FIFO);
37 /* Create each task in the system. */
38 /* Create task 0. */
39 NU_Allocate_Memory(&System_Memory, &pointer, 1000, NU_NO_SUSPEND);
40 NU_Create_Task(&Task_0, "TASK 0”, task_0, 0, NU_NULL, pointer, 1000, 1,
41 20, NU_PREEMPT, NU_START);
42 /* Create task 1. */
43 NU_Allocate_Memory(&System_Memory, &pointer, 1000, NU_NO_SUSPEND);
44 NU_Create_Task(&Task_1, "TASK 1”, task_1, 0, NU_NULL, pointer, 1000, 10,
45 5,NU_PREEMPT, NU_START);
46 /* Create task 2. */
47 NU_Allocate_Memory(&System_Memory, &pointer, 1000, NU_NO_SUSPEND);
48 NU_Create_Task(&Task_2, "TASK 2”, task_2, 0, NU_NULL, pointer, 1000,
49 10, 5, NU_PREEMPT, NU_START);
50 /* Create task 3. Note: task 4 uses the same instruction area. */
51 NU_Allocate_Memory(&System_Memory, &pointer, 1000, NU_NO_SUSPEND);
52 NU_Create_Task(&Task_3, "TASK 3”, task_3_and_4, 0, NU_NULL, pointer,
53 1000, 5, 0, NU_PREEMPT, NU_START);
54 /* Create task 4. Note that task 3 uses the same instruction area.*/
55 NU_Allocate_Memory(&System_Memory, &pointer, 1000, NU_NO_SUSPEND);
56 NU_Create_Task(&Task_4, "TASK 4”, task_3_and_4, 0, NU_NULL, pointer,
57 1000, 5, 0, NU_PREEMPT, NU_START);
58 /* Create task 5. */
59 NU_Allocate_Memory(&System_Memory, &pointer, 1000, NU_NO_SUSPEND);
60 NU_Create_Task(&Task_5, "TASK 5”, task_5, 0, NU_NULL, pointer, 1000, 7, 0,
61 NU_PREEMPT, NU_START);
62 /* Create communication queue. */
63 NU_Allocate_Memory(&System_Memory, &pointer, 100*sizeof(UNSIGNED),
64 NU_NO_SUSPEND);
65 NU_Create_Queue(&Queue_0, "QUEUE 0”, pointer, 100, NU_FIXED_SIZE, 1,
66 NU_FIFO);
67 /* Create synchronization semaphore. */
68 NU_Create_Semaphore(&Semaphore_0, "SEM 0”, 1, NU_FIFO);
69 /* Create event flag group. */
70 NU_Create_Event_Group(&Event_Group_0, "EVGROUP0”);
71 }
72
73 /* Define task 0. Task 0 increments the Task_Time variable every
74 18 clock ticks. Additionally, task 0 sets an event flag that
75 task 5 is waiting for, on each iteration of the loop. */
76 void task_0(UNSIGNED argc, VOID *argv)
77 {
78 STATUS status;
79 /* Access argc and argv just to avoid compilation warnings.*/
80 status = (STATUS) argc + (STATUS) argv;
81 /* Set the clock to 0. This clock ticks every 18 system timer ticks. */
82 Task_Time = 0;
83 while(1)
84 {
85 /* Sleep for 18 timer ticks. The value of the tick is programmable in
IND.ASM and is relative to the speed of the target system. */
86 NU_Sleep(18);
87 /* Increment the time. */
88 Task_Time++;
89 /* Set an event flag to lift the suspension on task 5.*/
90 NU_Set_Events(&Event_Group_0, 1, NU_OR);
91 }
92 }
93 /* Define the queue sending task. Note that the only things that cause
94 this task to suspend are queue full conditions and the time slice
95 specified in the configuration file. */
96 void task_1(UNSIGNED argc, VOID *argv)
97 {
98 STATUS status;
99 UNSIGNED Send_Message;
100 /* Access argc and argv just to avoid compilation warnings. */
101 status = (STATUS) argc + (STATUS) argv;
102 /* Initialize the message counter. */
103 Task_1_messages_sent = 0;
104 /* Initialize the message contents. The receiver will
105 examine the message contents for errors. */
106 Send_Message = 0;
107 while(1)
108 {
109
110 /* Send the message to Queue_0, which task 2 reads from. Note
111 that if the destination queue fills up this task suspends until
112 room becomes available. */
113 status = NU_Send_To_Queue(&Queue_0, &Send_Message, 1,
114 NU_SUSPEND);
115 /* Determine if the message was sent successfully. */
116 if (status == NU_SUCCESS)
117 Task_1_messages_sent++;
118 /* Modify the contents of the next message to send. */
119 Send_Message++;
120 }
121 }
/* Define the queue receiving task. Note that the only things that
122 cause this task to suspend are queue empty conditions and the
123 time slice specified in the configuration file. */
124 void task_2(UNSIGNED argc, VOID *argv)
125 {
126 STATUS status;
127 UNSIGNED Receive_Message;
128 UNSIGNED received_size;
129 UNSIGNED message_expected;
130 /* Access argc and argv just to avoid compilation warnings. */
131 status = (STATUS) argc + (STATUS) argv;
132 /* Initialize the message counter. */
133 Task_2_messages_received = 0;
134 /* Initialize the message error counter. */
135 Task_2_invalid_messages = 0;
136 /* Initialize the message contents to expect. */
137 message_expected = 0;
138 while(1)
139 {
140 /* Retrieve a message from Queue_0, which task 1 writes to.
141 Note that if the source queue is empty this task
142 suspends until something becomes available. */
143 status = NU_Receive_From_Queue(&Queue_0, &Receive_Message, 1,
144 &received_size, NU_SUSPEND);
145 /* Determine if the message was received successfully. */
146 if (status == NU_SUCCESS)
147 Task_2_messages_received++;
148 /* Check the contents of the message against what this task
149 is expecting. */
150 if ((received_size != 1) ||
151 (Receive_Message != message_expected))
152 Task_2_invalid_messages++;
153 /* Modify the expected contents of the next message. */
154 message_expected++;
155 }
156 }
157 /* Tasks 3 and 4 want a single resource. Once one of the tasks gets the
158 resource, it keeps it for 30 clock ticks before releasing it. During
159 this time the other task suspends waiting for the resource. Note that
160 both task 3 and 4 use the same instruction areas but have different
161 stacks. */
162 void task_3_and_4(UNSIGNED argc, VOID *argv)
163 {
164 STATUS status;
165 /* Access argc and argv just to avoid compilation warnings. */
166 status = (STATUS) argc + (STATUS) argv;
167 /* Loop to allocate and deallocate the resource. */
168 while(1)
169 {
170 /* Allocate the resource. Suspend until it becomes available. */
171 status = NU_Obtain_Semaphore(&Semaphore_0, NU_SUSPEND);
172 /* If the status is successful, show that this task owns the
173 resource. */
174 if (status == NU_SUCCESS)
175 {
176 Who_has_the_resource = NU_Current_Task_Pointer();
177 /* Sleep for 100 ticks to cause the other task to suspend on
178 the resource. */
179 NU_Sleep(100);
180 /* Release the semaphore. */
181 NU_Release_Semaphore(&Semaphore_0);
182 }
183 }
184 }
185 /* Define the task that waits for the event to be set by task 0. */
186 void task_5(UNSIGNED argc, VOID *argv)
187 {
188 STATUS status;
189 UNSIGNED event_group;
190 /* Access argc and argv just to avoid compilation warnings. */
191 status = (STATUS) argc + (STATUS) argv;
192 /* Initialize the event detection counter. */
193 Event_Detections = 0;
Nucleus PLUS Reference Manual  
194 /* Continue this process forever. */
195 while(1)
196 {
197 /* Wait for an event and consume it. */
198 status = NU_Retrieve_Events(&Event_Group_0, 1, NU_OR_CONSUME,
199 &event_group, NU_SUSPEND);
200 /* If the status is okay, increment the counter. */
201 if (status == NU_SUCCESS)
202 Event_Detections++;
203 }
204 }

⌨️ 快捷键说明

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