foxBMS - Unit Tests  1.5.0
The foxBMS Unit Tests API Documentation
ftask_freertos.c
Go to the documentation of this file.
1 /**
2  *
3  * @copyright © 2010 - 2023, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V.
4  * All rights reserved.
5  *
6  * SPDX-License-Identifier: BSD-3-Clause
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions are met:
10  *
11  * 1. Redistributions of source code must retain the above copyright notice, this
12  * list of conditions and the following disclaimer.
13  *
14  * 2. Redistributions in binary form must reproduce the above copyright notice,
15  * this list of conditions and the following disclaimer in the documentation
16  * and/or other materials provided with the distribution.
17  *
18  * 3. Neither the name of the copyright holder nor the names of its
19  * contributors may be used to endorse or promote products derived from
20  * this software without specific prior written permission.
21  *
22  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
23  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
25  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
26  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
28  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
29  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
30  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32  *
33  * We kindly request you to use one or more of the following phrases to refer to
34  * foxBMS in your hardware, software, documentation or advertising materials:
35  *
36  * - ″This product uses parts of foxBMS®″
37  * - ″This product includes parts of foxBMS®″
38  * - ″This product is derived from foxBMS®″
39  *
40  */
41 
42 /**
43  * @file ftask_freertos.c
44  * @author foxBMS Team
45  * @date 2019-08-27 (date of creation)
46  * @updated 2023-02-03 (date of last update)
47  * @version v1.5.0
48  * @ingroup TASK
49  * @prefix FTSK
50  *
51  * @brief OS specific, i.e., FreeRTOS specific, creation of the tasks
52  * @details TODO
53  */
54 
55 /*========== Includes =======================================================*/
56 #include "general.h"
57 
58 #include "can_cfg.h"
59 
60 #include "FreeRTOS.h"
61 #include "task.h"
62 
63 #include "afe.h"
64 #include "database.h"
65 #include "ftask.h"
66 
67 #include <stdint.h>
68 
69 /*========== Macros and Definitions =========================================*/
70 /** helper macro to translate the stack sizes from bytes into words as FreeRTOS requires words and not bytes */
71 #define FTSK_BYTES_TO_WORDS(VARIABLE_IN_BYTES) ((VARIABLE_IN_BYTES) / GEN_BYTES_PER_WORD)
72 /** Stack size of engine task in words */
73 #define FTSK_TASK_ENGINE_STACK_SIZE_IN_WORDS FTSK_BYTES_TO_WORDS(FTSK_TASK_ENGINE_STACK_SIZE_IN_BYTES)
74 /** @brief Stack size of cyclic 1 ms task in words */
75 #define FTSK_TASK_CYCLIC_1MS_STACK_SIZE_IN_WORDS FTSK_BYTES_TO_WORDS(FTSK_TASK_CYCLIC_1MS_STACK_SIZE_IN_BYTES)
76 /** @brief Stack size of cyclic 10 ms task in words */
77 #define FTSK_TASK_CYCLIC_10MS_STACK_SIZE_IN_WORDS FTSK_BYTES_TO_WORDS(FTSK_TASK_CYCLIC_10MS_STACK_SIZE_IN_BYTES)
78 /** @brief Stack size of cyclic 100 ms task in words */
79 #define FTSK_TASK_CYCLIC_100MS_STACK_SIZE_IN_WORDS FTSK_BYTES_TO_WORDS(FTSK_TASK_CYCLIC_100MS_STACK_SIZE_IN_BYTES)
80 /** @brief Stack size of cyclic 100 ms task for algorithms in words */
81 #define FTSK_TASK_CYCLIC_ALGORITHM_100MS_STACK_SIZE_IN_WORDS \
82  FTSK_BYTES_TO_WORDS(FTSK_TASK_CYCLIC_ALGORITHM_100MS_STACK_SIZE_IN_BYTES)
83 /** @brief Stack size of continuously running task for AFEs */
84 #define FTSK_TASK_AFE_STACK_SIZE_IN_WORDS FTSK_BYTES_TO_WORDS(FTSK_TASK_AFE_STACK_SIZE_IN_BYTES)
85 
86 /** size of storage area for the database queue */
87 #define FTSK_DATABASE_QUEUE_STORAGE_AREA (FTSK_DATABASE_QUEUE_LENGTH * FTSK_DATABASE_QUEUE_ITEM_SIZE_IN_BYTES)
88 
89 /** size of storage area for the IMD queue*/
90 #define FTSK_IMD_QUEUE_STORAGE_AREA (FTSK_IMD_QUEUE_LENGTH * FTSK_IMD_QUEUE_ITEM_SIZE_IN_BYTES)
91 
92 /** size of storage area for the CAN Rx queue*/
93 #define FTSK_CAN_RX_QUEUE_STORAGE_AREA (FTSK_CAN_RX_QUEUE_LENGTH * FTSK_CAN_RX_QUEUE_ITEM_SIZE_IN_BYTES)
94 
95 /** size of storage area for the RTC set time queue*/
96 #define FTSK_RTC_QUEUE_STORAGE_AREA (FTSK_RTC_QUEUE_LENGTH * FTSK_RTC_QUEUE_ITEM_SIZE_IN_BYTES)
97 
98 /** size of storage area for the I2C over AFE slave queue*/
99 #define FTSK_AFEI2C_QUEUE_STORAGE_AREA (FTSK_AFEI2C_QUEUE_LENGTH * FTSK_AFEI2C_QUEUE_ITEM_SIZE_IN_BYTES)
100 
101 /*========== Static Constant and Variable Definitions =======================*/
102 
103 /*========== Extern Constant and Variable Definitions =======================*/
104 /** @brief Definition of task handle for the AFE task */
105 OS_TASK_HANDLE ftsk_taskHandleAfe;
106 OS_TASK_HANDLE ftsk_taskHandleI2c;
107 
108 volatile bool ftsk_allQueuesCreated = false;
109 
111 
113 
114 /* INCLUDE MARKER FOR THE DOCUMENTATION; DO NOT MOVE can-documentation-rx-queue-handle-start-include */
116 /* INCLUDE MARKER FOR THE DOCUMENTATION; DO NOT MOVE can-documentation-rx-queue-handle-stop-include */
117 
120 
123 
124 /*========== Static Function Prototypes =====================================*/
125 
126 /*========== Static Function Implementations ================================*/
127 
128 /*========== Extern Function Implementations ================================*/
129 
130 extern void FTSK_CreateQueues(void) {
131  /* usage of 'StaticQueue_t' and 'vQueueAddToRegistry' here is okay (no
132  wrapper in 'os.h' needed) as it is only used in the internals of the
133  'ftask_freertos.c' implementation and not exposed to the BMS
134  application. */
135 
136  /* structure and array for static database queue */
137  static uint8_t ftsk_databaseQueueStorageArea[FTSK_DATABASE_QUEUE_STORAGE_AREA] = {0};
138  static StaticQueue_t ftsk_databaseQueueStructure = {0};
139 
140  /* Create a queue capable of containing a pointer of type DATA_QUEUE_MESSAGE_s
141  Data of Messages are passed by pointer as they contain a lot of data. */
142  ftsk_databaseQueue = xQueueCreateStatic(
145  ftsk_databaseQueueStorageArea,
146  &ftsk_databaseQueueStructure);
148  vQueueAddToRegistry(ftsk_databaseQueue, "Database Queue");
149 
150  /* structure and array for static IMD queue */
152  static StaticQueue_t ftsk_imdQueueStructure = {0};
153 
154  ftsk_imdCanDataQueue = xQueueCreateStatic(
156  vQueueAddToRegistry(ftsk_imdCanDataQueue, "IMD CAN Data Queue");
158 
159  /* INCLUDE MARKER FOR THE DOCUMENTATION; DO NOT MOVE can-documentation-rx-queue-vars-start-include */
160  /* structure and array for static CAN RX queue */
162  static StaticQueue_t ftsk_canRxQueueStructure = {0};
163  /* INCLUDE MARKER FOR THE DOCUMENTATION; DO NOT MOVE can-documentation-rx-queue-vars-stop-include */
164 
165  ftsk_canRxQueue = xQueueCreateStatic(
170  vQueueAddToRegistry(ftsk_canRxQueue, "CAN Receive Queue");
172 
173  /**
174  * @brief size of storage area for the AFE request queue
175  * @details The array that is used for the queue's storage area.
176  * This must be at least
177  * #FTSK_AFE_REQUEST_QUEUE_LENGTH * #FTSK_AFE_REQUEST_QUEUE_ITEM_SIZE
178  */
179  static uint8_t ftsk_afeRequestQueueStorageArea[FTSK_AFE_REQUEST_QUEUE_LENGTH * FTSK_AFE_REQUEST_QUEUE_ITEM_SIZE] = {
180  0};
181  static StaticQueue_t ftsk_afeRequestQueueStructure = {0}; /*!< structure for static database queue */
182 
183  /* Create a queue capable of containing a pointer of type DATA_QUEUE_MESSAGE_s
184  Data of Messages are passed by pointer as they contain a lot of data. */
185  ftsk_afeRequestQueue = xQueueCreateStatic(
188  ftsk_afeRequestQueueStorageArea,
189  &ftsk_afeRequestQueueStructure);
191  vQueueAddToRegistry(ftsk_afeRequestQueue, "LTC Request Queue");
192 
193  /* structure and array for static RTC queue */
194  static uint8_t ftsk_rtcQueueStorageArea[FTSK_RTC_QUEUE_STORAGE_AREA] = {0};
195  static StaticQueue_t ftsk_rtcQueueStructure = {0};
196 
197  ftsk_rtcSetTimeQueue = xQueueCreateStatic(
199  vQueueAddToRegistry(ftsk_rtcSetTimeQueue, "RTC set time Queue");
201 
202  /* structure and array for static I2C over AFE slave queue */
203  static uint8_t ftsk_afeToI2cQueueStorageArea[FTSK_AFEI2C_QUEUE_STORAGE_AREA] = {0};
204  static StaticQueue_t ftsk_afeToI2cQueueStructure = {0};
205 
206  ftsk_afeToI2cQueue = xQueueCreateStatic(
209  ftsk_afeToI2cQueueStorageArea,
210  &ftsk_afeToI2cQueueStructure);
211  vQueueAddToRegistry(ftsk_afeToI2cQueue, "I2C over AFE slave");
213 
214  /* structure and array for static I2C over AFE slave queue */
215  static uint8_t ftsk_afeFromI2cQueueStorageArea[FTSK_AFEI2C_QUEUE_STORAGE_AREA] = {0};
216  static StaticQueue_t ftsk_afeFromI2cQueueStructure = {0};
217 
218  ftsk_afeFromI2cQueue = xQueueCreateStatic(
221  ftsk_afeFromI2cQueueStorageArea,
222  &ftsk_afeFromI2cQueueStructure);
223  vQueueAddToRegistry(ftsk_afeFromI2cQueue, "I2C over AFE slave");
225 
227  ftsk_allQueuesCreated = true;
229 }
230 
231 extern void FTSK_CreateTasks(void) {
232  /* usage of the FreeRTOS internals here is okay (no wrapper in 'os.h'
233  needed) as it is only used in the internals of the 'ftask_freertos.c'
234  implementation and not exposed to the BMS application.
235  The only exception is the AFE task handle (ftsk_taskHandleAfe), see
236  below */
237 
238  /* Engine Task */
239  static StaticTask_t ftsk_taskEngine = {0};
240  static StackType_t ftsk_stackEngine[FTSK_TASK_ENGINE_STACK_SIZE_IN_WORDS] = {0};
241 
242  const TaskHandle_t ftsk_taskHandleEngine = xTaskCreateStatic(
243  (TaskFunction_t)FTSK_CreateTaskEngine,
244  (const portCHAR *)"TaskEngine",
247  (UBaseType_t)ftsk_taskDefinitionEngine.priority,
248  ftsk_stackEngine,
249  &ftsk_taskEngine);
250  FAS_ASSERT(ftsk_taskHandleEngine != NULL); /* Trap if initialization failed */
251 
252  /* Cyclic Task 1ms */
253  static StaticTask_t ftsk_taskCyclic1ms = {0};
254  static StackType_t ftsk_stackCyclic1ms[FTSK_TASK_CYCLIC_1MS_STACK_SIZE_IN_WORDS] = {0};
255 
256  const TaskHandle_t ftsk_taskHandleCyclic1ms = xTaskCreateStatic(
257  (TaskFunction_t)FTSK_CreateTaskCyclic1ms,
258  (const portCHAR *)"TaskCyclic1ms",
262  ftsk_stackCyclic1ms,
263  &ftsk_taskCyclic1ms);
264  FAS_ASSERT(ftsk_taskHandleCyclic1ms != NULL); /* Trap if initialization failed */
265 
266  /* Cyclic Task 10ms */
267  static StaticTask_t ftsk_taskCyclic10ms = {0};
268  static StackType_t ftsk_stackCyclic10ms[FTSK_TASK_CYCLIC_10MS_STACK_SIZE_IN_WORDS] = {0};
269 
270  const TaskHandle_t ftsk_taskHandleCyclic10ms = xTaskCreateStatic(
271  (TaskFunction_t)FTSK_CreateTaskCyclic10ms,
272  (const portCHAR *)"TaskCyclic10ms",
276  ftsk_stackCyclic10ms,
277  &ftsk_taskCyclic10ms);
278  FAS_ASSERT(ftsk_taskHandleCyclic10ms != NULL); /* Trap if initialization failed */
279 
280  /* Cyclic Task 100ms */
281  static StaticTask_t ftsk_taskCyclic100ms = {0};
282  static StackType_t ftsk_stackCyclic100ms[FTSK_TASK_CYCLIC_100MS_STACK_SIZE_IN_WORDS] = {0};
283 
284  const TaskHandle_t ftsk_taskHandleCyclic100ms = xTaskCreateStatic(
285  (TaskFunction_t)FTSK_CreateTaskCyclic100ms,
286  (const portCHAR *)"TaskCyclic100ms",
290  ftsk_stackCyclic100ms,
291  &ftsk_taskCyclic100ms);
292  FAS_ASSERT(ftsk_taskHandleCyclic100ms != NULL); /* Trap if initialization failed */
293 
294  /* Cyclic Task 100ms for algorithms */
295  static StaticTask_t ftsk_taskCyclicAlgorithm100ms = {0};
296  static StackType_t ftsk_stackCyclicAlgorithm100ms[FTSK_TASK_CYCLIC_ALGORITHM_100MS_STACK_SIZE_IN_WORDS] = {0};
297 
298  const TaskHandle_t ftsk_taskHandleCyclicAlgorithm100ms = xTaskCreateStatic(
299  (TaskFunction_t)FTSK_CreateTaskCyclicAlgorithm100ms,
300  (const portCHAR *)"TaskCyclicAlgorithm100ms",
304  ftsk_stackCyclicAlgorithm100ms,
305  &ftsk_taskCyclicAlgorithm100ms);
306  FAS_ASSERT(ftsk_taskHandleCyclicAlgorithm100ms != NULL); /* Trap if initialization failed */
307 
308  /* Continuously running Task for I2C */
309  static StaticTask_t ftsk_taskI2c = {0};
310  static StackType_t ftsk_stackSizeI2c[FTSK_TASK_AFE_STACK_SIZE_IN_WORDS] = {0};
311 
312  ftsk_taskHandleI2c = xTaskCreateStatic(
313  (TaskFunction_t)FTSK_CreateTaskI2c,
314  (const portCHAR *)"TaskI2c",
317  (UBaseType_t)ftsk_taskDefinitionI2c.priority,
318  ftsk_stackSizeI2c,
319  &ftsk_taskI2c);
320  FAS_ASSERT(ftsk_taskHandleI2c != NULL); /* Trap if initialization failed */
321 
322  /* This task is required in the BMS application and therefore declared by
323  the public name as defined in 'os.h'. The details how this task is
324  declared is however only important for the implementation and therefore
325  the FreeRTOS specific names can be used. */
326  /* Continuously running Task for AFE */
327  static StaticTask_t ftsk_taskAfe = {0};
328  static StackType_t ftsk_stackSizeAfe[FTSK_TASK_AFE_STACK_SIZE_IN_WORDS] = {0};
329 
330  ftsk_taskHandleAfe = xTaskCreateStatic(
331  (TaskFunction_t)FTSK_CreateTaskAfe,
332  (const portCHAR *)"TaskAfe",
335  (UBaseType_t)ftsk_taskDefinitionAfe.priority,
336  ftsk_stackSizeAfe,
337  &ftsk_taskAfe);
338  FAS_ASSERT(ftsk_taskHandleAfe != NULL); /* Trap if initialization failed */
339 }
340 
341 /*========== Externalized Static Function Implementations (Unit Test) =======*/
342 #ifdef UNITY_UNIT_TEST
343 #endif
AFE driver header.
Headers for the configuration for the CAN module.
Database module header.
#define FAS_ASSERT(x)
Assertion macro that asserts that x is true.
Definition: fassert.h:250
#define NULL
NULL definition.
Definition: fstd_types.h:67
#define NULL_PTR
Null pointer.
Definition: fstd_types.h:77
void FTSK_CreateTaskEngine(void *const pvParameters)
Database-Task.
Definition: ftask.c:76
void FTSK_CreateTaskCyclicAlgorithm100ms(void *const pvParameters)
Creation of cyclic 100 ms algorithm task.
Definition: ftask.c:188
void FTSK_CreateTaskCyclic100ms(void *const pvParameters)
Creation of cyclic 100 ms task.
Definition: ftask.c:159
void FTSK_CreateTaskCyclic10ms(void *const pvParameters)
Creation of cyclic 10 ms task.
Definition: ftask.c:130
void FTSK_CreateTaskAfe(void *const pvParameters)
Creation of continuously running task for AFEs.
Definition: ftask.c:239
void FTSK_CreateTaskCyclic1ms(void *const pvParameters)
Creation of cyclic 1 ms task.
Definition: ftask.c:98
void FTSK_CreateTaskI2c(void *const pvParameters)
Creation of continuously running task for I2c.
Definition: ftask.c:219
Header of task driver implementation.
#define FTSK_DATABASE_QUEUE_LENGTH
Definition: ftask.h:71
#define FTSK_DATABASE_QUEUE_ITEM_SIZE_IN_BYTES
Definition: ftask.h:74
#define FTSK_AFE_REQUEST_QUEUE_ITEM_SIZE
Definition: ftask.h:87
#define FTSK_CAN_RX_QUEUE_ITEM_SIZE_IN_BYTES
Definition: ftask.h:84
#define FTSK_AFEI2C_QUEUE_LENGTH
Definition: ftask.h:95
#define FTSK_CAN_RX_QUEUE_LENGTH
Definition: ftask.h:82
#define FTSK_AFEI2C_QUEUE_ITEM_SIZE_IN_BYTES
Definition: ftask.h:97
#define FTSK_IMD_QUEUE_ITEM_SIZE_IN_BYTES
Definition: ftask.h:79
#define FTSK_RTC_QUEUE_ITEM_SIZE_IN_BYTES
Definition: ftask.h:92
#define FTSK_RTC_QUEUE_LENGTH
Definition: ftask.h:90
#define FTSK_AFE_REQUEST_QUEUE_LENGTH
Definition: ftask.h:86
#define FTSK_IMD_QUEUE_LENGTH
Definition: ftask.h:77
OS_TASK_DEFINITION_s ftsk_taskDefinitionAfe
Task configuration of the continuously running task for AFEs.
Definition: ftask_cfg.c:145
OS_TASK_DEFINITION_s ftsk_taskDefinitionCyclic100ms
Task configuration of the cyclic 100 ms task.
Definition: ftask_cfg.c:127
OS_TASK_DEFINITION_s ftsk_taskDefinitionEngine
Definition of the engine task.
Definition: ftask_cfg.c:109
OS_TASK_DEFINITION_s ftsk_taskDefinitionCyclic1ms
Task configuration of the cyclic 1 ms task.
Definition: ftask_cfg.c:115
OS_TASK_DEFINITION_s ftsk_taskDefinitionCyclicAlgorithm100ms
Task configuration of the cyclic 100 ms task for algorithms.
Definition: ftask_cfg.c:133
OS_TASK_DEFINITION_s ftsk_taskDefinitionI2c
Task configuration of the continuously running task for MCU I2C communication.
Definition: ftask_cfg.c:139
OS_TASK_DEFINITION_s ftsk_taskDefinitionCyclic10ms
Task configuration of the cyclic 10 ms task.
Definition: ftask_cfg.c:121
OS_QUEUE ftsk_afeFromI2cQueue
#define FTSK_TASK_CYCLIC_1MS_STACK_SIZE_IN_WORDS
Stack size of cyclic 1 ms task in words.
OS_QUEUE ftsk_rtcSetTimeQueue
#define FTSK_IMD_QUEUE_STORAGE_AREA
#define FTSK_CAN_RX_QUEUE_STORAGE_AREA
#define FTSK_BYTES_TO_WORDS(VARIABLE_IN_BYTES)
OS_QUEUE ftsk_imdCanDataQueue
#define FTSK_RTC_QUEUE_STORAGE_AREA
volatile bool ftsk_allQueuesCreated
#define FTSK_AFEI2C_QUEUE_STORAGE_AREA
#define FTSK_TASK_ENGINE_STACK_SIZE_IN_WORDS
#define FTSK_TASK_AFE_STACK_SIZE_IN_WORDS
Stack size of continuously running task for AFEs.
#define FTSK_TASK_CYCLIC_ALGORITHM_100MS_STACK_SIZE_IN_WORDS
Stack size of cyclic 100 ms task for algorithms in words.
OS_TASK_HANDLE ftsk_taskHandleAfe
Definition of task handle for the AFE task.
#define FTSK_TASK_CYCLIC_10MS_STACK_SIZE_IN_WORDS
Stack size of cyclic 10 ms task in words.
OS_QUEUE ftsk_afeToI2cQueue
void FTSK_CreateTasks(void)
Creates all tasks of the group.
OS_QUEUE ftsk_canRxQueue
#define FTSK_DATABASE_QUEUE_STORAGE_AREA
#define FTSK_TASK_CYCLIC_100MS_STACK_SIZE_IN_WORDS
Stack size of cyclic 100 ms task in words.
OS_QUEUE ftsk_afeRequestQueue
OS_QUEUE ftsk_databaseQueue
void FTSK_CreateQueues(void)
Creates all queues.
OS_TASK_HANDLE ftsk_taskHandleI2c
Definition of task handles.
General macros and definitions for the whole platform.
void OS_ExitTaskCritical(void)
Exit Critical interface function for use in FreeRTOS-Tasks and FreeRTOS-ISR.
Definition: os_freertos.c:138
void OS_EnterTaskCritical(void)
Enter Critical interface function for use in FreeRTOS-Tasks and FreeRTOS-ISR.
Definition: os_freertos.c:134
uint32_t stackSize_B
Definition: os.h:136
void * pvParameters
Definition: os.h:137
OS_PRIORITY_e priority
Definition: os.h:133
static StaticQueue_t ftsk_rtcQueueStructure
Definition: test_ftask.c:119
static uint8_t ftsk_imdQueueStorageArea[FTSK_IMD_QUEUE_LENGTH *FTSK_IMD_QUEUE_ITEM_SIZE]
static StaticQueue_t ftsk_canRxQueueStructure
static StaticQueue_t ftsk_imdQueueStructure
static uint8_t ftsk_canRxQueueStorageArea[FTSK_CAN_RX_QUEUE_LENGTH *FTSK_CAN_RX_QUEUE_ITEM_SIZE]