1 /**************************************************************************/
2 /*                                                                        */
3 /*       Copyright (c) Microsoft Corporation. All rights reserved.        */
4 /*                                                                        */
5 /*       This software is licensed under the Microsoft Software License   */
6 /*       Terms for Microsoft Azure RTOS. Full text of the license can be  */
7 /*       found in the LICENSE file at https://aka.ms/AzureRTOS_EULA       */
8 /*       and in the root directory of this software.                      */
9 /*                                                                        */
10 /**************************************************************************/
11 
12 /**************************************************************************/
13 /**************************************************************************/
14 /**                                                                       */
15 /**   OSEK IMPLEMENTATION                                                 */
16 /**                                                                       */
17 /**************************************************************************/
18 /**************************************************************************/
19 
20 
21 /* Include necessary files.  */
22 
23 #include "os.h"
24 
25 /* Include some required internal headers. */
26 
27 #include <tx_timer.h>
28 #include <tx_thread.h>
29 #include <tx_initialize.h>
30 
31 
32 /* Declare a structure to hold application information.  */
33 
34 APPLICATION_INFO_PTR                    Application;
35 
36 
37 /* Define a global variable to hold operating mode of this wrapper.  */
38 
39 static UINT                             osek_wrapper_operation_mode = OSEK_INIT_NOT_DONE;
40 
41 
42 /* Define the threads for the System Manager.  */
43 
44 TX_THREAD                               osek_system_manager;
45 
46 
47 /* Define ThreadX message queues for System Manager.  */
48 
49 TX_QUEUE                                osek_work_queue;
50 
51 
52 /* Define a byte pool control block for the osek region0 memory used.  */
53 
54 TX_BYTE_POOL                            osek_region0_byte_pool;
55 
56 
57 /* Define ThreadX timer to act as a system timer.  */
58 
59 TX_TIMER                                osek_system_timer;
60 
61 
62 /************ OSEK System objects Definitions **************/
63 
64 /* Define a static pool of Task structures.  */
65 
66 static OSEK_TCB                         osek_tcb_pool[OSEK_MAX_TASKS];
67 
68 
69 /* Define a static pool of resource structures.  */
70 
71 static OSEK_RESOURCE                    osek_res_pool[OSEK_MAX_RES];
72 
73 
74 /* Defines a static pool of alarm structures.  */
75 
76 static OSEK_ALARM                       osek_alarm_pool[OSEK_MAX_ALARMS];
77 
78 
79 /* Defines a static pool of counter structures.  */
80 
81 static OSEK_COUNTER                     osek_counter_pool[OSEK_MAX_COUNTERS];
82 
83 
84 /* Define a Task Ready Queue.  */
85 /* For each OSEK priority there is a sub queue, each queue entry holds an id of a task ready to run.  */
86 
87 TaskType                                task_table [OSEK_ISR1_PRIORITY + 1u][TASK_QUEUE_DEPTH];
88 
89 
90 /* A global variable holding all 32 events (bit flags) for this OS implementation.  */
91 
92 EventMaskType                           global_events;
93 EventMaskType                           global_event_count;
94 
95 
96 /* Define some default system objects.  */
97 
98 ResourceType                            RES_SCHEDULER;
99 CounterType                             SYS_TIMER;
100 
101 
102 /* Variables to store current and last executed task details.  */
103 
104 ULONG                                   last_run_task;
105 ULONG                                   system_start;                   /* If TX_TRUE indicates a fresh system start.  */
106 UINT                                    task_terminated;
107 
108 
109 /* Define ISR2 controlling flags.  */
110 /* disable_ISR2 is the global enable/disable flag , if this flag is set no ISR2 is allowed or even kept pending.  */
111 /* suspend_ISR2 is NON Zero then any ISR2 is kept pending (provided that disable_ISR2 must be zero before hand).  */
112 
113 /* disable_ISR2 = TX_FALSE & suspend_ISR2 = TX_FALSE :: process ISR2 immediately
114    disable_ISR2 = TX_FALSE & suspend_ISR2 = TX_TRUE  :: log ISR2 but don't process till suspend_ISR2 becomes TX_FALSE
115    disable_ISR2 = TX_TRUE  & suspend_ISR2 DON't care :: No ISR2 logged and executed  */
116 
117 UINT                                    disable_ISR2 = TX_TRUE;         /* This flag must be TX_FALSE to allow ISR 2.  */
118 UINT                                    suspend_ISR2 = TX_TRUE;         /* This flag must be TX_FALSE to register and execute ISR2.  */
119 UINT                                    ISR2_pending = TX_FALSE;
120 
121 /* Track initialization status.  */
122 
123 static UINT                             osek_init_state; /* Set to 0 for uninitialized, 1 for initialized by not yet started and 2 if started.  */
124 
125 #define OSEK_NOT_INIT (0U)
126 #define OSEK_INIT     (1U)
127 #define OSEK_STARTED  (2U)
128 
129 #define OSEK_MAX_LINK_DEPTH (1024U) /* Maximum depth of linked resource, to prevent infinite loops in case of a corrupted list.  */
130 
131 /* OSEK API Services and associated structures.  */
132 
133 struct Service_ActivateTask             service_ActivateTask;
134 struct Service_TerminateTask            service_TerminateTask;
135 struct Service_ChainTask                service_ChainTask;
136 struct Service_Schedule                 service_Schedule;
137 struct Service_GetTaskID                service_GetTaskID;
138 struct Service_GetTaskState             service_GetTaskState;
139 
140 struct Service_DisableAllInterrupts     service_DisableAllInterrupts;
141 struct Service_EnableAllInterrupts      service_EnableAllInterrupts;
142 struct Service_SuspendAllInterrupts     service_SuspendAllInterrupts;
143 struct Service_ResumeAllInterrupts      service_ResumeAllInterrupts;
144 struct Service_SuspendOSInterrupts      service_SuspendOSInterrupts;
145 struct Service_ResumeOSInterrupts       service_ResumeOSInterrupts;
146 
147 struct Service_GetResource              service_GetResource;
148 struct Service_ReleaseResource          service_ReleaseResource;
149 
150 struct Service_SetEvent                 service_SetEvent;
151 struct Service_ClearEvent               service_ClearEvent;
152 struct Service_GetEvent                 service_GetEvent;
153 struct Service_WaitEvent                service_WaitEvent;
154 
155 struct Service_GetAlarmBase             service_GetAlarmBase;
156 struct Service_GetAlarm                 service_GetAlarm;
157 struct Service_SetRelAlarm              service_SetRelAlarm;
158 struct Service_SetAbsAlarm              service_SetAbsAlarm;
159 struct Service_CancelAlarm              service_CancelAlarm;
160 
161 struct Service_GetActiveApplicationMode service_GetActiveApplicationMode;
162 struct Service_StartOS                  service_StartOS;
163 struct Service_ShutdownOS               service_ShutdownOS;
164 
165 struct Service_GetServiceId             service_GetServiceId;
166 
167 
168 /**************************************************************************/
169 /*          OSEK internal functions prototypes                            */
170 /**************************************************************************/
171 
172 
173 /* Entry functions for various ThreadX threads used for OS management.  */
174 
175 static void             osek_system_manager_entry(ULONG input);
176 static void             osek_system_timer_entry(ULONG input);
177 static void             osek_task_wrapper(ULONG tcb);
178 
179 
180 /* Initialization and reset for OSEK system objects.  */
181 
182 static UINT             osek_memory_init (void *region0_ptr);
183 static void             osek_alarm_init(void);
184 static void             osek_tcb_init(void);
185 static void             osek_resource_init(void);
186 static void             osek_counter_init(void);
187 
188 static void             osek_reset_alarm(OSEK_ALARM  *alarm_ptr);
189 static void             osek_reset_counter(OSEK_COUNTER  *counter_ptr);
190 static void             osek_reset_tcb(OSEK_TCB  *tcb_ptr);
191 static void             osek_reset_res(OSEK_RESOURCE  *res_ptr);
192 
193 /* Some utilities.  */
194 
195 static ULONG            osek_task_independent_area(void);
196 static OSEK_TCB         *osek_thread2tcb(TX_THREAD *thread_ptr);
197 static UINT             osek_remap_priority(UINT osek_priority);
198 
199 /* Functions to obtain OSEK objects from predefined pools.  */
200 
201 static UINT            osek_memory_allocate(ULONG size, void **memory_ptr);
202 static UINT            osek_get_alarm(void);
203 static CounterType     osek_get_counter(void);
204 static ResourceType    osek_get_resource(void);
205 static EventMaskType   osek_get_event(void);
206 static ULONG           osek_allocate_tcb(ULONG stack_size, OSEK_TCB **tcb_ptr);
207 
208 /* Internal operation functions.  */
209 
210 static StatusType      osek_do_task_terminate(OSEK_TCB  *tcb_ptr);
211 static StatusType      osek_do_activate_task (OSEK_TCB  *tcb_ptr);
212 static StatusType      osek_create_task(OSEK_TCB *tcb_ptr);
213 static StatusType      get_internal_resource(OSEK_TCB  *tcb_ptr);
214 static StatusType      release_internal_resource(OSEK_TCB  *tcb_ptr);
215 static StatusType      check_external_resource(OSEK_TCB  *tcb_ptr);
216 static StatusType      TerminateISR(void);
217 
218 
219 /* OSEK internal error function and Hook routine executors.  */
220 
221 static void            osek_internal_error(ULONG error_code);
222 static void            exec_ErrorHook (StatusType error);
223 static void            exec_PreTaskHook(void);
224 static void            exec_PostTaskHook(void);
225 
226 
227 /*OSEK Scheduler helper functions.  */
228 
229 static void            add_task_to_table(OSEK_TCB *tcb_ptr);
230 static void            start_osek_tasks(void);
231 static void            push_task_to_table(OSEK_TCB *tcb_ptr);
232 static void            pop_task_from_table(OSEK_TCB *tcb_ptr);
233 static UINT            check_task_to_run (OSEK_TCB *tcb_ptr );
234 static void            check_linked_resources(void);
235 static StatusType      ActivateISR(ISRType ISRID);
236 
237 
238 /**************************************************************************/
239 
240 
241 /**************************************************************************/
242 /*                                                                        */
243 /*  FUNCTION                                               RELEASE        */
244 /*                                                                        */
245 /*    StartOS                                             PORTABLE C      */
246 /*                                                           6.1.7        */
247 /*  AUTHOR                                                                */
248 /*                                                                        */
249 /*    William E. Lamie, Microsoft Corporation                             */
250 /*                                                                        */
251 /*  DESCRIPTION                                                           */
252 /*                                                                        */
253 /*    This function starts the OS. If StartOSHook is defined it is        */
254 /*    called.                                                             */
255 /*                                                                        */
256 /*  INPUT                                                                 */
257 /*                                                                        */
258 /*    StatusType                     Application mode                     */
259 /*                                                                        */
260 /*  OUTPUT                                                                */
261 /*                                                                        */
262 /*    None                                                                */
263 /*                                                                        */
264 /*  CALLS                                                                 */
265 /*                                                                        */
266 /*    StartupHook                    If defined                           */
267 /*                                                                        */
268 /*  CALLED BY                                                             */
269 /*                                                                        */
270 /*    Application                                                         */
271 /*                                                                        */
272 /*  RELEASE HISTORY                                                       */
273 /*                                                                        */
274 /*    DATE              NAME                      DESCRIPTION             */
275 /*                                                                        */
276 /*  06-02-2021     William E. Lamie         Initial Version 6.1.7         */
277 /*                                                                        */
278 /**************************************************************************/
StartOS(StatusType os_mode)279 void   StartOS(StatusType  os_mode)
280 {
281 
282 ULONG               request[SYSMGR_QUEUE_MSG_LENGTH];
283 StatusType          status;
284 
285    check_linked_resources();
286 
287    Application->application_mode = OSDEFAULTAPPMODE;
288 
289    /* Check for any startup hook routine.  */
290    if (Application->startup_hook_handler != TX_NULL)
291    {
292        /* Change operation mode for to startuphook mode.  */
293        osek_wrapper_operation_mode = STARTUPHOOK_MODE;
294        (Application->startup_hook_handler)(os_mode);
295    }
296 
297    /* Change back to default operations mode.  */
298    osek_wrapper_operation_mode = NORMAL_EXECUTION_MODE;
299 
300    /* Now send message to system thread to start the task scheduler.  */
301 
302    /* Build the request.  */
303    request[0] = SYSMGR_START_OS;            /* Request type.  */
304    request[1] = 0u;                         /* Dummy.  */
305    request[2] = 0u;                         /* Dummy.  */
306    request[3] = 0u;                         /* Dummy.  */
307 
308    /* Now send a message to the SysMgr supervisor thread.        */
309    /* to start OS task scheduler.                                */
310 
311    status = tx_queue_send(&osek_work_queue, request, TX_NO_WAIT);
312 
313    /* This should always succeed.  */
314    if (status != TX_SUCCESS)
315    {
316        /* System internal error.  */
317        osek_internal_error(SYS_MGR_START_OS);
318    }
319 
320    return;
321 }
322 
323 
324 /**************************************************************************/
325 /*                                                                        */
326 /*  FUNCTION                                               RELEASE        */
327 /*                                                                        */
328 /*    CreateTask                                          PORTABLE C      */
329 /*                                                           6.1.7        */
330 /*  AUTHOR                                                                */
331 /*                                                                        */
332 /*    William E. Lamie, Microsoft Corporation                             */
333 /*                                                                        */
334 /*  DESCRIPTION                                                           */
335 /*                                                                        */
336 /*    This function creates a new task with specified attributes.         */
337 /*    This call is allowed only during Application Initialization.        */
338 /*    This is not a standard OSEK API call.                               */
339 /*                                                                        */
340 /*  INPUT                                                                 */
341 /*                                                                        */
342 /*    priority                      Priority of the Task                  */
343 /*    stack_size                    Stack size of the Task                */
344 /*    entry_function                Task entry function pointer           */
345 /*    policy                        Scheduling policy for this Task       */
346 /*    active_no                     Maximum activation number             */
347 /*    start                         Starting state of the task            */
348 /*    type                          Task type: Basic/Extended             */
349 /*                                                                        */
350 /*  OUTPUT                                                                */
351 /*                                                                        */
352 /*    TaskId                        Task Id if successful                 */
353 /*    TX_NULL                       Error while creating the task         */
354 /*                                                                        */
355 /*  CALLS                                                                 */
356 /*                                                                        */
357 /*    osek_allocate_tcb             Get a TCB from the pool               */
358 /*    osek_create_task              Create an OSEK Task                   */
359 /*                                                                        */
360 /*  CALLED BY                                                             */
361 /*                                                                        */
362 /*   Initialization code                                                  */
363 /*                                                                        */
364 /*  RELEASE HISTORY                                                       */
365 /*                                                                        */
366 /*    DATE              NAME                      DESCRIPTION             */
367 /*                                                                        */
368 /*  06-02-2021     William E. Lamie         Initial Version 6.1.7         */
369 /*                                                                        */
370 /**************************************************************************/
CreateTask(const CHAR * name,void (* entry_function)(),UINT priority,UINT max_activation,ULONG stack_size,SCHEDULE policy,AUTOSTART start,UINT type,AppModeType mode)371 TaskType       CreateTask(const CHAR *name, void(*entry_function)(), UINT priority, UINT max_activation,
372                             ULONG stack_size, SCHEDULE policy, AUTOSTART start, UINT type, AppModeType mode)
373 {
374 
375 OSEK_TCB       *tcb_ptr;      /* Pointer to task control block.  */
376 ULONG           temp32;
377 ULONG           status;
378 
379 
380    /* Check whether we are called during initialization.  */
381    /* This will ensure that no one calls this function after system is started.  */
382    if (osek_init_state != OSEK_INIT)
383    {
384        Application->osek_object_creation_error++;
385 
386        /* Return OSEK internal error. NOTE: This is not a standard OSEK error.  */
387        return ((TaskType)TX_NULL);
388    }
389 
390    /* Now check the validity of all input parameters.  */
391 
392    /* Entry point function.  */
393    if (entry_function == TX_NULL)
394    {
395        /* Entry function not specified! Return an error. This is not a standard OSEK error.  */
396        Application->osek_object_creation_error++;
397        return ((TaskType)TX_NULL);
398    }
399 
400    /*  Task priority. */
401    if (priority > OSEK_HIGHEST_PRIORITY)
402    {
403        /* Return an internal error. This is not a standard OSEK error.  */
404        Application->osek_object_creation_error++;
405        return ((TaskType)TX_NULL);
406    }
407 
408    /* The max_activation parameter must be within limit, that is a non zero value but less
409       than OSEK_MAX_ACTIVATION. */
410    if ((max_activation > OSEK_MAX_ACTIVATION) || (max_activation == 0u))
411    {
412        /* Return an internal error. This is not a standard OSEK error.  */
413        Application->osek_object_creation_error++;
414        return ((TaskType)TX_NULL);
415    }
416 
417    /* Adjust the input stack size and check. */
418    /* Force stack size to a multiple of 4 bytes, round up if needed.  */
419    temp32 = ((stack_size + 3u) & ~0x3u);
420 
421    /* Add a little extra padding to stack.  */
422    temp32 += OSEK_STACK_PADDING;
423 
424    /* Is task stack big enough? ThreadX needs a minimum stack size for each task.  */
425    if (temp32 < TX_MINIMUM_STACK)
426    {
427        /* Return an error as there is no enough stack.  This is not a standard OSEK error.  */
428        Application->osek_object_creation_error++;
429        return ((TaskType)TX_NULL);
430    }
431 
432    /* Scheduling Policy */
433    if ((policy != FULL) && (policy != NON))
434    {
435        /* Return an error as policy supplied is unknown.  This is not a standard OSEK error.  */
436        Application->osek_object_creation_error++;
437        return ((TaskType)TX_NULL);
438    }
439 
440    /* Task Type */
441    if ((type != BASIC) && (type != EXTENDED))
442    {
443      /* Return an error as task type supplied is unknown.  This is not a standard OSEK error.  */
444      Application->osek_object_creation_error++;
445      return ((TaskType)TX_NULL);
446    }
447 
448    /* AUTO START option.  */
449    if ((start != TRUE) && (start != FALSE))
450    {
451        /* Return an error as Start type is unknown.This is not a standard OSEK error.  */
452        Application->osek_object_creation_error++;
453        return ((TaskType)TX_NULL);
454    }
455 
456    /* Got all input parameters within limits, now try to get a free Task Control Block (TCB) for this new task.  */
457    tcb_ptr = TX_NULL;
458    status = osek_allocate_tcb(temp32, &tcb_ptr);
459 
460    /* Make sure we got a TCB.  */
461    if((status != TRUE) || (tcb_ptr == TX_NULL))
462    {
463        /* Return an error since no memory is available.  This is not a standard OSEK error.  */
464        Application->osek_object_creation_error++;
465        return ((TaskType)TX_NULL);
466    }
467 
468    /* Now fill up the TCB with all supplied parameters.  */
469 
470    /* Store TASK object ID this is same for all TCB, this helps in checking whether the data
471       structure is really a TASK CONTROL BLOCK.  */
472    tcb_ptr->osek_task_id = OSEK_TASK_ID;
473 
474    /* Store task's name and type.  */
475    tcb_ptr->name = name;
476    tcb_ptr->task_type = type;
477 
478    /* Store the statically assigned (design time) priority and same would be RUN time priority.  */
479    tcb_ptr->org_prio = priority;
480    tcb_ptr->cur_threshold = priority;
481 
482    /* Store the task entry point. This is where the task will begin upon activation or chaining.  */
483    tcb_ptr->task_entry = entry_function;
484 
485    /* Store current task activation number as well as the maximum activations defined for this task.  */
486    tcb_ptr->max_active = max_activation;
487    tcb_ptr->current_active = 0u;
488    tcb_ptr->internal_res = TX_FALSE;
489 
490    /* Store the scheduling policy defined for the task.  */
491    tcb_ptr->policy = policy;
492 
493    /* Store the start up condition of the task.  */
494    tcb_ptr->task_autostart = start;
495 
496    /* A task is always created in suspended state even though it is defined as an AUTO START.  */
497    tcb_ptr->suspended = TX_TRUE;
498    tcb_ptr->waiting = TX_FALSE;
499 
500    /* Store task's application mode.  */
501    tcb_ptr->task_Appl_Mode = mode;
502 
503    /* Now create the ThreadX thread which actually runs this task.  */
504    status = osek_create_task(tcb_ptr);
505 
506    /* Check whether we encounter any error during ThreadX thread creation.  */
507    if (status == E_OS_SYSTEM)
508    {
509        /* Can't create a task? This is not a standard OSEK error.*/
510        Application->osek_object_creation_error++;
511        return ((TaskType) TX_NULL);
512    }
513 
514    /* Everything worked fine so far. Return TaskID. This TaskID is nothing  but a TCB structure
515       type casted to TaskType UDT.  */
516    return ((TaskType)tcb_ptr);
517 }
518 
519 
520 /**************************************************************************/
521 /*                                                                        */
522 /*  FUNCTION                                               RELEASE        */
523 /*                                                                        */
524 /*    CreateISR                                           PORTABLE C      */
525 /*                                                           6.1.7        */
526 /*  AUTHOR                                                                */
527 /*                                                                        */
528 /*    William E. Lamie, Microsoft Corporation                             */
529 /*                                                                        */
530 /*  DESCRIPTION                                                           */
531 /*                                                                        */
532 /*    This function creates a new task which will execute an ISR.         */
533 /*    This call is allowed only during Application Initialization.        */
534 /*    This is not a standard OSEK API call.                               */
535 /*                                                                        */
536 /*  INPUT                                                                 */
537 /*                                                                        */
538 /*    priority                      Priority of the ISR                   */
539 /*    stack_size                    Stack size of the ISR                 */
540 /*    entry_function                Task entry function pointer           */
541 /*    policy                        Scheduling policy for this task       */
542 /*    active_no                     Maximum activation number             */
543 /*    start                         Starting state of the task            */
544 /*    type                          Task type: Basic/Extended             */
545 /*                                                                        */
546 /*  OUTPUT                                                                */
547 /*                                                                        */
548 /*    TaskId                        Task Id if successful                 */
549 /*    TX_NULL                       Error while creating the ISR          */
550 /*                                                                        */
551 /*  CALLS                                                                 */
552 /*                                                                        */
553 /*    osek_allocate_tcb             Get a TCB from the pool               */
554 /*    osek_create_task              Create an OSEK Task                   */
555 /*                                                                        */
556 /*  CALLED BY                                                             */
557 /*                                                                        */
558 /*   Initialization code                                                  */
559 /*                                                                        */
560 /*  RELEASE HISTORY                                                       */
561 /*                                                                        */
562 /*    DATE              NAME                      DESCRIPTION             */
563 /*                                                                        */
564 /*  06-02-2021     William E. Lamie         Initial Version 6.1.7         */
565 /*                                                                        */
566 /**************************************************************************/
567 
CreateISR(const CHAR * name,void (* entry_function)(),UINT category,ULONG stack_size)568 ISRType CreateISR(const CHAR *name, void (*entry_function)(), UINT category, ULONG stack_size)
569 {
570 
571 OSEK_TCB       *tcb_ptr;      /* Pointer to task control block.  */
572 ULONG           temp32;
573 ULONG           status;
574 
575 
576    /* Check if we are called during initialization.  */
577    if((osek_init_state != OSEK_INIT) ||  /* Not in initialization.  */
578         (_tx_thread_current_ptr == &_tx_timer_thread))
579    {
580        /* Return default error.  */
581        Application->osek_object_creation_error++;
582 
583        return((ResourceType)TX_NULL);
584    }
585 
586    /* Scheduling policy.  */
587    if ((category != CATEGORY1) && (category != CATEGORY2))
588    {
589        /* Return an error as policy supplied is unknown.  This is not a standard OSEK error. */
590        Application->osek_object_creation_error++;
591        return ((TaskType)TX_NULL);
592    }
593 
594    /* Entry point function.  */
595    if(entry_function == NULL)
596    {
597        /* Entry function not specified! Return an error. This is not a standard OSEK error.  */
598        Application->osek_object_creation_error++;
599        return ((TaskType)TX_NULL);
600    }
601 
602    /* Adjust the input stack size and check. */
603    /* Force stack size to a multiple of 4 bytes, round up if needed.  */
604    temp32 = ((stack_size + 3u) & ~0x3u);
605 
606    /* Add a little extra padding to stack.  */
607    temp32 += OSEK_STACK_PADDING;
608 
609    /* Is task stack big enough? ThreadX needs a minimum stack size for each task.  */
610    if (temp32 < TX_MINIMUM_STACK)
611    {
612        /* Return an error as there is not enough stack.  This is not a standard OSEK error. */
613        Application->osek_object_creation_error++;
614        return ((ISRType)TX_NULL);
615    }
616 
617    /* Got all input parameters within limits, now try to get a free task control block(TCB) for this new ISR.  */
618    tcb_ptr = TX_NULL;
619    status = osek_allocate_tcb(temp32, &tcb_ptr);
620    /* Make sure we got a TCB.  */
621    if((status != TRUE) || (tcb_ptr == TX_NULL))
622    {
623        /* Return an error since no memory is available.  This is not a standard OSEK error.  */
624        Application->osek_object_creation_error++;
625        return ((TaskType)TX_NULL);
626    }
627 
628    /* Got a tcb , now fill up the TCB with all supplied parameters.  */
629 
630    /* Store ISR objectID ,this is same for all ISRs, this helps in checking whether the data
631       structure is really a ISR CONTROL BLOCK.  */
632    tcb_ptr->osek_task_id = OSEK_ISR_ID;
633 
634    /* Store ISR name.  */
635    tcb_ptr->name = name;
636    /* Store ISR category.  */
637    tcb_ptr->task_type = category;
638 
639    /* Store the statically assigned (design time) priority and same would be runtime priority.  */
640 
641    if (category == 1u)
642    {
643        tcb_ptr->org_prio = OSEK_ISR1_PRIORITY;
644    }
645    else
646    {
647        tcb_ptr->org_prio = OSEK_ISR2_PRIORITY;
648    }
649 
650    tcb_ptr->cur_threshold = tcb_ptr->org_prio;
651 
652    /* Store the ISR entry point. This is where the ISR will begin.  */
653    tcb_ptr->task_entry = entry_function;
654 
655    /* Store maximum activations defined for ISR.  */
656    /* Only 1 ISR of this name can be pending.   */
657    tcb_ptr->max_active = 1u;
658    tcb_ptr->current_active = 0u;
659    tcb_ptr->internal_res = TX_FALSE;
660 
661    /* Store the scheduling policy defined for the task.  */
662    tcb_ptr->policy = NON;
663 
664    /* Store the start up condition of the ISR which of course is DO NOT START.  */
665    tcb_ptr->task_autostart = FALSE;
666 
667    /* An ISR is always created in suspended state.  */
668    tcb_ptr->suspended = TX_TRUE;
669    tcb_ptr->waiting = TX_FALSE;
670 
671    /* Now create the ThreadX thread which actually mimics this ISR.  */
672    status = osek_create_task(tcb_ptr);
673 
674    /* Check whether we encounter any error during ThreadX thread creation.  */
675    if (status == E_OS_SYSTEM)
676    {
677        /* Can't create a task? This is not a standard OSEK error.  */
678        Application->osek_object_creation_error++;
679        return ((ISRType)TX_NULL);
680    }
681 
682    /* Everything worked fine so far. Return ISRID. This  is nothing  but a TCB structure
683       type casted to ISRType UDT.  */
684    return ((ISRType)tcb_ptr);
685 }
686 
687 
688 /**************************************************************************/
689 /*                                                                        */
690 /*  FUNCTION                                               RELEASE        */
691 /*                                                                        */
692 /*    ActivateTask                                        PORTABLE C      */
693 /*                                                           6.1.7        */
694 /*  AUTHOR                                                                */
695 /*                                                                        */
696 /*    William E. Lamie, Microsoft Corporation                             */
697 /*                                                                        */
698 /*  DESCRIPTION                                                           */
699 /*                                                                        */
700 /*    This call transfers a task from suspended state into the ready      */
701 /*    state. The operating system ensures that the task code is being     */
702 /*    executed from the first statement. The service may be called both   */
703 /*    from interrupt level and from task level. Rescheduling after this   */
704 /*    call depends on   from where it is called from. Also if required    */
705 /*    resources are freed as well as this being the highest priority task */
706 /*    than the task executing at this instance. If E_OS_LIMIT is returned */
707 /*    then activation is ignored. When an extended task is transferred    */
708 /*    from suspended to ready state all its events are cleared.           */
709 /*                                                                        */
710 /*  INPUT                                                                 */
711 /*                                                                        */
712 /*    TaskId                                Task Name                     */
713 /*                                                                        */
714 /*  OUTPUT                                                                */
715 /*                                                                        */
716 /*    E_OK                                  If successful                 */
717 /*    E_OS_ID                               Invalid TaskId                */
718 /*    E_OS_LIMIT                            Task activation limit         */
719 /*                                          exceeded                      */
720 /*                                                                        */
721 /*  CALLS                                                                 */
722 /*                                                                        */
723 /*    tx_queue_send                         Send message to Sys Manager   */
724 /*    osek_internal_error                   OSEK internal error           */
725 /*    osek_task_independent_area            Check calling context         */
726 /*    tx_thread_identify                    Get ThreadX thread of caller  */
727 /*    osek_thread2tcb                       Convert ThreadX  to OSEK      */
728 /*                                                                        */
729 /*  CALLED BY                                                             */
730 /*                                                                        */
731 /*    Application                                                         */
732 /*                                                                        */
733 /*  RELEASE HISTORY                                                       */
734 /*                                                                        */
735 /*    DATE              NAME                      DESCRIPTION             */
736 /*                                                                        */
737 /*  06-02-2021     William E. Lamie         Initial Version 6.1.7         */
738 /*                                                                        */
739 /**************************************************************************/
ActivateTask(TaskType TaskId)740 StatusType ActivateTask(TaskType TaskId)
741 {
742 TX_INTERRUPT_SAVE_AREA
743 OSEK_TCB       *tcb_ptr;
744 OSEK_TCB       *tcb_ptr_self;
745 UINT            status;
746 ULONG           request[SYSMGR_QUEUE_MSG_LENGTH];
747 ULONG           area;
748 TX_THREAD       *p_thread;
749 
750 
751    /* Log this call and arguments passed, this is required for the macro 'OSErrorGetServiceId'.  */
752    service_GetServiceId.id = (OsServiceIdType)OSServiceId_ActivateTask;
753    service_ActivateTask.TaskID = TaskId;
754 
755    /* Check if we are in task context.  */
756    area = osek_task_independent_area();
757    if(area != TX_TRUE)
758    {
759        exec_ErrorHook(E_OS_CALLEVEL);
760        /* Return error. */
761        return (E_OS_CALLEVEL);
762    }
763 
764    /* Check operating mode */
765    if ((osek_wrapper_operation_mode != NORMAL_EXECUTION_MODE) && (osek_wrapper_operation_mode != ISR2_MODE))
766    {
767        /* Hook routines and alarm callbacks can't call  this service. */
768        /* This explicit check is required because all hook routines are
769           executed in task's context!  */
770        exec_ErrorHook(E_OS_ID);
771        return (E_OS_CALLEVEL);
772    }
773 
774    /* Get OSEK TCB of the calling task.  */
775    p_thread = tx_thread_identify();
776    tcb_ptr_self = osek_thread2tcb(p_thread);
777 
778    if ((tcb_ptr_self->osek_task_id != OSEK_TASK_ID) && (tcb_ptr_self->osek_task_id != OSEK_ISR_ID))
779    {
780        /* This call is allowed only from TASK and ISR */
781        return (E_OS_CALLEVEL);
782    }
783 
784    /* Get OSEK TCB of the TASK to activate.  */
785    tcb_ptr = (OSEK_TCB *)TaskId;
786    if ((tcb_ptr == TX_NULL) || (tcb_ptr->osek_task_id != OSEK_TASK_ID))
787    {
788        exec_ErrorHook(E_OS_ID);
789        return (E_OS_ID);
790    }
791 
792    TX_DISABLE
793 
794    /* Check whether the task to be activated is activated up to its defined activation limit.  */
795    if(tcb_ptr->current_active >= tcb_ptr->max_active)
796    {
797        TX_RESTORE
798        exec_ErrorHook(E_OS_LIMIT);
799        /* Reached its max activation limit.  */
800        return (E_OS_LIMIT);
801    }
802 
803    /* Now send a message to the system manager thread to activate this task.   */
804    /* Build the request. */
805    request[0] = SYSMGR_ACTIVATE_TASK;          /* Request type.  */
806    request[1] = (ULONG)tcb_ptr;                /* Task to activate.  */
807 
808    /* Now check who is calling this service, a task or an ISR?  */
809    if (tcb_ptr_self->osek_task_id == OSEK_TASK_ID)
810    {
811        request[2] = (ULONG)tcb_ptr_self;      /* Task id of the calling task.  */
812    }
813    else
814    {
815        request[2] = 0u;  /* When ISR activates a task rescheduling (if any) is held
816                             till ISR completes so no need to suspend ISR task.  */
817    }
818 
819    request[3] = 0u;
820 
821    /* Since the SysMgr supervisor thread has the highest priority, this call   */
822    /* will be preempted by SysMgr supervisor thread.                           */
823    /* SysMgr will eventually call osek_do_task_activate.                       */
824 
825    status = tx_queue_send(&osek_work_queue, request, TX_NO_WAIT);
826 
827    TX_RESTORE
828 
829    /* This should always succeed.  */
830    if (status != TX_SUCCESS)
831    {
832        /* System internal error.  */
833        osek_internal_error(SYS_MGR_SEND_ACTIVATETASK);
834    }
835 
836    /* Return status.  */
837    return(E_OK);
838 }
839 
840 
841 /**************************************************************************/
842 /*                                                                        */
843 /*  FUNCTION                                               RELEASE        */
844 /*                                                                        */
845 /*    TerminateTask                                       PORTABLE C      */
846 /*                                                           6.1.7        */
847 /*  AUTHOR                                                                */
848 /*                                                                        */
849 /*    William E. Lamie, Microsoft Corporation                             */
850 /*                                                                        */
851 /*  DESCRIPTION                                                           */
852 /*                                                                        */
853 /*   This service terminates the calling task, which means transferring   */
854 /*   the calling task from the running state into the suspended state.    */
855 /*   Only internal resources held by this task are released here. While   */
856 /*   it is assumed that any external resources occupied by the task must  */
857 /*   have been released before the call to TerminateTask. In case         */
858 /*   a resource is still occupied while calling this service, then the    */
859 /*   behaviour is undefined in STANDARD version of OSEK. In the EXTENDED  */
860 /*   version of OSEK, this service returns an error, which can be         */
861 /*   evaluated by the application.                                        */
862 /*   If successful, this call will causes rescheduling, this also means   */
863 /*   that upon success TerminateTask does not return to the call level.   */
864 /*                                                                        */
865 /*   NOTE:                                                                */
866 /*                                                                        */
867 /*   Ending a task function without call to TerminateTask or ChainTask is */
868 /*   strictly forbidden and may leave the system in an undefined state.   */
869 /*   But in this implementation TerminateTask service is called if needed.*/
870 /*                                                                        */
871 /*  INPUT                                                                 */
872 /*                                                                        */
873 /*    None                                                                */
874 /*                                                                        */
875 /*  OUTPUT                                                                */
876 /*                                                                        */
877 /*    None                            If success                          */
878 /*    Error Code.                     If error                            */
879 /*                                                                        */
880 /*  CALLS                                                                 */
881 /*                                                                        */
882 /*    osek_task_independent_area      Check if we are in task context     */
883 /*    osek_thread2tcb                 Get TCB pointer for thread pointer  */
884 /*    tx_queue_send                   Send message to Sys Manager Thread  */
885 /*    osek_internal_error             In case of any internal error       */
886 /*                                                                        */
887 /*  CALLED BY                                                             */
888 /*                                                                        */
889 /*    Application Code  (TASKs only)                                      */
890 /*                                                                        */
891 /*  RELEASE HISTORY                                                       */
892 /*                                                                        */
893 /*    DATE              NAME                      DESCRIPTION             */
894 /*                                                                        */
895 /*  06-02-2021     William E. Lamie         Initial Version 6.1.7         */
896 /*                                                                        */
897 /**************************************************************************/
TerminateTask(void)898 StatusType  TerminateTask(void)
899 {
900 TX_INTERRUPT_SAVE_AREA
901 OSEK_TCB       *tcb_ptr;
902 ULONG           request[SYSMGR_QUEUE_MSG_LENGTH];
903 UINT            index;
904 UINT            status;
905 ULONG           area;
906 TX_THREAD      *p_thread;
907 
908 
909    service_GetServiceId.id = (OsServiceIdType)OSServiceId_TerminateTask;
910    service_TerminateTask.TaskID = (StatusType)0u;
911 
912    /* Check for Task or ISR context. */
913    /* All ISRs are treated as as a high priority tasks.  */
914    area = osek_task_independent_area();
915    if(area != TX_TRUE)
916    {
917        exec_ErrorHook(E_OS_CALLEVEL);
918        /* Return error.  */
919        return (E_OS_CALLEVEL);
920    }
921 
922    /* Get OSEK TCB of this TASK/ISR.  */
923    p_thread = tx_thread_identify();
924    tcb_ptr = osek_thread2tcb(p_thread);
925    if (tcb_ptr == TX_NULL)
926    {
927        exec_ErrorHook(E_OS_CALLEVEL);
928        return (E_OS_CALLEVEL);
929    }
930 
931    if (tcb_ptr->osek_task_id != OSEK_TASK_ID)
932    {
933        /* This call is allowed only from TASK and ISR.  */
934        exec_ErrorHook(E_OS_CALLEVEL);
935        return (E_OS_CALLEVEL);
936    }
937 
938 
939    /* Check operating mode */
940    if (osek_wrapper_operation_mode != NORMAL_EXECUTION_MODE)
941    {
942        /* Hook routines and alarm callbacks can't call  this service.  */
943        /* This explicit check is required because all hook routines are
944           executed in task's context!  */
945        exec_ErrorHook(E_OS_CALLEVEL);
946 
947        return (E_OS_CALLEVEL);
948    }
949 
950    TX_DISABLE
951 
952    /* Check if any resource is occupied. A task can not be terminated if it is holding any resource.   */
953    if(tcb_ptr->res_ocp != 0u)
954    {
955       TX_RESTORE
956 
957       exec_ErrorHook(E_OS_RESOURCE);
958 
959       /* Return.  */
960       return (E_OS_RESOURCE);
961    }
962 
963    /* Release any internal resources held.  */
964    if (tcb_ptr->internal_res != 0u)
965    {
966        for (index = 0u; index < OSEK_MAX_INTERNAL_RES; index++)
967        {
968            if (tcb_ptr->internal_resource_occuplied_list[index] == 0u)
969            {
970                break;
971            }
972 
973            ((OSEK_RESOURCE *)(tcb_ptr->internal_resource_occuplied_list[index]))->taskid = 0u;
974            tcb_ptr->internal_resource_occuplied_list[index] = 0u;
975 
976        }   /* End of for loop.  */
977    }
978 
979    /* Now it's okay to terminate this task, clear its events.  */
980    tcb_ptr->waiting_events = 0u;
981    tcb_ptr->set_events = 0u;
982 
983    /* Now all set to terminate this task.  */
984    /* Send a message to the System Manager to terminate this task.  */
985    /* Build the request.  */
986 
987    request[0] = SYSMGR_TERMINATE_TASK;      /* Request type.  */
988    request[1] = (ULONG)tcb_ptr;             /* ID of the task to kill.  */
989    request[2] = 0u;
990    request[3] = 0u;
991 
992    /* Since the SysMgr supervisor thread has the highest priority,        */
993    /* this call will be preempted by SysMgr supervisor thread             */
994    /* SysMgr will eventually call osek_do_task_terminate and reschedule.  */
995 
996    status = tx_queue_send(&osek_work_queue, request, TX_NO_WAIT);
997 
998    TX_RESTORE
999 
1000    /* This should always succeed. and Sys Manager terminates this task    */
1001    /* This point will never be reached, as this thread itself will be     */
1002    /* deleted by the system manager!                                      */
1003 
1004    if (status != TX_SUCCESS)
1005    {
1006        osek_internal_error(SYS_MGR_SEND_TERMINATETASK);
1007    }
1008 
1009    return (E_OK);
1010 }
1011 
1012 
1013 /**************************************************************************/
1014 /*                                                                        */
1015 /*  FUNCTION                                               RELEASE        */
1016 /*                                                                        */
1017 /*    ChainTask                                           PORTABLE C      */
1018 /*                                                           6.1.7        */
1019 /*  AUTHOR                                                                */
1020 /*                                                                        */
1021 /*    William E. Lamie, Microsoft Corporation                             */
1022 /*                                                                        */
1023 /*  DESCRIPTION                                                           */
1024 /*                                                                        */
1025 /*    This service causes the termination of the calling task. After      */
1026 /*    termination of the calling task, a succeeding task (supplied as an  */
1027 /*    input argument for the call) is activated. If the succeeding task   */
1028 /*    is the same calling task, then this does not result in multiple     */
1029 /*    requests and the task is not transferred to the suspended state.    */
1030 /*    Only internal resources held by this task are released here, even   */
1031 /*    in case the calling task is identical with the task to chain.       */
1032 /*    While it is assumed that any external resources occupied by the     */
1033 /*    task must have been released before the call to TerminateTask.      */
1034 /*    In case a resource is still occupied while calling this service,    */
1035 /*    then the behaviour is undefined in STANDARD version of OSEK.        */
1036 /*    In the EXTENDED version of OSEK, an error is returned, which can be */
1037 /*    evaluated by the application.                                       */
1038 /*    If called successfully, ChainTask does not return to call level and */
1039 /*    the status can not be evaluated. In case of error the service       */
1040 /*    returns to the calling task and provides a status which can then be */
1041 /*    checked by the application.                                         */
1042 /*    If successful, this call will causes rescheduling, this also means  */
1043 /*    that upon success ChainTask does not return to the call level.      */
1044 /*                                                                        */
1045 /*                                                                        */
1046 /*  INPUT                                                                 */
1047 /*                                                                        */
1048 /*    Task_ID                              Task id to activate.           */
1049 /*  OUTPUT                                                                */
1050 /*                                                                        */
1051 /*    E_OK                                 If successful.                 */
1052 /*    E_OS_LIMIT                           Too many activations           */
1053 /*    E_OS_CALLEVEL                        Called at interrupt level      */
1054 /*    E_OS_RESOURCE                        Resources are not released     */
1055 /*                                                                        */
1056 /*  CALLS                                                                 */
1057 /*                                                                        */
1058 /*    osek_task_independent_area       Make sure called in Task context   */
1059 /*    osek_thread2tcb                  Get TCB pointer for the thread     */
1060 /*    tx_queue_send                    send message to sys manager thread */
1061 /*    osek_internal_error              Any internal errors                */
1062 /*                                                                        */
1063 /*  CALLED BY                                                             */
1064 /*                                                                        */
1065 /*    Application Code  (TASKs only)                                      */
1066 /*                                                                        */
1067 /*  RELEASE HISTORY                                                       */
1068 /*                                                                        */
1069 /*    DATE              NAME                      DESCRIPTION             */
1070 /*                                                                        */
1071 /*  06-02-2021     William E. Lamie         Initial Version 6.1.7         */
1072 /*                                                                        */
1073 /**************************************************************************/
ChainTask(TaskType TaskID)1074 StatusType ChainTask(TaskType  TaskID)
1075 {
1076 TX_INTERRUPT_SAVE_AREA
1077 OSEK_TCB       *tcb_ptr;
1078 OSEK_TCB       *tcb_ptr1;
1079 ULONG           request[SYSMGR_QUEUE_MSG_LENGTH];
1080 UINT            index;
1081 ULONG           area;
1082 TX_THREAD      *p_thread;
1083 
1084    service_GetServiceId.id = (OsServiceIdType)OSServiceId_ChainTask;
1085    service_ChainTask.TaskID = TaskID;
1086 
1087    /* Check if we are in task context.  */
1088    area = osek_task_independent_area();
1089    if(area != TX_TRUE)
1090    {
1091        exec_ErrorHook(E_OS_CALLEVEL);
1092        /* Return error.  */
1093        return(E_OS_CALLEVEL);
1094    }
1095 
1096    /* Get OSEK TCB of this TASK/ISR.  */
1097    p_thread = tx_thread_identify();
1098    tcb_ptr = osek_thread2tcb(p_thread);
1099    if (tcb_ptr == TX_NULL)
1100    {
1101        exec_ErrorHook(E_OS_ID);
1102        return (E_OS_ID);
1103    }
1104 
1105    if (tcb_ptr->osek_task_id != OSEK_TASK_ID)
1106    {
1107        /* This call is allowed only from TASK.  */
1108        exec_ErrorHook(E_OS_CALLEVEL);
1109        return (E_OS_CALLEVEL);
1110    }
1111 
1112    /* Check operating mode.  */
1113    if (osek_wrapper_operation_mode != NORMAL_EXECUTION_MODE)
1114    {
1115        /* ISRs, hook routines and alarm callbacks can't call  this service.  */
1116        /* This explicit check is required because all ISRs and hook routines are
1117           executed in task's context!  */
1118        exec_ErrorHook(E_OS_CALLEVEL);
1119 
1120        return (E_OS_CALLEVEL);
1121    }
1122 
1123    /* Check if any external resources are occupied.  */
1124    if(tcb_ptr->res_ocp != 0u)
1125    {
1126        exec_ErrorHook(E_OS_RESOURCE);
1127 
1128        /* The external resource is not released.  */
1129        return (E_OS_RESOURCE);
1130    }
1131 
1132    /* Get tcb of task to be chained.  */
1133    tcb_ptr1 = (OSEK_TCB *)TaskID;
1134 
1135    /* First, check for an invalid task pointer.  */
1136    if ((tcb_ptr1 == TX_NULL) || ((tcb_ptr1->osek_task_id) != OSEK_TASK_ID))
1137    {
1138        exec_ErrorHook(E_OS_ID);
1139 
1140        /* Return Error.  */
1141        return (E_OS_ID);
1142    }
1143 
1144    TX_DISABLE
1145 
1146    /* Check both calling task and task_to_be_chained are one and the same.  */
1147    if (tcb_ptr != tcb_ptr1)
1148    {
1149        /* Check for proper multiple activation.  */
1150        if(tcb_ptr1->current_active >= tcb_ptr1->max_active)
1151        {
1152            TX_RESTORE
1153 
1154            /* Reached its max activation limit.  */
1155            exec_ErrorHook(E_OS_LIMIT);
1156 
1157            return (E_OS_LIMIT);
1158        }
1159    }
1160 
1161    /* Store TaskID which is to be chained after termination of this task.  */
1162    tcb_ptr->task_to_chain = TaskID;
1163 
1164    /* Now release any internal resources held by the calling task.  */
1165    if (tcb_ptr->internal_res != 0u)
1166    {
1167        for (index = 0u ; index < OSEK_MAX_INTERNAL_RES; index++)
1168        {
1169            if (tcb_ptr->internal_resource_occuplied_list[index] == 0u)
1170            {
1171                break;
1172            }
1173 
1174            ((OSEK_RESOURCE *)(tcb_ptr->internal_resource_occuplied_list[index]))->taskid = 0u;
1175            tcb_ptr->internal_resource_occuplied_list[index] = 0u;
1176 
1177        }   /* End of for loop.  */
1178    }
1179 
1180    /* Now it's ok to terminate this task , clear its events.  */
1181    tcb_ptr->waiting_events = 0u;
1182    tcb_ptr->set_events = 0u;
1183 
1184    /* Send message to the system manager to suspend calling task and activate
1185       task to be chained.  */
1186 
1187    /* Build the request. */
1188    request[0] = SYSMGR_CHAIN_TASK;          /* Request type.  */
1189    request[1] = (ULONG)tcb_ptr;             /* TCB ptr of calling task.  */
1190    request[2] = TaskID;                     /* Task to chain.  */
1191    request[3] = 0u;
1192 
1193    /* Since the SysMgr supervisor thread has the highest priority,      */
1194    /* this routine will be preempted by SysMgr supervisor thread.       */
1195 
1196    tx_queue_send(&osek_work_queue, request, TX_NO_WAIT);
1197 
1198    TX_RESTORE
1199 
1200    /* This should always succeed and sys manager terminates this task   */
1201    /* This point will never be reached, as this thread itself will be    */
1202    /* deleted by the System Manager!                                     */
1203 
1204    osek_internal_error(SYS_MGR_SEND_CHAINTASK);
1205 
1206    return (E_OK);
1207 }
1208 
1209 
1210 /**************************************************************************/
1211 /*                                                                        */
1212 /*  FUNCTION                                               RELEASE        */
1213 /*                                                                        */
1214 /*    GetTaskID                                           PORTABLE C      */
1215 /*                                                           6.1.7        */
1216 /*  AUTHOR                                                                */
1217 /*                                                                        */
1218 /*    William E. Lamie, Microsoft Corporation                             */
1219 /*                                                                        */
1220 /*  DESCRIPTION                                                           */
1221 /*                                                                        */
1222 /*    GetTaskID returns the task id of the task currently running.        */
1223 /*    Calling GetTaskID is allowed from task level, ISR level and in      */
1224 /*    several hook routines. This service is intended to be used by       */
1225 /*    library functions and hook routines. If <TaskID> can�t be evaluated */
1226 /*    (no task currently running), the service returns INVALID_TASK as    */
1227 /*    TaskType.                                                           */
1228 /*                                                                        */
1229 /*  INPUT                                                                 */
1230 /*                                                                        */
1231 /*    TaskID                         Pointer to stored Task ID            */
1232 /*                                                                        */
1233 /*  OUTPUT                                                                */
1234 /*                                                                        */
1235 /*    E_OK                           If success                           */
1236 /*    INVALID_TASK                   If failure                           */
1237 /*                                                                        */
1238 /*  CALLS                                                                 */
1239 /*                                                                        */
1240 /*    tx_thread_identify             Identifies the current thread        */
1241 /*                                                                        */
1242 /*  CALLED BY                                                             */
1243 /*                                                                        */
1244 /*    Application code                                                    */
1245 /*                                                                        */
1246 /*  RELEASE HISTORY                                                       */
1247 /*                                                                        */
1248 /*    DATE              NAME                      DESCRIPTION             */
1249 /*                                                                        */
1250 /*  06-02-2021     William E. Lamie         Initial Version 6.1.7         */
1251 /*                                                                        */
1252 /**************************************************************************/
GetTaskID(TaskRefType TaskID)1253 StatusType GetTaskID(TaskRefType TaskID)
1254 {
1255 
1256 TX_THREAD      *thread_ptr;
1257 
1258 
1259    /* Check for valid pointer to store the task ID.  */
1260    if(TaskID == TX_NULL)
1261    {
1262        /* Return error.  */
1263        return (E_OS_ID);
1264    }
1265 
1266    /* Check for the pointer to thread.  */
1267    thread_ptr = tx_thread_identify();
1268 
1269    if ((thread_ptr == TX_NULL) || (thread_ptr == &_tx_timer_thread))
1270    {
1271        /* No task running TaskID can�t be evaluated return a special Error.  */
1272        *TaskID = INVALID_TASK;
1273 
1274        return (E_OK);
1275    }
1276 
1277    if ((osek_wrapper_operation_mode == STARTUPHOOK_MODE)     ||
1278        (osek_wrapper_operation_mode == SHUTDOWNHOOK_MODE)    ||
1279        (osek_wrapper_operation_mode == ALARM_CALLBACK_MODE))
1280    {
1281        *TaskID = INVALID_TASK;
1282    }
1283    else
1284    {
1285        *TaskID = last_run_task;
1286    }
1287 
1288     /* Return success.  */
1289     return (E_OK);
1290 }
1291 
1292 
1293 /**************************************************************************/
1294 /*                                                                        */
1295 /*  FUNCTION                                               RELEASE        */
1296 /*                                                                        */
1297 /*    GetTaskState                                        PORTABLE C      */
1298 /*                                                           6.1.7        */
1299 /*  AUTHOR                                                                */
1300 /*                                                                        */
1301 /*    William E. Lamie, Microsoft Corporation                             */
1302 /*                                                                        */
1303 /*  DESCRIPTION                                                           */
1304 /*                                                                        */
1305 /*    Returns the state of a task (running, ready, waiting, suspended) at */
1306 /*    the time of calling GetTaskState. The service may be called from    */
1307 /*    interrupt service routines, task level, and some hook routines.     */
1308 /*    Within a full preemptive system, calling this operating system      */
1309 /*    service only provides a meaningful result if the task runs in an    */
1310 /*    interrupt disabling state at the time of calling.                   */
1311 /*    When a call is made from a task in a full preemptive system, the    */
1312 /*    result may already be incorrect at the time of evaluation. When the */
1313 /*    service is called for a task, which is multiply activated, the      */
1314 /*    state is set to running if any instance of the task is running.     */
1315 /*                                                                        */
1316 /*  INPUT                                                                 */
1317 /*                                                                        */
1318 /*    Task_ID                              Task id to query               */
1319 /*    State                                Pointer to result state        */
1320 /*                                                                        */
1321 /*  OUTPUT                                                                */
1322 /*                                                                        */
1323 /*    E_OK                                 If successful                  */
1324 /*    E_OS_ID                              Task is invalid                */
1325 /*                                                                        */
1326 /*  CALLS                                                                 */
1327 /*                                                                        */
1328 /*    osek_task_independent_area           Check if called from task      */
1329 /*                                         independent area               */
1330 /*    tx_thread_identify                   Identify the current thread    */
1331 /*                                                                        */
1332 /*  CALLED BY                                                             */
1333 /*                                                                        */
1334 /*    Application Code                                                    */
1335 /*                                                                        */
1336 /*  RELEASE HISTORY                                                       */
1337 /*                                                                        */
1338 /*    DATE              NAME                      DESCRIPTION             */
1339 /*                                                                        */
1340 /*  06-02-2021     William E. Lamie         Initial Version 6.1.7         */
1341 /*                                                                        */
1342 /**************************************************************************/
GetTaskState(TaskType TaskID,TaskStateRefType State)1343 StatusType GetTaskState(TaskType TaskID, TaskStateRefType State)
1344 {
1345 TX_INTERRUPT_SAVE_AREA
1346 OSEK_TCB       *tcb_ptr;
1347 TX_THREAD      *this_thread;
1348 ULONG           area;
1349 TX_THREAD      *p_thread;
1350 
1351 
1352    service_GetServiceId.id = (OsServiceIdType)OSServiceId_GetTaskState;
1353    service_GetTaskState.TaskID = (StatusType)0;
1354 
1355    /* Check for valid task ID.  */
1356    if(TaskID == 0u)
1357    {
1358        exec_ErrorHook(E_OS_ID);
1359        /* Return error.  */
1360        return (E_OS_ID);
1361    }
1362 
1363    /* Get OSEK TCB.  */
1364    tcb_ptr = (OSEK_TCB *)TaskID;
1365 
1366    /* First, check for an invalid task pointer.  */
1367    if((tcb_ptr == TX_NULL) || ((tcb_ptr->osek_task_id) != OSEK_TASK_ID))
1368    {
1369        exec_ErrorHook(E_OS_ID);
1370        /* Return error.  */
1371        return (E_OS_ID);
1372    }
1373 
1374    TX_DISABLE
1375 
1376    if ((osek_wrapper_operation_mode == STARTUPHOOK_MODE)     ||
1377        (osek_wrapper_operation_mode == SHUTDOWNHOOK_MODE)    ||
1378        (osek_wrapper_operation_mode == ALARM_CALLBACK_MODE))
1379    {
1380        TX_RESTORE
1381 
1382        /* Return error.  */
1383        return (E_OS_ID);
1384    }
1385 
1386    /* Get the ThreadX TCB.  */
1387    this_thread = (TX_THREAD *)tcb_ptr;
1388 
1389    /* Check if we are only in task context.  */
1390    area = osek_task_independent_area();
1391    if (area == TX_TRUE)
1392    {
1393        /* Get the OSEK TCB.  */
1394        p_thread = tx_thread_identify();
1395        if(this_thread == p_thread)
1396        {
1397            TX_RESTORE
1398 
1399            /* This is the running thread.  */
1400            *State = RUNNING;
1401            return (E_OK);
1402        }
1403    }
1404 
1405    if (tcb_ptr->waiting == TX_TRUE)
1406    {
1407        TX_RESTORE
1408 
1409        *State = WAITING;
1410        return (E_OK);
1411    }
1412    if (tcb_ptr->suspended == TX_TRUE)
1413    {
1414        TX_RESTORE
1415 
1416        *State = SUSPENDED;
1417        return (E_OK);
1418    }
1419 
1420    TX_RESTORE
1421 
1422    *State = READY;
1423    return (E_OK);
1424 }
1425 
1426 
1427 /**************************************************************************/
1428 /*                                                                        */
1429 /*  FUNCTION                                               RELEASE        */
1430 /*                                                                        */
1431 /*    Schedule                                            PORTABLE C      */
1432 /*                                                           6.1.7        */
1433 /*  AUTHOR                                                                */
1434 /*                                                                        */
1435 /*    William E. Lamie, Microsoft Corporation                             */
1436 /*                                                                        */
1437 /*  DESCRIPTION                                                           */
1438 /*                                                                        */
1439 /*    If a higher-priority task is ready, the internal resource of the    */
1440 /*    task is released, the current task is put into the ready state, its */
1441 /*    context is saved and the higher-priority task is executed.          */
1442 /*    Otherwise the calling task is continued.                            */
1443 /*    Rescheduling can only take place if an internal resource is         */
1444 /*    assigned to the calling task during system generation. For these    */
1445 /*    tasks, schedule enables a processor assignment to other tasks with  */
1446 /*    lower or equal priority than the ceiling priority of the internal   */
1447 /*    resource and higher priority than the priority of the calling task  */
1448 /*    in application-specific locations. When returning from schedule,    */
1449 /*    the internal resource has been taken again.                         */
1450 /*    This service has no influence on tasks with no internal resource    */
1451 /*    assigned (preemptable tasks).                                       */
1452 /*                                                                        */
1453 /*  INPUT                                                                 */
1454 /*                                                                        */
1455 /*    None                                                                */
1456 /*                                                                        */
1457 /*  OUTPUT                                                                */
1458 /*                                                                        */
1459 /*    E_OK                                 If success.                    */
1460 /*    E_OS_CALLLEVEL                       Called at interrupt level      */
1461 /*                                                                        */
1462 /*  CALLS                                                                 */
1463 /*                                                                        */
1464 /*    osek_task_independent_area           Check if called from task      */
1465 /*                                                                        */
1466 /*  CALLED BY                                                             */
1467 /*                                                                        */
1468 /*    Application Code                                                    */
1469 /*                                                                        */
1470 /*  RELEASE HISTORY                                                       */
1471 /*                                                                        */
1472 /*    DATE              NAME                      DESCRIPTION             */
1473 /*                                                                        */
1474 /*  06-02-2021     William E. Lamie         Initial Version 6.1.7         */
1475 /*                                                                        */
1476 /**************************************************************************/
Schedule(void)1477 StatusType Schedule (void)
1478 {
1479 TX_INTERRUPT_SAVE_AREA
1480 OSEK_TCB       *tcb_ptr;
1481 TX_THREAD      *this_thread;
1482 ULONG           request[SYSMGR_QUEUE_MSG_LENGTH];
1483 UINT            status;
1484 ULONG           area;
1485 
1486    service_GetServiceId.id = (OsServiceIdType)OSServiceId_Schedule;
1487    service_GetTaskState.TaskID = (StatusType)0u;
1488 
1489    /* Check if we are in task context.  */
1490    area = osek_task_independent_area();
1491    if(area != TX_TRUE)
1492    {
1493        /* Return error.  */
1494        return (E_OS_CALLEVEL);
1495    }
1496 
1497    /* Get the ThreadX thread and OSEK TCB.  */
1498    this_thread = tx_thread_identify();
1499    tcb_ptr = osek_thread2tcb(this_thread);
1500 
1501    if (tcb_ptr == TX_NULL)
1502    {
1503        return (E_OS_ID);
1504    }
1505 
1506    if (tcb_ptr->osek_task_id != OSEK_TASK_ID)
1507    {
1508        /* This call is allowed only from TASK.  */
1509        return(E_OS_ID);
1510    }
1511 
1512    TX_DISABLE
1513 
1514    /* Check operating mode.  */
1515    if (osek_wrapper_operation_mode != NORMAL_EXECUTION_MODE)
1516    {
1517 
1518        TX_RESTORE
1519 
1520        /* Hook routines, alarm callbacks and ISRs can't call this service. */
1521        /* This explicit check is required because all hook routines are
1522           executed in task's context. */
1523        return (E_OS_ID);
1524    }
1525 
1526    /* Check if any resource is occupied.  */
1527    if(tcb_ptr->res_ocp != 0u)
1528    {
1529        TX_RESTORE
1530 
1531        exec_ErrorHook(E_OS_RESOURCE);
1532        /* Return.  */
1533        return (E_OS_RESOURCE);
1534 
1535    }
1536 
1537    /* Now release internal resources, if any, held by this task   */
1538    /* This call releases internal resources and moves the task to */
1539    /* a new queue position based on its new ceiling priority.     */
1540    /* release_internal_resource(tcb_ptr); */
1541 
1542    /* Now send message to system Manager to check any higher priority task is ready.  */
1543    /* Build the request.  */
1544    request[0] = SYSMGR_SCHEDULE;          /* Request type.  */
1545    request[1] = (ULONG)this_thread;       /* Self ID.  */
1546    request[2] = 0u;
1547    request[3] = 0u;
1548 
1549    /* Since the SysMgr supervisor thread has the highest priority,      */
1550    /* this routine will be preempted by SysMgr supervisor thread when   */
1551    /* queue read is successful.                                         */
1552    /* System Manager will eventually call start_osek_tasks.             */
1553 
1554    status = tx_queue_send(&osek_work_queue, request, TX_NO_WAIT);
1555 
1556    TX_RESTORE
1557 
1558    /* This should always succeed.  */
1559    if (status != TX_SUCCESS)
1560    {
1561        /* System internal error.  */
1562        osek_internal_error(SYS_MGR_SEND_CHAINTASK);
1563    }
1564 
1565    /* Assume that the sys manager does its job.  */
1566    /* And has returned from schedule, restore preemption threshold if any.  */
1567 
1568    /* Now we need to move this task back to its priority level */
1569    /* before coming here all internal resources (if any are taken).  */
1570 
1571    TX_DISABLE
1572 
1573    /* Now check task's scheduling policy */
1574    if (tcb_ptr->policy == NON)
1575    {
1576        pop_task_from_table(tcb_ptr);
1577        /* If policy is NON then restore to OSEK_NON_SCHEDULE priority.  */
1578        tcb_ptr->cur_threshold = OSEK_NON_SCHEDULE_PRIORITY;
1579        push_task_to_table(tcb_ptr);
1580    }
1581 
1582    TX_RESTORE
1583 
1584    return (E_OK);
1585 }
1586 
1587 
1588 /**************************************************************************/
1589 /*                                                                        */
1590 /*  FUNCTION                                               RELEASE        */
1591 /*                                                                        */
1592 /*    CreateResource                                      PORTABLE C      */
1593 /*                                                           6.1.7        */
1594 /*  AUTHOR                                                                */
1595 /*                                                                        */
1596 /*    William E. Lamie, Microsoft Corporation                             */
1597 /*                                                                        */
1598 /*  DESCRIPTION                                                           */
1599 /*                                                                        */
1600 /*    Creates  resources for inter-task mutual exclusion for resource     */
1601 /*    protection                                                          */
1602 /*                                                                        */
1603 /*  INPUT                                                                 */
1604 /*                                                                        */
1605 /*    name                         Name of the Resource.                  */
1606 /*    type                         Type of the resource standard/internal */
1607 /*                                                                        */
1608 /*  OUTPUT                                                                */
1609 /*                                                                        */
1610 /*    RES_ID                       If successful                          */
1611 /*    ZERO                         If error while creating resource       */
1612 /*                                                                        */
1613 /*  CALLS                                                                 */
1614 /*                                                                        */
1615 /*    osek_memory_allocate         Allocate memory from system            */
1616 /*    osek_get_resource            Get one resource from the pool         */
1617 /*    tx_mutex_create              Create a Mutex in ThreadX              */
1618 /*    osek_internal_error          OSEK internal Error                    */
1619 /*                                                                        */
1620 /*  CALLED BY                                                             */
1621 /*                                                                        */
1622 /*   Application Code                                                     */
1623 /*                                                                        */
1624 /*  RELEASE HISTORY                                                       */
1625 /*                                                                        */
1626 /*    DATE              NAME                      DESCRIPTION             */
1627 /*                                                                        */
1628 /*  06-02-2021     William E. Lamie         Initial Version 6.1.7         */
1629 /*                                                                        */
1630 /**************************************************************************/
CreateResource(const CHAR * name,StatusType type,ResourceType linked_res)1631 ResourceType  CreateResource(const CHAR *name, StatusType type, ResourceType linked_res)
1632 {
1633 
1634 OSEK_RESOURCE  *res_ptr;
1635 OSEK_RESOURCE  *linked_res_ptr;
1636 OSEK_RESOURCE  *res1_ptr;
1637 
1638 ResourceType    ID;
1639 ResourceType    linked_res_id;
1640 UINT            done_flag;
1641 UINT            iter_max;
1642 
1643    /* Check whether calling from task context or ISR.  */
1644    if ((osek_init_state != OSEK_INIT) ||  /* Not in Initialization.  */
1645        (_tx_thread_current_ptr == &_tx_timer_thread))
1646    {
1647        /* Return default error.  */
1648        Application->osek_object_creation_error++;
1649        return ((ResourceType) TX_NULL);
1650    }
1651 
1652    /* Check whether the linked resource (if specified) exists.  */
1653    if (type == LINKED)
1654    {
1655        if (linked_res == 0u)
1656        {
1657        /* Specified linked resource doesn't exist  */
1658        /* OR Resource is trying to link itself.  */
1659            Application->osek_object_creation_error++;
1660            return ((ResourceType) TX_NULL);
1661        }
1662 
1663        /* Check if the resource to which this resource is linked is external.  */
1664        linked_res_ptr = (OSEK_RESOURCE *)linked_res;
1665        if (linked_res_ptr->type == INTERNAL)
1666        {
1667            /* Specified linked resource is of INTERNAL type.  */
1668            Application->osek_object_creation_error++;
1669            return ((ResourceType) TX_NULL);
1670        }
1671    }
1672 
1673    /* Find out any resource is available.  */
1674    ID = osek_get_resource();
1675    if(ID == 0u)
1676    {
1677        /* Resource is not available.  */
1678        Application->osek_object_creation_error++;
1679        return ((ResourceType) TX_NULL);
1680    }
1681 
1682    /* Get the OSEK resource.  */
1683    res_ptr = (OSEK_RESOURCE *)ID;
1684 
1685    res_ptr->name = name;
1686 
1687    res_ptr->c_priority = 0u;
1688 
1689    res_ptr->type = type;
1690 
1691    res_ptr->linked_res = linked_res;
1692 
1693    res_ptr->resolved_res = 0u;
1694 
1695    /* Now resolve if chain of linked linked resources.  */
1696 
1697    if (res_ptr->type == LINKED)
1698    {
1699        done_flag = FALSE;
1700        res1_ptr = res_ptr;
1701        iter_max = OSEK_MAX_LINK_DEPTH; /* Safety count to prevent infinite loop.  */
1702        while(done_flag == 0u)
1703        {
1704            if(iter_max == 0u) {
1705                /* Maximum iteration count exceeded, return an error. */
1706                Application->osek_object_creation_error++;
1707                return ((ResourceType) TX_NULL);
1708            }
1709 
1710            linked_res_id = res1_ptr->linked_res;
1711            linked_res_ptr = (OSEK_RESOURCE *)linked_res_id;
1712            if (linked_res_ptr->type == STANDARD)
1713            {
1714                res_ptr->resolved_res = linked_res_id;
1715                done_flag = TRUE;
1716            }
1717            res1_ptr = linked_res_ptr;
1718 
1719            iter_max--;
1720        }
1721 
1722    }
1723 
1724 
1725    /* No task is occupying this resource.  */
1726    res_ptr->taskid = 0u;
1727 
1728    res_ptr->osek_res_id = OSEK_RES_ID;
1729 
1730    return (ID);
1731 }
1732 
1733 
1734 /**************************************************************************/
1735 /*                                                                        */
1736 /*  FUNCTION                                               RELEASE        */
1737 /*                                                                        */
1738 /*    GetResource                                         PORTABLE C      */
1739 /*                                                           6.1.7        */
1740 /*  AUTHOR                                                                */
1741 /*                                                                        */
1742 /*    William E. Lamie, Microsoft Corporation                             */
1743 /*                                                                        */
1744 /*  DESCRIPTION                                                           */
1745 /*                                                                        */
1746 /*   This call serves to enter critical sections in the code that are     */
1747 /*   assigned to the resource referenced by <ResID>. A critical section   */
1748 /*   must always be left using ReleaseResource. Nested resource           */
1749 /*   occupation is only allowed if the inner critical sections are        */
1750 /*   completely executed within the surrounding critical section.         */
1751 /*   Nested occupation of one and the same resource is also forbidden.    */
1752 /*   Corresponding calls to GetResource and ReleaseResource should appear */
1753 /*   within the same function on the same function level.                 */
1754 /*                                                                        */
1755 /*  INPUT                                                                 */
1756 /*                                                                        */
1757 /*    id                           Id of the resource.                    */
1758 /*                                                                        */
1759 /*  OUTPUT                                                                */
1760 /*                                                                        */
1761 /*    E_OK                         If success                             */
1762 /*    E_OS_CALLEVEL                Called from ISR                        */
1763 /*    E_OS_ACCESS                  Attempt to get a resource which is     */
1764 /*                                 already occupied by any task or ISR,   */
1765 /*                                 or the statically assigned priority of */
1766 /*                                 the calling task or interrupt routine  */
1767 /*                                 is higher than the calculated ceiling  */
1768 /*                                 priority,                              */
1769 /*                                                                        */
1770 /*  CALLS                                                                 */
1771 /*                                                                        */
1772 /*    osek_task_independent_area   See if called from task independent    */
1773 /*                                 area                                   */
1774 /*    tx_thread_identify           Identify the current thread            */
1775 /*    osek_internal_error          OSEK internal error                    */
1776 /*                                                                        */
1777 /*  CALLED BY                                                             */
1778 /*                                                                        */
1779 /*   Application Code                                                     */
1780 /*                                                                        */
1781 /*  RELEASE HISTORY                                                       */
1782 /*                                                                        */
1783 /*    DATE              NAME                      DESCRIPTION             */
1784 /*                                                                        */
1785 /*  06-02-2021     William E. Lamie         Initial Version 6.1.7         */
1786 /*                                                                        */
1787 /**************************************************************************/
GetResource(ResourceType id)1788 StatusType  GetResource(ResourceType id)
1789 {
1790 TX_INTERRUPT_SAVE_AREA
1791 OSEK_RESOURCE  *osek_res;
1792 OSEK_TCB       *tcb_ptr;
1793 TX_THREAD      *this_thread;
1794 UINT            index ;
1795 UINT            new_prio;
1796 ULONG           request[SYSMGR_QUEUE_MSG_LENGTH];
1797 UINT            status;
1798 ULONG           area;
1799 
1800 
1801 
1802    service_GetServiceId.id = (OsServiceIdType)OSServiceId_GetResource;
1803    service_GetResource.ResID = id;
1804 
1805    /* Check we are calling from task context only.  */
1806    area = osek_task_independent_area();
1807    if(area == 0u)
1808    {
1809        exec_ErrorHook(E_OS_CALLEVEL);
1810        /* Return default error.  */
1811        return (E_OS_CALLEVEL);
1812    }
1813 
1814    /* Check for valid ID.  */
1815    if(id == 0u)
1816    {
1817        exec_ErrorHook(E_OS_ID);
1818        /* Return error.  */
1819        return (E_OS_ID);
1820    }
1821 
1822    /* Get thread currently executed.  */
1823    this_thread = tx_thread_identify();
1824    if(this_thread == NULL)
1825    {
1826        exec_ErrorHook(E_OS_CALLEVEL);
1827        return (E_OS_CALLEVEL);
1828    }
1829 
1830    /* Get RES's control block.  */
1831    osek_res = (OSEK_RESOURCE *)id;
1832 
1833    /* First, check for an invalid resource pointer.  */
1834    if((osek_res == TX_NULL) || ((osek_res->osek_res_id) != OSEK_RES_ID))
1835    {
1836        exec_ErrorHook(E_OS_ID);
1837 
1838        /* Return Error.  */
1839        return (E_OS_ID);
1840    }
1841 
1842    /* Get the OSEK TCB.  */
1843    tcb_ptr = (OSEK_TCB *) this_thread;
1844 
1845    /* Now check whether this resource is standard or internal.  */
1846    if (osek_res->type == INTERNAL)
1847    {
1848        /* Internal Resource can not be occupied via GetResource call.  */
1849        exec_ErrorHook(E_OS_ID);
1850        return (E_OS_ID);
1851    }
1852 
1853    TX_DISABLE
1854 
1855    /* Now check whether this resource is occupied.  */
1856    if (osek_res->taskid != 0u)
1857    {
1858        TX_RESTORE
1859 
1860        /* Already occupied by this task or any other task, this also prevent double occupancy.  */
1861        exec_ErrorHook(E_OS_ACCESS);
1862 
1863        return (E_OS_ACCESS);
1864    }
1865 
1866    /* OK up to this point, now what type of resource is it? */
1867    /* Because 'RES_SCEDULER' is a special type of resource.  */
1868 
1869    if (id == RES_SCHEDULER)
1870    {
1871 
1872        /* This task has taken this resource so update this task's resource hold count.  */
1873        tcb_ptr->res_ocp++;
1874 
1875        /* Save this task's id in the res's control block.  */
1876        osek_res->taskid = (TaskType)tcb_ptr;
1877 
1878        tcb_ptr->resource_scheduler = TX_TRUE;
1879 
1880        /* Being RES_SCHEDULER no need to add RES_SCEDULER in the task's list of occupied resources.  */
1881 
1882        /* As task is occupying RES_SCHEDULER all preemptions are blocked so make the policy to NON PREEMP.  */
1883        /* A NON preempt type task is already having OSEK_NON_SCHEDULE_PRIORITY during RUN time, so need
1884           to change it.  */
1885 
1886        if (tcb_ptr->policy == FULL)
1887        {
1888            /* For a FULL preempt type task assign having highest preemption threshold */
1889            /* Now ask the System Manager to change this task's priority, and also check if there is
1890               any possibility of preemption.  */
1891            /* Send message to System Manager to check any preemption out of ReleaseResource call.  */
1892            new_prio = OSEK_NON_SCHEDULE_PRIORITY;
1893 
1894            /* Build the request.  */
1895            request[0] = SYSMGR_GET_RESOURCE;          /* Request type.  */
1896            request[1] = (ULONG)this_thread;
1897            request[2] = (ULONG)new_prio;
1898            request[3] = 0u;
1899 
1900            /* Since the SysMgr supervisor thread has the highest priority,      */
1901            /* this routine will be preempted by SysMgr supervisor thread when   */
1902            /* queue is successful.                                              */
1903            /* System Manager will eventually call start_osek_tasks.             */
1904 
1905            status = tx_queue_send(&osek_work_queue, request, TX_NO_WAIT);
1906 
1907            /* This should always succeed.  */
1908            if (status != TX_SUCCESS)
1909            {
1910                /* System internal error.  */
1911                osek_internal_error(SYS_MGR_SEND_CHAINTASK);
1912 
1913            }
1914        }
1915 
1916        TX_RESTORE
1917 
1918        return (E_OK);
1919 
1920    }   /* End if ( id == RES_SCHEDULER ).  */
1921 
1922 
1923    /* Not RES_SCEDULER. */
1924 
1925    /* Check whether this resource is assigned to this task or not?  */
1926    for (index = 0u; index < OSEK_MAX_EXTERNAL_RES; index++)
1927    {
1928        if (tcb_ptr-> external_resource_list[index] == id) {
1929            /* Yes it is registered with this task, stop searching.  */
1930            break;
1931        }
1932    } /* Check next in the list.  */
1933 
1934    /* Checked entire list and found that this resource is not in the list?  */
1935    if (index >= OSEK_MAX_EXTERNAL_RES)
1936    {
1937        TX_RESTORE
1938 
1939        exec_ErrorHook(E_OS_NOFUNC);
1940 
1941        /* Return error.  */
1942        return (E_OS_NOFUNC);
1943    }
1944 
1945    /* Yes this resource is assigned to this task.  */
1946    /* First check the task has room to hold one more resource?  */
1947 
1948    /* Find the next free entry in the task's res occupied list.  */
1949    for (index = 0u; index < OSEK_MAX_EXTERNAL_RES; index++)
1950    {
1951        if(tcb_ptr->external_resource_occuplied_list[index] == 0u)
1952        {
1953            /* Found next free entry but do not add this resource to the list at this moment.  */
1954            break;
1955        }
1956    }
1957 
1958    /* We got an entry or not?  */
1959    if (index >= OSEK_MAX_EXTERNAL_RES)
1960    {
1961        TX_RESTORE
1962 
1963        /* This is very unlikely, as list is big enough to hold all resources defined in the system.  */
1964        exec_ErrorHook(E_OS_ACCESS);
1965 
1966        /* Return Error.  */
1967        return (E_OS_ACCESS);
1968    }
1969 
1970    /* Now entry is available, take this resource.  */
1971 
1972    tcb_ptr->external_resource_occuplied_list[index] = id;
1973    /* Save this task's id in the res's control block to indicate that this is the owner of this res.  */
1974    osek_res->taskid = (TaskType)(tcb_ptr);
1975    /* This task has taken this resource so update this task's resource hold count.  */
1976    tcb_ptr->res_ocp++;
1977 
1978    /* Now we need to change this task's preemption threshold to this resource's ceiling priority.  */
1979    /* But if the task is of NON scheduling no need to take any action , it is already having
1980       highest preemption threshold.  */
1981 
1982    if ((tcb_ptr->policy == FULL) && (tcb_ptr->cur_threshold < osek_res->c_priority))
1983    {
1984        /* Need to change the at the task is having lower preemption threshold. */
1985        /* Remove this task from its current queue and place it in front of
1986           occupied resource's ceiling priority queue.  */
1987 
1988        new_prio = osek_res->c_priority;
1989 
1990        /* Build the request. */
1991        request[0] = SYSMGR_GET_RESOURCE;          /* Request type.  */
1992        request[1] = (ULONG)this_thread;
1993        request[2] = (ULONG)new_prio;
1994        request[3] = 0u;
1995 
1996        /* Since the SysMgr supervisor thread has the highest priority,      */
1997        /* this routine will be preempted by SysMgr supervisor thread when   */
1998        /* queue is successful.                                              */
1999        /* System Manager will eventually call start_osek_tasks.             */
2000 
2001        status = tx_queue_send(&osek_work_queue, request, TX_NO_WAIT);
2002 
2003        /* This should always succeed.  */
2004        if (status != TX_SUCCESS)
2005        {
2006            /* System internal error.  */
2007            osek_internal_error(SYS_MGR_SEND_CHAINTASK);
2008        }
2009    }
2010 
2011    TX_RESTORE
2012 
2013    return (E_OK);
2014 }
2015 
2016 
2017 /**************************************************************************/
2018 /*                                                                        */
2019 /*  FUNCTION                                               RELEASE        */
2020 /*                                                                        */
2021 /*    ReleaseResource                                     PORTABLE C      */
2022 /*                                                           6.1.7        */
2023 /*  AUTHOR                                                                */
2024 /*                                                                        */
2025 /*    William E. Lamie, Microsoft Corporation                             */
2026 /*                                                                        */
2027 /*  DESCRIPTION                                                           */
2028 /*                                                                        */
2029 /*   ReleaseResource is the counterpart of GetResource and serves to      */
2030 /*   leave critical sections in the code that are assigned to the         */
2031 /*   resource referenced by <ResID>. For information on nesting           */
2032 /*   conditions, see GetResource. The service may be called from an ISR   */
2033 /*   and from task level                                                  */
2034 /*                                                                        */
2035 /*  INPUT                                                                 */
2036 /*                                                                        */
2037 /*    id                           Id of the resource.                    */
2038 /*                                                                        */
2039 /*  OUTPUT                                                                */
2040 /*                                                                        */
2041 /*    E_OK                         If successful                          */
2042 /*    E_OS_NOFUNC                  Attempt to release a resource which is */
2043 /*                                 not occupied by any task or ISR, or    */
2044 /*                                 another resource has to be released    */
2045 /*                                 before,If error occurs while creating  */
2046 /*                                 task                                   */
2047 /*    E_OS_ACCESS                  Attempt to release a resource which has*/
2048 /*                                 a lower ceiling priority than the      */
2049 /*                                 statically assigned priority of the    */
2050 /*                                 calling task or interrupt routine.     */
2051 /*                                                                        */
2052 /*  CALLS                                                                 */
2053 /*                                                                        */
2054 /*                                                                        */
2055 /*    osek_task_independent_area   See if called from task independent    */
2056 /*                                 area                                   */
2057 /*    tx_thread_identify           Identify the current thread            */
2058 /*    osek_internal_error          OSEK internal error                    */
2059 /*                                                                        */
2060 /*  CALLED BY                                                             */
2061 /*                                                                        */
2062 /*   Application Code                                                     */
2063 /*                                                                        */
2064 /*  RELEASE HISTORY                                                       */
2065 /*                                                                        */
2066 /*    DATE              NAME                      DESCRIPTION             */
2067 /*                                                                        */
2068 /*  06-02-2021     William E. Lamie         Initial Version 6.1.7         */
2069 /*                                                                        */
2070 /**************************************************************************/
ReleaseResource(ResourceType id)2071 StatusType  ReleaseResource(ResourceType id)
2072 {
2073 TX_INTERRUPT_SAVE_AREA
2074 OSEK_RESOURCE  *osek_res;
2075 OSEK_TCB       *tcb_ptr;
2076 TX_THREAD      *this_thread;
2077 UINT           index;
2078 UINT           res_prio;
2079 UINT           location;
2080 UINT           new_prio;
2081 ULONG          request[SYSMGR_QUEUE_MSG_LENGTH];
2082 UINT           status;
2083 ULONG          area;
2084 
2085    service_GetServiceId.id = (OsServiceIdType)OSServiceId_ReleaseResource;
2086    service_ReleaseResource.ResID = id;
2087 
2088    /* Fist check valid resource id and proper calling context.  */
2089 
2090    /* Check we calling from from task context only.  */
2091    area = osek_task_independent_area();
2092    if(area == 0u)
2093    {
2094        exec_ErrorHook(E_OS_CALLEVEL);
2095 
2096        /* Return default error.  */
2097        return (E_OS_CALLEVEL);
2098    }
2099 
2100    /* Check for valid Resource ID.  */
2101    if(id == 0u)
2102    {
2103        exec_ErrorHook(E_OS_ID);
2104 
2105        /* Return error.  */
2106        return (E_OS_ID);
2107    }
2108 
2109    /* Get thread currently executed.  */
2110    this_thread = tx_thread_identify();
2111    if(this_thread == TX_NULL)
2112    {
2113        exec_ErrorHook(E_OS_CALLEVEL);
2114 
2115        return (E_OS_CALLEVEL);
2116    }
2117 
2118    /* Get OSEK resource control block.  */
2119    osek_res = (OSEK_RESOURCE *)id;
2120 
2121    /* Get the OSEK TCB.  */
2122    tcb_ptr = (OSEK_TCB *)this_thread;
2123 
2124    /* Now check whether this resource is standard or internal.  */
2125 
2126    if (osek_res->type == INTERNAL)
2127    {
2128        /* Internal resource can not be released via ReleaseResource call.  */
2129        exec_ErrorHook(E_OS_ID);
2130 
2131        return (E_OS_ID);
2132    }
2133 
2134    TX_DISABLE
2135 
2136    /* Is this task holding any resource? Check for resource count.  */
2137    if(tcb_ptr->res_ocp == 0u)
2138    {
2139        TX_RESTORE
2140 
2141        /* No resource taken yet trying to release resource?  */
2142        exec_ErrorHook(E_OS_NOFUNC);
2143 
2144        /* Return error.  */
2145        return(E_OS_NOFUNC);
2146    }
2147 
2148    /* Check whether this resource is occupied by this task.  */
2149    /* A task cannot release resource which are not occupied by itself.  */
2150 
2151    if (osek_res->taskid != (TaskType)tcb_ptr)
2152    {
2153        TX_RESTORE
2154 
2155        exec_ErrorHook(E_OS_NOFUNC);
2156 
2157        return (E_OS_NOFUNC);
2158    }
2159 
2160    /* Everything is valid up to this point, now try to release the resource requested.  */
2161    /* Check what type of Resource it is as RES_SCEDULER is a special case of resource.  */
2162 
2163    if (id == RES_SCHEDULER)
2164    {
2165 
2166        /* Remove this task's id from the res's control block which usually indicate that this is the
2167           owner of this res  and also update this task's resource hold count.  */
2168        osek_res->taskid = 0u;
2169        tcb_ptr->res_ocp--;
2170 
2171        /* As the task is giving up RES_SCHEDULER, make the associated flag FALSE.  */
2172        tcb_ptr->resource_scheduler = TX_FALSE;
2173 
2174        /* If Task is NON scheduling type, no preemption takes place.  */
2175        if (tcb_ptr->policy == NON)
2176        {
2177            TX_RESTORE
2178 
2179            /* Release this resource.  */
2180            return (E_OK);
2181        }
2182 
2183        /* With FULL scheduling, a change in preemption to highest
2184           ceiling priority of any other resources held by this task is needed.  */
2185        /* Check RES_SCEDULER is the only resource occupied by this task, then restore this task's threshold
2186           to its original priority.  */
2187 
2188        /* Assume no other resources are held.  */
2189        new_prio = tcb_ptr->org_prio;
2190 
2191        if (tcb_ptr->res_ocp > 0u)
2192        {
2193            /* If no other external resources are held the task will revert back to
2194               to its original design time priority.  */
2195            /* Or check the ceiling priorities of other external resources held by this task.  */
2196 
2197            for (index = 0u; index < OSEK_MAX_EXTERNAL_RES; index++)
2198            {
2199                if (tcb_ptr->external_resource_occuplied_list[index] == 0u)
2200                {
2201                    break;
2202                }
2203 
2204                res_prio = ((OSEK_RESOURCE *) (tcb_ptr->external_resource_occuplied_list[index]))->c_priority;
2205                if  (new_prio < res_prio) {
2206                    new_prio = res_prio;
2207                }
2208            }
2209        }
2210 
2211        /* Done with external resource, now check if there are any internal resources held?  */
2212        for ( index = 0u; index < OSEK_MAX_INTERNAL_RES; index++)
2213        {
2214            if (tcb_ptr->internal_resource_occuplied_list[index] == 0u)
2215            {
2216                break;
2217            }
2218 
2219            res_prio = ((OSEK_RESOURCE *) (tcb_ptr->internal_resource_occuplied_list[index]))->c_priority;
2220 
2221            if (new_prio < res_prio)
2222            {
2223                new_prio = res_prio;
2224            }
2225        }
2226 
2227 
2228        /* new_prio now holds the highest of ceiling priority of the remaining
2229       resources held by this task.  */
2230 
2231        /* Now ask the system manager to change this task's priority, and also check if there is
2232           any possibility of preemption.  */
2233        /* Send message to the system manager to check any preemption out of ReleaseResource call.  */
2234 
2235        /* Build the request. */
2236        request[0] = SYSMGR_RELEASE_RESOURCE;          /* Request type.  */
2237        request[1] = (ULONG)this_thread;
2238        request[2] = (ULONG)new_prio;
2239        request[3] = 0u;
2240 
2241        /* Since the SysMgr supervisor thread has the highest priority,      */
2242        /* this routine will be preempted by SysMgr supervisor thread when   */
2243        /* queue is successful.                                              */
2244        /* System Manager will eventually call start_osek_tasks.             */
2245 
2246        status = tx_queue_send(&osek_work_queue, request, TX_NO_WAIT);
2247 
2248        /* This should always succeed.  */
2249        if (status != TX_SUCCESS)
2250        {
2251            /* System internal error.  */
2252            osek_internal_error(SYS_MGR_SEND_CHAINTASK);
2253 
2254        }
2255 
2256        TX_RESTORE
2257 
2258        /* Assume that the system manager does its job.  */
2259        return (E_OK);
2260 
2261    } /* End if ( id == RES_SCHEDULER ).  */
2262 
2263 
2264    /* Not a RES_SCHEDULER.  */
2265 
2266    /* Are we releasing the resource which is last taken?  */
2267    for (index = 0u; index < OSEK_MAX_EXTERNAL_RES; index++)
2268    {
2269        if ( tcb_ptr->external_resource_occuplied_list[index] == 0u)
2270        {
2271            /* Reached at the last entry, stop searching.  */
2272            break;
2273        }
2274    } /* Next entry.  */
2275 
2276    if (index == 0u)
2277    {
2278        /* List is empty and resource is taken?  */
2279        return(E_OS_NOFUNC);
2280    }
2281 
2282    location = index - 1u; /* Save the location of last resource entry.  */
2283 
2284    /* Check the last resource taken.  */
2285    if (tcb_ptr->external_resource_occuplied_list[location] != id)
2286    {
2287        /* Are we trying to release the resource which was not in LIFO order.  */
2288        exec_ErrorHook(E_OS_NOFUNC);
2289 
2290        /* Return error.  */
2291        return(E_OS_NOFUNC);
2292    }
2293 
2294    /* Now to change preemption threshold to suit next resource with highest ceiling priority */
2295    /* But if the task has got NON scheduling policy then do nothing.  */
2296 
2297    tcb_ptr->external_resource_occuplied_list[location] = 0u;
2298    /* And remove this task's id from the res's control block.  */
2299    osek_res->taskid = 0u;
2300    tcb_ptr->res_ocp--;
2301 
2302    if ((tcb_ptr->policy == NON ) || (tcb_ptr->resource_scheduler == TX_TRUE))
2303    {
2304        /* In case of NON scheduling policy or if a Task holds a RES_SCHEDULER, no need to change preemption.  */
2305        /* Even if a resource is released the task is still remains in OSEK_NON_SCHEDULE_PRIORITY.  */
2306        /* just  remove this resource from the list.  */
2307        return (E_OK);
2308    }
2309 
2310    /* FULL scheduling policy and no RES_SCHEDULER held.  */
2311 
2312    /* Assume no other resources are held.  */
2313    new_prio = tcb_ptr->org_prio;
2314 
2315    if (tcb_ptr->res_ocp > 0u)
2316    {
2317        /* This task is holding more than one resources.  */
2318        /* Find out new highest ceiling priority.  */
2319        /* Assume task's original priority is the highest.  */
2320        for ( index = 0u; index < OSEK_MAX_EXTERNAL_RES; index++)
2321        {
2322 
2323            /* Get this resource's ceiling priority.  */
2324            if ( tcb_ptr->external_resource_occuplied_list[index] == 0u) {
2325                break;
2326            }
2327 
2328            res_prio = ((OSEK_RESOURCE *) (tcb_ptr->external_resource_occuplied_list[index]) )->c_priority;
2329            /* Check if this is more than Task's static priority.  */
2330            if (new_prio < res_prio)
2331            {
2332                 new_prio = res_prio;
2333            }
2334        }
2335 
2336    }
2337 
2338    /* Done with external resource, now check if there are any internal resources held?  */
2339    for (index = 0u; index < OSEK_MAX_INTERNAL_RES; index++)
2340    {
2341        if (tcb_ptr->internal_resource_occuplied_list[index] == 0u)
2342        {
2343            break;
2344        }
2345 
2346        res_prio = ( (OSEK_RESOURCE *) (tcb_ptr->internal_resource_occuplied_list[index]) )->c_priority;
2347 
2348        if (new_prio < res_prio )
2349        {
2350            new_prio = res_prio;
2351        }
2352    }
2353 
2354    /* new_prio now holds the highest of ceiling priority of the remaining
2355       resources held by this task.  */
2356 
2357    /* Now ask the system manager to change this task's priority, and also check if there is
2358       any possibility of preemption.  */
2359    /* Send message to system manager to check any preemption out of ReleaseResource call.  */
2360 
2361    /* Build the request.  */
2362    request[0] = SYSMGR_RELEASE_RESOURCE;          /* Request type.  */
2363    request[1] = (ULONG)this_thread;
2364    request[2] = (ULONG)new_prio;
2365    request[3] = 0u;
2366 
2367    /* Since the SysMgr supervisor thread has the highest priority,      */
2368    /* this routine will be preempted by SysMgr supervisor thread when   */
2369    /* queue is successful.                                              */
2370    /* System manager will eventually call start_osek_tasks.             */
2371 
2372    status = tx_queue_send(&osek_work_queue, request, TX_NO_WAIT);
2373 
2374    TX_RESTORE
2375 
2376    /* This should always succeed.  */
2377    if (status != TX_SUCCESS)
2378    {
2379        /* System internal error.  */
2380        osek_internal_error(SYS_MGR_SEND_CHAINTASK);
2381    }
2382 
2383    /* Assume that system manager does its job.  */
2384    return (E_OK);
2385 }
2386 
2387 
2388 /**************************************************************************/
2389 /*                                                                        */
2390 /*  FUNCTION                                               RELEASE        */
2391 /*                                                                        */
2392 /*    RegisterTasktoResource                              PORTABLE C      */
2393 /*                                                           6.1.7        */
2394 /*  AUTHOR                                                                */
2395 /*                                                                        */
2396 /*    William E. Lamie, Microsoft Corporation                             */
2397 /*                                                                        */
2398 /*  DESCRIPTION                                                           */
2399 /*                                                                        */
2400 /*   This function registers a resource to the task specified, provided   */
2401 /*   a free entry is available in the task's list of resources.           */
2402 /*   If entry is registered then resource's ceiling priority is also      */
2403 /*   adjusted to this task's priority provided that the task's priority   */
2404 /*   is higher than the resource's current ceiling priority.              */
2405 /*                                                                        */
2406 /*  INPUT                                                                 */
2407 /*                                                                        */
2408 /*    Resource                     Id of the resource.                    */
2409 /*    TaskID                       ID of the task                         */
2410 /*                                                                        */
2411 /*  OUTPUT                                                                */
2412 /*                                                                        */
2413 /*    E_OK                         If successful                          */
2414 /*    E_OS_NOFUNC                  No free entries                        */
2415 /*    E_OS_ID                      Invalid task or resource id.           */
2416 /*                                 not occupied by any task or ISR, or    */
2417 /*                                 another resource has to be released    */
2418 /*                                 before.                                */
2419 /*   E_OS_ACCESS                   Attempt to release an invalid resource */
2420 /*                                                                        */
2421 /*  CALLS                                                                 */
2422 /*                                                                        */
2423 /*    None                                                                */
2424 /*                                                                        */
2425 /*  CALLED BY                                                             */
2426 /*                                                                        */
2427 /*   Application Code  (System Creation section)                          */
2428 /*                                                                        */
2429 /*  RELEASE HISTORY                                                       */
2430 /*                                                                        */
2431 /*    DATE              NAME                      DESCRIPTION             */
2432 /*                                                                        */
2433 /*  06-02-2021     William E. Lamie         Initial Version 6.1.7         */
2434 /*                                                                        */
2435 /**************************************************************************/
RegisterTasktoResource(ResourceType Resource,TaskType TaskID)2436 StatusType     RegisterTasktoResource(ResourceType Resource, TaskType TaskID)
2437 {
2438 
2439 OSEK_TCB       *tcb_ptr;
2440 OSEK_RESOURCE  *resource_ptr;
2441 UINT            index;
2442 
2443    /* Check if we are in initialization.  */
2444    /* This will ensure that no one calls this function after system is started.  */
2445    if (osek_init_state != OSEK_INIT)
2446    {
2447        /* Return OSEK internal error. This is not a standard OSEK error.  */
2448        Application->osek_object_creation_error++;
2449        return ((StatusType)TX_NULL);
2450    }
2451 
2452    /* Check for valid Resource ID.  */
2453    if(Resource == 0u)
2454    {
2455        /* Return error.  */
2456        Application->osek_object_creation_error++;
2457        return (E_OS_ID);
2458    }
2459 
2460    /* Check if task id is valid.  */
2461    if(TaskID == 0u)
2462    {
2463        /* Return error.  */
2464        return (E_OS_ID);
2465    }
2466 
2467    /* Convert object IDs to object control block pointers.  */
2468    resource_ptr = (OSEK_RESOURCE *)Resource;
2469    tcb_ptr = (OSEK_TCB *)TaskID;
2470 
2471     /* Check for valid resource pointer.  */
2472    if (resource_ptr == TX_NULL)
2473    {
2474        Application->osek_object_creation_error++;
2475        return (E_OS_ID);
2476    }
2477 
2478    if (resource_ptr->osek_res_id != OSEK_RES_ID)
2479    {
2480        Application->osek_object_creation_error++;
2481        return (E_OS_ID);
2482    }
2483 
2484    /* Check for valid task pointer.  */
2485    if (tcb_ptr == TX_NULL)
2486    {
2487        Application->osek_object_creation_error++;
2488        return (E_OS_ID);
2489    }
2490 
2491    if ((tcb_ptr->osek_task_id != OSEK_TASK_ID) && (tcb_ptr->osek_task_id != OSEK_ISR_ID))
2492    {
2493        Application->osek_object_creation_error++;
2494        return (E_OS_ID);
2495    }
2496 
2497    /* This task is to be registered with this resource.  */
2498    /* Add this Resource to the task's list of resource.  */
2499    /* provided there is space left for this.  */
2500 
2501    /* Before check whether the resource is internal or standard?  */
2502    if ((resource_ptr->type == STANDARD)|| (resource_ptr->type == LINKED))
2503    {
2504 
2505        for (index = 0u; index < OSEK_MAX_EXTERNAL_RES; index++)
2506        {
2507            if (tcb_ptr->external_resource_list[index] == 0u)
2508            {
2509                /* Empty entry found, write this resource there.  */
2510                tcb_ptr->external_resource_list[index] = Resource;
2511 
2512                /* Also clear the resource occupancy count.  */
2513                tcb_ptr->external_resource_occuplied_list[index] = 0u;
2514 
2515                /* As this resource is attached to a TASK or ISR change this resource's ceiling priority
2516                   to task's (or ISR's) priority provided that  it is higher than resource's current ceiling priority.  */
2517                if (tcb_ptr->org_prio > resource_ptr->c_priority)
2518                {
2519                    resource_ptr->c_priority = tcb_ptr->org_prio;
2520                }
2521 
2522                /* Job done.  */
2523                break;
2524            } /* Try next entry.  */
2525        }
2526 
2527        if (index >= OSEK_MAX_EXTERNAL_RES) /* No free entry.  */
2528        {
2529            Application->osek_object_creation_error++;
2530            return (E_OS_NOFUNC);
2531        }
2532        else
2533        {
2534            return (E_OK);
2535        }
2536    } /* END STANDARD.  */
2537    else
2538    {
2539        /* Attaching Internal resource to this task, so set the flag.  */
2540        tcb_ptr->internal_res = TX_TRUE;
2541 
2542        for (index = 0u; index < OSEK_MAX_INTERNAL_RES; index++)
2543        {
2544            if (tcb_ptr->internal_resource_list[index] == 0u)
2545            {
2546                /* Empty entry found write this resource there.  */
2547                tcb_ptr->internal_resource_list[index] = Resource;
2548 
2549                /* As this resource is attached to the resource change this resource's ceiling priority
2550                   to this task's original priority provide it is higher than resource's current ceiling priority.  */
2551                if (tcb_ptr->org_prio > resource_ptr->c_priority)
2552                {
2553                    resource_ptr->c_priority =  tcb_ptr->org_prio;
2554                }
2555 
2556                /* Job done.  */
2557                break;
2558            } /* Try next entry.  */
2559        }
2560 
2561        if (index >= OSEK_MAX_INTERNAL_RES) /* No free entry.  */
2562        {
2563            Application->osek_object_creation_error++;
2564            return (E_OS_NOFUNC);
2565        }
2566        else
2567        {
2568            return (E_OK);
2569        }
2570    }
2571 }
2572 
2573 
2574 /**************************************************************************/
2575 /*                                                                        */
2576 /*  FUNCTION                                               RELEASE        */
2577 /*                                                                        */
2578 /*    RegisterISRtoResource                               PORTABLE C      */
2579 /*                                                           6.1.7        */
2580 /*  AUTHOR                                                                */
2581 /*                                                                        */
2582 /*    William E. Lamie, Microsoft Corporation                             */
2583 /*                                                                        */
2584 /*  DESCRIPTION                                                           */
2585 /*                                                                        */
2586 /*   This function registers a resource to the ISR specified, provided    */
2587 /*   a free entry is available in the ISR's list of resources.            */
2588 /*   If entry is registered then resource's ceiling priority is also      */
2589 /*   adjusted to this task's priority provided that the task's priority   */
2590 /*   is higher than the resource's current ceiling priority.              */
2591 /*                                                                        */
2592 /*  INPUT                                                                 */
2593 /*                                                                        */
2594 /*    Resource                     Id of the resource.                    */
2595 /*    TaskID                       ID of the task                         */
2596 /*                                                                        */
2597 /*  OUTPUT                                                                */
2598 /*                                                                        */
2599 /*    E_OK                         If successful                          */
2600 /*    E_OS_NOFUNC                  No free entries                        */
2601 /*    E_OS_ID                      Invalid task or resource id.           */
2602 /*                                 not occupied by any task or ISR, or    */
2603 /*                                 another resource has to be released    */
2604 /*                                 before                                 */
2605 /*   E_OS_ACCESS                   Attempt to release an invalid resource */
2606 /*                                                                        */
2607 /*  CALLS                                                                 */
2608 /*                                                                        */
2609 /*    RegisterTasktoResource       Register resource.                     */
2610 /*                                                                        */
2611 /*  CALLED BY                                                             */
2612 /*                                                                        */
2613 /*   Application Code                                                     */
2614 /*                                                                        */
2615 /*  RELEASE HISTORY                                                       */
2616 /*                                                                        */
2617 /*    DATE              NAME                      DESCRIPTION             */
2618 /*                                                                        */
2619 /*  06-02-2021     William E. Lamie         Initial Version 6.1.7         */
2620 /*                                                                        */
2621 /**************************************************************************/
RegisterISRtoResource(ResourceType Resource,ISRType ISRID)2622 StatusType     RegisterISRtoResource(ResourceType Resource, ISRType ISRID)
2623 {
2624 StatusType     status;
2625 
2626    status = RegisterTasktoResource(Resource, ISRID);
2627    return (status);
2628 }
2629 
2630 
2631 /**************************************************************************/
2632 /*                                                                        */
2633 /*  FUNCTION                                               RELEASE        */
2634 /*                                                                        */
2635 /*    CreateEvent                                         PORTABLE C      */
2636 /*                                                           6.1.7        */
2637 /*  AUTHOR                                                                */
2638 /*                                                                        */
2639 /*    William E. Lamie, Microsoft Corporation                             */
2640 /*                                                                        */
2641 /*  DESCRIPTION                                                           */
2642 /*                                                                        */
2643 /*    Creates an event. It is a 32 bit number with only one bit set.      */
2644 /*                                                                        */
2645 /*                                                                        */
2646 /*  OUTPUT                                                                */
2647 /*                                                                        */
2648 /*    eventid                      If success                             */
2649 /*    0                            If error occurs                        */
2650 /*                                                                        */
2651 /*  CALLS                                                                 */
2652 /*                                                                        */
2653 /*    osek_get_event               Get the event                          */
2654 /*    osek_internal_error          OSEK internal error                    */
2655 /*                                                                        */
2656 /*  CALLED BY                                                             */
2657 /*                                                                        */
2658 /*   OSEK internal call                                                   */
2659 /*                                                                        */
2660 /*  RELEASE HISTORY                                                       */
2661 /*                                                                        */
2662 /*    DATE              NAME                      DESCRIPTION             */
2663 /*                                                                        */
2664 /*  06-02-2021     William E. Lamie         Initial Version 6.1.7         */
2665 /*                                                                        */
2666 /**************************************************************************/
CreateEvent(void)2667 EventMaskType CreateEvent(void)
2668 {
2669 EventMaskType  event;
2670 
2671    event = osek_get_event();
2672    if (event == 0u)
2673    {
2674        /* Error will be returned whenever the ThreadX call fails.  */
2675        Application->osek_object_creation_error++;
2676        return (0u);
2677    }
2678 
2679    return (event);
2680 }
2681 
2682 
2683 /**************************************************************************/
2684 /*                                                                        */
2685 /*  FUNCTION                                               RELEASE        */
2686 /*                                                                        */
2687 /*    SetEvent                                            PORTABLE C      */
2688 /*                                                           6.1.7        */
2689 /*  AUTHOR                                                                */
2690 /*                                                                        */
2691 /*    William E. Lamie, Microsoft Corporation                             */
2692 /*                                                                        */
2693 /*  DESCRIPTION                                                           */
2694 /*                                                                        */
2695 /*    Sets events of the given task according to the event mask.          */
2696 /*                                                                        */
2697 /*  INPUT                                                                 */
2698 /*                                                                        */
2699 /*    task ID                      ID for the task                        */
2700 /*    mask                         Mask of the events to be set.          */
2701 /*                                                                        */
2702 /*  OUTPUT                                                                */
2703 /*                                                                        */
2704 /*    E_OK                         If successful                          */
2705 /*    E_OS_ID                      Invalid task or event id               */
2706 /*    E_OS_STATE                   Invalid target task state              */
2707 /*                                                                        */
2708 /*  CALLS                                                                 */
2709 /*                                                                        */
2710 /*    tx_event_flags_set            Set ThreadX event flag.               */
2711 /*    osek_internal_error           OSEK Internal error                   */
2712 /*                                                                        */
2713 /*  CALLED BY                                                             */
2714 /*                                                                        */
2715 /*   Application Code                                                     */
2716 /*                                                                        */
2717 /*  RELEASE HISTORY                                                       */
2718 /*                                                                        */
2719 /*    DATE              NAME                      DESCRIPTION             */
2720 /*                                                                        */
2721 /*  06-02-2021     William E. Lamie         Initial Version 6.1.7         */
2722 /*                                                                        */
2723 /**************************************************************************/
SetEvent(TaskType task_id,EventMaskType mask)2724 StatusType  SetEvent(TaskType task_id, EventMaskType mask)
2725 {
2726 TX_INTERRUPT_SAVE_AREA
2727 OSEK_TCB       *tcb_ptr;
2728 TX_THREAD      *this_thread;
2729 EventMaskType   balance_events;
2730 ULONG           request[SYSMGR_QUEUE_MSG_LENGTH];
2731 UINT            status;
2732 OSEK_TCB       *p_this_tcb;
2733 
2734 
2735    service_GetServiceId.id = (OsServiceIdType)OSServiceId_SetEvent;
2736    service_SetEvent.TaskID = task_id;
2737 
2738    /* Check if task id not valid.  */
2739    if(task_id == 0u)
2740    {
2741        exec_ErrorHook(E_OS_ID);
2742 
2743        /* Return error.  */
2744        return (E_OS_ID);
2745    }
2746 
2747    /* Get TCB_PTR.  */
2748    tcb_ptr = (OSEK_TCB *)task_id;
2749 
2750    if (tcb_ptr->osek_task_id != OSEK_TASK_ID)
2751    {
2752        exec_ErrorHook(E_OS_ID);
2753 
2754        /* Return error.  */
2755        return (E_OS_ID);
2756    }
2757 
2758    /* Check if any event is assigned to task.  */
2759    if ((tcb_ptr->events == 0u) || (tcb_ptr->task_type == BASIC))
2760    {
2761        exec_ErrorHook(E_OS_ACCESS);
2762 
2763        /* No event assigned to task, return error.  */
2764        return (E_OS_ACCESS);
2765    }
2766 
2767    TX_DISABLE
2768 
2769    if (tcb_ptr->suspended == TX_TRUE)
2770    {
2771        TX_RESTORE
2772 
2773        exec_ErrorHook(E_OS_STATE);
2774 
2775        /* Return error.  */
2776        return (E_OS_STATE);
2777    }
2778 
2779    /* Check this event mask with the task .  */
2780    /* Update the set events for this task with this new mask.  */
2781    tcb_ptr->set_events = tcb_ptr->set_events | mask;
2782 
2783    /* See how many events are set.  */
2784    balance_events = tcb_ptr->set_events & tcb_ptr->waiting_events;
2785 
2786    /* Is there any from waiting events.  */
2787    if (balance_events != 0u)
2788    {
2789        /* Get calling task's ThreadX thread */
2790        this_thread = tx_thread_identify();
2791 
2792        /* Check whether the same running task is setting its own events or
2793           the task is already out of wait state.  */
2794        /* if yes then no need to add this task in the ready list and of course no
2795           need to check for any preemption possibilities.  */
2796 
2797        p_this_tcb = osek_thread2tcb(this_thread);
2798        if ((tcb_ptr != p_this_tcb) && (tcb_ptr->waiting == TX_TRUE))
2799        {
2800             tcb_ptr->waiting = TX_FALSE;
2801             /* Now, send message to the system manager to check any preemption out of SetEvent() call.  */
2802 
2803            /* Build the request. */
2804            request[0] = SYSMGR_SETEVENT;              /* Request type.  */
2805            request[1] = (ULONG)this_thread;           /* ThreadX Thread for this task.  */
2806            request[2] = (ULONG)tcb_ptr;               /* id in OSEK_TCB format.  */
2807            request[3] = 0u;
2808 
2809            /* Since the SysMgr supervisor thread has the highest priority,      */
2810            /* this routine will be preempted by SysMgr supervisor thread when   */
2811            /* queue is successful.                                              */
2812            /* System Manager will eventually call start_osek_tasks.             */
2813 
2814            status = tx_queue_send(&osek_work_queue, request, TX_NO_WAIT);
2815 
2816            /* This should always succeed.  */
2817            if (status != TX_SUCCESS)
2818            {
2819                /* System internal error.  */
2820                osek_internal_error(SYS_MGR_SEND_CHAINTASK);
2821 
2822            }
2823        }
2824 
2825    }
2826 
2827    TX_RESTORE
2828 
2829    return (E_OK);
2830 }
2831 
2832 
2833 /**************************************************************************/
2834 /*                                                                        */
2835 /*  FUNCTION                                               RELEASE        */
2836 /*                                                                        */
2837 /*    ClearEvent                                          PORTABLE C      */
2838 /*                                                           6.1.7        */
2839 /*  AUTHOR                                                                */
2840 /*                                                                        */
2841 /*    William E. Lamie, Microsoft Corporation                             */
2842 /*                                                                        */
2843 /*  DESCRIPTION                                                           */
2844 /*                                                                        */
2845 /*    Clears events of the calling task according to the event mask.      */
2846 /*                                                                        */
2847 /*  INPUT                                                                 */
2848 /*                                                                        */
2849 /*    mask                         Mask of the events to be cleared       */
2850 /*                                                                        */
2851 /*  OUTPUT                                                                */
2852 /*                                                                        */
2853 /*    E_OK                         If success                             */
2854 /*    ERROR                        If error occurs while creating task    */
2855 /*                                                                        */
2856 /*  CALLS                                                                 */
2857 /*                                                                        */
2858 /*    tx_event_flags_set            Set or clears ThreadX event flag      */
2859 /*    osek_task_independent_area    See if out of task context            */
2860 /*    tx_thread_identify            Identify the current thread           */
2861 /*    tx_event_flags_set            Set the event Flags                   */
2862 /*    osek_internal_error           OSEK internal error                   */
2863 /*                                                                        */
2864 /*  CALLED BY                                                             */
2865 /*                                                                        */
2866 /*   Application Code                                                     */
2867 /*                                                                        */
2868 /*  RELEASE HISTORY                                                       */
2869 /*                                                                        */
2870 /*    DATE              NAME                      DESCRIPTION             */
2871 /*                                                                        */
2872 /*  06-02-2021     William E. Lamie         Initial Version 6.1.7         */
2873 /*                                                                        */
2874 /**************************************************************************/
ClearEvent(EventMaskType mask)2875 StatusType  ClearEvent(EventMaskType mask)
2876 {
2877 TX_INTERRUPT_SAVE_AREA
2878 TX_THREAD               *this_thread;
2879 OSEK_TCB                *tcb_ptr;
2880 ULONG                    area;
2881 
2882     service_GetServiceId.id = (OsServiceIdType)OSServiceId_ClearEvent;
2883     service_ClearEvent.EventID = mask;
2884     /* Check if we are calling from initialization.  */
2885     if (osek_init_state == OSEK_INIT)
2886     {
2887         exec_ErrorHook(E_OS_CALLEVEL);
2888 
2889         /* Return error.  */
2890         return (E_OS_CALLEVEL);
2891     }
2892 
2893     /* Check if we are not at task level.  */
2894     area = osek_task_independent_area();
2895     if(area == 0u)
2896     {
2897         exec_ErrorHook(E_OS_CALLEVEL);
2898 
2899         /* Return error.  */
2900         return (E_OS_CALLEVEL);
2901     }
2902 
2903     this_thread = tx_thread_identify();
2904 
2905     /* Get OSEK TCB.  */
2906     tcb_ptr = (OSEK_TCB *)this_thread;
2907 
2908     /* Check if any event is assigned to task.  */
2909     if ((tcb_ptr->events == 0u) || (tcb_ptr->task_type == BASIC))
2910     {
2911         exec_ErrorHook(E_OS_ACCESS);
2912 
2913         /* No event assigned to task, return error.  */
2914         return (E_OS_ACCESS);
2915     }
2916 
2917     TX_DISABLE
2918 
2919     /* Update the events.  */
2920     tcb_ptr->set_events = tcb_ptr->set_events & (~mask);
2921     TX_RESTORE
2922 
2923     return (E_OK);
2924 }
2925 
2926 
2927 /**************************************************************************/
2928 /*                                                                        */
2929 /*  FUNCTION                                               RELEASE        */
2930 /*                                                                        */
2931 /*    GetEvent                                            PORTABLE C      */
2932 /*                                                           6.1.7        */
2933 /*  AUTHOR                                                                */
2934 /*                                                                        */
2935 /*    William E. Lamie, Microsoft Corporation                             */
2936 /*                                                                        */
2937 /*  DESCRIPTION                                                           */
2938 /*                                                                        */
2939 /*    Gets the current event setting of the given task.                   */
2940 /*                                                                        */
2941 /*  INPUT                                                                 */
2942 /*                                                                        */
2943 /*    task_id                      ID or the task                         */
2944 /*    mask                         Mask of the events to be set.          */
2945 /*                                                                        */
2946 /*  OUTPUT                                                                */
2947 /*                                                                        */
2948 /*    E_OK                         If successful                          */
2949 /*    ERROR                        If an error occurs                     */
2950 /*                                                                        */
2951 /*  CALLS                                                                 */
2952 /*                                                                        */
2953 /*    osek_internal_error          OSEK internal error                    */
2954 /*                                                                        */
2955 /*  CALLED BY                                                             */
2956 /*                                                                        */
2957 /*   Application Code                                                     */
2958 /*                                                                        */
2959 /*  RELEASE HISTORY                                                       */
2960 /*                                                                        */
2961 /*    DATE              NAME                      DESCRIPTION             */
2962 /*                                                                        */
2963 /*  06-02-2021     William E. Lamie         Initial Version 6.1.7         */
2964 /*                                                                        */
2965 /**************************************************************************/
GetEvent(TaskType task_id,EventMaskRefType event)2966 StatusType  GetEvent(TaskType task_id, EventMaskRefType event)
2967 {
2968 TX_INTERRUPT_SAVE_AREA
2969 OSEK_TCB               *tcb_ptr;
2970 
2971     service_GetServiceId.id = (OsServiceIdType)OSServiceId_GetEvent;
2972     service_GetEvent.TaskID = task_id;
2973 
2974     /* Check if task id is valid.  */
2975     if(task_id == 0u)
2976     {
2977         exec_ErrorHook(E_OS_ID);
2978 
2979         /* Return error.  */
2980         return (E_OS_ID);
2981     }
2982 
2983     /* Get the tcb pointer.  */
2984     tcb_ptr = (OSEK_TCB *)task_id;
2985 
2986     if (tcb_ptr->osek_task_id != OSEK_TASK_ID)
2987     {
2988         exec_ErrorHook(E_OS_ID);
2989 
2990         /* Return error.  */
2991         return (E_OS_ID);
2992     }
2993 
2994     /* Check if any event is assigned to task and task is extended type.  */
2995     if ((tcb_ptr->events == 0u) || (tcb_ptr->task_type == BASIC))
2996     {
2997         exec_ErrorHook(E_OS_ACCESS);
2998 
2999         /* No event assigned to task, return error.  */
3000         return (E_OS_ACCESS);
3001     }
3002 
3003     TX_DISABLE
3004 
3005     if (tcb_ptr->suspended == TX_TRUE)
3006     {
3007         TX_RESTORE
3008 
3009         exec_ErrorHook(E_OS_STATE);
3010 
3011         /* Return error.  */
3012         return (E_OS_STATE);
3013     }
3014 
3015     /* Get the event.  */
3016     *event = tcb_ptr->set_events;
3017 
3018     TX_RESTORE
3019 
3020     return (E_OK);
3021 }
3022 
3023 
3024 /**************************************************************************/
3025 /*                                                                        */
3026 /*  FUNCTION                                               RELEASE        */
3027 /*                                                                        */
3028 /*    WaitEvent                                           PORTABLE C      */
3029 /*                                                           6.1.7        */
3030 /*  AUTHOR                                                                */
3031 /*                                                                        */
3032 /*    William E. Lamie, Microsoft Corporation                             */
3033 /*                                                                        */
3034 /*  DESCRIPTION                                                           */
3035 /*                                                                        */
3036 /*    Transfers the calling task into the waiting state until specified   */
3037 /*    events are set.                                                     */
3038 /*                                                                        */
3039 /*  INPUT                                                                 */
3040 /*                                                                        */
3041 /*    mask                         Mask of the events to be set           */
3042 /*                                                                        */
3043 /*  OUTPUT                                                                */
3044 /*                                                                        */
3045 /*    E_OK                         If success                             */
3046 /*    ERROR                        If error occurs while creating task    */
3047 /*                                                                        */
3048 /*  CALLS                                                                 */
3049 /*                                                                        */
3050 /*    tx_event_flags_get           Retrieves ThreadX event flag from      */
3051 /*                                 specified ThreadX event flag group     */
3052 /*    osek_internal_error          OSEK internal error                    */
3053 /*    tx_thread_identify           Identify current thread                */
3054 /*                                                                        */
3055 /*  CALLED BY                                                             */
3056 /*                                                                        */
3057 /*   Application Code                                                     */
3058 /*                                                                        */
3059 /*  RELEASE HISTORY                                                       */
3060 /*                                                                        */
3061 /*    DATE              NAME                      DESCRIPTION             */
3062 /*                                                                        */
3063 /*  06-02-2021     William E. Lamie         Initial Version 6.1.7         */
3064 /*                                                                        */
3065 /**************************************************************************/
WaitEvent(EventMaskType mask)3066 StatusType  WaitEvent(EventMaskType mask)
3067 {
3068 TX_INTERRUPT_SAVE_AREA
3069 OSEK_TCB              *tcb_ptr;
3070 TX_THREAD             *this_thread;
3071 ULONG                  request[SYSMGR_QUEUE_MSG_LENGTH];
3072 UINT                   index;
3073 UINT                   status;
3074 
3075 
3076     service_GetServiceId.id = (OsServiceIdType)OSServiceId_WaitEvent;
3077     service_WaitEvent.EventID = mask;
3078 
3079 
3080     /* Check if we are in interrupt.  */
3081     if((_tx_thread_current_ptr == TX_NULL) ||           /* Not in a task.  */
3082        (_tx_thread_system_state != 0u))                 /* In an ISR.      */
3083     {
3084         exec_ErrorHook(E_OS_CALLEVEL);
3085 
3086         /* Return error.  */
3087         return (E_OS_CALLEVEL);
3088     }
3089 
3090     /* Check if the thread is currently executed.  */
3091     this_thread = tx_thread_identify();
3092     if(this_thread == TX_NULL)
3093     {
3094         exec_ErrorHook(E_OS_CALLEVEL);
3095 
3096         /* Not allowed on the calling thread.  */
3097         return (E_OS_CALLEVEL);
3098     }
3099 
3100     /* Get OSEK TCB.  */
3101     tcb_ptr = (OSEK_TCB *)this_thread;
3102 
3103     /* Check if any event is assigned to task or the task is of BASIC type.  */
3104     if ((tcb_ptr->events == 0u) || (tcb_ptr->task_type == BASIC))
3105     {
3106         exec_ErrorHook(E_OS_ACCESS);
3107 
3108         /* No event assigned to task, return error.  */
3109         return (E_OS_ACCESS);
3110     }
3111 
3112     /* Check if any resource is occupied by this task.  */
3113     if(tcb_ptr->res_ocp != 0u)
3114     {
3115         exec_ErrorHook(E_OS_RESOURCE);
3116 
3117         /* Return error.  */
3118         return (E_OS_RESOURCE);
3119     }
3120 
3121     TX_DISABLE
3122 
3123     tcb_ptr->waiting_events = mask;
3124 
3125     /* Is any event set?  */
3126     if ((tcb_ptr->set_events & tcb_ptr->waiting_events) != 0u)
3127     {
3128         TX_RESTORE
3129 
3130         return (E_OK);
3131     }
3132     else
3133     {
3134         /* Events are not set wait for them.  */
3135         tcb_ptr->waiting = TX_TRUE;
3136     }
3137 
3138     /* Release any internal resources held.  */
3139     if (tcb_ptr->internal_res != 0u)
3140     {
3141         for (index = 0u; index < OSEK_MAX_INTERNAL_RES; index++)
3142         {
3143             if (tcb_ptr->internal_resource_occuplied_list[index] == 0u)
3144             {
3145                 break;
3146             }
3147 
3148             ((OSEK_RESOURCE *)(tcb_ptr->internal_resource_occuplied_list[index]))->taskid = 0u;
3149             tcb_ptr->internal_resource_occuplied_list[index] = 0u;
3150 
3151         }
3152     }
3153 
3154     /* Now, send message to system thread to check any preemption out of the WaitEvent() call.  */
3155 
3156     /* Build the request.  */
3157     request[0] = SYSMGR_WAITEVENT;               /* Request type.  */
3158     request[1] = (ULONG)this_thread;             /* Self ID.  */
3159     request[2] = (ULONG)tcb_ptr;                 /* Self Id in OSEK_TCB format.  */
3160     request[3] = 0u;
3161     /* Now send a message to the SysMgr supervisor thread and ask        */
3162     /* to check any preemption is possible.                              */
3163     /* Since the SysMgr supervisor thread has the highest priority,      */
3164     /* this routine will be preempted by SysMgr supervisor thread when   */
3165     /* queue is successful.                                              */
3166     /* System Manager will eventually call start_osek_tasks.             */
3167 
3168     status = tx_queue_send(&osek_work_queue, request, TX_NO_WAIT);
3169 
3170     TX_RESTORE
3171 
3172     /* This should always succeed.  */
3173     if (status != TX_SUCCESS)
3174     {
3175        /* System internal error.  */
3176        osek_internal_error(SYS_MGR_SEND_CHAINTASK);
3177     }
3178 
3179     return (E_OK);
3180 }
3181 
3182 
3183 /**************************************************************************/
3184 /*                                                                        */
3185 /*  FUNCTION                                               RELEASE        */
3186 /*                                                                        */
3187 /*    RegisterEventtoTask                                 PORTABLE C      */
3188 /*                                                           6.1.7        */
3189 /*  AUTHOR                                                                */
3190 /*                                                                        */
3191 /*    William E. Lamie, Microsoft Corporation                             */
3192 /*                                                                        */
3193 /*  DESCRIPTION                                                           */
3194 /*                                                                        */
3195 /*   This function registers an event to the task specified, provided     */
3196 /*   a free entry is available in the task's list of events.             */
3197 /*                                                                        */
3198 /*  INPUT                                                                 */
3199 /*                                                                        */
3200 /*    event_id                     Id of the event                        */
3201 /*    TaskID                       Id of the task                         */
3202 /*                                                                        */
3203 /*  OUTPUT                                                                */
3204 /*                                                                        */
3205 /*    E_OK                         If successful                          */
3206 /*    E_OS_NOFUNC                  No free entries                        */
3207 /*    E_OS_ID                      Invalid task or resource id.           */
3208 /*                                 not occupied by any task or ISR, or    */
3209 /*                                 another resource has to be released    */
3210 /*                                 before.                                */
3211 /*   E_OS_ACCESS                   Attempt to release an invalid resource */
3212 /*                                                                        */
3213 /*  CALLS                                                                 */
3214 /*                                                                        */
3215 /*    None                                                                */
3216 /*                                                                        */
3217 /*  CALLED BY                                                             */
3218 /*                                                                        */
3219 /*   Application Code  (System Creation section)                          */
3220 /*                                                                        */
3221 /*  RELEASE HISTORY                                                       */
3222 /*                                                                        */
3223 /*    DATE              NAME                      DESCRIPTION             */
3224 /*                                                                        */
3225 /*  06-02-2021     William E. Lamie         Initial Version 6.1.7         */
3226 /*                                                                        */
3227 /**************************************************************************/
RegisterEventtoTask(EventMaskType eventid,TaskType TaskID)3228 StatusType    RegisterEventtoTask(EventMaskType eventid, TaskType TaskID)
3229 {
3230 
3231 OSEK_TCB      *tcb_ptr;
3232 
3233     /* Check if we are in initialization.  */
3234     /* This will ensure that no one calls this function after system is started.  */
3235     if (osek_init_state != OSEK_INIT)
3236     {
3237         /* Return OSEK internal error. This is not a standard OSEK error.  */
3238         Application->osek_object_creation_error++;
3239         return ((StatusType)TX_NULL);
3240     }
3241 
3242     /* Check if task id is valid.  */
3243     if(TaskID == 0u)
3244     {
3245 
3246         /* Return error.  */
3247         Application->osek_object_creation_error++;
3248 
3249         return (E_OS_ID);
3250     }
3251 
3252 
3253 
3254     /* Convert object IDs to object control block pointers.  */
3255     tcb_ptr = (OSEK_TCB*)TaskID;
3256 
3257 
3258     /* Check for valid task pointer.  */
3259     if (tcb_ptr == TX_NULL)
3260     {
3261         Application->osek_object_creation_error++;
3262 
3263         return (E_OS_ID);
3264     }
3265 
3266     if(tcb_ptr->osek_task_id != OSEK_TASK_ID)
3267     {
3268         Application->osek_object_creation_error++;
3269 
3270         return (E_OS_ID);
3271     }
3272 
3273     /* This task is to be registered with this event.  */
3274     tcb_ptr->events = tcb_ptr->events | eventid;
3275 
3276 
3277     return (E_OK);
3278 }
3279 
3280 
3281 /**************************************************************************/
3282 /*                                                                        */
3283 /*  FUNCTION                                               RELEASE        */
3284 /*                                                                        */
3285 /*    EnableInterrupt                                     PORTABLE C      */
3286 /*                                                           6.1.7        */
3287 /*  AUTHOR                                                                */
3288 /*                                                                        */
3289 /*    William E. Lamie, Microsoft Corporation                             */
3290 /*                                                                        */
3291 /*  DESCRIPTION                                                           */
3292 /*                                                                        */
3293 /*    This service enables interrupts.                                    */
3294 /*                                                                        */
3295 /*  OUTPUT                                                                */
3296 /*                                                                        */
3297 /*    E_OK                         If successful                          */
3298 /*                                                                        */
3299 /*  CALLED BY                                                             */
3300 /*                                                                        */
3301 /*   Application Code                                                     */
3302 /*                                                                        */
3303 /*  RELEASE HISTORY                                                       */
3304 /*                                                                        */
3305 /*    DATE              NAME                      DESCRIPTION             */
3306 /*                                                                        */
3307 /*  06-02-2021     William E. Lamie         Initial Version 6.1.7         */
3308 /*                                                                        */
3309 /**************************************************************************/
EnableInterrupt(void)3310 StatusType  EnableInterrupt(void)
3311 {
3312     TX_INTERRUPT_SAVE_AREA
3313 
3314     TX_DISABLE
3315 
3316     if (disable_ISR2 != 0u) {
3317         disable_ISR2--;
3318     }
3319 
3320     TX_RESTORE
3321 
3322     return (E_OK);
3323 }
3324 
3325 
3326 /**************************************************************************/
3327 /*                                                                        */
3328 /*  FUNCTION                                               RELEASE        */
3329 /*                                                                        */
3330 /*    DisableInterrupt                                    PORTABLE C      */
3331 /*                                                           6.1.7        */
3332 /*  AUTHOR                                                                */
3333 /*                                                                        */
3334 /*    William E. Lamie, Microsoft Corporation                             */
3335 /*                                                                        */
3336 /*  DESCRIPTION                                                           */
3337 /*                                                                        */
3338 /*    This service disables interrupts.                                   */
3339 /*                                                                        */
3340 /*  OUTPUT                                                                */
3341 /*                                                                        */
3342 /*    E_OK                         If successful                          */
3343 /*                                                                        */
3344 /*  CALLED BY                                                             */
3345 /*                                                                        */
3346 /*   Application Code                                                     */
3347 /*                                                                        */
3348 /*  RELEASE HISTORY                                                       */
3349 /*                                                                        */
3350 /*    DATE              NAME                      DESCRIPTION             */
3351 /*                                                                        */
3352 /*  06-02-2021     William E. Lamie         Initial Version 6.1.7         */
3353 /*                                                                        */
3354 /**************************************************************************/
DisableInterrupt(void)3355 StatusType  DisableInterrupt(void)
3356 {
3357     TX_INTERRUPT_SAVE_AREA
3358 
3359     TX_DISABLE
3360 
3361     disable_ISR2++;
3362 
3363     TX_RESTORE
3364 
3365     return (E_OK);
3366 }
3367 
3368 
3369 /**************************************************************************/
3370 /*                                                                        */
3371 /*  FUNCTION                                               RELEASE        */
3372 /*                                                                        */
3373 /*    GetInterruptDescriptor                              PORTABLE C      */
3374 /*                                                           6.1.7        */
3375 /*  AUTHOR                                                                */
3376 /*                                                                        */
3377 /*    William E. Lamie, Microsoft Corporation                             */
3378 /*                                                                        */
3379 /*  DESCRIPTION                                                           */
3380 /*                                                                        */
3381 /*    Query of interrupt status and returns the current CPU interrupt     */
3382 /*    mask                                                                */
3383 /*                                                                        */
3384 /*  INPUT                                                                 */
3385 /*                                                                        */
3386 /*    mask                        A reference to the interrupt mask to be */
3387 /*                                filled. In the mask, a "1" means (Group */
3388 /*                                of) Interrupt is enabled.               */
3389 /*                                                                        */
3390 /*  OUTPUT                                                                */
3391 /*                                                                        */
3392 /*    E_OK                         If success                             */
3393 /*    ERROR                        If error occurs while creating task    */
3394 /*                                                                        */
3395 /*  CALLS                                                                 */
3396 /*                                                                        */
3397 /*    tx_interrupt_control         Enables or disables interrupts         */
3398 /*                                 specified by new_posture               */
3399 /*                                                                        */
3400 /*  CALLED BY                                                             */
3401 /*                                                                        */
3402 /*   Application Code                                                     */
3403 /*                                                                        */
3404 /*  RELEASE HISTORY                                                       */
3405 /*                                                                        */
3406 /*    DATE              NAME                      DESCRIPTION             */
3407 /*                                                                        */
3408 /*  06-02-2021     William E. Lamie         Initial Version 6.1.7         */
3409 /*                                                                        */
3410 /**************************************************************************/
GetInterruptDescriptor(UINT * mask)3411 StatusType  GetInterruptDescriptor(UINT *mask)
3412 {
3413 UINT       old_posture;
3414 UINT       new_posture;
3415 
3416     /* Get the old posture of the interrupt.  */
3417     old_posture = tx_interrupt_control(TX_INT_DISABLE);
3418 
3419     new_posture = old_posture;
3420 
3421     /* Invert the mask for OSEK interrupt.  */
3422     *mask = ~old_posture ;
3423 
3424     /* Restore the same interrupts.  */
3425     tx_interrupt_control(new_posture);
3426 
3427     return (E_OK);
3428 }
3429 
3430 
3431 /**************************************************************************/
3432 /*                                                                        */
3433 /*  FUNCTION                                               RELEASE        */
3434 /*                                                                        */
3435 /*    SuspendAllInterrupts                                PORTABLE C      */
3436 /*                                                           6.1.7        */
3437 /*  AUTHOR                                                                */
3438 /*                                                                        */
3439 /*    William E. Lamie, Microsoft Corporation                             */
3440 /*                                                                        */
3441 /*  DESCRIPTION                                                           */
3442 /*                                                                        */
3443 /*   This call serves to enter critical sections by disabling all         */
3444 /*   interrupts.                                                          */
3445 /*                                                                        */
3446 /*  OUTPUT                                                                */
3447 /*                                                                        */
3448 /*    E_OK                         If successful                          */
3449 /*                                                                        */
3450 /*  CALLED BY                                                             */
3451 /*                                                                        */
3452 /*   Application Code                                                     */
3453 /*                                                                        */
3454 /*  RELEASE HISTORY                                                       */
3455 /*                                                                        */
3456 /*    DATE              NAME                      DESCRIPTION             */
3457 /*                                                                        */
3458 /*  06-02-2021     William E. Lamie         Initial Version 6.1.7         */
3459 /*                                                                        */
3460 /**************************************************************************/
SuspendAllInterrupts(void)3461 void   SuspendAllInterrupts (void)
3462 {
3463     TX_INTERRUPT_SAVE_AREA
3464 
3465     TX_DISABLE
3466     suspend_ISR2++;
3467     TX_RESTORE
3468 }
3469 
3470 /**************************************************************************/
3471 /*                                                                        */
3472 /*  FUNCTION                                               RELEASE        */
3473 /*                                                                        */
3474 /*    ResumeAllInterrupts                                 PORTABLE C      */
3475 /*                                                           6.1.7        */
3476 /*  AUTHOR                                                                */
3477 /*                                                                        */
3478 /*    William E. Lamie, Microsoft Corporation                             */
3479 /*                                                                        */
3480 /*  DESCRIPTION                                                           */
3481 /*                                                                        */
3482 /*   Exits a critical section entered by calling SuspendAllInterrupts.    */
3483 /*                                                                        */
3484 /*  OUTPUT                                                                */
3485 /*                                                                        */
3486 /*    E_OK                         If successful                          */
3487 /*                                                                        */
3488 /*  CALLS                                                                 */
3489 /*                                                                        */
3490 /*    osek_task_independent_area   See if called from task independent    */
3491 /*                                 area                                   */
3492 /*    tx_thread_identify           Identify the current thread            */
3493 /*    osek_internal_error          Osek internal error                    */
3494 /*                                                                        */
3495 /*  CALLED BY                                                             */
3496 /*                                                                        */
3497 /*   Application Code                                                     */
3498 /*                                                                        */
3499 /*  RELEASE HISTORY                                                       */
3500 /*                                                                        */
3501 /*    DATE              NAME                      DESCRIPTION             */
3502 /*                                                                        */
3503 /*  06-02-2021     William E. Lamie         Initial Version 6.1.7         */
3504 /*                                                                        */
3505 /**************************************************************************/
ResumeAllInterrupts(void)3506 void   ResumeAllInterrupts (void)
3507 {
3508 TX_INTERRUPT_SAVE_AREA
3509 TX_THREAD      *thread_ptr;
3510 UINT           status;
3511 ULONG          request[SYSMGR_QUEUE_MSG_LENGTH];
3512 
3513     TX_DISABLE
3514    if (suspend_ISR2 != 0u)
3515    {
3516        suspend_ISR2--;
3517    }
3518 
3519    if (suspend_ISR2 == 0u)
3520    {
3521        /* Interrupts resume, check if any pending.  */
3522        /* get the pointer to the calling thread.  */
3523        thread_ptr = tx_thread_identify();
3524 
3525        /* Now send a message to the SysMgr supervisor thread to execute the error hook.  */
3526        /* Build the request.  */
3527        request[0] = SYSMGR_ERRORHOOK;           /* Request type.            */
3528        request[1] = (ULONG)thread_ptr;          /* Ptr of calling thread.   */
3529        request[2] = 0u;                         /* Input to Error hook.     */
3530        request[3] = 0u;
3531 
3532        /* Since the SysMgr supervisor thread is has the highest priority,  */
3533        /* this routine will be preempted by SysMgr supervisor thread when   */
3534        /* queue read is successful.                                         */
3535 
3536        status = tx_queue_send(&osek_work_queue, request, TX_NO_WAIT);
3537 
3538        /* This should always succeed.  */
3539        if (status != TX_SUCCESS)
3540        {
3541            TX_RESTORE
3542 
3543            /* System internal error.  */
3544            osek_internal_error(SYS_MGR_SEND_CHAINTASK);
3545 
3546            /* Return.  */
3547            return;
3548        }
3549 
3550    } /* end  if (!suspend_ISR2).  */
3551 
3552    TX_RESTORE
3553 
3554    return;
3555 }
3556 
3557 
3558 /**************************************************************************/
3559 /*                                                                        */
3560 /*  FUNCTION                                               RELEASE        */
3561 /*                                                                        */
3562 /*    DisableAllInterrupts                                PORTABLE C      */
3563 /*                                                           6.1.7        */
3564 /*  AUTHOR                                                                */
3565 /*                                                                        */
3566 /*    William E. Lamie, Microsoft Corporation                             */
3567 /*                                                                        */
3568 /*  DESCRIPTION                                                           */
3569 /*                                                                        */
3570 /*   This call serves to enter critical sections by disabling all         */
3571 /*   interrupts.                                                          */
3572 /*                                                                        */
3573 /*  CALLED BY                                                             */
3574 /*                                                                        */
3575 /*   Application Code                                                     */
3576 /*                                                                        */
3577 /*  RELEASE HISTORY                                                       */
3578 /*                                                                        */
3579 /*    DATE              NAME                      DESCRIPTION             */
3580 /*                                                                        */
3581 /*  06-02-2021     William E. Lamie         Initial Version 6.1.7         */
3582 /*                                                                        */
3583 /**************************************************************************/
DisableAllInterrupts(void)3584 void   DisableAllInterrupts (void)
3585 {
3586 TX_INTERRUPT_SAVE_AREA
3587 
3588     TX_DISABLE
3589     disable_ISR2++;
3590     TX_RESTORE
3591 }
3592 
3593 /**************************************************************************/
3594 /*                                                                        */
3595 /*  FUNCTION                                               RELEASE        */
3596 /*                                                                        */
3597 /*    EnableAllInterrupts                                 PORTABLE C      */
3598 /*                                                           6.1.7        */
3599 /*  AUTHOR                                                                */
3600 /*                                                                        */
3601 /*    William E. Lamie, Microsoft Corporation                             */
3602 /*                                                                        */
3603 /*  DESCRIPTION                                                           */
3604 /*                                                                        */
3605 /*   Exits a critical section entered by calling DisableAllInterrupts.    */
3606 /*                                                                        */
3607 /*  CALLED BY                                                             */
3608 /*                                                                        */
3609 /*   Application Code                                                     */
3610 /*                                                                        */
3611 /*  RELEASE HISTORY                                                       */
3612 /*                                                                        */
3613 /*    DATE              NAME                      DESCRIPTION             */
3614 /*                                                                        */
3615 /*  06-02-2021     William E. Lamie         Initial Version 6.1.7         */
3616 /*                                                                        */
3617 /**************************************************************************/
EnableAllInterrupts(void)3618 void   EnableAllInterrupts (void)
3619 {
3620 TX_INTERRUPT_SAVE_AREA
3621 
3622     TX_DISABLE
3623     if (disable_ISR2 != 0u)
3624     {
3625         disable_ISR2--;
3626     }
3627     TX_RESTORE
3628 }
3629 
3630 
3631 /**************************************************************************/
3632 /*                                                                        */
3633 /*  FUNCTION                                               RELEASE        */
3634 /*                                                                        */
3635 /*    SuspendOSInterrupts                                 PORTABLE C      */
3636 /*                                                           6.1.7        */
3637 /*  AUTHOR                                                                */
3638 /*                                                                        */
3639 /*    William E. Lamie, Microsoft Corporation                             */
3640 /*                                                                        */
3641 /*  DESCRIPTION                                                           */
3642 /*                                                                        */
3643 /*   This call serves to enter critical sections by disabling all         */
3644 /*   interrupts.                                                          */
3645 /*                                                                        */
3646 /*  CALLED BY                                                             */
3647 /*                                                                        */
3648 /*   Application Code                                                     */
3649 /*                                                                        */
3650 /*  RELEASE HISTORY                                                       */
3651 /*                                                                        */
3652 /*    DATE              NAME                      DESCRIPTION             */
3653 /*                                                                        */
3654 /*  06-02-2021     William E. Lamie         Initial Version 6.1.7         */
3655 /*                                                                        */
3656 /**************************************************************************/
SuspendOSInterrupts(void)3657 void   SuspendOSInterrupts (void)
3658 {
3659 TX_INTERRUPT_SAVE_AREA
3660 
3661     TX_DISABLE
3662     suspend_ISR2++;
3663     TX_RESTORE
3664 }
3665 
3666 /**************************************************************************/
3667 /*                                                                        */
3668 /*  FUNCTION                                               RELEASE        */
3669 /*                                                                        */
3670 /*    ResumeOSInterrupts                                  PORTABLE C      */
3671 /*                                                           6.1.7        */
3672 /*  AUTHOR                                                                */
3673 /*                                                                        */
3674 /*    William E. Lamie, Microsoft Corporation                             */
3675 /*                                                                        */
3676 /*  DESCRIPTION                                                           */
3677 /*                                                                        */
3678 /*   Exits a critical section entered by calling SuspendOSInterrupts.     */
3679 /*                                                                        */
3680 /*  CALLS                                                                 */
3681 /*                                                                        */
3682 /*    osek_task_independent_area   See if called from task independent    */
3683 /*                                 area                                   */
3684 /*    tx_thread_identify           Identify the current thread            */
3685 /*    osek_internal_error          OSEK internal error                    */
3686 /*                                                                        */
3687 /*  CALLED BY                                                             */
3688 /*                                                                        */
3689 /*   Application Code                                                     */
3690 /*                                                                        */
3691 /*  RELEASE HISTORY                                                       */
3692 /*                                                                        */
3693 /*    DATE              NAME                      DESCRIPTION             */
3694 /*                                                                        */
3695 /*  06-02-2021     William E. Lamie         Initial Version 6.1.7         */
3696 /*                                                                        */
3697 /**************************************************************************/
ResumeOSInterrupts(void)3698 void   ResumeOSInterrupts (void)
3699 {
3700 TX_INTERRUPT_SAVE_AREA
3701 TX_THREAD      *thread_ptr;
3702 UINT           status;
3703 ULONG          request[SYSMGR_QUEUE_MSG_LENGTH];
3704 
3705     TX_DISABLE
3706 
3707    if (suspend_ISR2 != 0u)
3708    {
3709        suspend_ISR2--;
3710    }
3711 
3712    if (suspend_ISR2 == 0u)
3713    {
3714        /* Interrupts resume, check if any pending.  */
3715        /* get the pointer to the calling thread.  */
3716        thread_ptr = tx_thread_identify();
3717 
3718        /* Now send a message to the SysMgr supervisor thread to execute the error hook  */
3719        /* Build the request.  */
3720        request[0] = SYSMGR_ERRORHOOK;           /* Request type.  */
3721        request[1] = (ULONG)thread_ptr;          /* Pointer of calling thread.  */
3722        request[2] = 0u;                         /* Input to Error hook.  */
3723        request[3] = 0u;
3724 
3725        /* Since the SysMgr supervisor thread is with the highest priority,  */
3726        /* this routine will be preempted by SysMgr supervisor thread when   */
3727        /* queue read is successful.                                         */
3728 
3729        status = tx_queue_send(&osek_work_queue, request, TX_NO_WAIT);
3730 
3731        /* This should always succeed.  */
3732        if (status != TX_SUCCESS)
3733        {
3734            TX_RESTORE
3735 
3736            /* System internal error.  */
3737            osek_internal_error(SYS_MGR_SEND_CHAINTASK);
3738 
3739            /* Return.  */
3740            return;
3741        }
3742 
3743    } /* end  if (!suspend_ISR2). */
3744 
3745    TX_RESTORE
3746 
3747    return;
3748 }
3749 
3750 
3751 /**************************************************************************/
3752 /*                                                                        */
3753 /*  FUNCTION                                               RELEASE        */
3754 /*                                                                        */
3755 /*    GetActiveApplicationMode                            PORTABLE C      */
3756 /*                                                           6.1.7        */
3757 /*  AUTHOR                                                                */
3758 /*                                                                        */
3759 /*    William E. Lamie, Microsoft Corporation                             */
3760 /*                                                                        */
3761 /*  DESCRIPTION                                                           */
3762 /*                                                                        */
3763 /*   This call returns the current application mode.                      */
3764 /*                                                                        */
3765 /*                                                                        */
3766 /*  OUTPUT                                                                */
3767 /*                                                                        */
3768 /*    Current application mode                                            */
3769 /*                                                                        */
3770 /*  CALLED BY                                                             */
3771 /*                                                                        */
3772 /*   Application Code                                                     */
3773 /*                                                                        */
3774 /*  RELEASE HISTORY                                                       */
3775 /*                                                                        */
3776 /*    DATE              NAME                      DESCRIPTION             */
3777 /*                                                                        */
3778 /*  06-02-2021     William E. Lamie         Initial Version 6.1.7         */
3779 /*                                                                        */
3780 /**************************************************************************/
GetActiveApplicationMode(void)3781 AppModeType GetActiveApplicationMode(void)
3782 {
3783     return (Application->application_mode);
3784 }
3785 
3786 
3787 /**************************************************************************/
3788 /*                                                                        */
3789 /*  FUNCTION                                               RELEASE        */
3790 /*                                                                        */
3791 /*    GetCounterValue                                     PORTABLE C      */
3792 /*                                                           6.1.7        */
3793 /*  AUTHOR                                                                */
3794 /*                                                                        */
3795 /*    William E. Lamie, Microsoft Corporation                             */
3796 /*                                                                        */
3797 /*  DESCRIPTION                                                           */
3798 /*                                                                        */
3799 /*    Returns the current value of a counter.                             */
3800 /*                                                                        */
3801 /*  INPUT                                                                 */
3802 /*                                                                        */
3803 /*    counter_ptr                          Pointer to OSEK Counter        */
3804 /*    tick_ptr                             Pointer to ticks               */
3805 /*                                                                        */
3806 /*  OUTPUT                                                                */
3807 /*                                                                        */
3808 /*    E_OK                                 If successful                  */
3809 /*    E_OS_ID                              Invalid counter object         */
3810 /*                                                                        */
3811 /*  CALLS                                                                 */
3812 /*                                                                        */
3813 /*   None                                                                 */
3814 /*                                                                        */
3815 /*  CALLED BY                                                             */
3816 /*                                                                        */
3817 /*   Application Code                                                     */
3818 /*                                                                        */
3819 /*  RELEASE HISTORY                                                       */
3820 /*                                                                        */
3821 /*    DATE              NAME                      DESCRIPTION             */
3822 /*                                                                        */
3823 /*  06-02-2021     William E. Lamie         Initial Version 6.1.7         */
3824 /*                                                                        */
3825 /**************************************************************************/
GetCounterValue(OSEK_COUNTER * counter_ptr,TickRefType tick_ptr)3826 StatusType  GetCounterValue(OSEK_COUNTER *counter_ptr, TickRefType tick_ptr)
3827 {
3828 
3829     /* Check for valid counter.  */
3830     if ((counter_ptr != TX_NULL) && (counter_ptr->osek_counter_id == OSEK_COUNTER_ID))
3831     {
3832         *tick_ptr = counter_ptr->counter_value;
3833     }
3834     else
3835     {
3836         /* There is error in counter object supplied.  */
3837         return (E_OS_ID);
3838     }
3839 
3840     return (E_OK);
3841 }
3842 
3843 
3844 /**************************************************************************/
3845 /*                                                                        */
3846 /*  FUNCTION                                               RELEASE        */
3847 /*                                                                        */
3848 /*    CreateCounter                                       PORTABLE C      */
3849 /*                                                           6.1.7        */
3850 /*  AUTHOR                                                                */
3851 /*                                                                        */
3852 /*    William E. Lamie, Microsoft Corporation                             */
3853 /*                                                                        */
3854 /*  DESCRIPTION                                                           */
3855 /*                                                                        */
3856 /*    Creates a counter.                                                  */
3857 /*                                                                        */
3858 /*  INPUT                                                                 */
3859 /*                                                                        */
3860 /*    N/A                                                                 */
3861 /*                                                                        */
3862 /*  OUTPUT                                                                */
3863 /*                                                                        */
3864 /*    COUNTER_ID                   Reference to counter                   */
3865 /*                                                                        */
3866 /*  CALLS                                                                 */
3867 /*                                                                        */
3868 /*    osek_memory_allocate         Allocate memory from system            */
3869 /*    osek_counter_name_check      Check if counter name duplicate        */
3870 /*    osek_get_counter             Get pointer to counter structure       */
3871 /*                                                                        */
3872 /*  CALLED BY                                                             */
3873 /*                                                                        */
3874 /*   Application Code                                                     */
3875 /*                                                                        */
3876 /*  RELEASE HISTORY                                                       */
3877 /*                                                                        */
3878 /*    DATE              NAME                      DESCRIPTION             */
3879 /*                                                                        */
3880 /*  06-02-2021     William E. Lamie         Initial Version 6.1.7         */
3881 /*                                                                        */
3882 /**************************************************************************/
CreateCounter(const CHAR * name,TickType max_allowed_value,TickType ticks_per_base,TickType min_cycle,TickType start_value)3883 CounterType  CreateCounter(const CHAR *name, TickType max_allowed_value, TickType ticks_per_base,
3884                        TickType min_cycle, TickType start_value)
3885 {
3886 
3887 CounterType      cntr_id;
3888 OSEK_COUNTER     *cntr_ptr;
3889 UINT             index;
3890 
3891     /* Check if we are in initialization.  */
3892     /* This will ensure that no one calls this function after system is started.  */
3893     if (osek_init_state != OSEK_INIT)
3894     {
3895         /* Return OSEK internal error. This is not a standard OSEK error.  */
3896         Application->osek_object_creation_error++;
3897 
3898         return((TaskType)TX_NULL);
3899     }
3900 
3901     /* Check if there is space for this counter.  */
3902     cntr_id = osek_get_counter();
3903     if (cntr_id == 0u)
3904     {
3905         /* Return error.  */
3906         Application->osek_object_creation_error++;
3907 
3908         return ((CounterType) TX_NULL);
3909     }
3910 
3911     /* Get the pointer to counter structure.  */
3912     cntr_ptr = (OSEK_COUNTER *)cntr_id;
3913 
3914 
3915     if (max_allowed_value > MAXALLOWEDVALUE)
3916     {
3917         /* Return OSEK internal error. This is not a standard OSEK error.  */
3918         Application->osek_object_creation_error++;
3919 
3920         return ((TaskType)TX_NULL);
3921     }
3922 
3923     /* Store maximum value of this counter.  */
3924     cntr_ptr->maxallowedvalue = max_allowed_value;
3925 
3926     if (min_cycle > MAXALLOWEDVALUE)
3927     {
3928         /* Return OSEK internal error. This is not a standard OSEK error.  */
3929         Application->osek_object_creation_error++;
3930 
3931         return ((TaskType)TX_NULL);
3932     }
3933 
3934     /* Store minimum allowed number of ticks of the counter.  */
3935     cntr_ptr->mincycle = min_cycle;
3936 
3937     if (ticks_per_base > MAXALLOWEDVALUE)
3938     {
3939         /* Return OSEK internal error. This is not a standard OSEK error.  */
3940         Application->osek_object_creation_error++;
3941 
3942         return ((TaskType)TX_NULL);
3943     }
3944 
3945     /* Store ticksperbase.  */
3946     cntr_ptr->ticksperbase = ticks_per_base;
3947 
3948     /* Store start up value.  */
3949     if (start_value > max_allowed_value)
3950     {
3951         cntr_ptr->counter_value = start_value;
3952     }
3953     else
3954     {
3955         cntr_ptr->counter_value = 0u;
3956     }
3957 
3958     /* Store object identifier.  */
3959     cntr_ptr->osek_counter_id = OSEK_COUNTER_ID;
3960 
3961     /* Now initialize the list of alarms attached to this counter.  */
3962 
3963     for (index = 0u; index < OSEK_MAX_ALARMS; index++)
3964     {
3965         cntr_ptr-> alarm_list[ index ] = 0u;
3966     }
3967 
3968     cntr_ptr->cntr_in_use = TX_TRUE;
3969 
3970     cntr_ptr->name = name;
3971 
3972     /* Return the created counter.  */
3973     return ((CounterType) cntr_ptr);
3974 }
3975 
3976 
3977 /**************************************************************************/
3978 /*                                                                        */
3979 /*  FUNCTION                                               RELEASE        */
3980 /*                                                                        */
3981 /*    IncrCouner                                          PORTABLE C      */
3982 /*                                                           6.1.7        */
3983 /*  AUTHOR                                                                */
3984 /*                                                                        */
3985 /*    William E. Lamie, Microsoft Corporation                             */
3986 /*                                                                        */
3987 /*  DESCRIPTION                                                           */
3988 /*                                                                        */
3989 /*    This function increments the specified counter, checks its new      */
3990 /*    value with all alarms attached to it and triggers expired alarms.   */
3991 /*    If an alarm is expired then its actions are executed from here.     */
3992 /*                                                                        */
3993 /*  INPUT                                                                 */
3994 /*                                                                        */
3995 /*    Counter                       Counter to update                     */
3996 /*                                                                        */
3997 /*  OUTPUT                                                                */
3998 /*                                                                        */
3999 /*    E_OK                          If successful                         */
4000 /*    E_OS_ID                       If counter id is not correct          */
4001 /*    E_OS_NOFUNC                   In case of any errors                 */
4002 /*                                                                        */
4003 /*  CALLS                                                                 */
4004 /*                                                                        */
4005 /*    osek_internal_error          OSEK internal error                    */
4006 /*                                                                        */
4007 /*  CALLED BY                                                             */
4008 /*                                                                        */
4009 /*   Application Code                                                     */
4010 /*                                                                        */
4011 /*  RELEASE HISTORY                                                       */
4012 /*                                                                        */
4013 /*    DATE              NAME                      DESCRIPTION             */
4014 /*                                                                        */
4015 /*  06-02-2021     William E. Lamie         Initial Version 6.1.7         */
4016 /*                                                                        */
4017 /**************************************************************************/
IncrCounter(CounterType cntr)4018 StatusType     IncrCounter(CounterType cntr)
4019 {
4020 
4021 TX_INTERRUPT_SAVE_AREA
4022 
4023 OSEK_COUNTER   *cntr_ptr;
4024 UINT           index;
4025 UINT           msg_cnt;
4026 UINT           save_op_mode;
4027 AlarmType      alarmid;
4028 OSEK_ALARM     *this_alarm;
4029 UINT           this_action;
4030 UINT           alarm_fired;
4031 UINT           status;
4032 OSEK_TCB       *tcb_ptr;
4033 ULONG          request[SYSMGR_QUEUE_MSG_LENGTH];
4034 EventMaskType  balance_events;
4035 
4036 cntr_ptr = (OSEK_COUNTER *)cntr;
4037 
4038     /* Check for valid counter.  */
4039     if ((cntr_ptr == TX_NULL) && (cntr_ptr->osek_counter_id != OSEK_COUNTER_ID))
4040     {
4041         /* There is error in counter object supplied.  */
4042         return (E_OS_ID);
4043     }
4044 
4045     /* Disable interrupt.  */
4046     TX_DISABLE
4047 
4048     if (cntr_ptr->cntr_in_use == TX_FALSE)
4049     {
4050         TX_RESTORE
4051 
4052         return (E_OS_ID);
4053     }
4054 
4055     if (cntr_ptr->ticksperbase == 0u)
4056     {
4057         TX_RESTORE
4058 
4059         return (E_OS_NOFUNC);
4060     }
4061 
4062 
4063     /* Increment counters sub count and check it with tick_pre-Base.  */
4064     cntr_ptr->sub_count++;
4065     if (cntr_ptr->sub_count < cntr_ptr->ticksperbase)
4066     {
4067         /* Still need to count enough to reach tics-per-base, no need to increment
4068            main count.  */
4069         TX_RESTORE
4070 
4071         return (E_OK);
4072     }
4073 
4074     /* Reached to tick-per-base, reset it and increment main count.  */
4075     cntr_ptr->sub_count = 0u;
4076 
4077     /* Now increment the counter value.  */
4078     if ( cntr_ptr->counter_value >= cntr_ptr->maxallowedvalue)
4079     {
4080         cntr_ptr->counter_value = 0u;
4081     }
4082     else
4083     {
4084         (cntr_ptr->counter_value)++;
4085     }
4086 
4087     /* Now check if counter is rolled back to zero.  */
4088     if ( cntr_ptr->counter_value == 0u)
4089     {
4090         /* Counter is rolled back set flags in all Alarms attached to this counter.  */
4091         for (index = 0u; index < OSEK_MAX_ALARMS; index++)
4092         {
4093             alarmid = cntr_ptr->alarm_list[index];
4094             if (alarmid == 0u)
4095             {
4096                 continue;
4097             }
4098 
4099             /* Something is defined.  */
4100             this_alarm = (OSEK_ALARM *)alarmid;
4101 
4102             /* But is it a valid OSEK ALARM?  */
4103             if((this_alarm == TX_NULL) || (this_alarm->osek_alarm_id != OSEK_ALARM_ID))
4104             {
4105                 continue;
4106             }
4107 
4108             /* Yes this is a valid alarm , but is it armed?  */
4109             if ( this_alarm->armed == TX_FALSE)
4110             {
4111                 continue;
4112             }
4113             /* This is an ALARM and is armed, set its rollback flag.  */
4114             /* This flag will be cleared when an alarm is armed again or expired.  */
4115             this_alarm->counter_rollback = TX_TRUE;
4116         }
4117     }
4118 
4119     /* Reset a count of messages sent to the system manager.  */
4120     msg_cnt = 0u;
4121 
4122     /* Now it is time to check all alarms for expiration.  */
4123     for (index = 0u; index < OSEK_MAX_ALARMS; index++)
4124     {
4125 
4126         alarm_fired = TX_FALSE;
4127 
4128         /* Get the alarm id.  */
4129         alarmid = cntr_ptr->alarm_list[index];
4130         if (alarmid == 0u)
4131         {
4132             continue;                                           /* This alarm is not for me, go to check next alarm.  */
4133         }
4134 
4135         /* Something is defined, try to get the AlarmID.  */
4136         this_alarm = (OSEK_ALARM *)alarmid;
4137 
4138         /* But is it a valid OSEK ALARM?  */
4139         if((this_alarm == TX_NULL) || (this_alarm->osek_alarm_id != OSEK_ALARM_ID))
4140         {
4141             continue;
4142         }
4143 
4144         /* Yes this is a valid alarm , but is it armed?  */
4145         if (this_alarm->armed == TX_FALSE)                     /* This alarm is not armed, go to check next alarm.  */
4146         {
4147             continue;
4148         }
4149 
4150         /* Now check this with counter's current value, if it is less than it do not fire alarm.  */
4151         if (this_alarm->rel_abs_mode == RELATIVE_ALARM)
4152         {
4153             /* It is a REALTIVE ALARM.  */
4154             if (cntr_ptr->counter_value < this_alarm->expiration_count)
4155             {
4156                 continue;                                                      /* Not yet expired.  */
4157             }
4158             else
4159             {
4160                 /* Alarm expired, set flag.  */
4161                 alarm_fired = TX_TRUE;
4162             }
4163         } /* End  It is a REALTIVE ALARM.  */
4164         else
4165         {
4166             /* It is ABSOLUTE ALARM.  */
4167             if (cntr_ptr->counter_value < this_alarm->expiration_count)
4168             {
4169                 /* counter is less than expiration. */
4170                 continue;                                                         /* Not yet expired.  */
4171             }
4172 
4173             if (cntr_ptr->counter_value == this_alarm->expiration_count)
4174             {
4175                 /* If both are equal alarm is fired.  */
4176                 alarm_fired = TX_TRUE;
4177             }
4178             else
4179             {
4180             /* count > expiration alarm to fire only if roll back occurred.  */
4181             /* This check is required, because when an Alarm is started in ABS mode, counter's current value could
4182                be more than the alarm's expiration count, so that may fire an Alarm the moment it is Armed,
4183                in fact, under such condition (counter's current value  more than
4184                the alarm's expiration count, at the time of arming the alarm) the alarm will expires only when , the
4185                counter counts to its max value then rolls back to zero then again counts up and now when it
4186                reaches the alarm's expiration count, the alarm gets fired.  */
4187 
4188                 if (this_alarm->counter_rollback == TX_FALSE)
4189                 {
4190                     continue;
4191                 }
4192                 else
4193                 {
4194                     alarm_fired = TX_TRUE;
4195                 }
4196 
4197             }
4198 
4199         }  /*   END:  else { ABSOLUTE ALARM ..  */
4200 
4201 
4202         /* STILL IN for  ( index = 0; index < OSEK_MAX_ALARMS; index++)  LOOP.  */
4203 
4204         /* Check alarm has fired?  */
4205 
4206         if (alarm_fired == TX_FALSE)
4207         {
4208             continue;
4209         }
4210 
4211         /* Reached here means an alarm has fired.  */
4212         /* Clear the counter roll back flag.  */
4213         this_alarm->counter_rollback = TX_FALSE;
4214 
4215         /* Dis arm the Alarm */
4216         this_alarm->armed = TX_FALSE;
4217 
4218         /* But is it cyclic?  */
4219         if (this_alarm->cycle != 0u)
4220         {
4221             /* Yes, then load new expiration count.  */
4222             this_alarm->expiration_count += this_alarm->cycle;
4223             /* Arm the alarm for next cycle.  */
4224             this_alarm->armed = TX_TRUE;
4225         }
4226 
4227         /* Get what action to be taken for this alarm.  */
4228         this_action = this_alarm->action;
4229 
4230         /* Check for action to be taken.  */
4231         switch(this_action)
4232         {
4233             case CALLBACK:
4234 
4235                 /* Call a call-back function.  */
4236                 if (this_alarm->alarm_callback != TX_NULL)
4237                 {
4238                     save_op_mode  = osek_wrapper_operation_mode;
4239                     osek_wrapper_operation_mode = ALARM_CALLBACK_MODE;
4240                     (this_alarm->alarm_callback)();
4241                     osek_wrapper_operation_mode = save_op_mode;
4242                  }
4243                  break;
4244 
4245             case ACTIVATETASK:
4246                 /* Activate a task.  */
4247                 /* Get the OSEK TCB for the task to be activated.  */
4248                 tcb_ptr = (OSEK_TCB *)(this_alarm->task);
4249 
4250                 /* Check for any invalid thread pointer.  */
4251                 if((tcb_ptr == TX_NULL) || ((tcb_ptr->task.tx_thread_id) != TX_THREAD_ID))
4252                 {
4253                     break;
4254                 }
4255 
4256                 /* Check whether the task is activated up to its defined multiple activations.  */
4257                 if(tcb_ptr->current_active >= tcb_ptr->max_active)
4258                 {
4259                     break;
4260                 }
4261 
4262                /* Now send a message to the System Manager thread to activate this task.  */
4263                /* Build the request.  */
4264                request[0] = SYSMGR_ACTIVATE_TASK;                /* Request type.  */
4265                request[1] = (ULONG)tcb_ptr;                      /* task to Activate.  */
4266                request[2] = last_run_task;                       /* task currently executing.  */
4267                request[3] = 0u;
4268                status = tx_queue_send (&osek_work_queue, request, TX_NO_WAIT);
4269 
4270                /* This should always succeed.  */
4271                if (status != TX_SUCCESS)
4272                {
4273                   /* System internal error.  */
4274                   osek_internal_error(SYS_MGR_SEND_ACTIVATETASK);
4275                }
4276 
4277                /* One message sent, increment the msg counter, this is required because
4278                   the System manager message queue can hold only certain number of messages.  */
4279                msg_cnt++;
4280                break;
4281 
4282             case SETEVENT:
4283                 /* Set the specified events for the specified task.  */
4284                 /* Check if task id not valid.  */
4285                 if (this_alarm->task == TX_NULL)
4286                 {
4287                     break;
4288                 }
4289 
4290                 /* Get TCB_PTR.  */
4291                 tcb_ptr = (OSEK_TCB *) (this_alarm->task);
4292 
4293                 if (tcb_ptr->osek_task_id != OSEK_TASK_ID)
4294                 {
4295                     break;
4296                 }
4297 
4298                     /* Check if any event is assigned to task.  */
4299                     if ((tcb_ptr->events == 0u) || (tcb_ptr->task_type == BASIC))
4300                     {
4301                         break;
4302                     }
4303 
4304                     if (tcb_ptr->suspended == TX_TRUE)
4305                     {
4306                         break;
4307                     }
4308 
4309                     /* Check this event mask with the task.  */
4310                     /* Update the set events for this task with this new mask.  */
4311                     tcb_ptr->set_events = tcb_ptr->set_events | (this_alarm->events);
4312 
4313                     /* See if any events is set.  */
4314                     balance_events = tcb_ptr->set_events & tcb_ptr->waiting_events;
4315 
4316                     /* Is there any from waiting events.  */
4317                     if (balance_events != 0u)
4318                     {
4319 
4320                         if (tcb_ptr->waiting == TX_TRUE)
4321                         {
4322                             tcb_ptr->waiting = TX_FALSE;
4323                             /* Now, send message to the system manager to check any preemption out of SetEvent call. */
4324 
4325                             /* Build the request. */
4326                             request[0] = SYSMGR_SETEVENT;            /* Request type.  */
4327                             request[1] = last_run_task;              /* Task currently executing.  */
4328                             request[2] = (ULONG)tcb_ptr;             /* Task id for which events are set.  */
4329                             request[3] = 0u;
4330                             status = tx_queue_send(&osek_work_queue, request, TX_NO_WAIT);
4331 
4332                             /* This should always succeed.  */
4333                             if (status != TX_SUCCESS)
4334                             {
4335                                 /* System internal error.  */
4336                                 osek_internal_error(SYS_MGR_SEND_CHAINTASK);
4337                             }
4338 
4339 
4340                             /* One message sent, increment the msg counter, this required because
4341                                System manager message queue can hold only certain number of messages.  */
4342                             msg_cnt++;
4343 
4344                         }  /* End if (tcb_ptr->waiting == TX_TRUE).  */
4345                     }      /* End if (balance_events).  */
4346                     break;
4347 
4348             default:
4349            break;
4350         } /* switch ends.  */
4351 
4352         /* A situation may arise that multiple alarms expire at time (being set to same expiration count and mode)
4353            Which means timer has to send multiple alarm action messages to the system manager. But as the system manager accepts
4354            only certain number of messages at a time, we can't send more than that number of alarm action
4355            messages (SetEvent, ActivateTask) in one loop,
4356            so check if the system manager queue is filled up if yes stop checking for next alarm, we'll come again to check
4357            balance alarms.  */
4358 
4359         if (msg_cnt == (SYSMGR_QUEUE_MSG_COUNT))
4360         {
4361             break;
4362         }
4363 
4364     }  /* for ends.  */
4365 
4366     /* Enable interrupt.  */
4367     TX_RESTORE
4368 
4369     return (E_OK);
4370 }
4371 
4372 
4373 /**************************************************************************/
4374 /*                                                                        */
4375 /*  FUNCTION                                               RELEASE        */
4376 /*                                                                        */
4377 /*    DefineSystemCounter                                 PORTABLE C      */
4378 /*                                                           6.1.7        */
4379 /*  AUTHOR                                                                */
4380 /*                                                                        */
4381 /*    William E. Lamie, Microsoft Corporation                             */
4382 /*                                                                        */
4383 /*  DESCRIPTION                                                           */
4384 /*                                                                        */
4385 /*    This functions sets the system counter by assigning the specified   */
4386 /*    counter as a system counter.                                        */
4387 /*    If a counter is already defined as a system counter this call will  */
4388 /*    return an error.                                                    */
4389 /*                                                                        */
4390 /*  INPUT                                                                 */
4391 /*                                                                        */
4392 /*    Counter                       Counter to assign as system counter   */
4393 /*                                                                        */
4394 /*  OUTPUT                                                                */
4395 /*                                                                        */
4396 /*    E_OK                          If successful                         */
4397 /*    E_OS_ID                       If counter id is invalid              */
4398 /*    E_OS_NOFUNC                   Counter already assigned              */
4399 /*                                                                        */
4400 /*  CALLS                                                                 */
4401 /*                                                                        */
4402 /*    tx_timer_activate             starts the Thread timer to update     */
4403 /*                                  this SystemCounter                    */
4404 /*                                                                        */
4405 /*  CALLED BY                                                             */
4406 /*                                                                        */
4407 /*   Application Code                                                     */
4408 /*                                                                        */
4409 /*  RELEASE HISTORY                                                       */
4410 /*                                                                        */
4411 /*    DATE              NAME                      DESCRIPTION             */
4412 /*                                                                        */
4413 /*  06-02-2021     William E. Lamie         Initial Version 6.1.7         */
4414 /*                                                                        */
4415 /**************************************************************************/
DefineSystemCounter(CounterType cntr)4416 StatusType DefineSystemCounter (CounterType cntr)
4417 {
4418 
4419 OSEK_COUNTER  *cntr_ptr;
4420 OSEK_COUNTER  *this_counter;
4421 UINT          index;
4422 UINT          attached;
4423 
4424     /* Check if we are in initialization.  */
4425     /* This will ensure that no one calls this function after system is started.  */
4426     if (osek_init_state != OSEK_INIT)
4427     {
4428         /* Return OSEK internal error. This is not a standard OSEK error.  */
4429         Application->osek_object_creation_error++;
4430 
4431         return ((TaskType)TX_NULL);
4432     }
4433 
4434     /* Convert counter id to counter pointer.  */
4435 
4436     cntr_ptr = (OSEK_COUNTER *)cntr;
4437 
4438     /* Check for valid counter.  */
4439     if ((cntr_ptr == TX_NULL) && (cntr_ptr->osek_counter_id != OSEK_COUNTER_ID))
4440     {
4441         /* There is error in counter object supplied.  */
4442         Application->osek_object_creation_error++;
4443 
4444         return (E_OS_ID);
4445     }
4446 
4447     if (cntr_ptr->cntr_in_use == TX_FALSE)
4448     {
4449         Application->osek_object_creation_error++;
4450 
4451         return (E_OS_ID);
4452     }
4453 
4454     /* Now check if there any a counter exists attached to system timer?  */
4455     attached = TX_FALSE;
4456 
4457     /* Search for a free counter.  */
4458     this_counter = osek_counter_pool;
4459     for (index = 0u; index < OSEK_MAX_COUNTERS; index++)
4460     {
4461         /* Is this guy is attached to system timer?  */
4462         if (this_counter->system_timer == TX_TRUE)
4463         {
4464             /* This counter is attached to system timer.  */
4465             attached = TX_TRUE;
4466             /* Stop searching.  */
4467             break;
4468         }
4469 
4470         this_counter++;
4471     } /* check all counters.  */
4472 
4473     /* No body attached to system timer?  */
4474     if (attached == TX_FALSE)
4475     {
4476         /* No one is attached, attach counter supplied to system timer.  */
4477         cntr_ptr->system_timer = TX_TRUE;
4478 
4479         /* Now start the system timer.  */
4480         tx_timer_activate(&osek_system_timer);
4481 
4482         return (E_OK);
4483     }
4484 
4485     /* One counter is already attached to system timer.  */
4486     Application->osek_object_creation_error++;
4487 
4488     return (E_OS_NOFUNC);
4489 }
4490 
4491 
4492 /**************************************************************************/
4493 /*                                                                        */
4494 /*  FUNCTION                                               RELEASE        */
4495 /*                                                                        */
4496 /*    CreateAlarm                                         PORTABLE C      */
4497 /*                                                           6.1.7        */
4498 /*  AUTHOR                                                                */
4499 /*                                                                        */
4500 /*    William E. Lamie, Microsoft Corporation                             */
4501 /*                                                                        */
4502 /*  DESCRIPTION                                                           */
4503 /*                                                                        */
4504 /*    Creates an alarm.                                                   */
4505 /*                                                                        */
4506 /*  INPUT                                                                 */
4507 /*                                                                        */
4508 /*    ticks                        Tick count                             */
4509 /*                                                                        */
4510 /*  OUTPUT                                                                */
4511 /*                                                                        */
4512 /*    ALARM_ID                     Reference to alarm                     */
4513 /*                                                                        */
4514 /*  CALLS                                                                 */
4515 /*                                                                        */
4516 /*    osek_get_alarm               Get the alarm if possible              */
4517 /*                                                                        */
4518 /*  CALLED BY                                                             */
4519 /*                                                                        */
4520 /*   Application Code                                                     */
4521 /*                                                                        */
4522 /*  RELEASE HISTORY                                                       */
4523 /*                                                                        */
4524 /*    DATE              NAME                      DESCRIPTION             */
4525 /*                                                                        */
4526 /*  06-02-2021     William E. Lamie         Initial Version 6.1.7         */
4527 /*                                                                        */
4528 /**************************************************************************/
CreateAlarm(const CHAR * name,CounterType cntr,UINT action,ULONG events,TaskType task,void (* callback)(),UINT Startup,TickType Alarmtime,TickType Cycle)4529 AlarmType  CreateAlarm(const CHAR *name, CounterType cntr, UINT action, ULONG events, TaskType task,
4530                      void (*callback)(), UINT Startup, TickType Alarmtime, TickType Cycle )
4531 {
4532 
4533 AlarmType        alarm_id;
4534 OSEK_COUNTER     *cntr_ptr;
4535 OSEK_TCB         *tcb_ptr;
4536 OSEK_ALARM       *this_alarm;
4537 UINT             index;
4538 TickType         current_value;
4539 StatusType       status;
4540 
4541     /* Check if we are in Initialization.  */
4542     /* This will ensure that no one calls this function after system is started.  */
4543     if (osek_init_state != OSEK_INIT)
4544     {
4545         /* Return OSEK internal error. This is not a standard OSEK error.  */
4546         Application->osek_object_creation_error++;
4547 
4548         return ((TaskType)TX_NULL);
4549     }
4550 
4551     /* Start with validating arguments passed.  */
4552     cntr_ptr = (OSEK_COUNTER*)cntr;
4553     if ((cntr_ptr == TX_NULL) || (cntr_ptr->osek_counter_id != OSEK_COUNTER_ID)|| (cntr_ptr->cntr_in_use == TX_FALSE))
4554     {
4555         /* Counter is not valid.  */
4556         Application->osek_object_creation_error++;
4557         return (E_OS_ID);
4558     }
4559 
4560     if (cntr_ptr->cntr_in_use != TX_TRUE)
4561     {
4562         /* Counter is not in use.  */
4563         Application->osek_object_creation_error++;
4564 
4565         return (E_OS_ID);
4566     }
4567 
4568     tcb_ptr = (OSEK_TCB *)task;
4569 
4570     /* Check the action to be taken and parameters passed.  */
4571     switch(action)
4572     {
4573         case SETEVENT:
4574 
4575             /* For SetEvents there should not be call back function.  */
4576             if((events == 0u) || (task == 0u) || (callback != TX_NULL))
4577             {
4578                 /* Return error.  */
4579                 Application->osek_object_creation_error++;
4580 
4581                 return (E_OS_NOFUNC);
4582             }
4583 
4584             if ((tcb_ptr == TX_NULL) || (tcb_ptr->osek_task_id != OSEK_TASK_ID))
4585             {
4586                 /* Task is not valid.  */
4587                 Application->osek_object_creation_error++;
4588 
4589                 return (E_OS_ID);
4590             }
4591 
4592             if (tcb_ptr->tcb_in_use != TX_TRUE)
4593             {
4594                 /* Task is not in use */
4595                 Application->osek_object_creation_error++;
4596                 return (E_OS_ID);
4597             }
4598 
4599             break;
4600 
4601         case ACTIVATETASK:
4602             /* For activate task there should not be any call-back function or any event.  */
4603             if((task == 0u) || (events != 0u) || (callback != TX_NULL))
4604             {
4605                 /* Return error.  */
4606                 Application->osek_object_creation_error++;
4607 
4608                 return (E_OS_NOFUNC);
4609             }
4610 
4611             if ((tcb_ptr == TX_NULL) || (tcb_ptr->osek_task_id != OSEK_TASK_ID))
4612             {
4613                 /* Task is not valid.  */
4614                 Application->osek_object_creation_error++;
4615                 return (E_OS_ID);
4616             }
4617 
4618             if (tcb_ptr->tcb_in_use != TX_TRUE)
4619             {
4620                 /* Task is not in use.  */
4621                 Application->osek_object_creation_error++;
4622                 return (E_OS_ID);
4623             }
4624 
4625             break;
4626 
4627         case CALLBACK:
4628             /* For ALARMCALLBACK there should not be task or any event.  */
4629             if((callback == TX_NULL) || (events != 0u) || (task != 0u))
4630             {
4631                 /* Return error.  */
4632                 Application->osek_object_creation_error++;
4633 
4634                 return (E_OS_NOFUNC);
4635             }
4636 
4637             break;
4638 
4639         default:
4640             /* Return error.  */
4641             Application->osek_object_creation_error++;
4642 
4643             return (E_OS_NOFUNC);
4644 
4645             break;
4646     }
4647 
4648     /* Check if there is space for this alarm.  */
4649     alarm_id = osek_get_alarm();
4650     if (alarm_id == 0u)
4651     {
4652         /* Return error.  */
4653         Application->osek_object_creation_error++;
4654 
4655         return (E_OS_NOFUNC);
4656     }
4657 
4658     /* Got correct inputs, get pointer to alarm.  */
4659     this_alarm = (OSEK_ALARM *)alarm_id;
4660 
4661     /* Store object id.  */
4662     this_alarm->osek_alarm_id = OSEK_ALARM_ID;
4663 
4664     /* Before attaching this alarm to a counter, disarm it.  */
4665     this_alarm->armed = TX_FALSE;
4666 
4667     this_alarm->name = name;
4668 
4669     /* Now, try attaching this alarm to the counter specified.  */
4670     for (index = 0u; index < OSEK_MAX_ALARMS; index++)
4671     {
4672         /* Find a free entry in the list maintained by the counter.  */
4673         if (cntr_ptr->alarm_list[index] == 0u)
4674         {
4675             /* Found one.  */
4676             cntr_ptr->alarm_list[index] = alarm_id;
4677 
4678             break;
4679         }
4680     }
4681 
4682     /* Searched the entire list and came empty handed?  */
4683     if (index >= OSEK_MAX_ALARMS)
4684     {
4685         /* Return error.  */
4686         osek_reset_alarm(this_alarm);
4687 
4688         Application->osek_object_creation_error++;
4689 
4690         return (E_OS_NOFUNC);
4691     }
4692 
4693     /* Got the counter, now save the counter in to ALARM structure.  */
4694     this_alarm->cntr = cntr_ptr;
4695 
4696     /*  Maximum allowed value and minimum cycles for this alarms this values are from */
4697     /*  the counter to which this alarm is attached.  */
4698     this_alarm->max_allowed_value = cntr_ptr->maxallowedvalue;
4699     this_alarm->min_cyc = cntr_ptr->mincycle;
4700     this_alarm->ticks_per_base = cntr_ptr->ticksperbase;
4701 
4702     this_alarm->name = name;
4703 
4704     /* Store the ACTION upon alarm expiration.  */
4705     this_alarm->action = action;
4706 
4707     /* Store event in case of SETEVENT action.  */
4708     this_alarm->events = events;
4709 
4710     /* Check for call back and store it.  */
4711     if(callback != TX_NULL)
4712     {
4713         this_alarm->alarm_callback = callback;
4714     }
4715 
4716     if (Startup != 0u)
4717     {
4718         this_alarm->auto_start = TX_TRUE;
4719     }
4720 
4721     /* Save the TASK in to ALARM structure.  */
4722     this_alarm->task = tcb_ptr;
4723 
4724     /* Everything is OK so far, now fill this alarm control block with some default parameters.  */
4725 
4726     /* Reset max cycles, current cycles and expiration count.  */
4727     this_alarm->expiration_count = 0u;
4728     this_alarm->cycle = 0u;
4729 
4730     /* Now it is time to check for AUTOSTART.  */
4731     if (this_alarm->auto_start != 0u)
4732     {
4733         /* Check start.  */
4734         if ((Alarmtime == 0u) || (Alarmtime > this_alarm->max_allowed_value))
4735         {
4736             /* Invalid input parameter.  */
4737             Application->osek_object_creation_error++;
4738 
4739             return (E_OS_VALUE);
4740         }
4741 
4742         /* Check cycle. */
4743         if (Cycle != 0u)
4744         {
4745             if ((Cycle < this_alarm->min_cyc) || (Cycle > this_alarm->max_allowed_value))
4746             {
4747                 /* Invalid input parameter.  */
4748                 Application->osek_object_creation_error++;
4749 
4750                 return (E_OS_VALUE);
4751             }
4752         }
4753 
4754         /* All input parameters are ok, store relative value and cycle.  */
4755         this_alarm->cycle = Cycle;
4756 
4757         status = GetCounterValue(cntr_ptr, &current_value);
4758         if (status != E_OK)
4759         {
4760             Application->osek_object_creation_error++;
4761 
4762             return (E_OS_VALUE);  /* Some problem in getting counter's current value.  */
4763         }
4764 
4765         this_alarm->expiration_count = current_value + Alarmtime; /* Load the counter with its expiration count.  */
4766 
4767         /* Now set the relative mode.  */
4768         this_alarm->rel_abs_mode = RELATIVE_ALARM;
4769         this_alarm->counter_rollback = TX_FALSE;
4770         this_alarm->armed = TX_TRUE;
4771         this_alarm->occupied = TX_TRUE;
4772 
4773     }  /* End..   this_alarm->auto_start.  */
4774 
4775     return(alarm_id);
4776 }
4777 
4778 
4779 /**************************************************************************/
4780 /*                                                                        */
4781 /*  FUNCTION                                               RELEASE        */
4782 /*                                                                        */
4783 /*    GetAlarmBase                                        PORTABLE C      */
4784 /*                                                           6.1.7        */
4785 /*  AUTHOR                                                                */
4786 /*                                                                        */
4787 /*    William E. Lamie, Microsoft Corporation                             */
4788 /*                                                                        */
4789 /*  DESCRIPTION                                                           */
4790 /*                                                                        */
4791 /*    Reads the alarm base characteristics. Returns info which is a       */
4792 /*    in which the information of the data type AlarmbaseType is          */
4793 /*    stored.                                                             */
4794 /*                                                                        */
4795 /*  INPUT                                                                 */
4796 /*                                                                        */
4797 /*    AlarmID                       Reference to alarm                    */
4798 /*                                                                        */
4799 /*  OUTPUT                                                                */
4800 /*                                                                        */
4801 /*    Info                          user_defined parameters of the        */
4802 /*                                  counter associated with alarm.        */
4803 /*  CALLS                                                                 */
4804 /*                                                                        */
4805 /*                                                                        */
4806 /*  CALLED BY                                                             */
4807 /*                                                                        */
4808 /*   Application Code                                                     */
4809 /*                                                                        */
4810 /*  RELEASE HISTORY                                                       */
4811 /*                                                                        */
4812 /*    DATE              NAME                      DESCRIPTION             */
4813 /*                                                                        */
4814 /*  06-02-2021     William E. Lamie         Initial Version 6.1.7         */
4815 /*                                                                        */
4816 /**************************************************************************/
GetAlarmBase(AlarmType AlarmID,AlarmBaseRefType info)4817 StatusType  GetAlarmBase(AlarmType AlarmID, AlarmBaseRefType info)
4818 {
4819 
4820 OSEK_ALARM          *alarm_ptr;
4821 
4822 
4823     service_GetServiceId.id = (OsServiceIdType)OSServiceId_GetAlarmBase;
4824     service_GetAlarmBase.AlarmID = AlarmID;
4825 
4826     /* Get the OSEK alarm.  */
4827     alarm_ptr = (OSEK_ALARM *) AlarmID;
4828 
4829     /* Check valid ID.  */
4830     if((alarm_ptr == 0u) || (alarm_ptr->osek_alarm_id != OSEK_ALARM_ID))
4831     {
4832         exec_ErrorHook (E_OS_ID);
4833 
4834         /* Invalid AlarmID.  */
4835         return (E_OS_ID);
4836     }
4837 
4838     info->maxallowedvalue = alarm_ptr->max_allowed_value;
4839     info->mincycle = alarm_ptr->min_cyc;
4840     info->ticksperbase = alarm_ptr->ticks_per_base;
4841 
4842     return (E_OK);
4843 }
4844 
4845 
4846 /**************************************************************************/
4847 /*                                                                        */
4848 /*  FUNCTION                                               RELEASE        */
4849 /*                                                                        */
4850 /*    SetAbsAlarm                                         PORTABLE C      */
4851 /*                                                           6.1.7        */
4852 /*  AUTHOR                                                                */
4853 /*                                                                        */
4854 /*    William E. Lamie, Microsoft Corporation                             */
4855 /*                                                                        */
4856 /*  DESCRIPTION                                                           */
4857 /*                                                                        */
4858 /*    Sets an alarm to an absolute cycle value.                           */
4859 /*                                                                        */
4860 /*  INPUT                                                                 */
4861 /*                                                                        */
4862 /*    AlarmID                      Reference to alarm.                    */
4863 /*    start                        Absolute value in ticks.               */
4864 /*    cycle                        Cycle value in case of cyclic alarm.   */
4865 /*                                 In case of single alarm it must be     */
4866 /*                                 zero.                                  */
4867 /*                                                                        */
4868 /*  OUTPUT                                                                */
4869 /*                                                                        */
4870 /*    E_OK                         If successful                          */
4871 /*    ERROR                        If error occurs while creating task    */
4872 /*                                                                        */
4873 /*  CALLS                                                                 */
4874 /*                                                                        */
4875 /*    osek_internal_error          OSEK internal error                    */
4876 /*    tx_time_get                  Get system time                        */
4877 /*    tx_timer_create              Create the timer is created            */
4878 /*                                                                        */
4879 /*  CALLED BY                                                             */
4880 /*                                                                        */
4881 /*   Application Code                                                     */
4882 /*                                                                        */
4883 /*  RELEASE HISTORY                                                       */
4884 /*                                                                        */
4885 /*    DATE              NAME                      DESCRIPTION             */
4886 /*                                                                        */
4887 /*  06-02-2021     William E. Lamie         Initial Version 6.1.7         */
4888 /*                                                                        */
4889 /**************************************************************************/
SetAbsAlarm(AlarmType AlarmID,TickType start,TickType cycle)4890 StatusType SetAbsAlarm(AlarmType  AlarmID, TickType start, TickType cycle)
4891 {
4892     TX_INTERRUPT_SAVE_AREA
4893     OSEK_ALARM          *osek_alarm;
4894 
4895 
4896     service_GetServiceId.id = (OsServiceIdType)OSServiceId_SetAbsAlarm;
4897     service_SetAbsAlarm.AlarmID = AlarmID;
4898     service_SetAbsAlarm.start = start;
4899     service_SetAbsAlarm.cycle = cycle;
4900 
4901     /* Convert AlarmID to OSEK_ALARM.  */
4902     osek_alarm = (OSEK_ALARM *) AlarmID;
4903 
4904     /* Check valid ID.  */
4905     if((osek_alarm == 0u) || (osek_alarm->osek_alarm_id != OSEK_ALARM_ID))
4906     {
4907         exec_ErrorHook (E_OS_ID);
4908 
4909         /* Invalid AlarmID.  */
4910         return (E_OS_ID);
4911     }
4912 
4913     TX_DISABLE
4914 
4915     /* Check already armed?  */
4916     if (osek_alarm->armed == TX_TRUE)
4917     {
4918         TX_RESTORE
4919 
4920         exec_ErrorHook(E_OS_STATE);
4921 
4922         return (E_OS_STATE);
4923     }
4924 
4925     /* Check start.  */
4926     if ((start == 0u) || ( start > osek_alarm->max_allowed_value))
4927     {
4928         TX_RESTORE
4929 
4930         /* Invalid input parameter.  */
4931         exec_ErrorHook(E_OS_VALUE);
4932 
4933         return (E_OS_VALUE);
4934     }
4935 
4936 
4937     /* Check cycle.  */
4938     if (cycle != 0u)
4939     {
4940         if ((cycle < osek_alarm->min_cyc) || ( cycle > osek_alarm->max_allowed_value))
4941         {
4942             TX_RESTORE
4943 
4944             exec_ErrorHook(E_OS_VALUE);
4945 
4946             /* Invalid input parameter.  */
4947             return (E_OS_VALUE);
4948         }
4949     }
4950 
4951     /* All input parameters are ok, store abs value and cycle.  */
4952     osek_alarm->cycle = cycle;
4953     osek_alarm->expiration_count = start; /* Load the counter with its expiration count.  */
4954 
4955     /* Now set the absolute mode.  */
4956     osek_alarm->rel_abs_mode = ABSOLUTE_ALARM;
4957 
4958     /* Now, arm the alarm.  */
4959     osek_alarm->armed = TX_TRUE;
4960     osek_alarm->occupied = TX_TRUE;
4961     osek_alarm->counter_rollback = TX_FALSE;
4962 
4963     TX_RESTORE
4964 
4965    /* Return OK.  */
4966     return (E_OK);
4967 }
4968 
4969 
4970 /**************************************************************************/
4971 /*                                                                        */
4972 /*  FUNCTION                                               RELEASE        */
4973 /*                                                                        */
4974 /*    SetRelAlarm                                         PORTABLE C      */
4975 /*                                                           6.1.7        */
4976 /*  AUTHOR                                                                */
4977 /*                                                                        */
4978 /*    William E. Lamie, Microsoft Corporation                             */
4979 /*                                                                        */
4980 /*  DESCRIPTION                                                           */
4981 /*                                                                        */
4982 /*    Sets an alarm to a relative cycle value from the current time.      */
4983 /*                                                                        */
4984 /*  INPUT                                                                 */
4985 /*                                                                        */
4986 /*    AlarmID                      Reference to alarm.                    */
4987 /*    increment                    Relative value in ticks                */
4988 /*    cycle                        Cycle value in case of cyclic alarm    */
4989 /*                                 In case of single alarm it must be     */
4990 /*                                 zero.                                  */
4991 /*                                                                        */
4992 /*  OUTPUT                                                                */
4993 /*                                                                        */
4994 /*    E_OK                         If successful                          */
4995 /*    ERROR                        If an error occurs                     */
4996 /*                                                                        */
4997 /*  CALLS                                                                 */
4998 /*                                                                        */
4999 /*    osek_internal_error          OSEK internal error                    */
5000 /*    tx_timer_change              Change the timer                       */
5001 /*                                                                        */
5002 /*  CALLED BY                                                             */
5003 /*                                                                        */
5004 /*   Application Code                                                     */
5005 /*                                                                        */
5006 /*  RELEASE HISTORY                                                       */
5007 /*                                                                        */
5008 /*    DATE              NAME                      DESCRIPTION             */
5009 /*                                                                        */
5010 /*  06-02-2021     William E. Lamie         Initial Version 6.1.7         */
5011 /*                                                                        */
5012 /**************************************************************************/
SetRelAlarm(AlarmType AlarmID,TickType increment,TickType cycle)5013 StatusType  SetRelAlarm(AlarmType AlarmID, TickType increment, TickType cycle)
5014 {
5015 TX_INTERRUPT_SAVE_AREA
5016 OSEK_ALARM          *osek_alarm;
5017 OSEK_COUNTER        *counter_ptr;
5018 TickType            current_value;
5019 StatusType          status;
5020 
5021 
5022     service_GetServiceId.id = (OsServiceIdType)OSServiceId_SetRelAlarm;
5023     service_SetRelAlarm.AlarmID = AlarmID;
5024     service_SetRelAlarm.increment = increment;
5025     service_SetRelAlarm.cycle = cycle;
5026 
5027     /* Convert AlarmID to OSEK_ALARM.  */
5028     osek_alarm = (OSEK_ALARM *)AlarmID;
5029 
5030     /* Check valid ID.  */
5031     if((osek_alarm == TX_NULL) || (osek_alarm->osek_alarm_id != OSEK_ALARM_ID))
5032     {
5033         exec_ErrorHook(E_OS_ID);
5034 
5035         /* Invalid AlarmID.  */
5036         return (E_OS_ID);
5037     }
5038 
5039     TX_DISABLE
5040 
5041     /* Check already armed?  */
5042     if (osek_alarm->armed == TX_TRUE)
5043     {
5044         TX_RESTORE
5045 
5046         exec_ErrorHook(E_OS_STATE);
5047 
5048         return (E_OS_STATE);
5049     }
5050 
5051     /* Check start.  */
5052     if ((increment == 0u) || (increment > osek_alarm->max_allowed_value))
5053     {
5054         TX_RESTORE
5055 
5056         exec_ErrorHook(E_OS_VALUE);
5057 
5058         /* Invalid input parameter.  */
5059         return (E_OS_VALUE);
5060     }
5061 
5062     /* Check cycle.  */
5063     if (cycle != 0u)
5064     {
5065        if ((cycle < osek_alarm->min_cyc) || (cycle > osek_alarm->max_allowed_value))
5066         {
5067            TX_RESTORE
5068 
5069             exec_ErrorHook(E_OS_VALUE);
5070 
5071             /* Invalid input parameter.  */
5072             return (E_OS_VALUE);
5073         }
5074     }
5075 
5076     /* All input parameters are ok, store rel value and cycle.  */
5077     osek_alarm->cycle = cycle;
5078     counter_ptr = osek_alarm->cntr;
5079 
5080     status = GetCounterValue(counter_ptr, &current_value);
5081     if (status != E_OK)
5082     {
5083         TX_RESTORE
5084         return (E_OS_STATE);
5085     }
5086 
5087     osek_alarm->expiration_count = current_value + increment; /* Load the counter with its expiration count.  */
5088 
5089     /* Now set the relative mode.  */
5090     osek_alarm->rel_abs_mode = RELATIVE_ALARM;
5091     osek_alarm->counter_rollback = TX_FALSE;
5092 
5093     /* Now, arm the alarm.  */
5094     osek_alarm->armed = TX_TRUE;
5095     osek_alarm->occupied = TX_TRUE;
5096 
5097     TX_RESTORE
5098 
5099     /* Return OK.  */
5100     return (E_OK);
5101 }
5102 
5103 
5104 /**************************************************************************/
5105 /*                                                                        */
5106 /*  FUNCTION                                               RELEASE        */
5107 /*                                                                        */
5108 /*    CancelAlarm                                         PORTABLE C      */
5109 /*                                                           6.1.7        */
5110 /*  AUTHOR                                                                */
5111 /*                                                                        */
5112 /*    William E. Lamie, Microsoft Corporation                             */
5113 /*                                                                        */
5114 /*  DESCRIPTION                                                           */
5115 /*                                                                        */
5116 /*    Cancels the alarm: the alarm transition into the stop state.        */
5117 /*                                                                        */
5118 /*  INPUT                                                                 */
5119 /*                                                                        */
5120 /*    AlarmID                      Reference to alarm                     */
5121 /*                                                                        */
5122 /*  OUTPUT                                                                */
5123 /*                                                                        */
5124 /*    E_OK                         If successful                          */
5125 /*    ERROR                        If an error occurs                     */
5126 /*                                                                        */
5127 /*  CALLS                                                                 */
5128 /*                                                                        */
5129 /*    tx_timer_deactivate         Timer deactivate                        */
5130 /*    osek_internal_error         OSEK internal error                     */
5131 /*                                                                        */
5132 /*  CALLED BY                                                             */
5133 /*                                                                        */
5134 /*   Application Code                                                     */
5135 /*                                                                        */
5136 /*  RELEASE HISTORY                                                       */
5137 /*                                                                        */
5138 /*    DATE              NAME                      DESCRIPTION             */
5139 /*                                                                        */
5140 /*  06-02-2021     William E. Lamie         Initial Version 6.1.7         */
5141 /*                                                                        */
5142 /**************************************************************************/
CancelAlarm(AlarmType AlarmID)5143 StatusType  CancelAlarm(AlarmType  AlarmID)
5144 {
5145 TX_INTERRUPT_SAVE_AREA
5146     OSEK_ALARM          *osek_alarm;
5147 
5148     service_GetServiceId.id = (OsServiceIdType)OSServiceId_CancelAlarm;
5149     service_CancelAlarm.AlarmID = AlarmID;
5150 
5151     /* Check valid ID and absolute ticks.  */
5152     osek_alarm = (OSEK_ALARM *) AlarmID;
5153     if((osek_alarm == TX_NULL) || (osek_alarm->osek_alarm_id != OSEK_ALARM_ID))
5154     {
5155         exec_ErrorHook(E_OS_ID);
5156 
5157         /* Invalid AlarmID.  */
5158         return (E_OS_ID);
5159     }
5160 
5161     TX_DISABLE
5162 
5163     /* Is this alarm in use?  */
5164     if ((osek_alarm->armed == TX_FALSE) || (osek_alarm->occupied == TX_FALSE))
5165     {
5166         TX_RESTORE
5167 
5168         exec_ErrorHook(E_OS_NOFUNC);
5169 
5170         return (E_OS_NOFUNC);
5171     }
5172 
5173     /* Alarm is in use so make it inactive.  */
5174     osek_alarm->armed = TX_FALSE;
5175 
5176     TX_RESTORE
5177 
5178     /* Return OK.  */
5179     return (E_OK);
5180 }
5181 
5182 
5183 /**************************************************************************/
5184 /*                                                                        */
5185 /*  FUNCTION                                               RELEASE        */
5186 /*                                                                        */
5187 /*    GetAlarm                                            PORTABLE C      */
5188 /*                                                           6.1.7        */
5189 /*  AUTHOR                                                                */
5190 /*                                                                        */
5191 /*    William E. Lamie, Microsoft Corporation                             */
5192 /*                                                                        */
5193 /*  DESCRIPTION                                                           */
5194 /*                                                                        */
5195 /*    Returns the no. of ticks before the alarm expires.                  */
5196 /*                                                                        */
5197 /*  INPUT                                                                 */
5198 /*                                                                        */
5199 /*    ticks                        Pointer to the returned tick count     */
5200 /*                                                                        */
5201 /*  OUTPUT                                                                */
5202 /*                                                                        */
5203 /*    N/A                                                                 */
5204 /*                                                                        */
5205 /*  CALLS                                                                 */
5206 /*                                                                        */
5207 /*    tx_timer_info_get            Retrieves information about specified  */
5208 /*                                 timer.                                 */
5209 /*    osek_internal_error          OSEK internal error                    */
5210 /*                                                                        */
5211 /*  CALLED BY                                                             */
5212 /*                                                                        */
5213 /*   Application Code                                                     */
5214 /*                                                                        */
5215 /*  RELEASE HISTORY                                                       */
5216 /*                                                                        */
5217 /*    DATE              NAME                      DESCRIPTION             */
5218 /*                                                                        */
5219 /*  06-02-2021     William E. Lamie         Initial Version 6.1.7         */
5220 /*                                                                        */
5221 /**************************************************************************/
GetAlarm(AlarmType AlarmID,TickRefType tick_ptr)5222 StatusType  GetAlarm(AlarmType AlarmID, TickRefType tick_ptr)
5223 {
5224 TX_INTERRUPT_SAVE_AREA
5225 OSEK_ALARM          *osek_alarm;
5226 OSEK_COUNTER        *counter_ptr;
5227 TickType             current_ticks;
5228 StatusType           status;
5229 
5230 
5231     service_GetServiceId.id = (OsServiceIdType)OSServiceId_GetAlarm;
5232     service_GetAlarm.AlarmID = AlarmID;
5233 
5234     /* Check valid ID and absolute ticks.  */
5235     osek_alarm = (OSEK_ALARM *) AlarmID;
5236     if((osek_alarm == TX_NULL) || (osek_alarm->osek_alarm_id != OSEK_ALARM_ID))
5237     {
5238         exec_ErrorHook (E_OS_ID);
5239 
5240         /* Invalid AlarmID.  */
5241         return (E_OS_ID);
5242     }
5243 
5244     TX_DISABLE
5245 
5246     if ((osek_alarm->armed == FALSE) || (osek_alarm->occupied == TX_FALSE))
5247     {
5248         TX_RESTORE
5249 
5250         exec_ErrorHook(E_OS_NOFUNC);
5251 
5252         return (E_OS_NOFUNC);      /* Alarm expired or not in use.  */
5253     }
5254 
5255     counter_ptr = osek_alarm->cntr;
5256 
5257     status = GetCounterValue(counter_ptr, &current_ticks);
5258     if (status != E_OK)
5259     {
5260         TX_RESTORE
5261 
5262         exec_ErrorHook (E_OS_ID);
5263         return (E_OS_ID);
5264     }
5265 
5266     if (osek_alarm->expiration_count < current_ticks)
5267     {
5268         /* Alarm's expiration count is less than current counter value means */
5269         /* alarm will expire after the counter rolls back and reach alarm's expiration count.  */
5270         *tick_ptr = (osek_alarm->max_allowed_value - current_ticks + osek_alarm->expiration_count);
5271     }
5272     else
5273     {
5274         /* Alarm's expiration is more than counter's current value. */
5275         *tick_ptr = (osek_alarm->max_allowed_value - current_ticks);
5276     }
5277 
5278     TX_RESTORE
5279 
5280     return (E_OK);
5281 }
5282 
5283 
5284 /**************************************************************************/
5285 /*                                                                        */
5286 /*  FUNCTION                                               RELEASE        */
5287 /*                                                                        */
5288 /*  osek_initialize                                       PORTABLE C      */
5289 /*                                                           6.1.7        */
5290 /*  AUTHOR                                                                */
5291 /*                                                                        */
5292 /*    William E. Lamie, Microsoft Corporation                             */
5293 /*                                                                        */
5294 /*  DESCRIPTION                                                           */
5295 /*                                                                        */
5296 /*    This function sets up, configures and initializes all the           */
5297 /*    "behind-the-scenes" data structures, tables, memory regions, etc.   */
5298 /*    used by the OSEK at run-time.                                       */
5299 /*                                                                        */
5300 /*  INPUT                                                                 */
5301 /*                                                                        */
5302 /*    osek_memory                            OSEK pointer                 */
5303 /*                                                                        */
5304 /*  OUTPUT                                                                */
5305 /*                                                                        */
5306 /*    None                                                                */
5307 /*                                                                        */
5308 /*  CALLS                                                                 */
5309 /*                                                                        */
5310 /*    tx_thread_create                      Create system manager thread  */
5311 /*    tx_timer_create                       Create a system timer         */
5312 /*    osek_memory_init                      Initialize OSEK memory        */
5313 /*    tx_queue_create                       Create system manager queue   */
5314 /*    osek_tcb_init                         Initialize OSEK tasks         */
5315 /*    osek_resource_init                    Initialize OSEK resources     */
5316 /*    osek_alarm_init                       Initialize OSEK alarms        */
5317 /*    osek_counter_init                     Initialize OSEK counter       */
5318 /*                                                                        */
5319 /*  CALLED BY                                                             */
5320 /*                                                                        */
5321 /*    Start-up code                                                       */
5322 /*                                                                        */
5323 /*  RELEASE HISTORY                                                       */
5324 /*                                                                        */
5325 /*    DATE              NAME                      DESCRIPTION             */
5326 /*                                                                        */
5327 /*  06-02-2021     William E. Lamie         Initial Version 6.1.7         */
5328 /*                                                                        */
5329 /**************************************************************************/
5330 
osek_initialize(void * osek_memory,APPLICATION_INFO_PTR application1)5331 UCHAR *osek_initialize(void *osek_memory, APPLICATION_INFO_PTR application1)
5332 {
5333 
5334 UCHAR       *pointer;
5335 UINT         status;
5336 UINT         i;
5337 UINT         j;
5338 
5339     /* Initialization started, set init state.  */
5340     osek_init_state = OSEK_INIT;
5341 
5342     Application = application1;
5343     Application->osek_object_creation_error = 0u;
5344     /* Setup temporary memory pointer so we can start allocating
5345        space for the OSEK data structures.  The important thing to
5346        remember here is that the system threads stack, the region0
5347        memory, and the queue are allocated sequentially from the
5348        address specified by OSEK_memory.  */
5349 
5350     pointer =  (UCHAR *)osek_memory;
5351 
5352     /* Create the work item message queue.  */
5353     status = tx_queue_create(&osek_work_queue, "OSEK work queue", SYSMGR_QUEUE_MSG_LENGTH,
5354                                 pointer, SYSMGR_QUEUE_DEPTH * SYSMGR_QUEUE_MSG_LENGTH);
5355     if(status != TX_SUCCESS)
5356     {
5357         Application->osek_object_creation_error++;
5358     }
5359 
5360     pointer = pointer + (SYSMGR_QUEUE_DEPTH * SYSMGR_QUEUE_MSG_LENGTH);
5361 
5362     /* Create the system manager thread.  */
5363     status = tx_thread_create(&osek_system_manager, "OSEK System Manager", osek_system_manager_entry,
5364                                  0, pointer, OSEK_SYSTEM_STACK_SIZE, SYSMGR_PRIORITY, SYSMGR_THRESHOLD,
5365                                  TX_NO_TIME_SLICE, TX_AUTO_START);
5366     if (status != TX_SUCCESS)
5367     {
5368         /* Error creating the system manager thread.  */
5369         Application->osek_object_creation_error++;
5370     }
5371 
5372     pointer =  pointer + OSEK_SYSTEM_STACK_SIZE;
5373 
5374     /* Set up a memory "heap" or TX_REGION0_SIZE_IN_BYTES used internally
5375        by the osek.  */
5376 
5377     status = osek_memory_init(pointer);
5378 
5379     if (status != TX_SUCCESS)
5380     {
5381         Application->osek_object_creation_error++;
5382     }
5383 
5384     pointer =  pointer + TX_REGION0_SIZE_IN_BYTES;
5385 
5386 
5387     /* Create the system timer.  */
5388     status = tx_timer_create( &osek_system_timer, "OSEK SYSTEM TIMER", osek_system_timer_entry,
5389                            0,5,5,TX_NO_ACTIVATE);
5390 
5391     if (status != TX_SUCCESS)
5392     {
5393         Application->osek_object_creation_error++;
5394     }
5395 
5396     /* Check whether any error occurred during system object creation.  */
5397     if (Application->osek_object_creation_error != 0u)
5398     {
5399         osek_internal_error(THREADX_OBJECT_CREATION_ERROR);
5400     }
5401 
5402     /* Initialize static pool of task control blocks.  */
5403     osek_tcb_init();
5404 
5405     /* Set up a pool of resource used internally by the OSEK layer.  */
5406     osek_resource_init();
5407 
5408     /* Set up a pool of counter used internally by the OSEK layer.  */
5409     osek_counter_init();
5410 
5411     /* Set up a pool of alarm used internally by the OSEK layer.  */
5412     osek_alarm_init();
5413 
5414     /* Clear all events.  */
5415     global_events = 0u;
5416     global_event_count = 0u;
5417 
5418      /* Clear task table.  */
5419 
5420     for (i = 0u; i < (OSEK_ISR1_PRIORITY + 1u); i++)
5421     {
5422         for (j = 0u; j < TASK_QUEUE_DEPTH; j++)
5423         {
5424             task_table[i][j] = 0u;
5425         }
5426     }
5427 
5428     /* Change OSEK mode.  */
5429     osek_wrapper_operation_mode = INITSYSTEM_MODE;
5430 
5431     system_start = TX_TRUE;
5432 
5433     /* All done.  */
5434     return (pointer);
5435 }
5436 
5437 
5438 /**************************************************************************/
5439 /*                                                                        */
5440 /*  FUNCTION                                               RELEASE        */
5441 /*                                                                        */
5442 /*  osek_cleanup                                          PORTABLE C      */
5443 /*                                                           6.1.7        */
5444 /*  AUTHOR                                                                */
5445 /*                                                                        */
5446 /*    William E. Lamie, Microsoft Corporation                             */
5447 /*                                                                        */
5448 /*  DESCRIPTION                                                           */
5449 /*                                                                        */
5450 /*    Cleans up after an OS shutdown. Used for testing.                   */
5451 /*                                                                        */
5452 /*  INPUT                                                                 */
5453 /*                                                                        */
5454 /*    application1                          Application pointer.          */
5455 /*                                                                        */
5456 /*  OUTPUT                                                                */
5457 /*                                                                        */
5458 /*    TX_SUCCESS                            If successful.                */
5459 /*                                                                        */
5460 /*  CALLED BY                                                             */
5461 /*                                                                        */
5462 /*    Start-up code                                                       */
5463 /*                                                                        */
5464 /*  RELEASE HISTORY                                                       */
5465 /*                                                                        */
5466 /*    DATE              NAME                      DESCRIPTION             */
5467 /*                                                                        */
5468 /*  06-02-2021     William E. Lamie         Initial Version 6.1.7         */
5469 /*                                                                        */
5470 /**************************************************************************/
5471 
osek_cleanup(APPLICATION_INFO_PTR application1)5472 UINT osek_cleanup(APPLICATION_INFO_PTR application1)
5473 {
5474 
5475 UINT status;
5476 UINT i;
5477 OSEK_TCB *p_tcb;
5478 
5479     /* Delete the system manager thread.  */
5480     status = tx_thread_delete(&osek_system_manager);
5481     if (status != TX_SUCCESS)
5482     {
5483         /* System internal error.  */
5484         osek_internal_error(SYS_MGR_START_OS);
5485     }
5486 
5487     /* Delete the system manager work queue.  */
5488     status = tx_queue_delete(&osek_work_queue);
5489     if (status != TX_SUCCESS)
5490     {
5491         /* System internal error.  */
5492         osek_internal_error(SYS_MGR_START_OS);
5493     }
5494 
5495     /* Delete the system timer. */
5496     status = tx_timer_delete(&osek_system_timer);
5497     if (status != TX_SUCCESS)
5498     {
5499         /* System internal error.  */
5500         osek_internal_error(SYS_MGR_START_OS);
5501     }
5502 
5503     /* Delete the memory pool used for OSEK objects.  */
5504     status = tx_byte_pool_delete(&osek_region0_byte_pool);
5505     if (status != TX_SUCCESS)
5506     {
5507         /* System internal error.  */
5508         osek_internal_error(SYS_MGR_START_OS);
5509     }
5510 
5511     /* Terminate and delete all the threads.  */
5512     for(i = 0u; i < OSEK_MAX_TASKS; i++) {
5513         p_tcb = &osek_tcb_pool[i];
5514         if(p_tcb->task.tx_thread_entry != NULL) {
5515             status = tx_thread_terminate(&p_tcb->task);
5516             if (status != TX_SUCCESS)
5517             {
5518                 /* System internal error.  */
5519                 osek_internal_error(SYS_MGR_START_OS);
5520             }
5521 
5522             status = tx_thread_delete(&p_tcb->task);
5523             if (status != TX_SUCCESS)
5524             {
5525                 /* System internal error.  */
5526                 osek_internal_error(SYS_MGR_START_OS);
5527             }
5528 
5529             p_tcb->task.tx_thread_entry = NULL;
5530         }
5531     }
5532 
5533     /* Clear the memory pool to prevent errors on restart.  */
5534     memset(osek_tcb_pool, 0u, sizeof(osek_tcb_pool));
5535 
5536     /* OSEK cleaned up, change init state to not initialized.  */
5537     osek_init_state = OSEK_NOT_INIT;
5538 
5539     return TX_SUCCESS;
5540 }
5541 
5542 
5543 /**************************************************************************/
5544 /*                                                                        */
5545 /*  FUNCTION                                               RELEASE        */
5546 /*                                                                        */
5547 /*    process_ISR2                                        PORTABLE C      */
5548 /*                                                           6.1.7        */
5549 /*  AUTHOR                                                                */
5550 /*                                                                        */
5551 /*    William E. Lamie, Microsoft Corporation                             */
5552 /*                                                                        */
5553 /*  DESCRIPTION                                                           */
5554 /*                                                                        */
5555 /*                                                                        */
5556 /*  INPUT                                                                 */
5557 /*                                                                        */
5558 /*    isrname                      ISR to process.                        */
5559 /*                                                                        */
5560 /*  CALLS                                                                 */
5561 /*                                                                        */
5562 /*    ActivateISR                  Puts ISR in the queue area             */
5563 /*                                                                        */
5564 /*  CALLED BY                                                             */
5565 /*                                                                        */
5566 /*   Wrapper Internal code (Not available for Application)                */
5567 /*                                                                        */
5568 /*  RELEASE HISTORY                                                       */
5569 /*                                                                        */
5570 /*    DATE              NAME                      DESCRIPTION             */
5571 /*                                                                        */
5572 /*  06-02-2021     William E. Lamie         Initial Version 6.1.7         */
5573 /*                                                                        */
5574 /**************************************************************************/
process_ISR2(ISRType isrname)5575 void   process_ISR2(ISRType isrname)
5576 {
5577 
5578    if (disable_ISR2 != 0u)
5579    {
5580        /* ISR2 disabled, do nothing.  */
5581        return;
5582    }
5583 
5584    ActivateISR(isrname);
5585 
5586    return;
5587 }
5588 
5589 
5590 /**************************************************************************/
5591 /*                                                                        */
5592 /*  FUNCTION                                               RELEASE        */
5593 /*                                                                        */
5594 /*    ShutdownOS                                          PORTABLE C      */
5595 /*                                                           6.1.7        */
5596 /*  AUTHOR                                                                */
5597 /*                                                                        */
5598 /*    William E. Lamie, Microsoft Corporation                             */
5599 /*                                                                        */
5600 /*  DESCRIPTION                                                           */
5601 /*                                                                        */
5602 /*    This function shuts down the OS. If ShutdownHook is defined it is   */
5603 /*    called.                                                             */
5604 /*                                                                        */
5605 /*  INPUT                                                                 */
5606 /*                                                                        */
5607 /*    StatusType                     Returned error to the hook           */
5608 /*                                                                        */
5609 /*  OUTPUT                                                                */
5610 /*                                                                        */
5611 /*    None                                                                */
5612 /*                                                                        */
5613 /*  CALLS                                                                 */
5614 /*                                                                        */
5615 /*    ErrorHook                      If defined                           */
5616 /*                                                                        */
5617 /*  CALLED BY                                                             */
5618 /*                                                                        */
5619 /*    Application or OS                                                   */
5620 /*                                                                        */
5621 /*  RELEASE HISTORY                                                       */
5622 /*                                                                        */
5623 /*    DATE              NAME                      DESCRIPTION             */
5624 /*                                                                        */
5625 /*  06-02-2021     William E. Lamie         Initial Version 6.1.7         */
5626 /*                                                                        */
5627 /**************************************************************************/
ShutdownOS(StatusType error)5628 void   ShutdownOS(StatusType error)
5629 {
5630 TX_INTERRUPT_SAVE_AREA
5631 ULONG       request[SYSMGR_QUEUE_MSG_LENGTH];
5632 UINT        status;
5633 
5634     TX_DISABLE
5635 
5636     /* Disable ISRs.  */
5637     disable_ISR2 = TX_TRUE;
5638 
5639    /* Check for any shutdown hook routine.  */
5640    if (Application->shutdown_hook_handler != TX_NULL)
5641    {
5642        /* Change operation mode for to shutdownhook mode. */
5643        osek_wrapper_operation_mode = SHUTDOWNHOOK_MODE;
5644 
5645        (Application->shutdown_hook_handler)(error);
5646 
5647    }
5648 
5649    /* Change to default operations mode.  */
5650    osek_wrapper_operation_mode = NORMAL_EXECUTION_MODE;
5651 
5652    /* Now send message to system thread to shut down the system.  */
5653    /* Build the request.  */
5654    request[0] = SYSMGR_SHUTDOWN_OS;         /* Request type.  */
5655    request[1] = 0u;                         /* Dummy.  */
5656    request[2] = 0u;                         /* Dummy.  */
5657    request[3] = 0u;                         /* Dummy.  */
5658 
5659    /* Now send a message to the SysMgr supervisor thread.  */
5660 
5661    status = tx_queue_send(&osek_work_queue, request, TX_NO_WAIT);
5662 
5663    TX_RESTORE
5664 
5665    /* This should always succeed.  */
5666    if (status != TX_SUCCESS)
5667    {
5668        /* System internal error.  */
5669        osek_internal_error(SYS_MGR_START_OS);
5670    }
5671 
5672    return;
5673 }
5674 
5675 
5676 /**************************************************************************/
5677 /*                                                                        */
5678 /*  FUNCTION                                               RELEASE        */
5679 /*                                                                        */
5680 /*    ActivateISR                                         PORTABLE C      */
5681 /*                                                           6.1.7        */
5682 /*  AUTHOR                                                                */
5683 /*                                                                        */
5684 /*    William E. Lamie, Microsoft Corporation                             */
5685 /*                                                                        */
5686 /*  DESCRIPTION                                                           */
5687 /*                                                                        */
5688 /*    This call activates a task which eventually executes an ISR code    */
5689 /*    This call puts the task in the ready queue.                         */
5690 /*    The operating system ensures that the task code is being executed   */
5691 /*    from the first statement. Rescheduling after this call depends on   */
5692 /*    whether required resources for this ISR are free or not and no      */
5693 /*    other higher priority are running.                                  */
5694 /*    If E_OS_LIMIT is returned then activation is ignored as there is    */
5695 /*    one request of same ISR is already pending.                         */
5696 /*                                                                        */
5697 /*    ** NOTE**                                                           */
5698 /*    This is not a standard OSEK API call.                               */
5699 /*                                                                        */
5700 /*  INPUT                                                                 */
5701 /*                                                                        */
5702 /*    ISRId                                 ISR Name                      */
5703 /*                                                                        */
5704 /*  OUTPUT                                                                */
5705 /*                                                                        */
5706 /*    E_OK                                  If successful                 */
5707 /*    E_OS_ID                               Invalid ISR id                */
5708 /*    E_OS_LIMIT                            One ISR already pending       */
5709 /*                                                                        */
5710 /*  CALLS                                                                 */
5711 /*                                                                        */
5712 /*    tx_queue_send                         Send message to Sys Manager   */
5713 /*    osek_internal_error                   OSEK internal error           */
5714 /*                                                                        */
5715 /*  CALLED BY                                                             */
5716 /*                                                                        */
5717 /*    OSEK Wrapper Internal code (not available for Applications)         */
5718 /*                                                                        */
5719 /*  RELEASE HISTORY                                                       */
5720 /*                                                                        */
5721 /*    DATE              NAME                      DESCRIPTION             */
5722 /*                                                                        */
5723 /*  06-02-2021     William E. Lamie         Initial Version 6.1.7         */
5724 /*                                                                        */
5725 /**************************************************************************/
ActivateISR(ISRType ISRID)5726 static StatusType ActivateISR(ISRType ISRID)
5727 {
5728 TX_INTERRUPT_SAVE_AREA
5729 OSEK_TCB       *tcb_ptr;
5730 UINT            status;
5731 ULONG           request[SYSMGR_QUEUE_MSG_LENGTH];
5732 
5733    /* Get the OSEK TCB for the ISR to be activated.  */
5734    tcb_ptr = (OSEK_TCB *)ISRID;
5735 
5736    /* Check for a valid ISR id.  */
5737    if((tcb_ptr == TX_NULL) || (tcb_ptr->osek_task_id != OSEK_ISR_ID))
5738    {
5739        /* Return Error.  */
5740        return (E_OS_ID);
5741    }
5742 
5743    TX_DISABLE
5744 
5745    /* Check whether an ISR of same name is pending.  */
5746    if(tcb_ptr->current_active >= tcb_ptr->max_active)
5747    {
5748        TX_RESTORE
5749        /* Reached its max activation limit.  */
5750        return (E_OS_LIMIT);
5751    }
5752 
5753    /* Now send a message to the system manager to activate this ISR.  */
5754    /* Build the request.  */
5755 
5756    request[0] = SYSMGR_ACTIVATE_TASK;          /* Request type.                */
5757    request[1] = (ULONG)tcb_ptr;                /* ISR to Activate,             */
5758    request[2] = last_run_task;                 /* Running task if any.         */
5759    request[3] = 0u;
5760 
5761    /* Since the SysMgr supervisor thread has the highest priority, this call   */
5762    /* will be preempted by SysMgr supervisor thread.                           */
5763    /* SysMgr will eventually call osek_do_task_activate().                     */
5764 
5765    status = tx_queue_send(&osek_work_queue, request, TX_NO_WAIT);
5766 
5767    TX_RESTORE
5768 
5769    /* This should always succeed.  */
5770    if (status != TX_SUCCESS)
5771    {
5772        /* System internal error.  */
5773        osek_internal_error(SYS_MGR_SEND_ACTIVATETASK);
5774    }
5775 
5776    /* Return status.  */
5777    return (E_OK);
5778 }
5779 
5780 
5781 /**************************************************************************/
5782 /*                                                                        */
5783 /*  FUNCTION                                               RELEASE        */
5784 /*                                                                        */
5785 /*    TerminateISR                                        PORTABLE C      */
5786 /*                                                           6.1.7        */
5787 /*  AUTHOR                                                                */
5788 /*                                                                        */
5789 /*    William E. Lamie, Microsoft Corporation                             */
5790 /*                                                                        */
5791 /*  DESCRIPTION                                                           */
5792 /*                                                                        */
5793 /*   This service terminates the calling ISR.                             */
5794 /*   Only internal resources held by this ISR are released here. While    */
5795 /*   it is assumed that any external resources occupied by the ISR must   */
5796 /*   have been released before the call to TerminateISR. In case          */
5797 /*   a resource is still occupied while calling this service, then the    */
5798 /*   behaviour is undefined in STANDARD version of OSEK. In the EXTENDED  */
5799 /*   version of OSEK, this service returns an error, which can be         */
5800 /*   evaluated by the application.                                        */
5801 /*   If successful, this call will causes rescheduling, this also means   */
5802 /*   that upon success TerminateTask does not return to the call level.   */
5803 /*                                                                        */
5804 /*                                                                        */
5805 /*  INPUT                                                                 */
5806 /*                                                                        */
5807 /*    None                                                                */
5808 /*                                                                        */
5809 /*  OUTPUT                                                                */
5810 /*                                                                        */
5811 /*    None                            If success                          */
5812 /*    Error Code.                     If error                            */
5813 /*                                                                        */
5814 /*  CALLS                                                                 */
5815 /*                                                                        */
5816 /*    osek_task_independent_area      Check if we are in task context     */
5817 /*    osek_thread2tcb                 Get TCB pointer for thread pointer  */
5818 /*    tx_queue_send                   Send message to sys manager thread  */
5819 /*    osek_internal_error             In case of any internal error       */
5820 /*                                                                        */
5821 /*  CALLED BY                                                             */
5822 /*                                                                        */
5823 /*    OSEK Wrapper Internal code (Not available for Applications)         */
5824 /*                                                                        */
5825 /*  RELEASE HISTORY                                                       */
5826 /*                                                                        */
5827 /*    DATE              NAME                      DESCRIPTION             */
5828 /*                                                                        */
5829 /*  06-02-2021     William E. Lamie         Initial Version 6.1.7         */
5830 /*                                                                        */
5831 /**************************************************************************/
TerminateISR(void)5832 static StatusType  TerminateISR(void)
5833 {
5834 TX_INTERRUPT_SAVE_AREA
5835 OSEK_TCB       *tcb_ptr;
5836 ULONG           request[SYSMGR_QUEUE_MSG_LENGTH];
5837 UINT            index;
5838 UINT            status;
5839 ULONG           area;
5840 TX_THREAD      *p_thread;
5841 
5842 
5843    /* Check for task or ISR context */
5844    /* All ISR are treated as as a high priority tasks.  */
5845    area = osek_task_independent_area();
5846    if(area != TX_TRUE)
5847    {
5848        /* Return error.  */
5849        return (E_OS_CALLEVEL);
5850    }
5851 
5852    /* Get OSEK TCB of this TASK/ISR  */
5853    p_thread = tx_thread_identify();
5854    tcb_ptr = osek_thread2tcb(p_thread);
5855    if (tcb_ptr == NULL)
5856    {
5857        return (E_OS_CALLEVEL);
5858    }
5859 
5860    if ((tcb_ptr->osek_task_id != OSEK_ISR_ID))
5861    {
5862        /* This call is allowed only from ISR.  */
5863        return (E_OS_CALLEVEL);
5864    }
5865 
5866 
5867    /* Check operating mode.  */
5868    if ((osek_wrapper_operation_mode != ISR1_MODE) && (osek_wrapper_operation_mode != ISR2_MODE))
5869    {
5870        /* Hook toutines and alarm callbacks can't call this service.  */
5871        /* This explicit check is required because all hook routines are
5872       executed in task's context.  */
5873        return (E_OS_CALLEVEL);
5874    }
5875 
5876    TX_DISABLE
5877 
5878    /* Check if any resource is occupied. A task can not be terminated if it is holding any resource.  */
5879    if(tcb_ptr->res_ocp != 0u)
5880    {
5881        TX_RESTORE
5882 
5883       /* Return.  */
5884       return (E_OS_RESOURCE);
5885    }
5886 
5887    /* Release any internal resources held.  */
5888    if (tcb_ptr->internal_res != 0u)
5889    {
5890        for (index = 0u; index < OSEK_MAX_INTERNAL_RES; index++)
5891        {
5892            if (tcb_ptr->internal_resource_occuplied_list[index] == 0u)
5893            {
5894                break;
5895            }
5896 
5897            ((OSEK_RESOURCE *)(tcb_ptr->internal_resource_occuplied_list[index]))->taskid = 0u;
5898            tcb_ptr->internal_resource_occuplied_list[index] = 0u;
5899 
5900        }   /* End of for loop.  */
5901    }
5902 
5903    /* Now all set to terminate this task.  */
5904    /* Send a message to the System Manager to terminate this task.  */
5905    /* Build the request.  */
5906 
5907    request[0] = SYSMGR_TERMINATE_TASK;      /* Request type.  */
5908    request[1] = (ULONG)tcb_ptr;             /* ID of the task to kill.  */
5909    request[2] = 0u;
5910    request[3] = 0u;
5911 
5912    /* Since the SysMgr supervisor thread has the highest priority,        */
5913    /* this call will be preempted by SysMgr supervisor thread             */
5914    /* SysMgr will eventually call osek_do_task_terminate and reschedule.  */
5915 
5916    status = tx_queue_send(&osek_work_queue, request, TX_NO_WAIT);
5917 
5918    TX_RESTORE
5919 
5920    /* This should always succeed. and Sys Manager terminates this task    */
5921    /* This point will never be reached, as this thread itself will be     */
5922    /* deleted by the system manager!                                      */
5923    /* Still as a safety precaution enter system internal error loop.      */
5924 
5925    if (status != TX_SUCCESS)
5926    {
5927        osek_internal_error(SYS_MGR_SEND_TERMINATETASK);
5928    }
5929 
5930    return (E_OK);
5931 }
5932 
5933 
5934 /**************************************************************************/
5935 /*                                                                        */
5936 /*  FUNCTION                                               RELEASE        */
5937 /*                                                                        */
5938 /*    osek_system_manager_entry                          PORTABLE C       */
5939 /*                                                           6.1.7        */
5940 /*  AUTHOR                                                                */
5941 /*                                                                        */
5942 /*    William E. Lamie, Microsoft Corporation                             */
5943 /*                                                                        */
5944 /*  DESCRIPTION                                                           */
5945 /*                                                                        */
5946 /*    This is the System Manager thread for the OSEK.                     */
5947 /*    All OSEK service calls that may cause rescheduling, ends up in      */
5948 /*    sending a message to a queue, and this highest priority thread      */
5949 /*    'System Manager' reads this message and acts upon it.               */
5950 /*    It then calls the actual task scheduler which selects the next ready*/
5951 /*    task from a queue of READY tasks.                                   */
5952 /*    After completing the request this routine returns back to read      */
5953 /*    next message which suspends this System Manager Thread and the task */
5954 /*    selected by the task scheduler starts running.                      */
5955 /*                                                                        */
5956 /*  INPUT                                                                 */
5957 /*                                                                        */
5958 /*    input                          Not used  (Don't care)               */
5959 /*                                                                        */
5960 /*  OUTPUT                                                                */
5961 /*                                                                        */
5962 /*    None                                                                */
5963 /*                                                                        */
5964 /*  CALLS                                                                 */
5965 /*                                                                        */
5966 /*    tx_queue_receive               Get message from ThreadX queue       */
5967 /*    osek_do_task_terminate         Terminate the OSEK task.             */
5968 /*    osek_do_task_activate          Activate the task                    */
5969 /*    osek_internal_error            OSEK internal error.                 */
5970 /*    osek_do_delete_task            Delete the OSEK task                 */
5971 /*    pop_task_from_table            Removes a task from the queue        */
5972 /*    tx_thread_suspend              Suspends the calling task            */
5973 /*    add_task_to_table              Adds a task to the TASK ready queue  */
5974 /*    start_osek_tasks               Runs the next ready task from queue  */
5975 /*                                                                        */
5976 /*  CALLED BY                                                             */
5977 /*                                                                        */
5978 /*    Wrapper Internal code (Not available to Application )               */
5979 /*                                                                        */
5980 /*  RELEASE HISTORY                                                       */
5981 /*                                                                        */
5982 /*    DATE              NAME                      DESCRIPTION             */
5983 /*                                                                        */
5984 /*  06-02-2021     William E. Lamie         Initial Version 6.1.7         */
5985 /*                                                                        */
5986 /**************************************************************************/
osek_system_manager_entry(ULONG input)5987 static void  osek_system_manager_entry(ULONG input)
5988 {
5989 TX_THREAD      *this_thread;
5990 OSEK_TCB       *tcb_ptr;
5991 UINT            status;
5992 StatusType      osek_status;
5993 UINT            i;
5994 UINT            j;
5995 ULONG           request[SYSMGR_QUEUE_MSG_LENGTH];
5996 
5997 
5998    /* The input argument 'input' is not needed , hence not used */
5999    /* This statement is added just to avoid compiler warning.  */
6000    (void)&input;
6001 
6002    /* Loop forever, waiting for any new message in the work queue.  */
6003    for(;;)
6004    {
6005        /* Wait forever for the next work request.  */
6006        status = tx_queue_receive(&osek_work_queue, &request, TX_WAIT_FOREVER);
6007 
6008        /* Make sure we didn't encounter any trouble.  */
6009        if (status != TX_SUCCESS)
6010        {
6011            osek_internal_error(SYSMGR_FATAL_ERROR);
6012            continue;
6013        }
6014 
6015        /* Look at the first entry in the message for the request type.  */
6016        switch(request[0u])
6017        {
6018            case    SYSMGR_TERMINATE_TASK:
6019 
6020               /* ISR ends up in terminating itself so there is no separate switch case
6021                  for 'Return from ISR'.  */
6022               /* As the task is terminated, remove it from the queue.  */
6023               pop_task_from_table((OSEK_TCB *)request[1u]);
6024               /* Now Terminate the task.  */
6025               osek_status = osek_do_task_terminate((OSEK_TCB *)request[1u]);
6026               if(osek_status != E_OK) {
6027                   osek_internal_error(SYSMGR_FATAL_ERROR);
6028               }
6029 
6030               task_terminated = TX_TRUE;
6031 
6032               /* Enforce default operations mode.  */
6033               osek_wrapper_operation_mode = NORMAL_EXECUTION_MODE;
6034 
6035               break;
6036 
6037 
6038            case    SYSMGR_CHAIN_TASK:
6039 
6040                /* As calling task is terminated remove it from the queue.  */
6041                pop_task_from_table ((OSEK_TCB *)request[1u]);
6042 
6043                /* Now terminate the calling task.  */
6044                osek_status = osek_do_task_terminate((OSEK_TCB *)request[1u]);
6045                if(osek_status != E_OK) {
6046                    osek_internal_error(SYSMGR_FATAL_ERROR);
6047                }
6048 
6049                task_terminated = TX_TRUE;
6050 
6051                /* Now activate the task to be chained.  */
6052                osek_status = osek_do_activate_task((OSEK_TCB *)request[2u]);
6053                if(osek_status != E_OK) {
6054                    osek_internal_error(SYSMGR_FATAL_ERROR);
6055                }
6056 
6057                break;
6058 
6059            case    SYSMGR_START_OS:
6060 
6061                system_start = TX_TRUE;                    /* Indicates a fresh OS start.  */
6062                disable_ISR2 = TX_FALSE;
6063                suspend_ISR2 = TX_FALSE;
6064 
6065                /* OSEK started change init mode.  */
6066                osek_init_state = OSEK_STARTED;
6067 
6068                break;
6069 
6070            case    SYSMGR_ACTIVATE_TASK:
6071 
6072                /* First suspend the calling task but if an ISR is activating a task then */
6073                /* no need to suspend ISR Task as rescheduling (if required) is done only */
6074                /* after ISR completes. With ISR calling this service the request[2] is   */
6075                /* always a NULL.  */
6076                if (request[2] != 0u)
6077                {
6078                    this_thread = (TX_THREAD *)request[2];
6079                    status = tx_thread_suspend(this_thread);
6080                    if (status != TX_SUCCESS)
6081                    {
6082                        osek_internal_error(SYSMGR_FATAL_ERROR);
6083                    }
6084                }
6085 
6086                /* Now activate the requested task.  */
6087                osek_status = osek_do_activate_task((OSEK_TCB *)request[1]);
6088                if(osek_status != E_OK) {
6089                    osek_internal_error(SYSMGR_FATAL_ERROR);
6090                }
6091 
6092                break;
6093 
6094            case    SYSMGR_RELEASE_RESOURCE:
6095 
6096                tcb_ptr = (OSEK_TCB *)request[1];
6097 
6098                /* First remove the task from its current queue position.  */
6099                pop_task_from_table( tcb_ptr);
6100 
6101                /* Now change this task prio to a new one after release res.  */
6102                tcb_ptr->cur_threshold = (UINT)request[2];
6103 
6104                /* Now move this task to its new position.  */
6105                push_task_to_table(tcb_ptr);
6106 
6107                /* Now suspend the calling task.  */
6108                if (request[1u] != 0u)
6109                {
6110                    this_thread = (TX_THREAD *)request[1];
6111                    status = tx_thread_suspend(this_thread);
6112                    if (status != TX_SUCCESS)
6113                    {
6114                        osek_internal_error(SYSMGR_FATAL_ERROR);
6115                    }
6116                }
6117                break;
6118 
6119            case    SYSMGR_GET_RESOURCE:
6120 
6121                tcb_ptr = (OSEK_TCB *)request[1];
6122 
6123                /* First remove the task from its current queue position.  */
6124                pop_task_from_table ( tcb_ptr);
6125 
6126                /* Now change this task prio to a new one after release res.  */
6127                tcb_ptr->cur_threshold = (UINT)request[2];
6128 
6129                /* Now move this task to its new position.  */
6130                push_task_to_table(tcb_ptr);
6131 
6132                /* Now suspend the calling task.  */
6133                if (request[1u] != 0u)
6134                {
6135                     this_thread = (TX_THREAD *)request[1u];
6136                     status = tx_thread_suspend(this_thread);
6137                     if (status != TX_SUCCESS)
6138                     {
6139                         osek_internal_error(SYSMGR_FATAL_ERROR);
6140                     }
6141                }
6142 
6143                break;
6144 
6145            case    SYSMGR_SCHEDULE:
6146 
6147                /* Get TCB for the calling task.  */
6148                tcb_ptr = (OSEK_TCB *)request[1u];
6149 
6150                /* Now release any internal resources held
6151                   and move the task to its original priority queue.  */
6152                osek_status = release_internal_resource(tcb_ptr);
6153                if(osek_status != E_OK) {
6154                    osek_internal_error(SYSMGR_FATAL_ERROR);
6155                }
6156 
6157                /* Suspend the calling task.  */
6158                if (request[1u] != 0u)
6159                {
6160                    this_thread = (TX_THREAD *)request[1u];
6161                    status = tx_thread_suspend(this_thread);
6162                    if (status != TX_SUCCESS)
6163                    {
6164                        osek_internal_error(SYSMGR_FATAL_ERROR);
6165                    }
6166                }
6167 
6168                break;
6169 
6170            case    SYSMGR_SETEVENT:
6171 
6172                /* Add this out of wait state task to the ready queue as a newest member.  */
6173                ((OSEK_TCB *)request[2u])->cur_threshold = ((OSEK_TCB *)request[2u])->org_prio;
6174 
6175                add_task_to_table((OSEK_TCB *)request[2u]);
6176 
6177                /* Suspend the calling task.  */
6178                if (request[1u] != 0u)
6179                {
6180                    this_thread = (TX_THREAD *)request[1u];
6181                    status = tx_thread_suspend(this_thread);
6182                    if (status != TX_SUCCESS)
6183                    {
6184                        osek_internal_error(SYSMGR_FATAL_ERROR);
6185                    }
6186                }
6187 
6188                break;
6189 
6190            case    SYSMGR_WAITEVENT:
6191 
6192                /* Remove from the queue the task that went into waiting state.  */
6193                pop_task_from_table((OSEK_TCB *)request[2u]);
6194 
6195                /* Suspend it.  */
6196                this_thread = (TX_THREAD *)request[1u];
6197 
6198                status = tx_thread_suspend(this_thread);
6199                if (status != TX_SUCCESS)
6200                {
6201                    osek_internal_error(SYSMGR_FATAL_ERROR);
6202                }
6203 
6204                break;
6205 
6206            case    SYSMGR_SHUTDOWN_OS:
6207                /* System shut down, clear task queue.  */
6208 
6209                for (i = 0u; i < (OSEK_ISR1_PRIORITY + 1u); i++)
6210                {
6211                    for (j = 0u; j < TASK_QUEUE_DEPTH; j++)
6212                    {
6213                        if (task_table[i][j] != 0u)
6214                        {
6215                            status = tx_thread_terminate((TX_THREAD *)(task_table[i][j]));
6216                            if(status != TX_SUCCESS) {
6217                                osek_internal_error(SYSMGR_FATAL_ERROR);
6218                            }
6219                            task_table [i][j] = 0u;
6220                        }
6221                    }
6222                }
6223 
6224                return;
6225 
6226                break;
6227 
6228            case    SYSMGR_ERRORHOOK:
6229                this_thread = (TX_THREAD *)request[1u];
6230 
6231                    /* Although an ERRORHOOK won't call any API Service that may cause
6232                       rescheduling there could be an ISR logged while an Errorhook
6233                       was executing, so Errorhook call ends up in sending a message to
6234                       SYS manager to reschedule if necessary.  */
6235 
6236                    /* Suspend the task causing Error condition.  */
6237                status = tx_thread_suspend(this_thread);
6238                if (status != TX_SUCCESS)
6239                {
6240                    osek_internal_error(SYSMGR_FATAL_ERROR);
6241                }
6242 
6243                    break;
6244 
6245            default:
6246 
6247                    /* We should NEVER get here... call a fatal error.  */
6248                    /* System internal error.  */
6249                    osek_internal_error(SYSMGR_FATAL_ERROR);
6250 
6251                    break;
6252 
6253        } /* End of switch.  */
6254 
6255        /* Now call scheduler to check for any preemption and resume.  */
6256        start_osek_tasks();
6257 
6258    }  /* wile (1) System Manager forever loop.  */
6259 
6260 }
6261 
6262 
6263 /**************************************************************************/
6264 /*                                                                        */
6265 /*  FUNCTION                                               RELEASE        */
6266 /*                                                                        */
6267 /*  osek_memory_init                                      PORTABLE C      */
6268 /*                                                           6.1.7        */
6269 /*  AUTHOR                                                                */
6270 /*                                                                        */
6271 /*    William E. Lamie, Microsoft Corporation                             */
6272 /*                                                                        */
6273 /*  DESCRIPTION                                                           */
6274 /*                                                                        */
6275 /*    This function attempts to create a ThreadX byte pool that will      */
6276 /*    act as a "heap" for the OSEK dynamic internal objects               */
6277 /*    memory needs.                                                       */
6278 /*                                                                        */
6279 /*  INPUT                                                                 */
6280 /*                                                                        */
6281 /*    region0_ptr                            OSEK memory pointer          */
6282 /*                                                                        */
6283 /*  OUTPUT                                                                */
6284 /*                                                                        */
6285 /*    None                                                                */
6286 /*                                                                        */
6287 /*  CALLS                                                                 */
6288 /*                                                                        */
6289 /*    tx_byte_pool_create                   Create region0 byte pool      */
6290 /*    osek_internal_error                   Internal OSEK error           */
6291 /*                                                                        */
6292 /*  CALLED BY                                                             */
6293 /*                                                                        */
6294 /*    Start-up code                                                       */
6295 /*                                                                        */
6296 /*  RELEASE HISTORY                                                       */
6297 /*                                                                        */
6298 /*    DATE              NAME                      DESCRIPTION             */
6299 /*                                                                        */
6300 /*  06-02-2021     William E. Lamie         Initial Version 6.1.7         */
6301 /*                                                                        */
6302 /**************************************************************************/
osek_memory_init(void * region0_ptr)6303 static UINT osek_memory_init (void  *region0_ptr)
6304 {
6305 UINT    retval;
6306 
6307     /* Create a ThreadX byte pool that will provide memory
6308        needed by the OSEK.  */
6309     retval = tx_byte_pool_create((TX_BYTE_POOL *)&osek_region0_byte_pool,
6310                                  "OSEK REGION 0",
6311                                  region0_ptr,
6312                                  TX_REGION0_SIZE_IN_BYTES);
6313 
6314     return (retval);
6315 }
6316 
6317 
6318 /**************************************************************************/
6319 /*                                                                        */
6320 /*  FUNCTION                                               RELEASE        */
6321 /*                                                                        */
6322 /*    osek_counter_init                                   PORTABLE C      */
6323 /*                                                           6.1.7        */
6324 /*  AUTHOR                                                                */
6325 /*                                                                        */
6326 /*    William E. Lamie, Microsoft Corporation                             */
6327 /*                                                                        */
6328 /*  DESCRIPTION                                                           */
6329 /*                                                                        */
6330 /*    This function sets up, configures and initializes all the           */
6331 /*    counter structures, which are defined at compile-time in order to   */
6332 /*    ensure that there is sufficient memory.                             */
6333 /*                                                                        */
6334 /*  INPUT                                                                 */
6335 /*                                                                        */
6336 /*    None                                                                */
6337 /*                                                                        */
6338 /*  OUTPUT                                                                */
6339 /*                                                                        */
6340 /*    None                                                                */
6341 /*                                                                        */
6342 /*  CALLS                                                                 */
6343 /*                                                                        */
6344 /*    osek_reset_counter                    Reset a Counters structure    */
6345 /*                                                                        */
6346 /*  CALLED BY                                                             */
6347 /*                                                                        */
6348 /*    Start-up code                                                       */
6349 /*                                                                        */
6350 /*  RELEASE HISTORY                                                       */
6351 /*                                                                        */
6352 /*    DATE              NAME                      DESCRIPTION             */
6353 /*                                                                        */
6354 /*  06-02-2021     William E. Lamie         Initial Version 6.1.7         */
6355 /*                                                                        */
6356 /**************************************************************************/
osek_counter_init(void)6357 static void  osek_counter_init(void)
6358 {
6359 
6360 ULONG       index;
6361 
6362     /* Loop through array of semaphores and initialize each one.  */
6363     for (index = 0u; index < OSEK_MAX_COUNTERS; index++)
6364     {
6365         osek_reset_counter(&(osek_counter_pool[index]));
6366     }
6367 }
6368 
6369 
6370 /**************************************************************************/
6371 /*                                                                        */
6372 /*  FUNCTION                                               RELEASE        */
6373 /*                                                                        */
6374 /*    osek_reset_counter                                  PORTABLE C      */
6375 /*                                                           6.1.7        */
6376 /*  AUTHOR                                                                */
6377 /*                                                                        */
6378 /*    William E. Lamie, Microsoft Corporation                             */
6379 /*                                                                        */
6380 /*  DESCRIPTION                                                           */
6381 /*                                                                        */
6382 /*    This function resets a counter structure.                           */
6383 /*                                                                        */
6384 /*  INPUT                                                                 */
6385 /*                                                                        */
6386 /*    counter_ptr                             Counter pointer             */
6387 /*                                                                        */
6388 /*  OUTPUT                                                                */
6389 /*                                                                        */
6390 /*    None                                                                */
6391 /*                                                                        */
6392 /*  CALLS                                                                 */
6393 /*                                                                        */
6394 /*    None                                                                */
6395 /*                                                                        */
6396 /*  CALLED BY                                                             */
6397 /*                                                                        */
6398 /*    Start-up code                                                       */
6399 /*                                                                        */
6400 /*  RELEASE HISTORY                                                       */
6401 /*                                                                        */
6402 /*    DATE              NAME                      DESCRIPTION             */
6403 /*                                                                        */
6404 /*  06-02-2021     William E. Lamie         Initial Version 6.1.7         */
6405 /*                                                                        */
6406 /**************************************************************************/
osek_reset_counter(OSEK_COUNTER * counter_ptr)6407 static void osek_reset_counter(OSEK_COUNTER *counter_ptr)
6408 {
6409 TX_INTERRUPT_SAVE_AREA
6410 UINT  index;
6411 
6412     TX_DISABLE
6413 
6414     /* This counter is now no longer in use.  */
6415     counter_ptr->cntr_in_use = TX_FALSE;
6416 
6417     /* Make any counter initial ticks to 0.  */
6418     counter_ptr->counter_value = 0u;
6419 
6420     /* Make max. allowable ticks to 0.  */
6421     counter_ptr->maxallowedvalue = 0u;
6422 
6423     /* Make no. of alarm repetition to 0.  */
6424     counter_ptr->mincycle = 0u;
6425 
6426     /* Make ticks per base = 1.  */
6427     counter_ptr->ticksperbase = 1u;
6428 
6429     /* Not attached yet to system timer.  */
6430     counter_ptr->system_timer = TX_FALSE;
6431 
6432     /* Clear alarm list.  */
6433     for (index = 0u; index < OSEK_MAX_ALARMS; index++)
6434     {
6435         counter_ptr->alarm_list[index] = 0u;
6436     }
6437 
6438     counter_ptr->osek_counter_id = 0u;
6439 
6440     TX_RESTORE
6441 
6442     return;
6443 }
6444 
6445 
6446 /**************************************************************************/
6447 /*                                                                        */
6448 /*  FUNCTION                                               RELEASE        */
6449 /*                                                                        */
6450 /*    osek_alarm_init                                   PORTABLE C        */
6451 /*                                                           6.1.7        */
6452 /*  AUTHOR                                                                */
6453 /*                                                                        */
6454 /*    William E. Lamie, Microsoft Corporation                             */
6455 /*                                                                        */
6456 /*  DESCRIPTION                                                           */
6457 /*                                                                        */
6458 /*    This function sets up, configures and initializes all the           */
6459 /*    alarm structures, which we define at compile-time in order to       */
6460 /*    ensure that there is sufficient memory.                             */
6461 /*                                                                        */
6462 /*  INPUT                                                                 */
6463 /*                                                                        */
6464 /*    None                                                                */
6465 /*                                                                        */
6466 /*  OUTPUT                                                                */
6467 /*                                                                        */
6468 /*    None                                                                */
6469 /*                                                                        */
6470 /*  CALLS                                                                 */
6471 /*                                                                        */
6472 /*    osek_reset_alarm                                                    */
6473 /*                                                                        */
6474 /*  CALLED BY                                                             */
6475 /*                                                                        */
6476 /*    Start-up code                                                       */
6477 /*                                                                        */
6478 /*  RELEASE HISTORY                                                       */
6479 /*                                                                        */
6480 /*    DATE              NAME                      DESCRIPTION             */
6481 /*                                                                        */
6482 /*  06-02-2021     William E. Lamie         Initial Version 6.1.7         */
6483 /*                                                                        */
6484 /**************************************************************************/
osek_alarm_init(void)6485 static void  osek_alarm_init(void)
6486 {
6487 
6488 ULONG       index;
6489 
6490     /* Loop through array of Semaphores and initialize each one.  */
6491     for(index = 0u; index < OSEK_MAX_ALARMS; index++)
6492     {
6493         osek_reset_alarm(&(osek_alarm_pool[index]));
6494     }
6495 }
6496 
6497 
6498 /**************************************************************************/
6499 /*                                                                        */
6500 /*  FUNCTION                                               RELEASE        */
6501 /*                                                                        */
6502 /*    osek_reset_alarm                                    PORTABLE C      */
6503 /*                                                           6.1.7        */
6504 /*  AUTHOR                                                                */
6505 /*                                                                        */
6506 /*    William E. Lamie, Microsoft Corporation                             */
6507 /*                                                                        */
6508 /*  DESCRIPTION                                                           */
6509 /*                                                                        */
6510 /*    This function resets an alarm structure to its default state.       */
6511 /*                                                                        */
6512 /*  INPUT                                                                 */
6513 /*                                                                        */
6514 /*    alarm_ptr                             Alarm pointer                 */
6515 /*                                                                        */
6516 /*  OUTPUT                                                                */
6517 /*                                                                        */
6518 /*    None                                                                */
6519 /*                                                                        */
6520 /*  CALLS                                                                 */
6521 /*                                                                        */
6522 /*    None                                                                */
6523 /*                                                                        */
6524 /*  CALLED BY                                                             */
6525 /*                                                                        */
6526 /*    Start-up code                                                       */
6527 /*                                                                        */
6528 /*  RELEASE HISTORY                                                       */
6529 /*                                                                        */
6530 /*    DATE              NAME                      DESCRIPTION             */
6531 /*                                                                        */
6532 /*  06-02-2021     William E. Lamie         Initial Version 6.1.7         */
6533 /*                                                                        */
6534 /**************************************************************************/
osek_reset_alarm(OSEK_ALARM * alarm_ptr)6535 static void osek_reset_alarm(OSEK_ALARM *alarm_ptr)
6536 {
6537 TX_INTERRUPT_SAVE_AREA
6538 
6539     TX_DISABLE
6540 
6541     /* First unarm the timer.  */
6542     alarm_ptr->armed = TX_FALSE;
6543 
6544     /* This alarm is now no longer in use.  */
6545     alarm_ptr->alarm_in_use = TX_FALSE;
6546     alarm_ptr->occupied = TX_FALSE;
6547 
6548     /* Make Call back function to TX_NULL.  */
6549     alarm_ptr->alarm_callback = TX_NULL;
6550 
6551     /* Make any counter reference to TX_NULL.  */
6552     alarm_ptr->cntr = TX_NULL;
6553 
6554     /* Make any task and event reference to TX_NULL.  */
6555     alarm_ptr->task = TX_NULL;
6556     alarm_ptr->events = 0u;
6557     alarm_ptr->action = 0u;
6558 
6559     /* Make its default value = 0.  */
6560     alarm_ptr->max_allowed_value = 0u;
6561     alarm_ptr->min_cyc = 0u;
6562     alarm_ptr->cycle = 0u;
6563     alarm_ptr->expiration_count = 0u;
6564     alarm_ptr->auto_start = 0u;
6565 
6566     alarm_ptr->osek_alarm_id = 0u;
6567 
6568     TX_RESTORE
6569 
6570     return;
6571 }
6572 
6573 
6574 /**************************************************************************/
6575 /*                                                                        */
6576 /*  FUNCTION                                               RELEASE        */
6577 /*                                                                        */
6578 /*    osek_tcb_init                                       PORTABLE C      */
6579 /*                                                           6.1.7        */
6580 /*  AUTHOR                                                                */
6581 /*                                                                        */
6582 /*    William E. Lamie, Microsoft Corporation                             */
6583 /*                                                                        */
6584 /*  DESCRIPTION                                                           */
6585 /*                                                                        */
6586 /*    This function sets up, configures and initializes all the           */
6587 /*    task control blocks, which are defined at compile-time in order to  */
6588 /*    ensure that there is sufficient memory.                             */
6589 /*                                                                        */
6590 /*  INPUT                                                                 */
6591 /*                                                                        */
6592 /*    None                                                                */
6593 /*                                                                        */
6594 /*  OUTPUT                                                                */
6595 /*                                                                        */
6596 /*    None                                                                */
6597 /*                                                                        */
6598 /*  CALLS                                                                 */
6599 /*                                                                        */
6600 /*    osek_reset_tcb                         Reset a task control block   */
6601 /*                                                                        */
6602 /*  CALLED BY                                                             */
6603 /*                                                                        */
6604 /*    Start-up code                                                       */
6605 /*                                                                        */
6606 /*  RELEASE HISTORY                                                       */
6607 /*                                                                        */
6608 /*    DATE              NAME                      DESCRIPTION             */
6609 /*                                                                        */
6610 /*  06-02-2021     William E. Lamie         Initial Version 6.1.7         */
6611 /*                                                                        */
6612 /**************************************************************************/
osek_tcb_init(void)6613 static void  osek_tcb_init(void)
6614 {
6615 
6616 ULONG       index;
6617 
6618     /* Loop through array of TCBs and initialize each one.  */
6619     for(index = 0u; index < OSEK_MAX_TASKS; index++)
6620     {
6621         osek_reset_tcb(&(osek_tcb_pool[index]));
6622     }
6623 }
6624 
6625 /**************************************************************************/
6626 /*                                                                        */
6627 /*  FUNCTION                                               RELEASE        */
6628 /*                                                                        */
6629 /*    osek_resource_init                                  PORTABLE C      */
6630 /*                                                           6.1.7        */
6631 /*  AUTHOR                                                                */
6632 /*                                                                        */
6633 /*    William E. Lamie, Microsoft Corporation                             */
6634 /*                                                                        */
6635 /*  DESCRIPTION                                                           */
6636 /*                                                                        */
6637 /*    This function sets up, configures and initializes all the           */
6638 /*    resource structures, which are defined at compile-time in order to  */
6639 /*    ensure that there is sufficient memory.                             */
6640 /*                                                                        */
6641 /*  INPUT                                                                 */
6642 /*                                                                        */
6643 /*    None                                                                */
6644 /*                                                                        */
6645 /*  OUTPUT                                                                */
6646 /*                                                                        */
6647 /*    None                                                                */
6648 /*                                                                        */
6649 /*  CALLS                                                                 */
6650 /*                                                                        */
6651 /*    osek_reset_res                        Reset a semaphore structure   */
6652 /*    CreateResource                        Create the resource in OSEK   */
6653 /*                                                                        */
6654 /*  CALLED BY                                                             */
6655 /*                                                                        */
6656 /*    Start-up code                                                       */
6657 /*                                                                        */
6658 /*  RELEASE HISTORY                                                       */
6659 /*                                                                        */
6660 /*    DATE              NAME                      DESCRIPTION             */
6661 /*                                                                        */
6662 /*  06-02-2021     William E. Lamie         Initial Version 6.1.7         */
6663 /*                                                                        */
6664 /**************************************************************************/
osek_resource_init(void)6665 static void  osek_resource_init(void)
6666 {
6667 
6668 ULONG             index;
6669 OSEK_RESOURCE     *res_ptr;
6670 
6671 
6672     /* Loop through array of resources and initialize each one.  */
6673     for(index = 0u; index < OSEK_MAX_RES; index++)
6674     {
6675         osek_reset_res(&(osek_res_pool[index]));
6676     }
6677 
6678     RES_SCHEDULER = CreateResource("RES_SCHEDULER", STANDARD, 0u);
6679     res_ptr = (OSEK_RESOURCE *)RES_SCHEDULER;
6680     res_ptr->c_priority = OSEK_NON_SCHEDULE_PRIORITY;
6681 }
6682 
6683 /**************************************************************************/
6684 /*                                                                        */
6685 /*  FUNCTION                                               RELEASE        */
6686 /*                                                                        */
6687 /*    osek_reset_res                                      PORTABLE C      */
6688 /*                                                           6.1.7        */
6689 /*  AUTHOR                                                                */
6690 /*                                                                        */
6691 /*    William E. Lamie, Microsoft Corporation                             */
6692 /*                                                                        */
6693 /*  DESCRIPTION                                                           */
6694 /*                                                                        */
6695 /*    This function resets a resource a structure to its default state.   */
6696 /*                                                                        */
6697 /*  INPUT                                                                 */
6698 /*                                                                        */
6699 /*    res_ptr                               Resource pointer              */
6700 /*                                                                        */
6701 /*  OUTPUT                                                                */
6702 /*                                                                        */
6703 /*    None                                                                */
6704 /*                                                                        */
6705 /*  CALLS                                                                 */
6706 /*                                                                        */
6707 /*    None                                                                */
6708 /*                                                                        */
6709 /*  CALLED BY                                                             */
6710 /*                                                                        */
6711 /*    Start-up code                                                       */
6712 /*                                                                        */
6713 /*  RELEASE HISTORY                                                       */
6714 /*                                                                        */
6715 /*    DATE              NAME                      DESCRIPTION             */
6716 /*                                                                        */
6717 /*  06-02-2021     William E. Lamie         Initial Version 6.1.7         */
6718 /*                                                                        */
6719 /**************************************************************************/
osek_reset_res(OSEK_RESOURCE * res_ptr)6720 static void osek_reset_res(OSEK_RESOURCE  *res_ptr)
6721 {
6722 TX_INTERRUPT_SAVE_AREA
6723 
6724     TX_DISABLE
6725 
6726     /* Indicate this entry is not in use.  */
6727     res_ptr->res_in_use = TX_FALSE;
6728 
6729     TX_RESTORE
6730 
6731     return;
6732 }
6733 
6734 
6735 /**************************************************************************/
6736 /*                                                                        */
6737 /*  FUNCTION                                               RELEASE        */
6738 /*                                                                        */
6739 /*    osek_do_task_terminate                              PORTABLE C      */
6740 /*                                                           6.1.7        */
6741 /*  AUTHOR                                                                */
6742 /*                                                                        */
6743 /*    William E. Lamie, Microsoft Corporation                             */
6744 /*                                                                        */
6745 /*  DESCRIPTION                                                           */
6746 /*                                                                        */
6747 /*    This function terminates the specified task.                        */
6748 /*                                                                        */
6749 /*  INPUT                                                                 */
6750 /*                                                                        */
6751 /*    tcb_ptr                         Task to activate                    */
6752 /*                                                                        */
6753 /*  OUTPUT                                                                */
6754 /*                                                                        */
6755 /*    None                            If successful                       */
6756 /*    Error Code.                     If an error occurs                  */
6757 /*                                                                        */
6758 /*  CALLS                                                                 */
6759 /*                                                                        */
6760 /*    osek_internal_error             Internal error                      */
6761 /*    tx_thread_terminate             Terminate the thread                */
6762 /*    tx_thread_create                Create the thread                   */
6763 /*    osek_reset_tcb                  Free the task control block         */
6764 /*                                                                        */
6765 /*  CALLED BY                                                             */
6766 /*                                                                        */
6767 /*    OSEK only (internal)                                                */
6768 /*                                                                        */
6769 /*  RELEASE HISTORY                                                       */
6770 /*                                                                        */
6771 /*    DATE              NAME                      DESCRIPTION             */
6772 /*                                                                        */
6773 /*  06-02-2021     William E. Lamie         Initial Version 6.1.7         */
6774 /*                                                                        */
6775 /**************************************************************************/
osek_do_task_terminate(OSEK_TCB * tcb_ptr)6776 static StatusType osek_do_task_terminate(OSEK_TCB  *tcb_ptr)
6777 {
6778 TX_INTERRUPT_SAVE_AREA
6779 UINT                  retval;
6780 TX_THREAD            *thread_ptr;
6781 UINT                  priority;
6782 
6783 
6784     /* Converts OSEK into ThreadX.  */
6785     priority = osek_remap_priority(tcb_ptr->org_prio);
6786 
6787     /* Make the current threshold as original priority.  */
6788     tcb_ptr->cur_threshold = tcb_ptr->org_prio;
6789 
6790     /* Get the ThreadX thread pointer.  */
6791     thread_ptr = (TX_THREAD *)tcb_ptr;
6792 
6793     /* Terminate the task's thread.  */
6794     retval = tx_thread_terminate(thread_ptr);
6795 
6796     /* See if every thing is fine.  */
6797     if (retval != TX_SUCCESS)
6798     {
6799         /* System internal error.  */
6800         osek_internal_error(THREADX_THREAD_TERMINATE_TERMINATETASK);
6801 
6802         /* Error will be returned whenever the ThreadX call fails.  */
6803         return (E_OS_SYSTEM);
6804     }
6805 
6806     TX_DISABLE
6807 
6808     /* Delete the ThreadX thread.  */
6809     retval = tx_thread_delete(thread_ptr);
6810 
6811     /* Check if everything is fine.  */
6812     if (retval != TX_SUCCESS)
6813     {
6814         /* System internal error.  */
6815         osek_internal_error(THREADX_THREAD_DELETE_TERMINATETASK);
6816 
6817         /* Error will be returned whenever the ThreadX call fails.  */
6818         return (E_OS_SYSTEM);
6819     }
6820 
6821 
6822     if (tcb_ptr->current_active != 0u)
6823     {
6824         /* Decrement the activation count.  */
6825         tcb_ptr->current_active--;
6826     }
6827 
6828     /* Now check if there is any activations pending?  */
6829     if (tcb_ptr->current_active == 0u)
6830     {
6831         /* If no activations pending then make this task SUSPENDED.  */
6832         tcb_ptr->suspended = TX_TRUE;
6833     }
6834 
6835     TX_RESTORE
6836 
6837     tcb_ptr->waiting = TX_FALSE;
6838 
6839     /* Create ThreadX thread.  */
6840     retval = tx_thread_create(thread_ptr,
6841                               (char *)tcb_ptr->name,
6842                               osek_task_wrapper,
6843                               (ULONG)tcb_ptr,
6844                               tcb_ptr->pStackBase,
6845                               tcb_ptr->stack_size,
6846                               priority,
6847                               priority,
6848                               TX_NO_TIME_SLICE,
6849                               TX_DONT_START);
6850 
6851     /* See if ThreadX encountered an error.  */
6852     if (retval != TX_SUCCESS)
6853     {
6854         /* Free the task TCB structure.  */
6855         osek_reset_tcb(tcb_ptr);
6856 
6857         /* Internal error */
6858         osek_internal_error(THREADX_OBJECT_CREATION_ERROR);
6859 
6860         /* Error will be returned whenever the ThreadX call fails.  */
6861         return (E_OS_SYSTEM);
6862     }
6863 
6864     /* Everything is OK. */
6865     return (E_OK);
6866 }
6867 
6868 
6869 /**************************************************************************/
6870 /*                                                                        */
6871 /*  FUNCTION                                               RELEASE        */
6872 /*                                                                        */
6873 /*    osek_do_activate_task                               PORTABLE C      */
6874 /*                                                           6.1.7        */
6875 /*  AUTHOR                                                                */
6876 /*                                                                        */
6877 /*    William E. Lamie, Microsoft Corporation                             */
6878 /*                                                                        */
6879 /*  DESCRIPTION                                                           */
6880 /*                                                                        */
6881 /*    This function activates the specified task.                         */
6882 /*                                                                        */
6883 /*  INPUT                                                                 */
6884 /*                                                                        */
6885 /*    *tcb_ptr                        task to activate                    */
6886 /*                                                                        */
6887 /*  OUTPUT                                                                */
6888 /*                                                                        */
6889 /*    None                            If successful                       */
6890 /*    Error Code.                     If an error occurs.                 */
6891 /*                                                                        */
6892 /*  CALLS                                                                 */
6893 /*                                                                        */
6894 /*    osek_internal_error             Internal error                      */
6895 /*    tx_thread_resume                Activate  the thread                */
6896 /*                                                                        */
6897 /*  CALLED BY                                                             */
6898 /*                                                                        */
6899 /*    OSEK only (internal)                                                */
6900 /*                                                                        */
6901 /*  RELEASE HISTORY                                                       */
6902 /*                                                                        */
6903 /*    DATE              NAME                      DESCRIPTION             */
6904 /*                                                                        */
6905 /*  06-02-2021     William E. Lamie         Initial Version 6.1.7         */
6906 /*                                                                        */
6907 /**************************************************************************/
osek_do_activate_task(OSEK_TCB * tcb_ptr)6908 static StatusType osek_do_activate_task (OSEK_TCB  *tcb_ptr)
6909 {
6910 TX_INTERRUPT_SAVE_AREA
6911     /*  Activate a task means making it READY and place into the TASK READY queue.  */
6912 
6913     TX_DISABLE
6914     /* Increment current multiple activation count.  */
6915     tcb_ptr->current_active++ ;
6916 
6917     /* Move this task from suspended state to ready state.  */
6918     tcb_ptr->suspended = TX_FALSE;
6919 
6920     /* And add to the queue as a newest member.  */
6921     add_task_to_table(tcb_ptr);
6922 
6923     TX_RESTORE;
6924 
6925     return (E_OK);
6926 }
6927 
6928 
6929 /**************************************************************************/
6930 /*                                                                        */
6931 /*  FUNCTION                                               RELEASE        */
6932 /*                                                                        */
6933 /*  osek_thread2tcb                                      PORTABLE C       */
6934 /*                                                           6.1.7        */
6935 /*  AUTHOR                                                                */
6936 /*                                                                        */
6937 /*    William E. Lamie, Microsoft Corporation                             */
6938 /*                                                                        */
6939 /*  DESCRIPTION                                                           */
6940 /*                                                                        */
6941 /*  This function returns a ThreadX thread pointer to an OSEK task        */
6942 /*  pointer.                                                              */
6943 /*                                                                        */
6944 /*  INPUT                                                                 */
6945 /*                                                                        */
6946 /*    thread                         Thread pointer                       */
6947 /*                                                                        */
6948 /*  OUTPUT                                                                */
6949 /*                                                                        */
6950 /*    *tcb                           TCB pointer                          */
6951 /*                                   On error a null pointer is returned  */
6952 /*                                                                        */
6953 /*  CALLS                                                                 */
6954 /*                                                                        */
6955 /*    None                                                                */
6956 /*                                                                        */
6957 /*  CALLED BY                                                             */
6958 /*                                                                        */
6959 /*    Internal Code                                                       */
6960 /*                                                                        */
6961 /*  RELEASE HISTORY                                                       */
6962 /*                                                                        */
6963 /*    DATE              NAME                      DESCRIPTION             */
6964 /*                                                                        */
6965 /*  06-02-2021     William E. Lamie         Initial Version 6.1.7         */
6966 /*                                                                        */
6967 /**************************************************************************/
osek_thread2tcb(TX_THREAD * thread_ptr)6968 static OSEK_TCB  *osek_thread2tcb(TX_THREAD *thread_ptr)
6969 {
6970 
6971 OSEK_TCB   *tcb;
6972 
6973     /* Make sure we were called from a thread.  */
6974     if (thread_ptr == TX_NULL)
6975     {
6976         /* Communicate error by means of a NULL pointer.  */
6977         return ((OSEK_TCB *)0u);
6978     }
6979 
6980     /* We can do this because the Thread information is intentionally
6981        located as the first field in the structure.  */
6982     tcb = (OSEK_TCB *)thread_ptr;
6983 
6984     /* All done.  */
6985     return (tcb);
6986 }
6987 
6988 
6989 /**************************************************************************/
6990 /*                                                                        */
6991 /*  FUNCTION                                               RELEASE        */
6992 /*                                                                        */
6993 /*    osek_task_independent_area                          PORTABLE C      */
6994 /*                                                           6.1.7        */
6995 /*  AUTHOR                                                                */
6996 /*                                                                        */
6997 /*    William E. Lamie, Microsoft Corporation                             */
6998 /*                                                                        */
6999 /*  DESCRIPTION                                                           */
7000 /*                                                                        */
7001 /*    This function determines if the system is currently in a thread     */
7002 /*    context, i.e. not timer routine, not ISR, not idling,               */
7003 /*    not in initialization phase.                                        */
7004 /*                                                                        */
7005 /*  INPUT                                                                 */
7006 /*                                                                        */
7007 /*    None                                                                */
7008 /*                                                                        */
7009 /*  OUTPUT                                                                */
7010 /*                                                                        */
7011 /*    TX_TRUE                       If in task area                       */
7012 /*    TX_FALSE                      If not in task area                   */
7013 /*                                                                        */
7014 /*  CALLS                                                                 */
7015 /*                                                                        */
7016 /*    None                                                                */
7017 /*                                                                        */
7018 /*  CALLED BY                                                             */
7019 /*                                                                        */
7020 /*    osek internal code                                                  */
7021 /*                                                                        */
7022 /*  RELEASE HISTORY                                                       */
7023 /*                                                                        */
7024 /*    DATE              NAME                      DESCRIPTION             */
7025 /*                                                                        */
7026 /*  06-02-2021     William E. Lamie         Initial Version 6.1.7         */
7027 /*                                                                        */
7028 /**************************************************************************/
osek_task_independent_area(void)7029 static ULONG  osek_task_independent_area(void)
7030 {
7031 
7032     if (osek_init_state != OSEK_STARTED)
7033     {
7034 
7035         /* We are calling from initialization, return FALSE.  */
7036         return (TX_FALSE);
7037     }
7038     else if ((_tx_thread_current_ptr == TX_NULL) ||         /* Not in a thread.  */
7039              (_tx_thread_system_state != 0u) ||             /* In an ISR.  */
7040              (_tx_thread_current_ptr == &_tx_timer_thread)) /* Timer routine.  */
7041 
7042     {
7043         /* We are NOT in thread (task) context.  */
7044         return (TX_FALSE);
7045     }
7046     else
7047     {
7048         /* We ARE in thread (task) context.  */
7049         return (TX_TRUE);
7050     }
7051 }
7052 
7053 
7054 /**************************************************************************/
7055 /*                                                                        */
7056 /*  FUNCTION                                               RELEASE        */
7057 /*                                                                        */
7058 /*    osek_create_task                                    PORTABLE C      */
7059 /*                                                           6.1.7        */
7060 /*  AUTHOR                                                                */
7061 /*                                                                        */
7062 /*    William E. Lamie, Microsoft Corporation                             */
7063 /*                                                                        */
7064 /*  DESCRIPTION                                                           */
7065 /*                                                                        */
7066 /*    This function creates an OSEK task under ThreadX.                   */
7067 /*                                                                        */
7068 /*  INPUT                                                                 */
7069 /*                                                                        */
7070 /*    tcb_ptr                               Task control block pointer    */
7071 /*                                                                        */
7072 /*  OUTPUT                                                                */
7073 /*                                                                        */
7074 /*    E_OK                                  If successful                 */
7075 /*    E_OS_SYSTEM                           If failure                    */
7076 /*                                                                        */
7077 /*  CALLS                                                                 */
7078 /*                                                                        */
7079 /*    osek_tcb2thread                       Convert TCB to thread         */
7080 /*    tx_thread_create                      Create thread                 */
7081 /*    osek_reset_tcb                        OSEK free task control block  */
7082 /*    add_task_to_table                     Add this task to queue        */
7083 /*                                                                        */
7084 /*  CALLED BY                                                             */
7085 /*                                                                        */
7086 /*    OSEK only (internal)                                                */
7087 /*                                                                        */
7088 /*  RELEASE HISTORY                                                       */
7089 /*                                                                        */
7090 /*    DATE              NAME                      DESCRIPTION             */
7091 /*                                                                        */
7092 /*  06-02-2021     William E. Lamie         Initial Version 6.1.7         */
7093 /*                                                                        */
7094 /**************************************************************************/
osek_create_task(OSEK_TCB * tcb_ptr)7095 static StatusType osek_create_task(OSEK_TCB * tcb_ptr)
7096 {
7097 
7098 TX_INTERRUPT_SAVE_AREA
7099 
7100 UINT                  retval;
7101 UINT                  priority;
7102 
7103 TX_DISABLE
7104 
7105    /* Converts OSEK priority into ThreadX. In ThreadX '0' is highest priority and '31' is the lowest
7106        while in OSEK it is exactly the opposite.  */
7107 
7108    priority = osek_remap_priority(tcb_ptr->org_prio);
7109 
7110    /* Create a ThreadX thread, osek_task_wrapper is the entry function which is common for all thread
7111       implementing an OSEK task to differentiate which task we supply 'task id' as an input for
7112       thread entry function.  */
7113 
7114     retval = tx_thread_create ( &(tcb_ptr->task),
7115                                  (char *)tcb_ptr->name,
7116                                  osek_task_wrapper,
7117                                  (ULONG)tcb_ptr,
7118                                  tcb_ptr->pStackBase,
7119                                  tcb_ptr->stack_size,
7120                                  priority,
7121                                  priority,
7122                                  TX_NO_TIME_SLICE,
7123                                  TX_DONT_START);       /* All threads implementing an OSEK TASK are created in SUSPENDED state.  */
7124 
7125     /* Check for any error.  */
7126     if (retval != TX_SUCCESS)
7127     {
7128         /* Free the task tcb structure.  */
7129         osek_reset_tcb(tcb_ptr);
7130 
7131         /* Internal error.  */
7132         osek_internal_error(THREADX_OBJECT_CREATION_ERROR);
7133 
7134         /* Error will be returned whenever the ThreadX call fails.  */
7135         retval = E_OS_SYSTEM;
7136     }
7137     else
7138     {
7139         /* Got the thread, now check AUTO START Specified for this task.  */
7140         /* If the task is not specified as 'AUTO RUN' then it is not in 'READY' State,
7141            so won't be added to task queue at this stage.  */
7142 
7143         if (tcb_ptr->task_autostart == TRUE)
7144         {
7145             /* With AUTO START the task will attain READY state
7146                the moment it is created, whether it will execute (RUN) will depend on Scheduler.  */
7147 
7148             tcb_ptr->suspended = TX_FALSE;
7149 
7150             /* As this task will be in Ready immediately after creation its
7151                Current activation counter must be increment to 1 from 0.  */
7152             tcb_ptr->current_active = 1u;
7153 
7154             /* Now add this task to Schedulers 'READY' task queue.  */
7155             add_task_to_table(tcb_ptr);
7156         }
7157 
7158         /* Everything is fine.  */
7159         retval = E_OK;
7160     }
7161 
7162 
7163 TX_RESTORE
7164 
7165     return(retval);
7166 }
7167 
7168 
7169 /**************************************************************************/
7170 /*                                                                        */
7171 /*  FUNCTION                                               RELEASE        */
7172 /*                                                                        */
7173 /*    osek_allocate_tcb                                   PORTABLE C      */
7174 /*                                                           6.1.7        */
7175 /*  AUTHOR                                                                */
7176 /*                                                                        */
7177 /*    William E. Lamie, Microsoft Corporation                             */
7178 /*                                                                        */
7179 /*  DESCRIPTION                                                           */
7180 /*                                                                        */
7181 /*    This function attempts to allocate memory for a task stack and an   */
7182 /*    OSEK Thread Control Block (TCB).                                    */
7183 /*                                                                        */
7184 /*  INPUT                                                                 */
7185 /*                                                                        */
7186 /*    stack_size                            Requested task stack size     */
7187 /*    tcb_ptr                               Pointer to tcb pointer        */
7188 /*                                                                        */
7189 /*  OUTPUT                                                                */
7190 /*                                                                        */
7191 /*    TX_TRUE                               If successful.                */
7192 /*    TX_FALSE                              If an error occurs.           */
7193 /*                                                                        */
7194 /*  CALLS                                                                 */
7195 /*                                                                        */
7196 /*    osek_memory_allocate                   Allocate task's stack        */
7197 /*    osek_reset_tcb                         Free task control block      */
7198 /*                                                                        */
7199 /*  CALLED BY                                                             */
7200 /*                                                                        */
7201 /*    OSEK internal code                                                  */
7202 /*                                                                        */
7203 /*  RELEASE HISTORY                                                       */
7204 /*                                                                        */
7205 /*    DATE              NAME                      DESCRIPTION             */
7206 /*                                                                        */
7207 /*  06-02-2021     William E. Lamie         Initial Version 6.1.7         */
7208 /*                                                                        */
7209 /**************************************************************************/
osek_allocate_tcb(ULONG stack_size,OSEK_TCB ** tcb_ptr)7210 static ULONG osek_allocate_tcb(ULONG stack_size, OSEK_TCB **tcb_ptr)
7211 {
7212 OSEK_TCB         * tcb;
7213 ULONG             index;
7214 ULONG             retval;
7215 
7216     /* Assume the worst.  */
7217     tcb = (OSEK_TCB *)TX_NULL;
7218 
7219     /* This next search is optimized for simplicity, not speed.  */
7220     tcb = osek_tcb_pool;
7221     for (index = 0u; index < OSEK_MAX_TASKS; index++)
7222     {
7223         /* Is thisTCB in use? If not, we can use it.  */
7224         if (tcb->tcb_in_use == TX_FALSE)
7225         {
7226             /* This TCB is now in use.  */
7227             tcb->tcb_in_use = TX_TRUE;
7228 
7229             /* Stop searching.  */
7230             break;
7231         }
7232 
7233         tcb++;
7234     } /* try next TCB.  */
7235 
7236     /* Did we search all TCBs and come up empty?  */
7237     if (index == OSEK_MAX_TASKS)
7238     {
7239         /* No more TCBs available - user configuration error.  */
7240         return(E_OS_SYS_STACK);
7241     }
7242     else
7243     {
7244         /* Found one.  */
7245         *tcb_ptr = tcb;
7246     }
7247 
7248     /* Reset stack pointer.  */
7249     tcb->pStackBase  = (CHAR *)TX_NULL;
7250 
7251     /* Allocate memory for the task stack.  */
7252     retval = osek_memory_allocate(stack_size,
7253                               ((void **)&(tcb->pStackBase)));
7254 
7255     /* Make sure we got the memory for the task stack.  */
7256     if ((retval == 0u) || (tcb->pStackBase == TX_NULL))
7257     {
7258         /* Failed - at least try to return the OSEK TCB memory.  */
7259         osek_reset_tcb(tcb);
7260 
7261         /* Indicate failure.  */
7262         return (E_OS_SYS_STACK);
7263     }
7264 
7265     /* Remember the size of the stack.  */
7266     tcb->stack_size  = stack_size;
7267 
7268     /* Return OSEK TCB to caller.  */
7269     return (TX_TRUE);
7270 }
7271 
7272 
7273 /**************************************************************************/
7274 /*                                                                        */
7275 /*  FUNCTION                                               RELEASE        */
7276 /*                                                                        */
7277 /*    osek_memory_allocate                                PORTABLE C      */
7278 /*                                                           6.1.7        */
7279 /*  AUTHOR                                                                */
7280 /*                                                                        */
7281 /*    William E. Lamie, Microsoft Corporation                             */
7282 /*                                                                        */
7283 /*  DESCRIPTION                                                           */
7284 /*                                                                        */
7285 /*    This function attempts to obtain the specified amount of memory     */
7286 /*    from the OSEK heap.                                                 */
7287 /*                                                                        */
7288 /*  INPUT                                                                 */
7289 /*                                                                        */
7290 /*    size                                  Number of bytes to allocate   */
7291 /*    memory_ptr                            Pointer to the returned       */
7292 /*                                          memory                        */
7293 /*                                                                        */
7294 /*  OUTPUT                                                                */
7295 /*                                                                        */
7296 /*    TX_TRUE                               If successful                 */
7297 /*    TX_FALSE                              If an error occurs            */
7298 /*                                                                        */
7299 /*  CALLS                                                                 */
7300 /*                                                                        */
7301 /*    tx_byte_allocate                      Allocate from the pool        */
7302 /*                                                                        */
7303 /*  CALLED BY                                                             */
7304 /*                                                                        */
7305 /*    OSEK internal code                                                  */
7306 /*                                                                        */
7307 /*  RELEASE HISTORY                                                       */
7308 /*                                                                        */
7309 /*    DATE              NAME                      DESCRIPTION             */
7310 /*                                                                        */
7311 /*  06-02-2021     William E. Lamie         Initial Version 6.1.7         */
7312 /*                                                                        */
7313 /**************************************************************************/
osek_memory_allocate(ULONG size,void ** memory_ptr)7314 static UINT osek_memory_allocate(ULONG size, void  **memory_ptr)
7315 {
7316 ULONG   size_align;
7317 UINT    retval;
7318 
7319    /* Initialize the pointer to NULL in case we fail.  */
7320    *memory_ptr = (void *)TX_NULL;
7321 
7322    /* Force all alignments to long word boundaries to be safe.  */
7323    size_align = size;
7324    if ((size_align) != 0u)
7325    {
7326        /* Bump size up to next 4 byte boundary.  */
7327        size_align = ((size_align + 0x03u) & ~0x03u);
7328    }
7329 
7330    /* Attempt to allocate the desired memory from the OSEK heap.  */
7331    /* Do not wait - if memory isn't available, flag an error.  */
7332    retval = tx_byte_allocate((TX_BYTE_POOL *)&osek_region0_byte_pool, memory_ptr,
7333            size_align, TX_NO_WAIT);
7334 
7335    /* Make sure the memory was obtained successfully.  */
7336    if(retval != TX_SUCCESS)
7337    {
7338        /* Error obtaining memory.  */
7339        return (TX_FALSE);
7340    }
7341 
7342    /* Return to caller.  */
7343    return (TX_TRUE);
7344 }
7345 
7346 
7347 /**************************************************************************/
7348 /*                                                                        */
7349 /*  FUNCTION                                               RELEASE        */
7350 /*                                                                        */
7351 /*    osek_reset_tcb                                      PORTABLE C      */
7352 /*                                                           6.1.7        */
7353 /*  AUTHOR                                                                */
7354 /*                                                                        */
7355 /*    William E. Lamie, Microsoft Corporation                             */
7356 /*                                                                        */
7357 /*  DESCRIPTION                                                           */
7358 /*                                                                        */
7359 /*    This function resets a task TCB to its default state.               */
7360 /*                                                                        */
7361 /*  INPUT                                                                 */
7362 /*                                                                        */
7363 /*    tcb                                   Task control block pointer    */
7364 /*                                                                        */
7365 /*  OUTPUT                                                                */
7366 /*                                                                        */
7367 /*    None                                                                */
7368 /*                                                                        */
7369 /*  CALLS                                                                 */
7370 /*                                                                        */
7371 /*    None                                                                */
7372 /*                                                                        */
7373 /*  CALLED BY                                                             */
7374 /*                                                                        */
7375 /*    Start-up code                                                       */
7376 /*                                                                        */
7377 /*  RELEASE HISTORY                                                       */
7378 /*                                                                        */
7379 /*    DATE              NAME                      DESCRIPTION             */
7380 /*                                                                        */
7381 /*  06-02-2021     William E. Lamie         Initial Version 6.1.7         */
7382 /*                                                                        */
7383 /**************************************************************************/
osek_reset_tcb(OSEK_TCB * tcb_ptr)7384 static void osek_reset_tcb(OSEK_TCB  *tcb_ptr)
7385 {
7386 TX_INTERRUPT_SAVE_AREA
7387 
7388 UINT  index;
7389 
7390    /* Disable interrupt.  */
7391    TX_DISABLE
7392 
7393    /* Indicate this TCB is not in use.  */
7394    tcb_ptr->tcb_in_use = TX_FALSE;
7395 
7396    /* Make suspended and waiting to FALSE.  */
7397    tcb_ptr->suspended = TX_TRUE;
7398    tcb_ptr->waiting = TX_FALSE;
7399 
7400    /* Make this task as BASIC.  */
7401    tcb_ptr->task_type = BASIC;
7402 
7403    /* No AUTOSTART */
7404    tcb_ptr->task_autostart = 0u;
7405 
7406    /* Erase TCB id */
7407    tcb_ptr->osek_task_id = 0u;
7408 
7409    /* Make original priority of the task to 0 (the lowest possible).  */
7410    tcb_ptr->org_prio = 0u;
7411 
7412    /* Set the thread preemption threshold to default.  */
7413    tcb_ptr->cur_threshold = THREADX_LOWEST_PRIORITY;
7414 
7415    /* Make the stack size to 0.  */
7416    tcb_ptr->stack_size = 0u;
7417 
7418    /* No task to chain.  */
7419    tcb_ptr->task_to_chain = 0u;
7420 
7421    /* Since now event is not attached Make it to TX_NULL.  */
7422    tcb_ptr->events = 0u;
7423 
7424    /* Make task entry function to TX_NULL.  */
7425    tcb_ptr->task_entry = TX_NULL;
7426 
7427    /* Make maximum activation to 0.  */
7428    tcb_ptr->max_active = 0u;
7429 
7430    /* Make current activation to 0.  */
7431    tcb_ptr->current_active = 0u;
7432 
7433    /* Clear lists for external Resource attached and Resource occupied.  */
7434    for (index = 0u; index < OSEK_MAX_EXTERNAL_RES; index++)
7435    {
7436        tcb_ptr->external_resource_list[index] = 0u;
7437        tcb_ptr->external_resource_occuplied_list[index] = 0u;
7438    }
7439 
7440    /* Clear lists for Internal Resource attached and resource occupied.  */
7441    for (index = 0u; index < OSEK_MAX_INTERNAL_RES; index++)
7442    {
7443        tcb_ptr->internal_resource_list[index] = 0u;
7444        tcb_ptr->internal_resource_occuplied_list[index] = 0u;
7445    }
7446 
7447    /* Since resource is not occupied make it to FALSE.  */
7448    tcb_ptr->res_ocp = 0u;
7449 
7450    /* All done. */
7451 
7452    /* Enable interrupt.  */
7453    TX_RESTORE
7454 
7455    return;
7456 }
7457 
7458 
7459 /**************************************************************************/
7460 /*                                                                        */
7461 /*  FUNCTION                                               RELEASE        */
7462 /*                                                                        */
7463 /*    osek_get_resource                                   PORTABLE C      */
7464 /*                                                           6.1.7        */
7465 /*  AUTHOR                                                                */
7466 /*                                                                        */
7467 /*    William E. Lamie, Microsoft Corporation                             */
7468 /*                                                                        */
7469 /*  DESCRIPTION                                                           */
7470 /*                                                                        */
7471 /*    This function finds if any resource is available in the pool.       */
7472 /*                                                                        */
7473 /*  INPUT                                                                 */
7474 /*                                                                        */
7475 /*    tcb                              Task control block pointer         */
7476 /*                                                                        */
7477 /*  OUTPUT                                                                */
7478 /*                                                                        */
7479 /*    res_ptr                          Resource pointer OR null           */
7480 /*                                                                        */
7481 /*  CALLS                                                                 */
7482 /*                                                                        */
7483 /*    None                                                                */
7484 /*                                                                        */
7485 /*  CALLED BY                                                             */
7486 /*                                                                        */
7487 /*    Start-up code                                                       */
7488 /*                                                                        */
7489 /*  RELEASE HISTORY                                                       */
7490 /*                                                                        */
7491 /*    DATE              NAME                      DESCRIPTION             */
7492 /*                                                                        */
7493 /*  06-02-2021     William E. Lamie         Initial Version 6.1.7         */
7494 /*                                                                        */
7495 /**************************************************************************/
osek_get_resource(void)7496 static ResourceType osek_get_resource(void)
7497 {
7498 TX_INTERRUPT_SAVE_AREA
7499 ULONG             index;
7500 OSEK_RESOURCE     *res_ptr;
7501 
7502     TX_DISABLE
7503 
7504    /* Start out pessimistic - assume we won't find a match.  */
7505    res_ptr = (OSEK_RESOURCE *)TX_NULL;
7506 
7507    /* Search the resource from resource pool.  */
7508    res_ptr = &(osek_res_pool[0u]);
7509    for (index = 0u; index < OSEK_MAX_RES; index++)
7510    {
7511        /* Make sure the resource is not already in use.  */
7512        if (res_ptr->res_in_use == TX_FALSE)
7513        {
7514            /* This Resource is now in use.  */
7515            res_ptr->res_in_use = TX_TRUE;
7516            break;
7517        }
7518 
7519        res_ptr++;
7520    }
7521 
7522    TX_RESTORE
7523 
7524    /* Did we search all OSEK RESOURCES and come up empty?  */
7525    if (index == OSEK_MAX_RES)
7526    {
7527        return ((ResourceType) TX_NULL);
7528    }
7529 
7530    return ((ResourceType) res_ptr);
7531 }
7532 
7533 
7534 /**************************************************************************/
7535 /*                                                                        */
7536 /*  FUNCTION                                               RELEASE        */
7537 /*                                                                        */
7538 /*  osek_get_alarm                                        PORTABLE C      */
7539 /*                                                           6.1.7        */
7540 /*  AUTHOR                                                                */
7541 /*                                                                        */
7542 /*    William E. Lamie, Microsoft Corporation                             */
7543 /*                                                                        */
7544 /*  DESCRIPTION                                                           */
7545 /*                                                                        */
7546 /*    This function gets an alarm if it is available.                     */
7547 /*                                                                        */
7548 /*  INPUT                                                                 */
7549 /*                                                                        */
7550 /*    NONE                                                                */
7551 /*                                                                        */
7552 /*  OUTPUT                                                                */
7553 /*                                                                        */
7554 /*    ALARM_ID             AlarmID if found                               */
7555 /*    TX_FALSE             If not available                               */
7556 /*                                                                        */
7557 /*  CALLS                                                                 */
7558 /*                                                                        */
7559 /*    NONE                                                                */
7560 /*                                                                        */
7561 /*  CALLED BY                                                             */
7562 /*                                                                        */
7563 /*  API function.                                                         */
7564 /*                                                                        */
7565 /*  RELEASE HISTORY                                                       */
7566 /*                                                                        */
7567 /*    DATE              NAME                      DESCRIPTION             */
7568 /*                                                                        */
7569 /*  06-02-2021     William E. Lamie         Initial Version 6.1.7         */
7570 /*                                                                        */
7571 /**************************************************************************/
osek_get_alarm(void)7572 static UINT   osek_get_alarm(void)
7573 {
7574 TX_INTERRUPT_SAVE_AREA
7575 OSEK_ALARM        *this_alarm;
7576 UINT              index;
7577 
7578     TX_DISABLE
7579 
7580    /* Assume the worst.  */
7581    this_alarm = (OSEK_ALARM *)TX_NULL;
7582 
7583    /* Search for a free alarm.  */
7584    this_alarm = osek_alarm_pool;
7585 
7586    for (index = 0u;
7587         index < OSEK_MAX_ALARMS;
7588         index++)
7589    {
7590        /* Is this alarm in use? If not, we can use it.  */
7591        if (this_alarm->alarm_in_use == TX_FALSE)
7592        {
7593            /* This alarm is now in use.  */
7594            this_alarm->alarm_in_use = TX_TRUE;
7595 
7596            /* Stop searching.  */
7597            break;
7598        }
7599 
7600        this_alarm++;
7601    } /* check next if this one is in use.  */
7602 
7603    TX_RESTORE
7604 
7605    /* Did we search alarms all and come up empty?  */
7606    if (index == OSEK_MAX_ALARMS)
7607    {
7608        /* No more alarms available - user configuration error.  */
7609        return ((AlarmType)0u);
7610    }
7611 
7612    /* Found one.  */
7613 
7614    return ((AlarmType) this_alarm);
7615 }
7616 
7617 
7618 /**************************************************************************/
7619 /*                                                                        */
7620 /*  FUNCTION                                               RELEASE        */
7621 /*                                                                        */
7622 /*  osek_get_events                                       PORTABLE C      */
7623 /*                                                           6.1.7        */
7624 /*  AUTHOR                                                                */
7625 /*                                                                        */
7626 /*    William E. Lamie, Microsoft Corporation                             */
7627 /*                                                                        */
7628 /*  DESCRIPTION                                                           */
7629 /*                                                                        */
7630 /*    This function gets events if it is available in the pool.           */
7631 /*                                                                        */
7632 /*  INPUT                                                                 */
7633 /*                                                                        */
7634 /*    NONE                                                                */
7635 /*                                                                        */
7636 /*  OUTPUT                                                                */
7637 /*                                                                        */
7638 /*    COUNTER_ID           CounterID if found                             */
7639 /*    TX_FALSE             if not available                               */
7640 /*                                                                        */
7641 /*  CALLS                                                                 */
7642 /*                                                                        */
7643 /*    NONE                                                                */
7644 /*                                                                        */
7645 /*  CALLED BY                                                             */
7646 /*                                                                        */
7647 /*    API function                                                        */
7648 /*                                                                        */
7649 /*  RELEASE HISTORY                                                       */
7650 /*                                                                        */
7651 /*    DATE              NAME                      DESCRIPTION             */
7652 /*                                                                        */
7653 /*  06-02-2021     William E. Lamie         Initial Version 6.1.7         */
7654 /*                                                                        */
7655 /**************************************************************************/
osek_get_event(void)7656 static EventMaskType  osek_get_event(void)
7657 {
7658 TX_INTERRUPT_SAVE_AREA
7659 EventMaskType     event_mask;
7660 
7661     TX_DISABLE
7662 
7663    if (global_event_count >= OSEK_MAX_EVENTS)
7664    {
7665        TX_RESTORE
7666 
7667        /* Already alloted all possible events.  */
7668        return ((EventMaskType)0u);
7669    }
7670 
7671    /* Next event.  */
7672    event_mask = 1u;
7673    event_mask <<= global_event_count;
7674    global_event_count++;
7675 
7676    TX_RESTORE
7677 
7678    return (event_mask);
7679 }
7680 
7681 
7682 /**************************************************************************/
7683 /*                                                                        */
7684 /*  FUNCTION                                               RELEASE        */
7685 /*                                                                        */
7686 /*  osek_get_alarm                                        PORTABLE C      */
7687 /*                                                           6.1.7        */
7688 /*  AUTHOR                                                                */
7689 /*                                                                        */
7690 /*    William E. Lamie, Microsoft Corporation                             */
7691 /*                                                                        */
7692 /*  DESCRIPTION                                                           */
7693 /*                                                                        */
7694 /*    This function gets an alarm if it is available.                     */
7695 /*                                                                        */
7696 /*  INPUT                                                                 */
7697 /*                                                                        */
7698 /*    NONE                                                                */
7699 /*                                                                        */
7700 /*  OUTPUT                                                                */
7701 /*                                                                        */
7702 /*    COUNTER_ID           CounterID if found                             */
7703 /*    TX_FALSE             If not available                               */
7704 /*                                                                        */
7705 /*  CALLS                                                                 */
7706 /*                                                                        */
7707 /*    NONE                                                                */
7708 /*                                                                        */
7709 /*  CALLED BY                                                             */
7710 /*                                                                        */
7711 /*    API function                                                        */
7712 /*                                                                        */
7713 /*  RELEASE HISTORY                                                       */
7714 /*                                                                        */
7715 /*    DATE              NAME                      DESCRIPTION             */
7716 /*                                                                        */
7717 /*  06-02-2021     William E. Lamie         Initial Version 6.1.7         */
7718 /*                                                                        */
7719 /**************************************************************************/
osek_get_counter(void)7720 static CounterType   osek_get_counter(void)
7721 {
7722 TX_INTERRUPT_SAVE_AREA
7723 OSEK_COUNTER       *this_counter;
7724 UINT               index;
7725 
7726     TX_DISABLE
7727 
7728    /* Assume the worst.  */
7729    this_counter = (OSEK_COUNTER *)TX_NULL;
7730 
7731    /* Search for a free counter.  */
7732    this_counter = osek_counter_pool;
7733    for ( index = 0u;
7734          index < OSEK_MAX_COUNTERS;
7735          index++)
7736    {
7737        /* Is this guy in use? If not, we can use it.  */
7738        if (this_counter->cntr_in_use == TX_FALSE)
7739        {
7740            /* This counter is now in use.  */
7741            this_counter->cntr_in_use = TX_TRUE;
7742            /* Stop searching.  */
7743            break;
7744        }
7745 
7746        this_counter++;
7747    } /* Try next counter.  */
7748 
7749    TX_RESTORE
7750 
7751    /* Did we search all OSEK COUNTERS and come up empty?  */
7752    if (index >= OSEK_MAX_COUNTERS)
7753    {
7754        /* No more Counters available - user configuration error.  */
7755        return ((CounterType) E_OS_SYS_STACK);
7756    }
7757 
7758    /* Found one.  */
7759    return ((CounterType)this_counter);
7760 }
7761 
7762 
7763 /**************************************************************************/
7764 /*                                                                        */
7765 /*  FUNCTION                                               RELEASE        */
7766 /*                                                                        */
7767 /*    osek_system_timer_entry                             PORTABLE C      */
7768 /*                                                           6.1.7        */
7769 /*  AUTHOR                                                                */
7770 /*                                                                        */
7771 /*    William E. Lamie, Microsoft Corporation                             */
7772 /*                                                                        */
7773 /*  DESCRIPTION                                                           */
7774 /*                                                                        */
7775 /*   This wrapper acts as a system timer and maintains a system counter   */
7776 /*   It is up to the user to assign any one of the OSEK counter as        */
7777 /*   a system counter by defining it.                                     */
7778 /*   This counter will then be updated by this system timer.              */
7779 /*                                                                        */
7780 /*  INPUT                                                                 */
7781 /*                                                                        */
7782 /*    input                             Not used                          */
7783 /*                                                                        */
7784 /*  OUTPUT                                                                */
7785 /*                                                                        */
7786 /*    None                                                                */
7787 /*                                                                        */
7788 /*  CALLS                                                                 */
7789 /*                                                                        */
7790 /*  CALLED BY                                                             */
7791 /*                                                                        */
7792 /*    OSEK system timer expiry function                                   */
7793 /*                                                                        */
7794 /*  RELEASE HISTORY                                                       */
7795 /*                                                                        */
7796 /*    DATE              NAME                      DESCRIPTION             */
7797 /*                                                                        */
7798 /*  06-02-2021     William E. Lamie         Initial Version 6.1.7         */
7799 /*                                                                        */
7800 /**************************************************************************/
osek_system_timer_entry(ULONG input)7801 static void osek_system_timer_entry(ULONG input)
7802 {
7803 TX_INTERRUPT_SAVE_AREA
7804 OSEK_COUNTER      *this_counter;
7805 UINT               index;
7806 UINT               found;
7807 
7808     TX_DISABLE
7809 
7810     (void)&input; /* Prevent unused parameter warnings.  */
7811 
7812    found = TX_FALSE;
7813    /* Search for a counter acting as a system counter.  */
7814    this_counter = osek_counter_pool;
7815    for ( index = 0u;
7816          index < OSEK_MAX_COUNTERS;
7817          index++)
7818    {
7819        /* Is this guy in a system counter.  */
7820        if (this_counter->system_timer == TX_TRUE)
7821        {
7822            /* Got system counter.  */
7823            found = TX_TRUE;
7824            /* Stop searching.  */
7825            break;
7826        }
7827 
7828        this_counter++;
7829    } /* Try next counter.  */
7830 
7831    /* Did we search all OSEK COUNTERS and come up empty?  */
7832    if (found == TX_TRUE)
7833    {
7834        /* Got a system counter, update it.  */
7835        IncrCounter((CounterType)this_counter);
7836    }
7837 
7838    TX_RESTORE
7839 
7840    return;
7841 }
7842 
7843 
7844 /**************************************************************************/
7845 /*                                                                        */
7846 /*  FUNCTION                                               RELEASE        */
7847 /*                                                                        */
7848 /*    osek_remap_priority                                 PORTABLE C      */
7849 /*                                                           6.1.7        */
7850 /*  AUTHOR                                                                */
7851 /*                                                                        */
7852 /*    William E. Lamie, Microsoft Corporation                             */
7853 /*                                                                        */
7854 /*  DESCRIPTION                                                           */
7855 /*                                                                        */
7856 /*    This function converts a OSEK task priority into a ThreadX          */
7857 /*    priority.                                                           */
7858 /*                                                                        */
7859 /*  INPUT                                                                 */
7860 /*                                                                        */
7861 /*    osek_priority                       Priority of task                */
7862 /*                                                                        */
7863 /*  OUTPUT                                                                */
7864 /*                                                                        */
7865 /*    ThreadX priority                    Converted priority              */
7866 /*                                                                        */
7867 /*  CALLS                                                                 */
7868 /*                                                                        */
7869 /*    None                                                                */
7870 /*                                                                        */
7871 /*  CALLED BY                                                             */
7872 /*                                                                        */
7873 /*    OSEK internal code                                                  */
7874 /*                                                                        */
7875 /*  RELEASE HISTORY                                                       */
7876 /*                                                                        */
7877 /*    DATE              NAME                      DESCRIPTION             */
7878 /*                                                                        */
7879 /*  06-02-2021     William E. Lamie         Initial Version 6.1.7         */
7880 /*                                                                        */
7881 /**************************************************************************/
osek_remap_priority(UINT osek_priority)7882 static UINT osek_remap_priority(UINT osek_priority)
7883 {
7884 
7885    /* Remap OSEK task priority to ThreadX thread priority.              */
7886    /* In OSEK 0 = lowest priority and in ThreadX, 0 = highest priority, */
7887    /* Means ThreadX priority of a thread acting as a OSEK Task          */
7888    /* would be ThreadX max priority - osek_priority.                    */
7889 
7890    /* Return the ThreadX priority.  */
7891    return (THREADX_MAX_PRIORITY - 1u - osek_priority);
7892 }
7893 
7894 
7895 /**************************************************************************/
7896 /*                                                                        */
7897 /*  FUNCTION                                               RELEASE        */
7898 /*                                                                        */
7899 /*    osek_task_wrapper                                   PORTABLE C      */
7900 /*                                                           6.1.7        */
7901 /*  AUTHOR                                                                */
7902 /*                                                                        */
7903 /*    William E. Lamie, Microsoft Corporation                             */
7904 /*                                                                        */
7905 /*  DESCRIPTION                                                           */
7906 /*                                                                        */
7907 /*    Every thread that is modeling a OSEK task uses this routine has     */
7908 /*    its entry point. This routine calls the OSEK task entry function.   */
7909 /*                                                                        */
7910 /*    A task must end with either TerminateTask() or ChainTask(), if this */
7911 /*    is not the way a task is ended, the control will come back to this  */
7912 /*    osek_task_wrapper and call osek_internal_error() with an error code */
7913 /*    'TASK_ENDING_WITHOUT_CHAIN_OR_TERMINATE'.                           */
7914 /*                                                                        */
7915 /*  INPUT                                                                 */
7916 /*                                                                        */
7917 /*    tcb                                Task control block pointer       */
7918 /*                                                                        */
7919 /*  OUTPUT                                                                */
7920 /*                                                                        */
7921 /*    None                                                                */
7922 /*                                                                        */
7923 /*  CALLS                                                                 */
7924 /*                                                                        */
7925 /*    task_entry                         OSEK task entry                  */
7926 /*    osek_internal_error                                                 */
7927 /*                                                                        */
7928 /*  CALLED BY                                                             */
7929 /*                                                                        */
7930 /*    Internal code                                                       */
7931 /*                                                                        */
7932 /*  RELEASE HISTORY                                                       */
7933 /*                                                                        */
7934 /*    DATE              NAME                      DESCRIPTION             */
7935 /*                                                                        */
7936 /*  06-02-2021     William E. Lamie         Initial Version 6.1.7         */
7937 /*                                                                        */
7938 /**************************************************************************/
osek_task_wrapper(ULONG tcb)7939 static void osek_task_wrapper(ULONG tcb)
7940 {
7941 TX_INTERRUPT_SAVE_AREA
7942 OSEK_TCB        *tcb_ptr;
7943 StatusType      status;
7944 
7945     TX_DISABLE
7946 
7947    /* The input argument is really a pointer to the task's TCB.  */
7948    tcb_ptr = (OSEK_TCB *)tcb;
7949    /* Check whether it is a Task or an ISR.  */
7950    if (tcb_ptr->osek_task_id == OSEK_TASK_ID)
7951    {
7952        osek_wrapper_operation_mode = NORMAL_EXECUTION_MODE;
7953 
7954        /* last_run_task now holds this new task being run.  */
7955        last_run_task = (ULONG)((TX_THREAD*)tcb_ptr);
7956 
7957        /* Check this task's scheduling policy.  */
7958        if (tcb_ptr->policy == NON)
7959        {
7960            pop_task_from_table(tcb_ptr);   /* This routine remove task from table based on its cur_threshold.  */
7961 
7962            /* Store the new preemption threshold.  */
7963            tcb_ptr->cur_threshold = OSEK_NON_SCHEDULE_PRIORITY;
7964 
7965            /* Place this task to its proper priority queue based on Scheduling policy.  */
7966            push_task_to_table(tcb_ptr);       /* This routine pushes a task at the front of a queue based on its cur_threshold.  */
7967        }
7968 
7969    }
7970    else
7971    {
7972        if (tcb_ptr->task_type == CATEGORY1)
7973        {
7974                osek_wrapper_operation_mode = ISR1_MODE;
7975        }
7976        else
7977        {
7978                osek_wrapper_operation_mode = ISR2_MODE;
7979        }
7980    }
7981 
7982    TX_RESTORE
7983 
7984    /* Invoke the OSEK task entry point with appropriate arguments.  */
7985    (tcb_ptr->task_entry)();
7986 
7987    /* In case of a task we shouldn't be here- because tasks are always ended with either
7988       a TerminateTask() or ChainTask() but ISR will return here.  */
7989    /* If it is a TASK then seems to be ended without any ChainTask or TerminateTask call
7990       anyway, as the task is ended it is better to Terminate it so that next available ready
7991       task can be run.  */
7992 
7993 
7994    /* Terminate the task.  */
7995    if (tcb_ptr->osek_task_id == OSEK_TASK_ID)
7996    {
7997        /* Change to default operations mode.  */
7998        osek_wrapper_operation_mode = NORMAL_EXECUTION_MODE;
7999 
8000        status = TerminateTask();
8001        if(status != E_OK) {
8002            osek_internal_error(SYS_MGR_SEND_TERMINATETASK);
8003        }
8004    }
8005    else
8006    {
8007        status = TerminateISR();
8008        if(status != E_OK) {
8009            osek_internal_error(SYS_MGR_SEND_TERMINATETASK);
8010        }
8011    }
8012 }
8013 
8014 
8015 /**************************************************************************/
8016 /*                                                                        */
8017 /*  FUNCTION                                               RELEASE        */
8018 /*                                                                        */
8019 /*    osek_internal_error                                  PORTABLE C     */
8020 /*                                                           6.1.7        */
8021 /*  AUTHOR                                                                */
8022 /*                                                                        */
8023 /*    William E. Lamie, Microsoft Corporation                             */
8024 /*                                                                        */
8025 /*  DESCRIPTION                                                           */
8026 /*                                                                        */
8027 /*    This function is invoked whenever an error is encountered           */
8028 /*    in the OSEK code. This is an endless loop.                          */
8029 /*    Source of the error can be traced by the error code.                */
8030 /*                                                                        */
8031 /*  INPUT                                                                 */
8032 /*                                                                        */
8033 /*    error_code                            Error code                    */
8034 /*                                                                        */
8035 /*  OUTPUT                                                                */
8036 /*                                                                        */
8037 /*    None                                                                */
8038 /*                                                                        */
8039 /*  CALLS                                                                 */
8040 /*                                                                        */
8041 /*    None                                                                */
8042 /*                                                                        */
8043 /*  CALLED BY                                                             */
8044 /*                                                                        */
8045 /*    OSEK internal code                                                  */
8046 /*                                                                        */
8047 /*  RELEASE HISTORY                                                       */
8048 /*                                                                        */
8049 /*    DATE              NAME                      DESCRIPTION             */
8050 /*                                                                        */
8051 /*  06-02-2021     William E. Lamie         Initial Version 6.1.7         */
8052 /*                                                                        */
8053 /**************************************************************************/
osek_internal_error(ULONG error_code)8054 static void osek_internal_error(ULONG error_code)
8055 {
8056    /* This just an end less loop, to trap error.  */
8057    for(;;)
8058    {
8059        ; /* Empty loop.  */
8060    }
8061 }
8062 
8063 
8064 /**************************************************************************/
8065 /*                                                                        */
8066 /*  FUNCTION                                               RELEASE        */
8067 /*                                                                        */
8068 /*    exec_ErrorHook                                       PORTABLE C     */
8069 /*                                                           6.1.7        */
8070 /*  AUTHOR                                                                */
8071 /*                                                                        */
8072 /*    William E. Lamie, Microsoft Corporation                             */
8073 /*                                                                        */
8074 /*  DESCRIPTION                                                           */
8075 /*                                                                        */
8076 /*    This function invokes ErroHook routine whenever an error is         */
8077 /*    encountered, provided ErroHook is defined.                          */
8078 /*    Hook routines are called by the operating system, in a special      */
8079 /*    context have higher prior than all tasks, and not interrupted by    */
8080 /*    category 2 interrupt routines.                                      */
8081 /*    These functions are implemented by the user with user defined       */
8082 /*    functionality. Usually hook routines are allowed to use only a      */
8083 /*    subset of API functions. Whether to execute these routine or not is */
8084 /*    user configurable via OIL.                                          */
8085 /*                                                                        */
8086 /*  INPUT                                                                 */
8087 /*                                                                        */
8088 /*    error_code                            Passed to ErrorHook           */
8089 /*                                                                        */
8090 /*  OUTPUT                                                                */
8091 /*                                                                        */
8092 /*    None                                                                */
8093 /*                                                                        */
8094 /*  CALLS                                                                 */
8095 /*                                                                        */
8096 /*    Application->error_handler          That is ErrorHook (if defined)  */
8097 /*                                                                        */
8098 /*  CALLED BY                                                             */
8099 /*                                                                        */
8100 /*    OSEK internal code                                                  */
8101 /*                                                                        */
8102 /*  RELEASE HISTORY                                                       */
8103 /*                                                                        */
8104 /*    DATE              NAME                      DESCRIPTION             */
8105 /*                                                                        */
8106 /*  06-02-2021     William E. Lamie         Initial Version 6.1.7         */
8107 /*                                                                        */
8108 /**************************************************************************/
exec_ErrorHook(StatusType error)8109 static void  exec_ErrorHook (StatusType error)
8110 {
8111 
8112 TX_THREAD     *thread_ptr;
8113 UINT           save_op_mode;
8114 UINT           status;
8115 ULONG          request[SYSMGR_QUEUE_MSG_LENGTH];
8116 
8117    /* Check for any startup hook routine.  */
8118    if (Application->error_hook_handler != TX_NULL)
8119    {
8120        /* But check whether already in ErrorHook routine? There must not be nested ErrorHook calls.  */
8121        if (osek_wrapper_operation_mode == ERRORHOOK_MODE)
8122        {
8123            /* Already in ErroHook.  */
8124            return;
8125        }
8126 
8127        /* Save old operation mode.  */
8128        save_op_mode = osek_wrapper_operation_mode;
8129 
8130        /* Change to ErroHOOK mode.  */
8131        osek_wrapper_operation_mode = ERRORHOOK_MODE;
8132 
8133        /* Now execute user defined ErroHook routine.  */
8134        (Application->error_hook_handler)(error);
8135 
8136        /* Get the pointer to thread.  */
8137        thread_ptr = tx_thread_identify();
8138 
8139        /* Restore original operation mode.  */
8140        osek_wrapper_operation_mode = save_op_mode;
8141 
8142        /* If this ErrorHook is called by a task then check for any ISR came while executing this ErrorHook.  */
8143        if (osek_wrapper_operation_mode == NORMAL_EXECUTION_MODE)
8144        {
8145            /* Now send a message to the SysMgr supervisor thread to execute the Error Hook.  */
8146            /* Build the request. */
8147            request[0] = SYSMGR_ERRORHOOK;           /* Request type.            */
8148            request[1] = (ULONG)thread_ptr;          /* ptr of calling thread.   */
8149            request[2] = 0u;                         /* input to Error Hook.     */
8150            request[3] = 0u;
8151 
8152            /* Since the system manager supervisor thread is with the highest priority,  */
8153            /* this routine will be preempted by SysMgr supervisor thread when   */
8154            /* queue read is successful.                                         */
8155 
8156            status = tx_queue_send(&osek_work_queue, request, TX_NO_WAIT);
8157 
8158            /* This should always succeed.  */
8159            if (status != TX_SUCCESS)
8160            {
8161                /* System internal error.  */
8162                osek_internal_error(SYS_MGR_SEND_CHAINTASK);
8163 
8164                /* Return.  */
8165                return;
8166            }
8167        }  /* End if ( osek_wrapper_operation_mode ==.  */
8168 
8169    } /* end  if (Application->error_handler).  */
8170 
8171     return;
8172 }
8173 
8174 
8175 /**************************************************************************/
8176 /*                                                                        */
8177 /*  FUNCTION                                               RELEASE        */
8178 /*                                                                        */
8179 /*    exec_PreTaskHook                                    PORTABLE C      */
8180 /*                                                           6.1.7        */
8181 /*  AUTHOR                                                                */
8182 /*                                                                        */
8183 /*    William E. Lamie, Microsoft Corporation                             */
8184 /*                                                                        */
8185 /*  DESCRIPTION                                                           */
8186 /*                                                                        */
8187 /*    This function invokes the PreTaskHook routine whenever a task       */
8188 /*    starts provided PreTaskHook is defined.                             */
8189 /*                                                                        */
8190 /*  INPUT                                                                 */
8191 /*                                                                        */
8192 /*    None                                                                */
8193 /*                                                                        */
8194 /*  OUTPUT                                                                */
8195 /*                                                                        */
8196 /*    None                                                                */
8197 /*                                                                        */
8198 /*  CALLS                                                                 */
8199 /*                                                                        */
8200 /*    None                                                                */
8201 /*                                                                        */
8202 /*  CALLED BY                                                             */
8203 /*                                                                        */
8204 /*    OSEK internal code                                                  */
8205 /*                                                                        */
8206 /*  RELEASE HISTORY                                                       */
8207 /*                                                                        */
8208 /*    DATE              NAME                      DESCRIPTION             */
8209 /*                                                                        */
8210 /*  06-02-2021     William E. Lamie         Initial Version 6.1.7         */
8211 /*                                                                        */
8212 /**************************************************************************/
exec_PreTaskHook(void)8213 static void  exec_PreTaskHook(void)
8214 {
8215 
8216 UINT           save_op_mode;
8217 
8218    if (Application->pretask_hook_handler != TX_NULL)
8219    {
8220        /* Set up the mode.  */
8221        save_op_mode = osek_wrapper_operation_mode;
8222        osek_wrapper_operation_mode = PRETASKHOOK_MODE;
8223 
8224        /* Call the Pretask hook.  */
8225        (Application->pretask_hook_handler)();
8226 
8227        /* Restore mode.  */
8228        osek_wrapper_operation_mode = save_op_mode;
8229 
8230    }  /* end  if (Application->PretaskHook_handler).  */
8231 
8232     return;
8233 }
8234 
8235 
8236 /**************************************************************************/
8237 /*                                                                        */
8238 /*  FUNCTION                                               RELEASE        */
8239 /*                                                                        */
8240 /*    exec_PostTaskHook                                    PORTABLE C     */
8241 /*                                                           6.1.7        */
8242 /*  AUTHOR                                                                */
8243 /*                                                                        */
8244 /*    William E. Lamie, Microsoft Corporation                             */
8245 /*                                                                        */
8246 /*  DESCRIPTION                                                           */
8247 /*                                                                        */
8248 /*    This function invokes PostTaskHook routine whenever a task          */
8249 /*    terminates provided PostTaskHook is defined.                        */
8250 /*                                                                        */
8251 /*  INPUT                                                                 */
8252 /*                                                                        */
8253 /*    None                                                                */
8254 /*                                                                        */
8255 /*  OUTPUT                                                                */
8256 /*                                                                        */
8257 /*    None                                                                */
8258 /*                                                                        */
8259 /*  CALLS                                                                 */
8260 /*                                                                        */
8261 /*    None                                                                */
8262 /*                                                                        */
8263 /*  CALLED BY                                                             */
8264 /*                                                                        */
8265 /*    OSEK internal code                                                  */
8266 /*                                                                        */
8267 /*  RELEASE HISTORY                                                       */
8268 /*                                                                        */
8269 /*    DATE              NAME                      DESCRIPTION             */
8270 /*                                                                        */
8271 /*  06-02-2021     William E. Lamie         Initial Version 6.1.7         */
8272 /*                                                                        */
8273 /**************************************************************************/
exec_PostTaskHook(void)8274 static void  exec_PostTaskHook(void)
8275 {
8276 
8277 UINT           sav_op_mode;
8278 
8279    if (Application->posttask_hook_handler != TX_NULL)
8280    {
8281        /* Set up the mode.  */
8282        sav_op_mode = osek_wrapper_operation_mode;
8283        osek_wrapper_operation_mode = POSTTASKHOOK_MODE;
8284 
8285        /* Call the Posttask hook.  */
8286        (Application->posttask_hook_handler)();
8287 
8288        /* Restore mode.  */
8289        osek_wrapper_operation_mode = sav_op_mode;
8290 
8291     }  /* end  if (Application->PosttaskHook_handler).  */
8292 
8293     return;
8294 }
8295 
8296 
8297 /**************************************************************************/
8298 /*                                                                        */
8299 /*  FUNCTION                                               RELEASE        */
8300 /*                                                                        */
8301 /*    add_task_to_table                                   PORTABLE C      */
8302 /*                                                           6.1.7        */
8303 /*  AUTHOR                                                                */
8304 /*                                                                        */
8305 /*    William E. Lamie, Microsoft Corporation                             */
8306 /*                                                                        */
8307 /*  DESCRIPTION                                                           */
8308 /*                                                                        */
8309 /*    This function adds a ready task in the task queue.                  */
8310 /*                                                                        */
8311 /*  INPUT                                                                 */
8312 /*                                                                        */
8313 /*    *tcb_ptr              Pointer to the task to be added to the queue  */
8314 /*                                                                        */
8315 /*  OUTPUT                                                                */
8316 /*                                                                        */
8317 /*    None                                                                */
8318 /*                                                                        */
8319 /*  CALLS                                                                 */
8320 /*                                                                        */
8321 /*    None                                                                */
8322 /*                                                                        */
8323 /*  CALLED BY                                                             */
8324 /*                                                                        */
8325 /*    OSEK internal code                                                  */
8326 /*                                                                        */
8327 /*  RELEASE HISTORY                                                       */
8328 /*                                                                        */
8329 /*    DATE              NAME                      DESCRIPTION             */
8330 /*                                                                        */
8331 /*  06-02-2021     William E. Lamie         Initial Version 6.1.7         */
8332 /*                                                                        */
8333 /**************************************************************************/
add_task_to_table(OSEK_TCB * tcb_ptr)8334 static void  add_task_to_table(OSEK_TCB *tcb_ptr)
8335 {
8336 TX_INTERRUPT_SAVE_AREA
8337 UINT         priority;
8338 UINT         i;
8339 
8340     TX_DISABLE
8341 
8342    /* Get the priority of this task.  */
8343    priority = tcb_ptr-> org_prio;
8344 
8345    for (i = 0u; i < TASK_QUEUE_DEPTH; i++)
8346    {
8347        /* Add this task to the a queue assigned for this task's priority level.  */
8348        /* Find next free entry in the queue.  */
8349        /* Oldest activated task is at the front of the queue, so this new entry.  */
8350        /* will go at the end of the queue.  */
8351 
8352        if (task_table[priority][i] == 0u)
8353        {
8354            task_table[priority][i] = (TaskType)tcb_ptr;
8355            break;
8356        }
8357    }
8358 
8359    if (i >= TASK_QUEUE_DEPTH)
8360    {
8361        osek_internal_error(SYSMGR_FATAL_ERROR);
8362    }
8363 
8364    TX_RESTORE
8365 
8366 }
8367 
8368 
8369 /**************************************************************************/
8370 /*                                                                        */
8371 /*  FUNCTION                                               RELEASE        */
8372 /*                                                                        */
8373 /*    push_task_to_table                                   PORTABLE C     */
8374 /*                                                           6.1.7        */
8375 /*  AUTHOR                                                                */
8376 /*                                                                        */
8377 /*    William E. Lamie, Microsoft Corporation                             */
8378 /*                                                                        */
8379 /*  DESCRIPTION                                                           */
8380 /*                                                                        */
8381 /*    This function pushes a task at the front of the task queue.         */
8382 /*                                                                        */
8383 /*  INPUT                                                                 */
8384 /*                                                                        */
8385 /*    *tcb_ptr              Pointer to the task to be added to the queue  */
8386 /*                                                                        */
8387 /*  OUTPUT                                                                */
8388 /*                                                                        */
8389 /*    None                                                                */
8390 /*                                                                        */
8391 /*  CALLS                                                                 */
8392 /*                                                                        */
8393 /*    None                                                                */
8394 /*                                                                        */
8395 /*  CALLED BY                                                             */
8396 /*                                                                        */
8397 /*    OSEK internal code                                                  */
8398 /*                                                                        */
8399 /*  RELEASE HISTORY                                                       */
8400 /*                                                                        */
8401 /*    DATE              NAME                      DESCRIPTION             */
8402 /*                                                                        */
8403 /*  06-02-2021     William E. Lamie         Initial Version 6.1.7         */
8404 /*                                                                        */
8405 /**************************************************************************/
push_task_to_table(OSEK_TCB * tcb_ptr)8406 static void   push_task_to_table(OSEK_TCB *tcb_ptr)
8407 {
8408 TX_INTERRUPT_SAVE_AREA
8409 UINT    priority;
8410 UINT    i;
8411 UINT    k;
8412 
8413     TX_DISABLE
8414 
8415    priority = tcb_ptr->cur_threshold;
8416 
8417    i = (TASK_QUEUE_DEPTH - 2u);
8418 
8419    while (i != 0u)
8420    {
8421        /* Add this task to the queue (of for priority level supplied).  */
8422        /* Place the entry at the front of the queue and push back all entries by one */
8423        k = i + 1u;
8424        task_table[priority][k] = task_table[priority][i];
8425        i--;
8426    }
8427 
8428    task_table[priority][1u] = task_table[priority][0u];
8429 
8430    /* Now push the calling task's id  at the front of the queue.  */
8431    task_table[priority][0u] = (ULONG)tcb_ptr;
8432 
8433    TX_RESTORE
8434 }
8435 
8436 
8437 /**************************************************************************/
8438 /*                                                                        */
8439 /*  FUNCTION                                               RELEASE        */
8440 /*                                                                        */
8441 /*    start_osek_tasks                                     PORTABLE C     */
8442 /*                                                           6.1.7        */
8443 /*  AUTHOR                                                                */
8444 /*                                                                        */
8445 /*    William E. Lamie, Microsoft Corporation                             */
8446 /*                                                                        */
8447 /*  DESCRIPTION                                                           */
8448 /*                                                                        */
8449 /*    This function schedules the first task upon StatOS                  */
8450 /*                                                                        */
8451 /*  INPUT                                                                 */
8452 /*                                                                        */
8453 /*    None                                                                */
8454 /*                                                                        */
8455 /*  OUTPUT                                                                */
8456 /*                                                                        */
8457 /*    Error Code                                                          */
8458 /*                                                                        */
8459 /*  CALLS                                                                 */
8460 /*                                                                        */
8461 /*    tx_thread_resume                                                    */
8462 /*                                                                        */
8463 /*  CALLED BY                                                             */
8464 /*                                                                        */
8465 /*    osek_system_manager_entry                                           */
8466 /*                                                                        */
8467 /*  RELEASE HISTORY                                                       */
8468 /*                                                                        */
8469 /*    DATE              NAME                      DESCRIPTION             */
8470 /*                                                                        */
8471 /*  06-02-2021     William E. Lamie         Initial Version 6.1.7         */
8472 /*                                                                        */
8473 /**************************************************************************/
start_osek_tasks(void)8474 static void start_osek_tasks(void)
8475 {
8476 TX_INTERRUPT_SAVE_AREA
8477 TX_THREAD  *task_thread;
8478 UINT       i;
8479 UINT       j;
8480 UINT       found;
8481 
8482     TX_DISABLE
8483 
8484    /* Start with the highest priority */
8485    j = OSEK_ISR1_PRIORITY;
8486    found = FALSE;
8487 
8488    while (found == FALSE)
8489    {
8490        for (i = 0u; i < TASK_QUEUE_DEPTH; i++)
8491        {
8492            /* Search for any ready but not waiting task within this priority level.  */
8493            if (( task_table[j][i] != 0u) && (((OSEK_TCB*)task_table[j][i] )->waiting == TX_FALSE))
8494            {
8495                /* Found it but check whether this task can be run,
8496                   This task must have higher priority than current task's ceiling priority
8497                   This task must have all needed Internal/External resources.  */
8498                task_thread = &((OSEK_TCB*)task_table[j][i])->task;
8499                found = check_task_to_run((OSEK_TCB*)task_table[j][i]);
8500                if (found == TRUE)
8501                {
8502                    break;
8503                }
8504            }
8505 
8506        }
8507 
8508        /* No ready task found for this priority level, check for next lower priority level
8509           but are we at the lowest priority level?  */
8510        if ((j == 0u) || (found == TRUE))
8511        {
8512            break;
8513        }
8514 
8515        j--;
8516 
8517    } /* End while.  */
8518 
8519    /* Reached here means either a ready Task is found or no task is READY.  */
8520    /* if found = 1, task is found.  */
8521 
8522    if (found == FALSE)
8523    {
8524        last_run_task = INVALID_TASK;
8525    }
8526    else
8527    {
8528        if (((OSEK_TCB*)task_thread)->osek_task_id == OSEK_ISR_ID)
8529        {
8530        /* If it is an ISR , set the op mode and no need to:
8531           call pre and post task hooks as well as change last_run_task data.  */
8532           osek_wrapper_operation_mode = ISR2_MODE;
8533        }
8534        else
8535        {
8536            osek_wrapper_operation_mode = NORMAL_EXECUTION_MODE;
8537            /* Check whether it is a fresh OS start, for fresh start no need to run pre & post task hooks.  */
8538            if (system_start == 0u)
8539            {
8540                /* If no preemption takes place , then no need to execute pre and post task hooks.  */
8541                if ((last_run_task != (ULONG)task_thread )|| (task_terminated == TX_TRUE))
8542                {
8543                    exec_PostTaskHook();
8544 
8545                    /* Update last run task data to reflect next task to run.  */
8546                    last_run_task = (ULONG)task_thread;
8547 
8548                    exec_PreTaskHook();
8549                }
8550 
8551            }
8552 
8553            last_run_task = (ULONG)task_thread;
8554        } /* End else. */
8555 
8556        tx_thread_resume(task_thread);
8557 
8558        system_start = TX_FALSE;
8559 
8560        task_terminated = TX_FALSE;
8561 
8562    } /* end of else part of if (!found).  */
8563 
8564    TX_RESTORE
8565 }
8566 
8567 
8568 /**************************************************************************/
8569 /*                                                                        */
8570 /*  FUNCTION                                               RELEASE        */
8571 /*                                                                        */
8572 /*    check_task_to_run                                    PORTABLE C     */
8573 /*                                                           6.1.7        */
8574 /*  AUTHOR                                                                */
8575 /*                                                                        */
8576 /*    William E. Lamie, Microsoft Corporation                             */
8577 /*                                                                        */
8578 /*  DESCRIPTION                                                           */
8579 /*                                                                        */
8580 /*    This function schedules the first task upon StatOS                  */
8581 /*    This is called by system manager thread when StartOS is called.     */
8582 /*                                                                        */
8583 /*  INPUT                                                                 */
8584 /*                                                                        */
8585 /*    None                                                                */
8586 /*                                                                        */
8587 /*  OUTPUT                                                                */
8588 /*                                                                        */
8589 /*    Error Code                                                          */
8590 /*                                                                        */
8591 /*  CALLS                                                                 */
8592 /*                                                                        */
8593 /*    tx_thread_resume                                                    */
8594 /*                                                                        */
8595 /*  CALLED BY                                                             */
8596 /*                                                                        */
8597 /*    osek_system_manager_entry                                           */
8598 /*                                                                        */
8599 /*  RELEASE HISTORY                                                       */
8600 /*                                                                        */
8601 /*    DATE              NAME                      DESCRIPTION             */
8602 /*                                                                        */
8603 /*  06-02-2021     William E. Lamie         Initial Version 6.1.7         */
8604 /*                                                                        */
8605 /**************************************************************************/
check_task_to_run(OSEK_TCB * tcb_ptr)8606 static UINT check_task_to_run (OSEK_TCB *tcb_ptr)
8607 {
8608 TX_INTERRUPT_SAVE_AREA
8609    UINT     status;
8610 
8611     TX_DISABLE
8612 
8613    if (tcb_ptr->osek_task_id != OSEK_TASK_ID)
8614    {
8615        /* if selection is an ISR,
8616           it can't be run if ISRs are suspended or any HOOK mode is ON.  */
8617        if ((suspend_ISR2 == TX_TRUE) ||
8618            (osek_wrapper_operation_mode == ERRORHOOK_MODE)      ||
8619            (osek_wrapper_operation_mode == PRETASKHOOK_MODE)    ||
8620            (osek_wrapper_operation_mode == POSTTASKHOOK_MODE)   ||
8621            (osek_wrapper_operation_mode == STARTUPHOOK_MODE)    ||
8622            (osek_wrapper_operation_mode == SHUTDOWNHOOK_MODE)   ||
8623            (osek_wrapper_operation_mode == ALARM_CALLBACK_MODE))
8624        {
8625            TX_RESTORE
8626 
8627            return (FALSE);
8628        }
8629    }
8630 
8631    if (tcb_ptr->internal_res != 0u)
8632    {
8633        status = get_internal_resource(tcb_ptr);
8634 
8635        if (status != E_OK)
8636        {
8637            TX_RESTORE
8638 
8639            return (FALSE);
8640        }
8641    }
8642 
8643    status = check_external_resource(tcb_ptr);
8644    if (status != E_OK)
8645    {
8646        TX_RESTORE
8647 
8648        return (FALSE);
8649    }
8650 
8651    /* Now check for NON scheduling policy.  */
8652    if (tcb_ptr->policy == NON)
8653    {
8654        /* First remove task from its current queue position.  */
8655        pop_task_from_table(tcb_ptr);
8656 
8657        tcb_ptr->cur_threshold = OSEK_NON_SCHEDULE_PRIORITY;
8658 
8659        push_task_to_table(tcb_ptr);
8660    }
8661 
8662    TX_RESTORE
8663 
8664    return (TRUE);
8665 }
8666 
8667 
8668 /**************************************************************************/
8669 /*                                                                        */
8670 /*  FUNCTION                                               RELEASE        */
8671 /*                                                                        */
8672 /*    pop_task_from_table                                 PORTABLE C      */
8673 /*                                                           6.1.7        */
8674 /*  AUTHOR                                                                */
8675 /*                                                                        */
8676 /*    William E. Lamie, Microsoft Corporation                             */
8677 /*                                                                        */
8678 /*  DESCRIPTION                                                           */
8679 /*    Removes a task from the table of active tasks.                      */
8680 /*                                                                        */
8681 /*  INPUT                                                                 */
8682 /*                                                                        */
8683 /*    id                           Id of the resource.                    */
8684 /*                                                                        */
8685 /*  OUTPUT                                                                */
8686 /*                                                                        */
8687 /*                                                                        */
8688 /*  CALLS                                                                 */
8689 /*                                                                        */
8690 /*                                                                        */
8691 /*  CALLED BY                                                             */
8692 /*                                                                        */
8693 /*   Application Code                                                     */
8694 /*                                                                        */
8695 /*  RELEASE HISTORY                                                       */
8696 /*                                                                        */
8697 /*    DATE              NAME                      DESCRIPTION             */
8698 /*                                                                        */
8699 /*  06-02-2021     William E. Lamie         Initial Version 6.1.7         */
8700 /*                                                                        */
8701 /**************************************************************************/
pop_task_from_table(OSEK_TCB * tcb_ptr)8702 static void  pop_task_from_table(OSEK_TCB *tcb_ptr)
8703 {
8704 TX_INTERRUPT_SAVE_AREA
8705 UINT         priority;
8706 UINT         i;
8707 UINT         j;
8708 UINT         k;
8709 
8710     TX_DISABLE
8711 
8712    /* Get the priority of this task.  */
8713    priority = tcb_ptr-> cur_threshold;
8714    j = (TASK_QUEUE_DEPTH - 2u);
8715    for (i = 0u; i < j; i++)
8716    {
8717        /* Move N+1 th element to Nth location.  */
8718        /* Oldest task is at the bottom of the queue.  */
8719        k = i + 1u;
8720        task_table[priority][i] = task_table[priority][k];
8721    }
8722 
8723    /* Make the top most element in the queue NULL as the oldest task is removed from the bottom.  */
8724    j = (TASK_QUEUE_DEPTH) - 1u;
8725    task_table[priority][j] = 0u;
8726 
8727    TX_RESTORE
8728 }
8729 
8730 
8731 /**************************************************************************/
8732 /*                                                                        */
8733 /*  FUNCTION                                               RELEASE        */
8734 /*                                                                        */
8735 /*    check_linked_resources                              PORTABLE C      */
8736 /*                                                           6.1.7        */
8737 /*  AUTHOR                                                                */
8738 /*                                                                        */
8739 /*    William E. Lamie, Microsoft Corporation                             */
8740 /*                                                                        */
8741 /*  DESCRIPTION                                                           */
8742 /*                                                                        */
8743 /*   Check if resources are linked                                        */
8744 /*                                                                        */
8745 /*  CALLED BY                                                             */
8746 /*                                                                        */
8747 /*   Application Code                                                     */
8748 /*                                                                        */
8749 /*  RELEASE HISTORY                                                       */
8750 /*                                                                        */
8751 /*    DATE              NAME                      DESCRIPTION             */
8752 /*                                                                        */
8753 /*  06-02-2021     William E. Lamie         Initial Version 6.1.7         */
8754 /*                                                                        */
8755 /**************************************************************************/
check_linked_resources(void)8756 static void        check_linked_resources(void)
8757 {
8758 TX_INTERRUPT_SAVE_AREA
8759 ULONG              index;
8760 OSEK_RESOURCE     *res_ptr;
8761 OSEK_RESOURCE     *linked_res_ptr;
8762 
8763     TX_DISABLE
8764 
8765     /* Search the Resource from resource pool.  */
8766     for (index = 0u; index < OSEK_MAX_RES; index++)
8767     {
8768 
8769         res_ptr = &(osek_res_pool[index]);
8770         if ((res_ptr->res_in_use == TX_TRUE) && (res_ptr->type == LINKED))
8771         {
8772             /* Get the res linked to this resource.  */
8773             linked_res_ptr = (OSEK_RESOURCE *)(res_ptr->resolved_res);
8774 
8775             /* Make this resources's ceiling priority equal to the ceiling priority of linked resource.  */
8776             if ( res_ptr->c_priority < linked_res_ptr->c_priority)
8777             {
8778                 res_ptr->c_priority = linked_res_ptr->c_priority;
8779             }
8780         }
8781     }
8782 
8783     TX_RESTORE
8784 }
8785 
8786 
8787 /**************************************************************************/
8788 /*                                                                        */
8789 /*  FUNCTION                                               RELEASE        */
8790 /*                                                                        */
8791 /*    get_internal_resource                               PORTABLE C      */
8792 /*                                                           6.1.7        */
8793 /*  AUTHOR                                                                */
8794 /*                                                                        */
8795 /*    William E. Lamie, Microsoft Corporation                             */
8796 /*                                                                        */
8797 /*  DESCRIPTION                                                           */
8798 /*                                                                        */
8799 /*   This call serves to enter critical sections in the code that are     */
8800 /*   assigned to the resource referenced by <ResID>. A critical section   */
8801 /*   must always be left using ReleaseResource. Nested resource           */
8802 /*   occupation is only allowed if the inner critical sections are        */
8803 /*   completely executed within the surrounding critical section.         */
8804 /*   Nested occupation of one and the same resource is also forbidden.    */
8805 /*   Corresponding calls to GetResource and ReleaseResource should appear */
8806 /*   within the same function on the same function level.                 */
8807 /*                                                                        */
8808 /*  INPUT                                                                 */
8809 /*                                                                        */
8810 /*    id                           Id of the resource.                    */
8811 /*                                                                        */
8812 /*  OUTPUT                                                                */
8813 /*                                                                        */
8814 /*    E_OK                         If success                             */
8815 /*    E_OS_CALLEVEL                Called from ISR                        */
8816 /*    E_OS_ACCESS                  Attempt to get a resource which is     */
8817 /*                                 already occupied by any task or ISR,   */
8818 /*                                 or the statically assigned priority of */
8819 /*                                 the calling task or interrupt routine  */
8820 /*                                 is higher than the calculated ceiling  */
8821 /*                                 priority,                              */
8822 /*                                                                        */
8823 /*  CALLS                                                                 */
8824 /*                                                                        */
8825 /*    osek_task_independent_area   See if called from task independent    */
8826 /*                                 area                                   */
8827 /*    tx_thread_identify           Identify the current thread            */
8828 /*    osek_internal_error          Osek internal error                    */
8829 /*                                                                        */
8830 /*  CALLED BY                                                             */
8831 /*                                                                        */
8832 /*   Application Code                                                     */
8833 /*                                                                        */
8834 /*  RELEASE HISTORY                                                       */
8835 /*                                                                        */
8836 /*    DATE              NAME                      DESCRIPTION             */
8837 /*                                                                        */
8838 /*  06-02-2021     William E. Lamie         Initial Version 6.1.7         */
8839 /*                                                                        */
8840 /**************************************************************************/
get_internal_resource(OSEK_TCB * tcb_ptr)8841 static StatusType get_internal_resource(OSEK_TCB  *tcb_ptr)
8842 {
8843 TX_INTERRUPT_SAVE_AREA
8844 OSEK_RESOURCE  *osek_res;
8845 UINT            res_prio;
8846 UINT            index;
8847 
8848 
8849 TX_DISABLE
8850 
8851    for (index = 0u; index < OSEK_MAX_INTERNAL_RES; index++)
8852    {
8853 
8854        if (tcb_ptr->internal_resource_list[index] == 0u)
8855        {
8856            break;   /* No Internal Resource in the list.  */
8857        }
8858 
8859        /* Get internal RES's control block.  */
8860        osek_res = (OSEK_RESOURCE *)tcb_ptr->internal_resource_list[index];
8861 
8862        /* Now check whether this resource is already occupied by other task.  */
8863        if (osek_res->taskid != 0u)
8864        {
8865            /* Some entry is there, is it occupied by any other task?  */
8866            if (osek_res->taskid != (TaskType)tcb_ptr)
8867            {
8868                TX_RESTORE
8869 
8870                return (E_OS_ACCESS);
8871            }
8872        }
8873 
8874        /* Take this resource.  */
8875        tcb_ptr->internal_resource_occuplied_list[index] = tcb_ptr->internal_resource_list[index];
8876 
8877        /* Save this task's id in the res's control block to indicate that this task is the owner of this res.  */
8878        osek_res->taskid = (TaskType)(tcb_ptr);
8879 
8880    }   /* End for (index..  */
8881 
8882    /* Now all internal resources are taken, this needs to change task's preemption
8883       to highest ceiling priority of internal resource occupied.  */
8884 
8885    /* First remove task from its current queue position.  */
8886    pop_task_from_table(tcb_ptr);
8887 
8888    /* Now need to change this task's preemption threshold to resource's ceiling priority.  */
8889    /* Assume task's original priority is the highest.  */
8890    if ((tcb_ptr->resource_scheduler != 0u) || (tcb_ptr->policy == NON))
8891    {
8892        tcb_ptr->cur_threshold = OSEK_NON_SCHEDULE_PRIORITY;
8893    }
8894 
8895    for (index = 0u; index < OSEK_MAX_INTERNAL_RES; index++)
8896    {
8897        if (tcb_ptr->internal_resource_occuplied_list[index] == 0u) {
8898            break;
8899        }
8900 
8901        res_prio = ((OSEK_RESOURCE *) (tcb_ptr->internal_resource_occuplied_list[index]))->c_priority;
8902        if  (tcb_ptr->cur_threshold < res_prio )
8903        {
8904            tcb_ptr->cur_threshold = res_prio;
8905        }
8906    }
8907    /* Now the task's current threshold reflect the highest of ceiling priority of the remaining
8908       resources held by this task, move this task to the front of that priority queue.  */
8909    push_task_to_table(tcb_ptr);
8910 
8911    TX_RESTORE
8912 
8913    return (E_OK);
8914 }
8915 
8916 
8917 /**************************************************************************/
8918 /*                                                                        */
8919 /*  FUNCTION                                               RELEASE        */
8920 /*                                                                        */
8921 /*    release_internal_resource                           PORTABLE C      */
8922 /*                                                           6.1.7        */
8923 /*  AUTHOR                                                                */
8924 /*                                                                        */
8925 /*    William E. Lamie, Microsoft Corporation                             */
8926 /*                                                                        */
8927 /*  DESCRIPTION                                                           */
8928 /*                                                                        */
8929 /*   This call releases any internal resources held by the calling task.  */
8930 /*   It also changes the calling task's priority to reflect either its    */
8931 /*   original priority, NON SCHEDULE priority or maximum ceiling          */
8932 /*   priority of any any external resources held by this task.            */
8933 /*   At the end this task is then moved to a queue appropriate to its new */
8934 /*   ceiling priority.                                                    */
8935 /*                                                                        */
8936 /*  INPUT                                                                 */
8937 /*                                                                        */
8938 /*    id                           Task id.                               */
8939 /*                                                                        */
8940 /*  OUTPUT                                                                */
8941 /*                                                                        */
8942 /*    E_OK                         Always                                 */
8943 /*                                                                        */
8944 /*  CALLS                                                                 */
8945 /*                                                                        */
8946 /*   pop_task_from_table           Removes a task from its current queue  */
8947 /*   push_task_to_table            Pushes a task at the front of a queue  */
8948 /*                                                                        */
8949 /*  CALLED BY                                                             */
8950 /*                                                                        */
8951 /*   Wrapper internal code (not available for application)                */
8952 /*                                                                        */
8953 /*  RELEASE HISTORY                                                       */
8954 /*                                                                        */
8955 /*    DATE              NAME                      DESCRIPTION             */
8956 /*                                                                        */
8957 /*  06-02-2021     William E. Lamie         Initial Version 6.1.7         */
8958 /*                                                                        */
8959 /**************************************************************************/
release_internal_resource(OSEK_TCB * tcb_ptr)8960 static StatusType  release_internal_resource(OSEK_TCB  *tcb_ptr)
8961 {
8962 TX_INTERRUPT_SAVE_AREA
8963 UINT           index;
8964 
8965     TX_DISABLE
8966 
8967     /* Release any internal resources held?  */
8968     for (index = 0u; index < OSEK_MAX_INTERNAL_RES; index++)
8969     {
8970 
8971         if (tcb_ptr->internal_resource_occuplied_list[index] == 0u)
8972         {
8973              break;
8974         }
8975 
8976         ((OSEK_RESOURCE *)(tcb_ptr->internal_resource_occuplied_list[index]))->taskid = 0u;
8977 
8978         tcb_ptr->internal_resource_occuplied_list[index] = 0u;
8979     }
8980 
8981     /* First remove task from its current queue position.  */
8982     pop_task_from_table(tcb_ptr);
8983 
8984     /* As all internal resources are released and no external resources are held
8985        this task must be reverted to its original design time priority.  */
8986 
8987     tcb_ptr->cur_threshold = tcb_ptr->org_prio;
8988 
8989     /* Now move this task to the front of that priority queue.  */
8990     push_task_to_table(tcb_ptr);
8991 
8992     TX_RESTORE
8993 
8994     return (E_OK);
8995 }
8996 
8997 
8998 /**************************************************************************/
8999 /*                                                                        */
9000 /*  FUNCTION                                               RELEASE        */
9001 /*                                                                        */
9002 /*    check_external_resource                             PORTABLE C      */
9003 /*                                                           6.1.7        */
9004 /*  AUTHOR                                                                */
9005 /*                                                                        */
9006 /*    William E. Lamie, Microsoft Corporation                             */
9007 /*                                                                        */
9008 /*  DESCRIPTION                                                           */
9009 /*                                                                        */
9010 /*   This call serves to enter critical sections in the code that are     */
9011 /*   assigned to the resource referenced by <ResID>. A critical section   */
9012 /*   must always be left using releaseResource. Nested resource           */
9013 /*   occupation is only allowed if the inner critical sections are        */
9014 /*   completely executed within the surrounding critical section.         */
9015 /*   Nested occupation of one and the same resource is also forbidden.    */
9016 /*   Corresponding calls to GetResource and ReleaseResource should appear */
9017 /*   within the same function on the same function level.                 */
9018 /*                                                                        */
9019 /*  INPUT                                                                 */
9020 /*                                                                        */
9021 /*    id                           Id of the resource.                    */
9022 /*                                                                        */
9023 /*  OUTPUT                                                                */
9024 /*                                                                        */
9025 /*    E_OK                         If success                             */
9026 /*    E_OS_CALLEVEL                Called from ISR                        */
9027 /*    E_OS_ACCESS                  Attempt to get a resource which is     */
9028 /*                                 already occupied by any task or ISR,   */
9029 /*                                 or the statically assigned priority of */
9030 /*                                 the calling task or interrupt routine  */
9031 /*                                 is higher than the calculated ceiling  */
9032 /*                                 priority.                              */
9033 /*                                                                        */
9034 /*  CALLS                                                                 */
9035 /*                                                                        */
9036 /*    osek_task_independent_area   See if called from task independent    */
9037 /*                                 area                                   */
9038 /*    tx_thread_identify           Identify the current thread            */
9039 /*    osek_internal_error          OSEK internal error                    */
9040 /*                                                                        */
9041 /*  CALLED BY                                                             */
9042 /*                                                                        */
9043 /*   Application Code                                                     */
9044 /*                                                                        */
9045 /*  RELEASE HISTORY                                                       */
9046 /*                                                                        */
9047 /*    DATE              NAME                      DESCRIPTION             */
9048 /*                                                                        */
9049 /*  06-02-2021     William E. Lamie         Initial Version 6.1.7         */
9050 /*                                                                        */
9051 /**************************************************************************/
check_external_resource(OSEK_TCB * tcb_ptr)9052 static StatusType      check_external_resource(OSEK_TCB *tcb_ptr)
9053 {
9054 TX_INTERRUPT_SAVE_AREA
9055 OSEK_RESOURCE  *osek_res;
9056 OSEK_RESOURCE  *osek_res1;
9057 StatusType      status;
9058 UINT            index;
9059 
9060    /* Check that all assigned external resources for this task are free.  */
9061    /* Here only availability of resources is checked, no resource will be taken.  */
9062 
9063     TX_DISABLE
9064 
9065    status = E_OK;       /* Assuming that everything is OK.  */
9066    for (index = 0u; index < OSEK_MAX_EXTERNAL_RES; index++)
9067    {
9068 
9069        if (tcb_ptr->external_resource_list[index] == 0u)
9070        {
9071            break;    /* No External Resource left in the list.  */
9072        }
9073 
9074        /* Get External RES's control block.  */
9075        osek_res = (OSEK_RESOURCE *)tcb_ptr->external_resource_list[index];
9076 
9077        /* Now check whether this resource is already occupied by other task.  */
9078        if (osek_res->taskid != 0u)
9079        {
9080            if (osek_res->taskid != (TaskType)tcb_ptr)
9081            {
9082                status = E_OS_ACCESS; /* Already occupied by any other task.  */
9083                break;
9084            }
9085 
9086        }
9087 
9088        if (osek_res->type == LINKED)
9089        {
9090 
9091            osek_res1 = (OSEK_RESOURCE *)(osek_res->resolved_res);
9092 
9093            if (osek_res1->taskid != 0u)
9094                {
9095                if (osek_res1->taskid != (TaskType)tcb_ptr)
9096                {
9097                    status = E_OS_ACCESS; /* Already occupied by any other task.  */
9098                    break;
9099                }
9100            }
9101 
9102        } /* End (osek_res->type == LINKED) */
9103 
9104 
9105    }   /* End for.  */
9106 
9107    TX_RESTORE
9108 
9109    return (status);
9110 }
9111 
9112 
9113 /***************************  END OF FILE ************************************/
9114