AutosarOS
Resource.c
Go to the documentation of this file.
1 
14 #include "Resource.h"
15 #include "Types.h"
16 #include "OS.h"
17 #include "assert.h"
18 
19 #include <util/atomic.h>
20 
22 {
23  OS_SET_ERROR_INFO1(OSServiceId_GetResource, &ResID, sizeof(ResID));
24 
25  if (OS_EXTENDED && ResID >= RESOURCE_COUNT) {
27 
28  return E_OS_ID;
29  }
30 
31  ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
32  if (OS_EXTENDED && Res_Cfg[ResID]->assigned) {
34 
35  return E_OS_ACCESS;
36  }
37 
38  if (OS_EXTENDED && ((!isCat2ISR && TCB_Cfg[currentTask]->prio > Res_Cfg[ResID]->prio)
39  || (isCat2ISR && isCat2ISR > Res_Cfg[ResID]->prio))) {
40  // Prio of requested resource is lower than static prio of calling task or ISR
42 
43  return E_OS_ACCESS;
44  }
45 
46  Res_Cfg[ResID]->assigned = true;
47 
48  struct resource_s* volatile* resPtr;
49 
50  if (isCat2ISR) {
51  // Set pointer to start of ISR resourceQueue
52  resPtr = &isrResourceQueue;
53  } else {
54  // Set pointer to start of resourceQueue
55  resPtr = &(TCB_Cfg[currentTask]->resourceQueue);
56  }
57 
58  /* Find next empty spot */
59  while (*resPtr != NULL) {
60  resPtr = &(*resPtr)->next;
61  }
62 
63  // Set requested resource in empty spot found above
64  *resPtr = (struct resource_s*) Res_Cfg[ResID];
65 
66  if (!isCat2ISR) {
67  /* Increase current task priority if ceiling priority is higher */
68  if (TCB_Cfg[currentTask]->curPrio < Res_Cfg[ResID]->prio) {
70  }
71  }
72  }
73 
74  return E_OK;
75 }
76 
78 {
79  OS_SET_ERROR_INFO1(OSServiceId_ReleaseResource, &ResID, sizeof(ResID));
80 
81  if (OS_EXTENDED && ResID >= RESOURCE_COUNT) {
83 
84  return E_OS_ID;
85  }
86 
87  ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
88  if (OS_EXTENDED && !Res_Cfg[ResID]->assigned) {
90 
91  return E_OS_NOFUNC;
92  }
93 
94  if (OS_EXTENDED && ((!isCat2ISR && TCB_Cfg[currentTask]->prio > Res_Cfg[ResID]->prio)
95  || (isCat2ISR && isCat2ISR > Res_Cfg[ResID]->prio))) {
96  // Prio of requested resource is lower than static prio of calling task or ISR
98 
99  return E_OS_ACCESS;
100  }
101 
102  uint8_t ceilingPrio;
103  struct resource_s* volatile* resPtr;
104 
105  if (isCat2ISR) {
106  // Set pointer to start of ISR resourceQueue and initial ceiling prio to the maximum value
107  resPtr = &isrResourceQueue;
108  ceilingPrio = UINT8_MAX;
109  } else {
110  // Set pointer to start of task resourceQueue
111  resPtr = &(TCB_Cfg[currentTask]->resourceQueue);
112 
113  if (TCB_Cfg[currentTask]->internalResource == &IntResourceNULL_s) {
114  // Set initial prio to static task prio
115  ceilingPrio = TCB_Cfg[currentTask]->prio;
116  } else {
117  // Set initial prio to prio of internal resource
118  ceilingPrio = TCB_Cfg[currentTask]->internalResource->prio;
119  }
120  }
121 
122  /* Check if queue has any elements */
123  if (OS_EXTENDED && *resPtr == NULL) {
125 
126  return E_OS_NOFUNC;
127  }
128 
129  /* Find last element in queue and new ceiling priority */
130  while ((*resPtr)->next != NULL) {
131  if (ceilingPrio < (*resPtr)->prio) {
132  ceilingPrio = (*resPtr)->prio;
133  }
134 
135  resPtr = &(*resPtr)->next;
136  }
137 
138  if (OS_EXTENDED && *resPtr != Res_Cfg[ResID]) {
140 
141  return E_OS_NOFUNC;
142  }
143 
144  // Remove element from queue
145  *resPtr = NULL;
146 
147  Res_Cfg[ResID]->assigned = false;
148 
149  if (!isCat2ISR) {
150  // Set new task priority
151  TCB_Cfg[currentTask]->curPrio = ceilingPrio;
152  }
153  }
154 
155  // Rescheduling might be required because of possible change in priority
156  OS_Schedule();
157 
158  return E_OK;
159 }
160 
162 {
163  if (TCB_Cfg[currentTask]->internalResource != &IntResourceNULL_s) {
164  assert(TCB_Cfg[currentTask]->internalResource->prio >= TCB_Cfg[currentTask]->prio);
165 
167 
168  if (TCB_Cfg[currentTask]->curPrio < TCB_Cfg[currentTask]->internalResource->prio) {
170  }
171  }
172 }
173 
175 {
176  if (TCB_Cfg[currentTask]->internalResource != &IntResourceNULL_s) {
177  assert(TCB_Cfg[currentTask]->internalResource->assigned == true);
178 
180 
181  // Reset task priority
183 
184  uint8_t ceilingPrio = TCB_Cfg[currentTask]->prio;
185  struct resource_s* volatile* resPtr = &(TCB_Cfg[currentTask]->resourceQueue);
186 
187  /* Find ceiling priority */
188  if (*resPtr != NULL) {
189  while ((*resPtr)->next != NULL) {
190  if (ceilingPrio < (*resPtr)->prio) {
191  ceilingPrio = (*resPtr)->prio;
192  }
193 
194  resPtr = &(*resPtr)->next;
195  }
196  }
197 
198  // Set new task priority
199  TCB_Cfg[currentTask]->curPrio = ceilingPrio;
200  }
201 }
task_s::curPrio
uint8_t curPrio
Current priority.
Definition: TaskTypes.h:95
StatusType
enum StatusType_e StatusType
Type for status.
isrResourceQueue
struct resource_s *volatile isrResourceQueue
Resource queue for resources taken by Cat2 ISRs.
Definition: OCB.c:32
task_s::internalResource
volatile struct internalResource_s *const internalResource
Pointer to internal resource.
Definition: TaskTypes.h:92
OS.h
Operating system control.
E_OS_NOFUNC
@ E_OS_NOFUNC
Definition: Types.h:45
RESOURCE_COUNT
#define RESOURCE_COUNT
Count of resources defined.
Definition: CfgGenMacros.h:318
task_s::resourceQueue
struct resource_s * resourceQueue
Current queue of allocated resources.
Definition: TaskTypes.h:104
assert.h
Assert macros and functions.
IntResourceNULL_s
volatile struct internalResource_s IntResourceNULL_s
Internal resource for tasks with no internal resource defined.
currentTask
volatile TaskType currentTask
Task currently being executed.
Definition: OCB.c:23
Res_Cfg
volatile struct resource_s * Res_Cfg[]
Current resource control blocks.
Resource_ReleaseResource
StatusType Resource_ReleaseResource(ResourceType ResID)
Release a resource.
Definition: Resource.c:77
E_OK
@ E_OK
Definition: Types.h:40
Resource.h
Resource management.
OS_SET_ERROR_INFO1
#define OS_SET_ERROR_INFO1(serviceId, paramPtr1, size1)
Set error info with up to one parameter.
Definition: ErrorTypes.h:220
Resource_GetInternalResource
void Resource_GetInternalResource(void)
Get internal resource of the current task if one is assigned.
Definition: Resource.c:161
Resource_GetResource
StatusType Resource_GetResource(ResourceType ResID)
Request a resource.
Definition: Resource.c:21
OS_Schedule
void OS_Schedule(void)
Schedule task.
TCB_Cfg
volatile struct task_s * TCB_Cfg[]
Current task control blocks.
E_OS_ACCESS
@ E_OS_ACCESS
Definition: Types.h:41
resource_s::assigned
bool assigned
If true the resource is currently assigned to a task or ISR.
Definition: ResourceTypes.h:31
isCat2ISR
volatile uint8_t isCat2ISR
Priority of current Cat 2 ISR (zero if not in Cat 2 ISR)
Definition: OCB.c:21
internalResource_s::prio
const uint8_t prio
Ceiling priority of resource.
Definition: ResourceTypes.h:39
OSServiceId_ReleaseResource
@ OSServiceId_ReleaseResource
Definition: ErrorTypes.h:46
assert
#define assert(expression)
Definition: assert.h:37
resource_s
Data structure for OS resource.
Definition: ResourceTypes.h:29
task_s::prio
const uint8_t prio
Static priority of the task.
Definition: TaskTypes.h:86
OSServiceId_GetResource
@ OSServiceId_GetResource
Definition: ErrorTypes.h:45
Types.h
Type definitions.
OS_EXTENDED
#define OS_EXTENDED
Definition: OCB.h:156
Resource_ReleaseInternalResource
void Resource_ReleaseInternalResource(void)
Release internal resource of the current task if one is assigned.
Definition: Resource.c:174
internalResource_s::assigned
bool assigned
If true the resource is currently assigned to a task.
Definition: ResourceTypes.h:40
ResourceType
enum resources_e ResourceType
Type for resource reference.
Definition: ResourceTypes.h:24
resource_s::next
struct resource_s * next
Pointer to next resource in resource queue.
Definition: ResourceTypes.h:32
E_OS_ID
@ E_OS_ID
Definition: Types.h:43
OS_CALL_ERROR_HOOK
#define OS_CALL_ERROR_HOOK(error)
Call error hook if configured.
Definition: ErrorTypes.h:93
resource_s::prio
const uint8_t prio
Ceiling priority of resource.
Definition: ResourceTypes.h:30