M471M/R1/S BSP V3.01.000
The Board Support Package for M4521
mem_alloc.c
Go to the documentation of this file.
1/**************************************************************************/
9#include <stdio.h>
10#include <stdlib.h>
11#include <string.h>
12
13#include "NuMicro.h"
14
15#include "usb.h"
16
17
19
20//#define MEM_DEBUG
21
22#ifdef MEM_DEBUG
23#define mem_debug printf
24#else
25#define mem_debug(...)
26#endif
27
28#ifdef __ICCARM__
29#pragma data_alignment=32
30static uint8_t _mem_pool[MEM_POOL_UNIT_NUM][MEM_POOL_UNIT_SIZE];
31#else
32static uint8_t _mem_pool[MEM_POOL_UNIT_NUM][MEM_POOL_UNIT_SIZE] __attribute__((aligned(32)));
33#endif
34static uint8_t _unit_used[MEM_POOL_UNIT_NUM];
35
36static volatile int _usbh_mem_used;
37static volatile int _usbh_max_mem_used;
38static volatile int _mem_pool_used;
39
40
41UDEV_T * g_udev_list;
42
43uint8_t _dev_addr_pool[128];
44static volatile int _device_addr;
45
46/*--------------------------------------------------------------------------*/
47/* Memory alloc/free recording */
48/*--------------------------------------------------------------------------*/
49
50void usbh_memory_init(void)
51{
52 if(sizeof(TD_T) > MEM_POOL_UNIT_SIZE)
53 {
54 USB_error("TD_T - MEM_POOL_UNIT_SIZE too small!\n");
55 while(1);
56 }
57
58 if(sizeof(ED_T) > MEM_POOL_UNIT_SIZE)
59 {
60 USB_error("ED_T - MEM_POOL_UNIT_SIZE too small!\n");
61 while(1);
62 }
63
64 _usbh_mem_used = 0L;
65 _usbh_max_mem_used = 0L;
66
67 memset(_unit_used, 0, sizeof(_unit_used));
68 _mem_pool_used = 0;
69
70 g_udev_list = NULL;
71
72 memset(_dev_addr_pool, 0, sizeof(_dev_addr_pool));
73 _device_addr = 1;
74}
75
76uint32_t usbh_memory_used(void)
77{
78 printf("USB static memory: %d/%d, heap used: %d\n", _mem_pool_used, MEM_POOL_UNIT_NUM, _usbh_mem_used);
79 return _usbh_mem_used;
80}
81
82static void memory_counter(int size)
83{
84 _usbh_mem_used += size;
85 if(_usbh_mem_used > _usbh_max_mem_used)
86 _usbh_max_mem_used = _usbh_mem_used;
87}
88
89void * usbh_alloc_mem(int size)
90{
91 void *p;
92
93 p = malloc(size);
94 if(p == NULL)
95 {
96 USB_error("usbh_alloc_mem failed! %d\n", size);
97 return NULL;
98 }
99
100 memset(p, 0, size);
101 memory_counter(size);
102 return p;
103}
104
105void usbh_free_mem(void *p, int size)
106{
107 free(p);
108 memory_counter(0 - size);
109}
110
111
112/*--------------------------------------------------------------------------*/
113/* USB device allocate/free */
114/*--------------------------------------------------------------------------*/
115
116UDEV_T * alloc_device(void)
117{
118 UDEV_T *udev;
119
120 udev = malloc(sizeof(*udev));
121 if(udev == NULL)
122 {
123 USB_error("alloc_device failed!\n");
124 return NULL;
125 }
126 memset(udev, 0, sizeof(*udev));
127 memory_counter(sizeof(*udev));
128 udev->cur_conf = -1; /* must! used to identify the first SET CONFIGURATION */
129 udev->next = g_udev_list; /* chain to global device list */
130 g_udev_list = udev;
131 return udev;
132}
133
134void free_device(UDEV_T *udev)
135{
136 UDEV_T *d;
137
138 if(udev == NULL)
139 return;
140
141 if(udev->cfd_buff != NULL)
142 usbh_free_mem(udev->cfd_buff, MAX_DESC_BUFF_SIZE);
143
144 /*
145 * Remove it from the global device list
146 */
147 if(g_udev_list == udev)
148 {
149 g_udev_list = g_udev_list->next;
150 }
151 else
152 {
153 d = g_udev_list;
154 while(d != NULL)
155 {
156 if(d->next == udev)
157 {
158 d->next = udev->next;
159 break;
160 }
161 d = d->next;
162 }
163 }
164
165 free(udev);
166 memory_counter(-sizeof(*udev));
167}
168
169int alloc_dev_address(void)
170{
171 _device_addr++;
172
173 if(_device_addr >= 128)
174 _device_addr = 1;
175
176 while(1)
177 {
178 if(_dev_addr_pool[_device_addr] == 0)
179 {
180 _dev_addr_pool[_device_addr] = 1;
181 return _device_addr;
182 }
183 _device_addr++;
184 if(_device_addr >= 128)
185 _device_addr = 1;
186 }
187}
188
189void free_dev_address(int dev_addr)
190{
191 if(dev_addr < 128)
192 _dev_addr_pool[dev_addr] = 0;
193}
194
195/*--------------------------------------------------------------------------*/
196/* UTR (USB Transfer Request) allocate/free */
197/*--------------------------------------------------------------------------*/
198
199UTR_T * alloc_utr(UDEV_T *udev)
200{
201 UTR_T *utr;
202
203 utr = malloc(sizeof(*utr));
204 if(utr == NULL)
205 {
206 USB_error("alloc_utr failed!\n");
207 return NULL;
208 }
209 memory_counter(sizeof(*utr));
210 memset(utr, 0, sizeof(*utr));
211 utr->udev = udev;
212 mem_debug("[ALLOC] [UTR] - 0x%x\n", (int)utr);
213 return utr;
214}
215
216void free_utr(UTR_T *utr)
217{
218 if(utr == NULL)
219 return;
220
221 mem_debug("[FREE] [UTR] - 0x%x\n", (int)utr);
222 free(utr);
223 memory_counter(0 - (int)sizeof(*utr));
224}
225
226/*--------------------------------------------------------------------------*/
227/* OHCI ED allocate/free */
228/*--------------------------------------------------------------------------*/
229
230ED_T * alloc_ohci_ED(void)
231{
232 int i;
233 ED_T *ed;
234
235 for(i = 0; i < MEM_POOL_UNIT_NUM; i++)
236 {
237 if(_unit_used[i] == 0)
238 {
239 _unit_used[i] = 1;
240 _mem_pool_used++;
241 ed = (ED_T *)&_mem_pool[i];
242 memset(ed, 0, sizeof(*ed));
243 mem_debug("[ALLOC] [ED] - 0x%x\n", (int)ed);
244 return ed;
245 }
246 }
247 USB_error("alloc_ohci_ED failed!\n");
248 return NULL;
249}
250
251void free_ohci_ED(ED_T *ed)
252{
253 int i;
254
255 for(i = 0; i < MEM_POOL_UNIT_NUM; i++)
256 {
257 if((uint32_t)&_mem_pool[i] == (uint32_t)ed)
258 {
259 mem_debug("[FREE] [ED] - 0x%x\n", (int)ed);
260 _unit_used[i] = 0;
261 _mem_pool_used--;
262 return;
263 }
264 }
265 USB_debug("free_ohci_ED - not found! (ignored in case of multiple UTR)\n");
266}
267
268/*--------------------------------------------------------------------------*/
269/* OHCI TD allocate/free */
270/*--------------------------------------------------------------------------*/
271TD_T * alloc_ohci_TD(UTR_T *utr)
272{
273 int i;
274 TD_T *td;
275
276 for(i = 0; i < MEM_POOL_UNIT_NUM; i++)
277 {
278 if(_unit_used[i] == 0)
279 {
280 _unit_used[i] = 1;
281 _mem_pool_used++;
282 td = (TD_T *)&_mem_pool[i];
283
284 memset(td, 0, sizeof(*td));
285 td->utr = utr;
286 mem_debug("[ALLOC] [TD] - 0x%x\n", (int)td);
287 return td;
288 }
289 }
290 USB_error("alloc_ohci_TD failed!\n");
291 return NULL;
292}
293
294void free_ohci_TD(TD_T *td)
295{
296 int i;
297
298 for(i = 0; i < MEM_POOL_UNIT_NUM; i++)
299 {
300 if((uint32_t)&_mem_pool[i] == (uint32_t)td)
301 {
302 mem_debug("[FREE] [TD] - 0x%x\n", (int)td);
303 _unit_used[i] = 0;
304 _mem_pool_used--;
305 return;
306 }
307 }
308 USB_error("free_ohci_TD - not found!\n");
309}
310
312
313/*** (C) COPYRIGHT 2020 Nuvoton Technology Corp. ***/
314
void *__dso_handle __attribute__((weak))
Definition: _syscalls.c:35
NuMicro peripheral access layer header file.
#define NULL
Definition: M471M_R1_S.h:13908
USB Host library header file.