]> git.sur5r.net Git - freertos/blob - FreeRTOS/Source/portable/ThirdParty/XCC/Xtensa/portclib.c
Add Xtensa port
[freertos] / FreeRTOS / Source / portable / ThirdParty / XCC / Xtensa / portclib.c
1 /*******************************************************************************\r
2 // Copyright (c) 2003-2015 Cadence Design Systems, Inc.\r
3 //\r
4 // Permission is hereby granted, free of charge, to any person obtaining\r
5 // a copy of this software and associated documentation files (the\r
6 // "Software"), to deal in the Software without restriction, including\r
7 // without limitation the rights to use, copy, modify, merge, publish,\r
8 // distribute, sublicense, and/or sell copies of the Software, and to\r
9 // permit persons to whom the Software is furnished to do so, subject to\r
10 // the following conditions:\r
11 //\r
12 // The above copyright notice and this permission notice shall be included\r
13 // in all copies or substantial portions of the Software.\r
14 //\r
15 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,\r
16 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\r
17 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\r
18 // IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\r
19 // CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\r
20 // TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\r
21 // SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\r
22 --------------------------------------------------------------------------------\r
23 */\r
24 \r
25 #include "FreeRTOS.h"\r
26 \r
27 #if XT_USE_THREAD_SAFE_CLIB\r
28 \r
29 #if XSHAL_CLIB == XTHAL_CLIB_XCLIB\r
30 \r
31 #include <errno.h>\r
32 #include <sys/reent.h>\r
33 \r
34 #include "semphr.h"\r
35 \r
36 typedef SemaphoreHandle_t       _Rmtx;\r
37 \r
38 //-----------------------------------------------------------------------------\r
39 //  Override this and set to nonzero to enable locking.\r
40 //-----------------------------------------------------------------------------\r
41 int32_t _xclib_use_mt = 1;\r
42 \r
43 \r
44 //-----------------------------------------------------------------------------\r
45 //  Init lock.\r
46 //-----------------------------------------------------------------------------\r
47 void\r
48 _Mtxinit(_Rmtx * mtx)\r
49 {\r
50     *mtx = xSemaphoreCreateRecursiveMutex();\r
51 }\r
52 \r
53 //-----------------------------------------------------------------------------\r
54 //  Destroy lock.\r
55 //-----------------------------------------------------------------------------\r
56 void\r
57 _Mtxdst(_Rmtx * mtx)\r
58 {\r
59     if ((mtx != NULL) && (*mtx != NULL)) {\r
60         vSemaphoreDelete(*mtx);\r
61     }\r
62 }\r
63 \r
64 //-----------------------------------------------------------------------------\r
65 //  Lock.\r
66 //-----------------------------------------------------------------------------\r
67 void\r
68 _Mtxlock(_Rmtx * mtx)\r
69 {\r
70     if ((mtx != NULL) && (*mtx != NULL)) {\r
71         xSemaphoreTakeRecursive(*mtx, portMAX_DELAY);\r
72     }\r
73 }\r
74 \r
75 //-----------------------------------------------------------------------------\r
76 //  Unlock.\r
77 //-----------------------------------------------------------------------------\r
78 void\r
79 _Mtxunlock(_Rmtx * mtx)\r
80 {\r
81     if ((mtx != NULL) && (*mtx != NULL)) {\r
82         xSemaphoreGiveRecursive(*mtx);\r
83     }\r
84 }\r
85 \r
86 //-----------------------------------------------------------------------------\r
87 //  Called by malloc() to allocate blocks of memory from the heap.\r
88 //-----------------------------------------------------------------------------\r
89 void *\r
90 _sbrk_r (struct _reent * reent, int32_t incr)\r
91 {\r
92     extern char _end;\r
93     extern char _heap_sentry;\r
94     static char * _heap_sentry_ptr = &_heap_sentry;\r
95     static char * heap_ptr;\r
96     char * base;\r
97 \r
98     if (!heap_ptr)\r
99         heap_ptr = (char *) &_end;\r
100 \r
101     base = heap_ptr;\r
102     if (heap_ptr + incr >= _heap_sentry_ptr) {\r
103         reent->_errno = ENOMEM;\r
104         return (char *) -1;\r
105     }\r
106 \r
107     heap_ptr += incr;\r
108     return base;\r
109 }\r
110 \r
111 //-----------------------------------------------------------------------------\r
112 //  Global initialization for C library.\r
113 //-----------------------------------------------------------------------------\r
114 void\r
115 vPortClibInit(void)\r
116 {\r
117 }\r
118 \r
119 //-----------------------------------------------------------------------------\r
120 //  Per-thread cleanup stub provided for linking, does nothing.\r
121 //-----------------------------------------------------------------------------\r
122 void\r
123 _reclaim_reent(void * ptr)\r
124 {\r
125 }\r
126 \r
127 #endif /* XSHAL_CLIB == XTHAL_CLIB_XCLIB */\r
128 \r
129 #if XSHAL_CLIB == XTHAL_CLIB_NEWLIB\r
130 \r
131 #include <errno.h>\r
132 #include <malloc.h>\r
133 #include <stdio.h>\r
134 #include <stdlib.h>\r
135 #include <string.h>\r
136 \r
137 #include "semphr.h"\r
138 \r
139 static SemaphoreHandle_t xClibMutex;\r
140 static uint32_t  ulClibInitDone = 0;\r
141 \r
142 //-----------------------------------------------------------------------------\r
143 //  Get C library lock.\r
144 //-----------------------------------------------------------------------------\r
145 void\r
146 __malloc_lock(struct _reent * ptr)\r
147 {\r
148     if (!ulClibInitDone)\r
149         return;\r
150 \r
151     xSemaphoreTakeRecursive(xClibMutex, portMAX_DELAY);\r
152 }\r
153 \r
154 //-----------------------------------------------------------------------------\r
155 //  Release C library lock.\r
156 //-----------------------------------------------------------------------------\r
157 void\r
158 __malloc_unlock(struct _reent * ptr)\r
159 {\r
160     if (!ulClibInitDone)\r
161         return;\r
162 \r
163     xSemaphoreGiveRecursive(xClibMutex);\r
164 }\r
165 \r
166 //-----------------------------------------------------------------------------\r
167 //  Lock for environment. Since we have only one global lock we can just call\r
168 //  the malloc() lock function.\r
169 //-----------------------------------------------------------------------------\r
170 void\r
171 __env_lock(struct _reent * ptr)\r
172 {\r
173     __malloc_lock(ptr);\r
174 }\r
175 \r
176 \r
177 //-----------------------------------------------------------------------------\r
178 //  Unlock environment.\r
179 //-----------------------------------------------------------------------------\r
180 void\r
181 __env_unlock(struct _reent * ptr)\r
182 {\r
183     __malloc_unlock(ptr);\r
184 }\r
185 \r
186 //-----------------------------------------------------------------------------\r
187 //  Called by malloc() to allocate blocks of memory from the heap.\r
188 //-----------------------------------------------------------------------------\r
189 void *\r
190 _sbrk_r (struct _reent * reent, int32_t incr)\r
191 {\r
192     extern char _end;\r
193     extern char _heap_sentry;\r
194     static char * _heap_sentry_ptr = &_heap_sentry;\r
195     static char * heap_ptr;\r
196     char * base;\r
197 \r
198     if (!heap_ptr)\r
199         heap_ptr = (char *) &_end;\r
200 \r
201     base = heap_ptr;\r
202     if (heap_ptr + incr >= _heap_sentry_ptr) {\r
203         reent->_errno = ENOMEM;\r
204         return (char *) -1;\r
205     }\r
206 \r
207     heap_ptr += incr;\r
208     return base;\r
209 }\r
210 \r
211 //-----------------------------------------------------------------------------\r
212 //  Global initialization for C library.\r
213 //-----------------------------------------------------------------------------\r
214 void\r
215 vPortClibInit(void)\r
216 {\r
217     configASSERT(!ulClibInitDone);\r
218 \r
219     xClibMutex = xSemaphoreCreateRecursiveMutex();\r
220     ulClibInitDone  = 1;\r
221 }\r
222 \r
223 #endif /* XSHAL_CLIB == XTHAL_CLIB_NEWLIB */\r
224 \r
225 #endif /* XT_USE_THREAD_SAFE_CLIB */\r