Arm-2D  
2D Image Processing Library for Cortex-M Processors
arm_2d_utils.h
1/*
2 * Copyright (C) 2010-2022 Arm Limited or its affiliates. All rights reserved.
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 *
6 * Licensed under the Apache License, Version 2.0 (the License); you may
7 * not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
9 *
10 * www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an AS IS BASIS, WITHOUT
14 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 */
18
19/* ----------------------------------------------------------------------
20 * Project: Arm-2D Library
21 * Title: arm_2d_utils.h
22 * Description: Public header file for Arm-2D Library
23 *
24 * $Date: 14. Nov 2024
25 * $Revision: V.1.4.8
26 *
27 * -------------------------------------------------------------------- */
28
29#ifndef __ARM_2D_UTILS_H__
30#define __ARM_2D_UTILS_H__
31
32/*============================ INCLUDES ======================================*/
33
34#if defined(__clang__)
35# pragma clang diagnostic push
36# pragma clang diagnostic ignored "-Wunknown-warning-option"
37# pragma clang diagnostic ignored "-Wreserved-identifier"
38# pragma clang diagnostic ignored "-Wgnu-zero-variadic-macro-arguments"
39# pragma clang diagnostic ignored "-Wpadded"
40# pragma clang diagnostic ignored "-Wsign-conversion"
41# pragma clang diagnostic ignored "-Wimplicit-int-conversion"
42# pragma clang diagnostic ignored "-Wdollar-in-identifier-extension"
43# pragma clang diagnostic ignored "-Wundef"
44#elif defined(__IS_COMPILER_GCC__)
45# pragma GCC diagnostic push
46# pragma GCC diagnostic ignored "-Wpedantic"
47# pragma GCC diagnostic ignored "-Wstrict-aliasing"
48# pragma GCC diagnostic ignored "-Wnonnull-compare"
49#endif
50
51#ifdef __ARM_2D_HAS_USER_HEADER__
52# include __ARM_2D_HAS_USER_HEADER__
53#endif
54
55
56
57#undef __IS_SUPPORTED_ARM_ARCH__
58#if ( (defined(__ARM_ARCH) && __ARM_ARCH) \
59 || defined(__TARGET_ARCH_ARM)) && !defined(__APPLE__)
60# define __IS_SUPPORTED_ARM_ARCH__ 1
61#else
62# define __IS_SUPPORTED_ARM_ARCH__ 0
63#endif
64
65/*! \note arm-2d relies on CMSIS 5.8.0 and above.
66 */
67#if __IS_SUPPORTED_ARM_ARCH__
68
69#ifdef __cplusplus
70extern "C" {
71#endif
72
73# include "cmsis_compiler.h"
74
75#ifdef __cplusplus
76}
77#endif
78
79#else
80# include "arm_2d_user_arch_port.h"
81#endif
82
83
84#ifdef __cplusplus
85extern "C" {
86#endif
87
88/*!
89 * \addtogroup gKernel 1 Kernel
90 * @{
91 */
92
93/*============================ MACROS ========================================*/
94
95
96/*----------------------------------------------------------------------------*
97 * Environment Detection *
98 *----------------------------------------------------------------------------*/
99
100
101/* The macros to identify compilers */
102
103/* detect IAR */
104#undef __IS_COMPILER_IAR__
105#if defined(__IAR_SYSTEMS_ICC__)
106# define __IS_COMPILER_IAR__ 1
107#endif
108
109/* detect arm compiler 5 */
110#undef __IS_COMPILER_ARM_COMPILER_5__
111#if ((__ARMCC_VERSION >= 5000000) && (__ARMCC_VERSION < 6000000))
112# define __IS_COMPILER_ARM_COMPILER_5__ 1
113#endif
114
115
116/* detect arm compiler 6 */
117#undef __IS_COMPILER_ARM_COMPILER_6__
118#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
119# define __IS_COMPILER_ARM_COMPILER_6__ 1
120#endif
121
122/* detect arm compilers */
123#undef __IS_COMPILER_ARM_COMPILER__
124#if defined(__IS_COMPILER_ARM_COMPILER_5__) && __IS_COMPILER_ARM_COMPILER_5__ \
125|| defined(__IS_COMPILER_ARM_COMPILER_6__) && __IS_COMPILER_ARM_COMPILER_6__
126# define __IS_COMPILER_ARM_COMPILER__ 1
127#endif
128
129/* detect clang (llvm) */
130#undef __IS_COMPILER_LLVM__
131#if defined(__clang__) && !__IS_COMPILER_ARM_COMPILER_6__
132# define __IS_COMPILER_LLVM__ 1
133#else
134
135/* detect gcc */
136# undef __IS_COMPILER_GCC__
137# if defined(__GNUC__) && !( defined(__IS_COMPILER_ARM_COMPILER__) \
138 || defined(__IS_COMPILER_LLVM__) \
139 || defined(__IS_COMPILER_IAR__))
140# define __IS_COMPILER_GCC__ 1
141# endif
142
143#endif
144
145/*----------------------------------------------------------------------------*
146 * OOC and Private Protection *
147 *----------------------------------------------------------------------------*/
148/* minimal support for OOPC */
149#undef __implement_ex
150#undef __implement
151#undef implement
152#undef implement_ex
153#undef inherit
154#undef inherit_ex
155
156/*!
157 * \note do NOT use this macro directly
158 */
159#ifdef __cplusplus
160# define __implement_ex(__type, __name) __type __name
161#else
162# define __implement_ex(__type, __name) \
163 union { \
164 __type __name; \
165 __type; \
166 }
167#endif
168/*!
169 * \note do NOT use this macro
170 */
171#define __inherit_ex(__type, __name) __type __name
172
173
174/*!
175 * \note do NOT use this macro directly
176 */
177#define __implement(__type) __implement_ex( __type, \
178 use_as__##__type)
179
180
181/*!
182 * \note do NOT use this macro directly
183 */
184#define __inherit(__type) __inherit_ex(__type,use_as__##__type)
185
186
187/*!
188 * \brief inherit a given class
189 * \param __type the base class, you can use .use_as_xxxxx for referencing
190 * the base.
191 * \note this macro supports microsoft extensions (-fms-extensions)
192 */
193#define implement(__type) __implement(__type)
194
195/*!
196 * \brief inherit a given class and give it an alias name
197 * \param __type the base class
198 * \param __name an alias name for referencing the base class
199 * \note this macro supports microsoft extensions (-fms-extensions)
200 */
201#define implement_ex(__type, __name) __implement_ex(__type, __name)
202
203
204/*!
205 * \brief inherit a given class
206 * \param __type the base class, you can use .use_as_xxxxx for referencing
207 * the base.
208 * \note this macro does NOT support microsoft extensions (-fms-extensions)
209 */
210#define inherit(__type) __inherit(__type)
211
212/*!
213 * \brief inherit a given class and give it an alias name
214 * \param __type the base class
215 * \param __name an alias name for referencing the base class
216 * \note this macro does NOT support microsoft extensions (-fms-extensions)
217 */
218#define inherit_ex(__type, __name) __inherit_ex(__type, __name)
219
220
221/*----------------------------------------------------------------------------*
222 * Misc *
223 *----------------------------------------------------------------------------*/
224
225/*!
226 * \brief a macro to mark unused variables and let the compiler happy
227 */
228#ifndef ARM_2D_UNUSED
229# define ARM_2D_UNUSED(__VAR) (void)(__VAR)
230#endif
231
232#undef ARM_TYPE_CONVERT
233/*!
234 * \brief convert a given variable to a specified type, the converted result
235 * can be used as lvalue.
236 * \param __VAR the target variable
237 * \param __TYPE the target type
238 */
239#define ARM_TYPE_CONVERT(__VAR, __TYPE) (*((__TYPE *)&(__VAR)))
240
241/*!
242 * \brief a macro to test the boolean result for a given value using a given
243 * bitmask
244 * \param[in] __VALUE the target value
245 * \param[in] __BITS a bitmask
246 * \retval true all bits in the bitmask is 1
247 * \retval false not all bits in the bitmask is 1
248 */
249#ifndef ARM_TEST_BITS
250# define ARM_TEST_BITS(__VALUE, __BITS) ((__BITS) == ((__VALUE) & (__BITS)))
251#endif
252
253/*!
254 * \brief get the number of items in an given array
255 */
256#ifndef dimof
257# define dimof(__array) (sizeof(__array)/sizeof(__array[0]))
258#endif
259
260/*!
261 * \brief get the offset of a given member in a specified structure/union
262 * \param __type the host type
263 * \param __member the name of the target member
264 * \return size_t the offset (in bytes)
265 */
266#ifndef offsetof
267# define offsetof(__type, __member) \
268 ((uintptr_t)&(((__type *)NULL)->__member))
269#endif
270
271/*!
272 * \note do NOT use this macro directly
273 */
274#define __ARM_TO_STRING(__STR) #__STR
275
276/*!
277 * \brief convert a string to C string
278 */
279#define ARM_TO_STRING(__STR) __ARM_TO_STRING(__STR)
280
281/*!
282 * \note do NOT use this macro directly
283 */
284#define __ARM_VA_NUM_ARGS_IMPL( _0,_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12, \
285 _13,_14,_15,_16,__N,...) __N
286
287/*!
288 * \brief A macro to count the number of parameters
289 *
290 * \note if GNU extension is not supported or enabled, the following express will
291 * be false: (__ARM_VA_NUM_ARGS() != 0)
292 * This might cause problems when in this library.
293 */
294#define __ARM_VA_NUM_ARGS(...) \
295 __ARM_VA_NUM_ARGS_IMPL( 0,##__VA_ARGS__,16,15,14,13,12,11,10,9, \
296 8,7,6,5,4,3,2,1,0)
297
298/*!
299 * \brief detect whether GNU extension is enabled in compilation or not
300 */
301#if __ARM_VA_NUM_ARGS() != 0
302# warning Please enable GNU extensions, it is required by the Arm-2D.
303#endif
304
305
306#undef ARM_2D_PARAM
307
308/*!
309 * \brief a macro helper to be used with ARM_2D_INVODE to improve the
310 * readability of the code
311 */
312#define ARM_2D_PARAM(...) __VA_ARGS__
313
314#ifndef ARM_2D_INVOKE
315/*!
316 * \brief A macro to safely invode a function pointer
317 *
318 * \param[in] __FUNC_PTR the target function pointer
319 * \param[in] ... an optional parameter list
320 */
321# define ARM_2D_INVOKE(__FUNC_PTR, ...) \
322 ((NULL == (__FUNC_PTR)) ? 0 : ((*(__FUNC_PTR))(__VA_ARGS__)))
323
324#endif
325
326#ifndef ARM_2D_INVOKE_RT_VOID
327/*!
328 * \brief A macro to safely call a function pointer that has no return value
329 *
330 * \param[in] __FUNC_PTR the target function pointer
331 * \param[in] ... an optional parameter list
332 */
333# define ARM_2D_INVOKE_RT_VOID(__FUNC_PTR, ...) \
334 if (NULL != (__FUNC_PTR)) (*(__FUNC_PTR))(__VA_ARGS__)
335
336#endif
337
338/*!
339 * \note do NOT use this macro directly
340 */
341#define __ARM_CONNECT2(__A, __B) __A##__B
342
343/*!
344 * \note do NOT use this macro directly
345 */
346#define __ARM_CONNECT2_ALT(__A, __B) __A##__B
347
348/*!
349 * \note do NOT use this macro directly
350 */
351#define __ARM_CONNECT3(__A, __B, __C) __A##__B##__C
352
353/*!
354 * \note do NOT use this macro directly
355 */
356#define __ARM_CONNECT4(__A, __B, __C, __D) __A##__B##__C##__D
357
358/*!
359 * \note do NOT use this macro directly
360 */
361#define __ARM_CONNECT5(__A, __B, __C, __D, __E) __A##__B##__C##__D##__E
362
363/*!
364 * \note do NOT use this macro directly
365 */
366#define __ARM_CONNECT6(__A, __B, __C, __D, __E, __F) \
367 __A##__B##__C##__D##__E##__F
368
369/*!
370 * \note do NOT use this macro directly
371 */
372#define __ARM_CONNECT7(__A, __B, __C, __D, __E, __F, __G) \
373 __A##__B##__C##__D##__E##__F##__G
374
375/*!
376 * \note do NOT use this macro directly
377 */
378#define __ARM_CONNECT8(__A, __B, __C, __D, __E, __F, __G, __H) \
379 __A##__B##__C##__D##__E##__F##__G##__H
380
381/*!
382 * \note do NOT use this macro directly
383 */
384#define __ARM_CONNECT9(__A, __B, __C, __D, __E, __F, __G, __H, __I) \
385 __A##__B##__C##__D##__E##__F##__G##__H##__I
386
387/*!
388 * \brief connect two symbol names as one
389 */
390#define ARM_CONNECT2(__A, __B) __ARM_CONNECT2(__A, __B)
391
392/*!
393 * \brief connect two symbol names as one
394 */
395#define ARM_CONNECT2_ALT(__A, __B) __ARM_CONNECT2_ALT(__A, __B)
396
397/*!
398 * \brief connect three symbol names as one
399 */
400#define ARM_CONNECT3(__A, __B, __C) __ARM_CONNECT3(__A, __B, __C)
401
402/*!
403 * \brief connect four symbol names as one
404 */
405#define ARM_CONNECT4(__A, __B, __C, __D) __ARM_CONNECT4(__A, __B, __C, __D)
406
407/*!
408 * \brief connect five symbol names as one
409 */
410#define ARM_CONNECT5(__A, __B, __C, __D, __E) \
411 __ARM_CONNECT5(__A, __B, __C, __D, __E)
412
413/*!
414 * \brief connect six symbol names as one
415 */
416#define ARM_CONNECT6(__A, __B, __C, __D, __E, __F) \
417 __ARM_CONNECT6(__A, __B, __C, __D, __E, __F)
418
419/*!
420 * \brief connect seven symbol names as one
421 */
422#define ARM_CONNECT7(__A, __B, __C, __D, __E, __F, __G) \
423 __ARM_CONNECT7(__A, __B, __C, __D, __E, __F, __G)
424
425/*!
426 * \brief connect eight symbol names as one
427 */
428#define ARM_CONNECT8(__A, __B, __C, __D, __E, __F, __G, __H) \
429 __ARM_CONNECT8(__A, __B, __C, __D, __E, __F, __G, __H)
430
431/*!
432 * \brief connect nine symbol names as one
433 */
434#define ARM_CONNECT9(__A, __B, __C, __D, __E, __F, __G, __H, __I) \
435 __ARM_CONNECT9(__A, __B, __C, __D, __E, __F, __G, __H, __I)
436
437/*!
438 * \brief connect up to 9 symbol names as one
439 */
440#define arm_connect(...) \
441 ARM_CONNECT2_ALT(ARM_CONNECT, __ARM_VA_NUM_ARGS(__VA_ARGS__)) \
442 (__VA_ARGS__)
443
444/*!
445 * \brief connect up to 9 symbol names as one
446 */
447#define ARM_CONNECT(...) arm_connect(__VA_ARGS__)
448
449/*!
450 * \note do NOT use this macro directly
451 */
452#define __ARM_USING1(__declare) \
453 for (__declare, *ARM_CONNECT3(__ARM_USING_, __LINE__,_ptr) = NULL; \
454 ARM_CONNECT3(__ARM_USING_, __LINE__,_ptr)++ == NULL; \
455 )
456
457/*!
458 * \note do NOT use this macro directly
459 */
460#define __ARM_USING2(__declare, __on_leave_expr) \
461 for (__declare, *ARM_CONNECT3(__ARM_USING_, __LINE__,_ptr) = NULL; \
462 ARM_CONNECT3(__ARM_USING_, __LINE__,_ptr)++ == NULL; \
463 (__on_leave_expr) \
464 )
465
466/*!
467 * \note do NOT use this macro directly
468 */
469#define __ARM_USING3(__declare, __on_enter_expr, __on_leave_expr) \
470 for (__declare, *ARM_CONNECT3(__ARM_USING_, __LINE__,_ptr) = NULL; \
471 ARM_CONNECT3(__ARM_USING_, __LINE__,_ptr)++ == NULL ? \
472 ((__on_enter_expr),1) : 0; \
473 (__on_leave_expr) \
474 )
475
476/*!
477 * \note do NOT use this macro directly
478 */
479#define __ARM_USING4(__dcl1, __dcl2, __on_enter_expr, __on_leave_expr) \
480 for (__dcl1,__dcl2,*ARM_CONNECT3(__ARM_USING_, __LINE__,_ptr)= NULL;\
481 ARM_CONNECT3(__ARM_USING_, __LINE__,_ptr)++ == NULL ? \
482 ((__on_enter_expr),1) : 0; \
483 (__on_leave_expr) \
484 )
485
486/*!
487 * \brief create a code segment with up to two local variables and
488 * entering/leaving operations
489 * \note prototype 1
490 * arm_using(local variable declaration) {
491 * code body
492 * }
493 *
494 * \note prototype 2
495 * arm_using(local variable declaration, {code segment before leaving the body}) {
496 * code body
497 * }
498 *
499 * \note prototype 3
500 * arm_using( local variable declaration,
501 * {code segment before entering the body},
502 * {code segment before leaving the body}
503 * ) {
504 * code body
505 * }
506 *
507 * \note prototype 4
508 * arm_using( local variable1 declaration,
509 local variable2 with the same type as the local variable 1,
510 * {code segment before entering the body},
511 * {code segment before leaving the body}
512 * ) {
513 * code body
514 * }
515 */
516#define arm_using(...) \
517 ARM_CONNECT2(__ARM_USING, __ARM_VA_NUM_ARGS(__VA_ARGS__))(__VA_ARGS__)
518
519
520/*!
521 * \note do NOT use this macro directly
522 */
523#define __ARM_WITH2(__type, __addr) \
524 arm_using(__type *_=(__addr))
525
526/*!
527 * \note do NOT use this macro directly
528 */
529#define __ARM_WITH3(__type, __addr, __item) \
530 arm_using(__type *_=(__addr), *__item = _, (void)_, (void)0)
531
532/*!
533 * \brief a with block to access members of a given object
534 *
535 * \note prototype 1
536 * arm_with(object type, address of the object) {
537 * you can use _.xxxx to access the members of the object
538 * }
539 *
540 * \note prototype 2
541 * arm_with(object type, address of the object, name of the iterator) {
542 * you can use your own iterator to access the members of the object
543 * }
544 */
545#define arm_with(...) \
546 ARM_CONNECT2(__ARM_WITH, __ARM_VA_NUM_ARGS(__VA_ARGS__))(__VA_ARGS__)
547
548/*!
549 * \brief access each items in a given array
550 * \param __type the type of the array
551 * \param __array the target array
552 * \note you can use "_" as the current object (iterator)
553 */
554#define ARM_FOREACH2(__type, __array) \
555 arm_using(__type *_ = __array) \
556 for ( uint_fast32_t ARM_CONNECT2(count,__LINE__) = dimof(__array);\
557 ARM_CONNECT2(count,__LINE__) > 0; \
558 _++, ARM_CONNECT2(count,__LINE__)-- \
559 )
560
561/*!
562 * \brief access each items in a given array
563 * \param __type the type of the array
564 * \param __array the target array
565 * \param __item a name for the current item (iterator)
566 */
567#define ARM_FOREACH3(__type, __array, __item) \
568 arm_using(__type *_ = __array, *__item = _, (void)_, (void)0 ) \
569 for ( uint_fast32_t ARM_CONNECT2(count,__LINE__) = dimof(__array);\
570 ARM_CONNECT2(count,__LINE__) > 0; \
571 _++, __item = _, ARM_CONNECT2(count,__LINE__)-- \
572 )
573
574/*!
575 * \brief access each items in a given array
576 * \param __type the type of the array
577 * \param __array the target array or the pointer of an memory block
578 * \param __count number of items in the array/memory block
579 * \param __item a name for the current item (iterator)
580 */
581#define ARM_FOREACH4(__type, __array, __count, __item) \
582 arm_using(__type *_ = __array, *__item = _, (void)_, (void)0) \
583 for ( uint_fast32_t ARM_CONNECT2(count,__LINE__) = (__count); \
584 ARM_CONNECT2(count,__LINE__) > 0; \
585 _++, __item = _, ARM_CONNECT2(count,__LINE__)-- \
586 )
587
588/*!
589 * \brief access each items in a given array
590 * \note there are 3 prototypes, please refer to ARM_FOREACH1/2/3 for details
591 */
592#define arm_foreach(...) \
593 ARM_CONNECT2(ARM_FOREACH, __ARM_VA_NUM_ARGS(__VA_ARGS__))(__VA_ARGS__)
594
595
596/*!
597 * \brief a wrapper for __attribute__((nonnull))
598 */
599#ifndef ARM_NONNULL
600# if defined(__IS_COMPILER_ARM_COMPILER_5__) ||\
601 defined(__IS_COMPILER_ARM_COMPILER_6__) ||\
602 defined(__IS_COMPILER_GCC__) ||\
603 defined(__IS_COMPILER_LLVM__)
604# define ARM_NONNULL(...) __attribute__((nonnull(__VA_ARGS__)))
605# else
606# define ARM_NONNULL(...)
607# endif
608#endif
609
610/*!
611 * \note do NOT use this macro directly
612 */
613#define __ARM_SECTION(__X) __attribute__((section(__X)))
614
615/*!
616 * \brief an attribute to specify the section
617 * \note it works for both functions and static/global variables
618 */
619#ifndef ARM_SECTION
620# define ARM_SECTION(__X) __ARM_SECTION(__X)
621#endif
622
623/*!
624 * \brief an attribute for static variables that no initialisation is required
625 * in the C startup process.
626 */
627#ifndef ARM_NOINIT
628# if defined(__IS_COMPILER_ARM_COMPILER_5__)
629# define ARM_NOINIT __attribute__(( section( ".bss.noinit"),zero_init))
630# elif defined(__IS_COMPILER_ARM_COMPILER_6__)
631# define ARM_NOINIT __attribute__(( section( ".bss.noinit")))
632# elif defined(__IS_COMPILER_IAR__)
633# define ARM_NOINIT __no_init
634# elif (defined(__IS_COMPILER_GCC__) || defined(__IS_COMPILER_LLVM__)) && !defined(__APPLE__)
635# define ARM_NOINIT __attribute__(( section( ".bss.noinit")))
636# else
637# define ARM_NOINIT
638# endif
639#endif
640
641#undef __ARM_ALIGN
642
643/*!
644 * \note do NOT use this macro directly
645 */
646#define __ARM_ALIGN(__N) __attribute__((aligned(__N)))
647
648/*!
649 * \brief an attribute to specify aligment requirement
650 * \note it works for both functions and static/global variables
651 */
652#ifndef ARM_ALIGN
653# define ARM_ALIGN(__N) __ARM_ALIGN(__N)
654#endif
655
656
657
658/*!
659 * \brief local variable decoration for pointers: restrict
660 */
661#ifndef __RESTRICT
662# define __RESTRICT __restrict
663#endif
664
665/*!
666 * \brief an decoration for claiming that the immediate following symbol
667 * (variable / function) is not WEAK. If there is an __WEAK symbol, the
668 * __OVERRIDE_WEAK one can override it.
669 *
670 */
671#ifndef __OVERRIDE_WEAK
672# define __OVERRIDE_WEAK
673#endif
674
675/*!
676 * \brief A macro to generate a safe name, usually used in macro template as the
677 * name of local variables
678 *
679 */
680#define ARM_2D_SAFE_NAME(...) ARM_CONNECT(__,__LINE__,##__VA_ARGS__)
681
682/*!
683 * \brief A macro to generate a safe name, usually used in macro template as the
684 * name of local variables
685 *
686 */
687#define arm_2d_safe_name(...) ARM_2D_SAFE_NAME(__VA_ARGS__)
688
689/*!
690 * \brief a decoration to make the immediate following code irq-safe
691 *
692 * \code
693 arm_irq_safe {
694 // code inside the brackets are IRQ safe
695 ...
696 }
697
698 // the printf is IRQ safe
699 arm_irq_safe printf("IRQ safe printf\n");
700
701 \endcode
702 */
703#if __IS_SUPPORTED_ARM_ARCH__
704# undef arm_irq_safe
705# undef arm_exit_irq_safe
706# define arm_irq_safe \
707 arm_using( uint32_t ARM_2D_SAFE_NAME(temp) = \
708 ({uint32_t temp=__get_PRIMASK();__disable_irq();temp;}),\
709 __set_PRIMASK(ARM_2D_SAFE_NAME(temp)))
710# define arm_exit_irq_safe continue
711#endif
712
713
714#undef ARM_2D_WRAP_FUNC
715#undef __ARM_2D_WRAP_FUNC
716#undef ARM_2D_ORIG_FUNC
717#undef __ARM_2D_ORIG_FUNC
718
719#if defined(__IS_COMPILER_ARM_COMPILER_6__)
720
721/*!
722 * \note do NOT use this macro directly
723 */
724# define __ARM_2D_WRAP_FUNC(__FUNC) $Sub$$##__FUNC
725
726/*!
727 * \note do NOT use this macro directly
728 */
729# define __ARM_2D_ORIG_FUNC(__FUNC) $Super$$## __FUNC
730#else
731
732/*!
733 * \note do NOT use this macro directly
734 */
735# define __ARM_2D_WRAP_FUNC(x) __wrap_ ## x
736
737/*!
738 * \note do NOT use this macro directly
739 */
740# define __ARM_2D_ORIG_FUNC(x) __real_ ## x
741#endif
742
743/*!
744 * \brief a symbol wrapper to override a specified function
745 */
746#define ARM_2D_WRAP_FUNC(__FUNC) __ARM_2D_WRAP_FUNC(__FUNC)
747
748/*!
749 * \brief a symbol wrapper to refer the original function with a given name
750 */
751#define ARM_2D_ORIG_FUNC(__FUNC) __ARM_2D_ORIG_FUNC(__FUNC)
752
753/*----------------------------------------------------------------------------*
754 * List Operations *
755 *----------------------------------------------------------------------------*/
756
757/* ALL the parameters passed to following macros must be pointer variables. */
758
759/*!
760 * \note do NOT use this macro directly
761 */
762#define __ARM_LIST_STACK_PUSH(__P_TOP, __P_NODE) \
763 do { \
764 ((__arm_slist_node_t *)(__P_NODE))->ptNext = \
765 (__arm_slist_node_t *)(__P_TOP); \
766 (*(__arm_slist_node_t **)&(__P_TOP)) = \
767 (__arm_slist_node_t *)(__P_NODE); \
768 } while(0)
769
770/*!
771 * \brief push a item to a list
772 * \param[in] __P_TOP a pointer points to the first item of a list
773 * \param[in] __P_NODE a pointer points to the new item
774 */
775#define ARM_LIST_STACK_PUSH(__P_TOP, __P_NODE) \
776 __ARM_LIST_STACK_PUSH((__P_TOP), (__P_NODE))
777
778/*!
779 * \brief insert a item after a specified node
780 * \param[in] __P_TARGET a pointer points to the target node
781 * \param[in] __P_NODE a pointer points to the new item
782 */
783#define ARM_LIST_INSERT_AFTER(__P_TARGET, __P_NODE) \
784 __ARM_LIST_STACK_PUSH((__P_TARGET), (__P_NODE))
785
786/*!
787 * \note do NOT use this macro directly
788 */
789#define __ARM_LIST_STACK_POP(__P_TOP, __P_NODE) \
790 do { \
791 (*(__arm_slist_node_t **)&(__P_NODE)) = \
792 (__arm_slist_node_t *)(__P_TOP); \
793 if (NULL != (__P_TOP)) { \
794 (*(__arm_slist_node_t **)&(__P_TOP)) = \
795 ((__arm_slist_node_t *)(__P_NODE))->ptNext; \
796 ((__arm_slist_node_t *)(__P_NODE))->ptNext = NULL; \
797 } \
798 } while(0)
799
800/*!
801 * \brief pop a item from a list
802 * \param[in] __P_TOP a pointer points to the first item of a list
803 * \param[out] __P_NODE a pointer variable for the node
804 */
805#define ARM_LIST_STACK_POP(__P_TOP, __P_NODE) \
806 __ARM_LIST_STACK_POP((__P_TOP), (__P_NODE))
807
808/*!
809 * \brief remove a item after a specified node
810 * \param[in] __P_TARGET a pointer points to the target node
811 * \param[out] __P_NODE a pointer variable for the node
812 */
813#define ARM_LIST_REMOVE_AFTER(__P_TARGET, __P_NODE) \
814 ARM_LIST_STACK_POP((__P_TARGET), (__P_NODE))
815
816/*!
817 * \note do NOT use this macro directly
818 */
819#define __ARM_LIST_QUEUE_ENQUEUE(__HEAD, __TAIL, __ITEM) \
820 do { \
821 if (NULL == (__TAIL)) { \
822 (*((__arm_slist_node_t **)&(__TAIL))) = \
823 (__arm_slist_node_t *)(__ITEM); \
824 (*((__arm_slist_node_t **)&(__HEAD))) = \
825 (__arm_slist_node_t *)(__ITEM); \
826 } else { \
827 ((__arm_slist_node_t *)(__TAIL))->ptNext = \
828 (__arm_slist_node_t *)(__ITEM); \
829 (*(__arm_slist_node_t **)&(__TAIL)) = \
830 (__arm_slist_node_t *)(__ITEM); \
831 } \
832 ((__arm_slist_node_t *)(__ITEM))->ptNext = NULL; \
833 } while(0)
834
835/*!
836 * \brief enter a node to a queue
837 * \param[in] __HEAD a pointer points to the queue head
838 * \param[in] __TAIL a pointer points to the queue tail
839 * \param[in] __ITEM a pointer variable for the new node
840 */
841#define ARM_LIST_QUEUE_ENQUEUE(__HEAD, __TAIL, __ITEM) \
842 __ARM_LIST_QUEUE_ENQUEUE((__HEAD), (__TAIL), (__ITEM))
843
844/*!
845 * \note do NOT use this macro directly
846 */
847#define __ARM_LIST_QUEUE_DEQUEUE(__HEAD, __TAIL, __ITEM) \
848 do { \
849 (*(__arm_slist_node_t **)&(__ITEM)) = (__arm_slist_node_t *)(__HEAD); \
850 if (NULL != (__HEAD)) { \
851 (*(__arm_slist_node_t **)&(__HEAD)) = \
852 ((__arm_slist_node_t *)(__HEAD))->ptNext; \
853 if (NULL == (__HEAD)) { \
854 (__TAIL) = NULL; \
855 } \
856 } \
857 if (NULL != (__ITEM)) { \
858 ((__arm_slist_node_t *)(__ITEM))->ptNext = NULL; \
859 } \
860 } while(0)
861
862/*!
863 * \brief fetch a node from a queue
864 * \param[in] __HEAD a pointer points to the queue head
865 * \param[in] __TAIL a pointer points to the queue tail
866 * \param[out] __ITEM a pointer variable for the node
867 */
868#define ARM_LIST_QUEUE_DEQUEUE(__HEAD, __TAIL, __ITEM) \
869 __ARM_LIST_QUEUE_DEQUEUE((__HEAD), (__TAIL), (__ITEM))
870
871/*!
872 * \note do NOT use this macro directly
873 */
874#define __ARM_LIST_QUEUE_PEEK(__HEAD, __TAIL, __ITEM) \
875 do { \
876 (*(__arm_slist_node_t **)&(__ITEM)) = (__arm_slist_node_t *)(__HEAD); \
877 } while(0)
878
879/*!
880 * \brief peek a node from a queue
881 * \param[in] __HEAD a pointer points to the queue head
882 * \param[in] __TAIL a pointer points to the queue tail
883 * \param[out] __ITEM a pointer variable for the node
884 */
885#define ARM_LIST_QUEUE_PEEK(__HEAD, __TAIL, __ITEM) \
886 __ARM_LIST_QUEUE_PEEK((__HEAD), (__TAIL), (__ITEM)) \
887
888/*!
889 * \note do NOT use this macro directly
890 */
891#define __ARM_LIST_QUEUE_IS_EMPTY(__HEAD, __TAIL) \
892 ((__HEAD) == NULL)
893
894
895/*!
896 * \brief check whether a list FIFO is empty or not
897 * \param[in] __HEAD a pointer points to the queue head
898 * \param[in] __TAIL a pointer points to the queue tail
899 * \retval true the list FIFO is empty
900 * \retval false the list FIFO is not empty
901 */
902#define ARM_LIST_QUEUE_IS_EMPTY(__HEAD, __TAIL) \
903 __ARM_LIST_QUEUE_IS_EMPTY((__HEAD), (__TAIL))
904/*----------------------------------------------------------------------------*
905 * PT Operations *
906 *----------------------------------------------------------------------------*/
907/*
908Protothreads open source BSD-style license
909The protothreads library is released under an open source license that allows
910both commercial and non-commercial use without restrictions. The only
911requirement is that credits is given in the source code and in the documentation
912for your product.
913
914The full license text follows.
915
916Copyright (c) 2004-2005, Swedish Institute of Computer Science.
917All rights reserved.
918
919Redistribution and use in source and binary forms, with or without
920modification, are permitted provided that the following conditions
921are met:
9221. Redistributions of source code must retain the above copyright
923notice, this list of conditions and the following disclaimer.
9242. Redistributions in binary form must reproduce the above copyright
925notice, this list of conditions and the following disclaimer in the
926documentation and/or other materials provided with the distribution.
9273. Neither the name of the Institute nor the names of its contributors
928may be used to endorse or promote products derived from this software
929without specific prior written permission.
930
931THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS `AS IS' AND
932ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
933IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
934ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
935FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
936DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
937OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
938HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
939LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
940OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
941SUCH DAMAGE.
942
943Author: Adam Dunkels
944*/
945
946#define ARM_PT_BEGIN(__STATE) \
947 enum { \
948 count_offset = __COUNTER__ + 1, \
949 }; \
950 uint8_t *ptPTState = &(__STATE); \
951 switch (__STATE) { \
952 case __COUNTER__ - count_offset:
953
954#define ARM_PT_ENTRY(...) \
955 (*ptPTState) = (__COUNTER__ - count_offset + 1) >> 1; \
956 __VA_ARGS__ \
957 case (__COUNTER__ - count_offset) >> 1: (void)(*ptPTState);
958
959#define ARM_PT_YIELD(...) \
960 ARM_PT_ENTRY(return __VA_ARGS__;)
961
962#define ARM_PT_END() \
963 (*ptPTState) = 0; \
964 break;}
965
966#define ARM_PT_GOTO_PREV_ENTRY(...) return __VA_ARGS__;
967
968#define ARM_PT_WAIT_UNTIL(__CONDITION, ...) \
969 ARM_PT_ENTRY() \
970 __VA_ARGS__; \
971 if (!(__CONDITION)) { \
972 ARM_PT_GOTO_PREV_ENTRY(arm_fsm_rt_on_going); \
973 }
974
975#define ARM_PT_WAIT_OBJ_UNTIL(__CONDITION, ...) \
976 ARM_PT_ENTRY() \
977 __VA_ARGS__; \
978 if (!(__CONDITION)) { \
979 ARM_PT_GOTO_PREV_ENTRY(arm_fsm_rt_wait_for_obj); \
980 }
981
982#define ARM_PT_WAIT_RESOURCE_UNTIL(__CONDITION, ...) \
983 ARM_PT_ENTRY() \
984 __VA_ARGS__; \
985 if (!(__CONDITION)) { \
986 ARM_PT_GOTO_PREV_ENTRY(arm_fsm_rt_wait_for_res); \
987 }
988
989#define ARM_PT_DELAY_MS(__MS, ...) \
990 ARM_PT_ENTRY( \
991 static int64_t ARM_2D_SAFE_NAME(s_lTimestamp); \
992 ) \
993 do { \
994 int64_t *ARM_2D_SAFE_NAME(plTimestamp) \
995 = (&ARM_2D_SAFE_NAME(s_lTimestamp), ##__VA_ARGS__); \
996 int64_t ARM_2D_SAFE_NAME(lElapsedMs) = \
997 arm_2d_helper_convert_ticks_to_ms( \
998 arm_2d_helper_get_system_timestamp() \
999 - *ARM_2D_SAFE_NAME(plTimestamp)); \
1000 if (ARM_2D_SAFE_NAME(lElapsedMs) < (__MS)) { \
1001 ARM_PT_GOTO_PREV_ENTRY(arm_fsm_rt_on_going); \
1002 } \
1003 } while(0)
1004
1005
1006#define ARM_PT_REPORT_STATUS(...) \
1007 ARM_PT_ENTRY( \
1008 return __VA_ARGS__; \
1009 )
1010
1011#define ARM_PT_RETURN(...) \
1012 (*ptPTState) = 0; \
1013 return __VA_ARGS__;
1014
1015/*----------------------------------------------------------------------------*
1016 * Definition Template *
1017 *----------------------------------------------------------------------------*/
1018
1019/*!
1020 * \note do NOT use this macro directly
1021 */
1022#define __def_low_lv_io(__NAME, __SW, ...) \
1023const __arm_2d_low_level_io_t LOW_LEVEL_IO##__NAME = { \
1024 .SW = (__arm_2d_io_func_t *)&(__SW), \
1025 .HW = (NULL, ##__VA_ARGS__) \
1026}
1027
1028
1029/*!
1030 * \brief a template to implement a specified low-level io interface
1031 * \param __NAME the IO name
1032 * \param __SW the default c implementation
1033 * \param ... you can specify an optional implementation using some acceleration.
1034 */
1035#define def_low_lv_io(__NAME, __SW, ...) \
1036 __def_low_lv_io(__NAME, __SW, ##__VA_ARGS__)
1037
1038/*!
1039 * \note do NOT use this macro directly
1040 */
1041#define __ref_low_lv_io(__NAME) &LOW_LEVEL_IO##__NAME
1042
1043/*!
1044 * \brief a symbol wrapper for referencing a specified low-level IO
1045 */
1046#define ref_low_lv_io(__NAME) __ref_low_lv_io(__NAME)
1047
1048/*----------------------------------------------------------------------------*
1049 * LOG *
1050 *----------------------------------------------------------------------------*/
1051
1052/*!
1053 * \brief the bit-mask for log channels
1054 */
1055#define ARM_2D_LOG_CHN_TYPE_USER _BV(28) //!< the channel for user messages
1056#define ARM_2D_LOG_CHN_TYPE_INFO _BV(29) //!< the channel for generic information
1057#define ARM_2D_LOG_CHN_TYPE_WARNING _BV(30) //!< the channel for warnings messages
1058#define ARM_2D_LOG_CHN_TYPE_ERROR _BV(31) //!< the channel for error messages
1059
1060#define ARM_2D_LOG_CHN_PIPELINE _BV(0) //!< the channel dedicated to the pixel-pipeline
1061#define ARM_2D_LOG_CHN_OPCODE _BV(1) //!< the channel dedicated to OPCODEs and related algorithms
1062#define ARM_2D_LOG_CHN_HELPER _BV(2) //!< the channel dedicated to Helper services
1063#define ARM_2D_LOG_CHN_HELPER_PFB _BV(3) //!< the channel dedicated to the PFB helper service
1064#define ARM_2D_LOG_CHN_SCENE_PLAYER _BV(4) //!< the channel dedicated to the scene player service
1065#define ARM_2D_LOG_CHN_DIRTY_REGION_OPTIMISATION _BV(5) //!< the channel dedicated to the dirty region optimization services
1066#define ARM_2D_LOG_CHN_STATISTICS _BV(6) //!< the channel dedicated to show statistics
1067#define ARM_2D_LOG_CHN_CONTROLS _BV(7) //!< the channel dedicated to example controls
1068
1069#define ARM_2D_LOG_CHN_GUI_STACK _BV(16) //!< the channel dedicated to USER defined GUI stack
1070
1071#define ARM_2D_LOG_CHN_APP _BV(24) //!< the channel dedicated to applications and examples
1072
1073
1074#if defined(__ARM_2D_CFG_LOG_OUTPUT_SUPPORT_COLOUR__) && __ARM_2D_CFG_LOG_OUTPUT_SUPPORT_COLOUR__
1075# define ARM_2D_TERMINAL_COLOUR_DEFAULT "\x1b[0m"
1076# define ARM_2D_TERMINAL_COLOUR_GREEN "\x1b[32m"
1077# define ARM_2D_TERMINAL_COLOUR_RED "\x1b[31m"
1078# define ARM_2D_TERMINAL_COLOUR_YELLOW "\x1b[33m"
1079# define ARM_2D_TERMINAL_COLOUR_WHITE "\x1b[97m"
1080# define ARM_2D_TERMINAL_COLOUR_BRIGHT_BLACK "\x1b[90m"
1081#else
1082# define ARM_2D_TERMINAL_COLOUR_DEFAULT
1083# define ARM_2D_TERMINAL_COLOUR_GREEN
1084# define ARM_2D_TERMINAL_COLOUR_RED
1085# define ARM_2D_TERMINAL_COLOUR_YELLOW
1086# define ARM_2D_TERMINAL_COLOUR_WHITE
1087# define ARM_2D_TERMINAL_COLOUR_BRIGHT_BLACK
1088#endif
1089
1090/*!
1091 * \brief the filter to enable log channels
1092 */
1093#ifndef __ARM_2D_LOG_CHANNEL_MASK_FILTER__
1094# define __ARM_2D_LOG_CHANNEL_MASK_FILTER__ 0xFFFFFFFF
1095#endif
1096
1097#ifndef __ARM_2D_LOG_PRINTF_PIPELINE
1098
1099/*!
1100 * \brief the log printf entry dedicated to pixel pipeline
1101 */
1102# define __ARM_2D_LOG_PRINTF_PIPELINE __arm_2d_log_printf
1103#endif
1104
1105#ifndef __ARM_2D_LOG_PRINTF_OPCODE
1106/*!
1107 * \brief the log printf entry dedicated to OPCODEs and related algorithms
1108 */
1109# define __ARM_2D_LOG_PRINTF_OPCODE __arm_2d_log_printf
1110#endif
1111
1112#ifndef __ARM_2D_LOG_PRINTF_HELPER
1113/*!
1114 * \brief the log printf entry dedicated to Helper services
1115 */
1116# define __ARM_2D_LOG_PRINTF_HELPER __arm_2d_log_printf
1117#endif
1118
1119#ifndef __ARM_2D_LOG_PRINTF_HELPER_PFB
1120/*!
1121 * \brief the log printf entry dedicated to the PFB helper service
1122 */
1123# define __ARM_2D_LOG_PRINTF_HELPER_PFB __arm_2d_log_printf
1124#endif
1125
1126#ifndef __ARM_2D_LOG_PRINTF_SCENE_PLAYER
1127/*!
1128 * \brief the log printf entry dedicated to the scene player service
1129 */
1130# define __ARM_2D_LOG_PRINTF_SCENE_PLAYER __arm_2d_log_printf
1131#endif
1132
1133#ifndef __ARM_2D_LOG_PRINTF_DIRTY_REGION_OPTIMISATION
1134/*!
1135 * \brief the log printf entry dedicated to the dirty region optimization service
1136 */
1137# define __ARM_2D_LOG_PRINTF_DIRTY_REGION_OPTIMISATION \
1138 __arm_2d_log_printf
1139#endif
1140
1141#ifndef __ARM_2D_LOG_PRINTF_STATISTICS
1142/*!
1143 * \brief the log printf entry dedicated to show statistics
1144 */
1145# define __ARM_2D_LOG_PRINTF_STATISTICS __arm_2d_log_printf
1146#endif
1147
1148#ifndef __ARM_2D_LOG_PRINTF_CONTROLS
1149/*!
1150 * \brief the log printf entry dedicated to example controls
1151 */
1152# define __ARM_2D_LOG_PRINTF_CONTROLS __arm_2d_log_printf
1153#endif
1154
1155#ifndef __ARM_2D_LOG_PRINTF_GUI_STACK
1156/*!
1157 * \brief the log printf entry dedicated to applications and examples
1158 */
1159# define __ARM_2D_LOG_PRINTF_GUI_STACK __arm_2d_log_printf
1160#endif
1161
1162#ifndef __ARM_2D_LOG_PRINTF_APP
1163/*!
1164 * \brief the log printf entry dedicated to applications and examples
1165 */
1166# define __ARM_2D_LOG_PRINTF_APP __arm_2d_log_printf
1167#endif
1168
1169#if defined(__ARM_2D_CFG_ENABLE_LOG__) && __ARM_2D_CFG_ENABLE_LOG__
1170/*!
1171 * \brief the log entry for generic information
1172 * \param[in] __CHN the channel name, e.g. PIPELINE, OPCODE, HELPER, HELPER_PFB etc.
1173 * \param[in] __INDENT number of indents before print actual content
1174 * \param[in] __PREFIX a string used as prefix, we can use it to print content
1175 * like function name, service name etc.
1176 * \param[in] __FORMAT_STR the format string used in printf
1177 * \param[in] ... the optional parameters
1178 */
1179# define ARM_2D_LOG_INFO(__CHN, __INDENT, __PREFIX, __FORMAT_STR, ...) \
1180 __ARM_2D_LOG_PRINTF_##__CHN( \
1181 (__INDENT), \
1182 (ARM_2D_LOG_CHN_TYPE_INFO | ARM_2D_LOG_CHN_##__CHN), \
1183 (__PREFIX), \
1184 (__FORMAT_STR),##__VA_ARGS__)
1185
1186/*!
1187 * \brief the log entry for warning messages
1188 * \param[in] __CHN the channel name, e.g. PIPELINE, OPCODE, HELPER, HELPER_PFB etc.
1189 * \param[in] __INDENT number of indents before print actual content
1190 * \param[in] __PREFIX a string used as prefix, we can use it to print content
1191 * like function name, service name etc.
1192 * \param[in] __FORMAT_STR the format string used in printf
1193 * \param[in] ... the optional parameters
1194 */
1195# define ARM_2D_LOG_WARNING(__CHN, __INDENT, __PREFIX, __FORMAT_STR, ...) \
1196 __ARM_2D_LOG_PRINTF_##__CHN( \
1197 (__INDENT), \
1198 (ARM_2D_LOG_CHN_TYPE_WARNING | ARM_2D_LOG_CHN_##__CHN), \
1199 (__PREFIX), \
1200 (__FORMAT_STR),##__VA_ARGS__)
1201
1202/*!
1203 * \brief the log entry for error messages
1204 * \param[in] __CHN the channel name, e.g. PIPELINE, OPCODE, HELPER, HELPER_PFB etc.
1205 * \param[in] __INDENT number of indents before print actual content
1206 * \param[in] __PREFIX a string used as prefix, we can use it to print content
1207 * like function name, service name etc.
1208 * \param[in] __FORMAT_STR the format string used in printf
1209 * \param[in] ... the optional parameters
1210 */
1211# define ARM_2D_LOG_ERROR(__CHN, __INDENT, __PREFIX, __FORMAT_STR, ...) \
1212 __ARM_2D_LOG_PRINTF_##__CHN( \
1213 (__INDENT), \
1214 (ARM_2D_LOG_CHN_TYPE_ERROR | ARM_2D_LOG_CHN_##__CHN), \
1215 (__PREFIX), \
1216 (__FORMAT_STR),##__VA_ARGS__)
1217
1218/*!
1219 * \brief the log entry for user messages
1220 * \param[in] __CHN the channel name, e.g. PIPELINE, OPCODE, HELPER, HELPER_PFB etc.
1221 * \param[in] __INDENT number of indents before print actual content
1222 * \param[in] __PREFIX a string used as prefix, we can use it to print content
1223 * like function name, service name etc.
1224 * \param[in] __FORMAT_STR the format string used in printf
1225 * \param[in] ... the optional parameters
1226 */
1227# define ARM_2D_LOG_USER(__CHN, __INDENT, __PREFIX, __FORMAT_STR, ...) \
1228 __ARM_2D_LOG_PRINTF_##__CHN( \
1229 (__INDENT), \
1230 (ARM_2D_LOG_CHN_TYPE_USER | ARM_2D_LOG_CHN_##__CHN), \
1231 (__PREFIX), \
1232 (__FORMAT_STR),##__VA_ARGS__)
1233
1234#else
1235# define ARM_2D_LOG_INFO(__CHN, __INDENT, __PREFIX, __FORMAT_STR, ...)
1236# define ARM_2D_LOG_WARNING(__CHN, __INDENT, __PREFIX, __FORMAT_STR, ...)
1237# define ARM_2D_LOG_ERROR(__CHN, __INDENT, __PREFIX, __FORMAT_STR, ...)
1238# define ARM_2D_LOG_USER(__CHN, __INDENT, __PREFIX, __FORMAT_STR, ...)
1239#endif
1240
1241
1242#ifndef __ARM_2D_PORT_PRINTF__
1243/*!
1244 * \brief the low level entry for printf
1245 * \note you can define this macro for retargeting
1246 */
1247# define __ARM_2D_PORT_PRINTF__(__format, ...) printf((__format), ##__VA_ARGS__)
1248#endif
1249
1250#ifndef __ARM_2D_LOG_MAX_STRING_LEN__
1251/*!
1252 * \brief the maximum allowed string length. The log service requests the specified
1253 * number of bytes for storing string. default value is 256
1254 * \note please make sure there are sufficient memory in HEAP.
1255 */
1256# define __ARM_2D_LOG_MAX_STRING_LEN__ 256
1257#endif
1258
1259/*============================ TYPES =========================================*/
1260
1261/*!
1262 * \brief a type for generic list
1263 *
1264 * \note to avoid using container_of() operand, please put __arm_slist_node_t
1265 * at the beginning of a class/structure
1266 */
1269 __arm_slist_node_t *ptNext; //!< the next node
1270};
1271
1272
1273/*============================ GLOBAL VARIABLES ==============================*/
1274/*============================ PROTOTYPES ====================================*/
1275
1276/*!
1277 * \brief an entry for log printf
1278 * \param[in] nIndentLevel number of indents before print actual content
1279 * \param[in] wChannelMask a bit-mask to indicate the log channel
1280 * \param[in] pchPrefix a string used as prefix, we can use it to print content
1281 * like function name, service name etc.
1282 * \param[in] pchFormatString the format string used in printf
1283 * \param[in] ... the optional parameters
1284 */
1285extern
1286void __arm_2d_log_printf(int32_t nIndentLevel,
1287 uint32_t wChannelMask,
1288 const char *pchPrefix,
1289 const char *pchFormatString,
1290 ...);
1291
1292
1293#if defined(__clang__)
1294# pragma clang diagnostic pop
1295#elif __IS_COMPILER_ARM_COMPILER_5__
1296#elif __IS_COMPILER_GCC__
1297# pragma GCC diagnostic pop
1298#endif
1299
1300#ifdef __cplusplus
1301}
1302#endif
1303
1304
1305#endif /* end of __ARM_2D_UTILS_H__ */
1306
1307
1308/*! @} */
1309
1310/*============================ MACROS ========================================*/
1311/*----------------------------------------------------------------------------*
1312 * Reentrant Macros *
1313 *----------------------------------------------------------------------------*/
1314
1315/* un-define macros */
1316#undef ARM_PRIVATE
1317#undef ARM_PROTECTED
1318#undef ARM_PUBLIC
1319
1320#define ARM_PUBLIC(...) struct {__VA_ARGS__};
1321
1322/* redefine macros */
1323#if defined(__cplusplus)
1324# define ARM_PRIVATE(...) \
1325 struct { \
1326 __VA_ARGS__ \
1327 };
1328
1329# define ARM_PROTECTED(...) \
1330 struct { \
1331 __VA_ARGS__ \
1332 };
1333
1334#elif defined(__ARM_2D_IMPL__) || defined(__IS_COMPILER_IAR__)
1335
1336# define ARM_PRIVATE(...) \
1337 struct { \
1338 __VA_ARGS__ \
1339 } __ALIGNED(__alignof__(struct {__VA_ARGS__}));
1340
1341# define ARM_PROTECTED(...) \
1342 struct { \
1343 __VA_ARGS__ \
1344 } __ALIGNED(__alignof__(struct {__VA_ARGS__}));
1345
1346#elif defined(__ARM_2D_INHERIT__)
1347
1348# define ARM_PRIVATE(...) \
1349 uint8_t ARM_CONNECT3(chMask,__LINE__,__COUNTER__) \
1350 [sizeof(struct {__VA_ARGS__})] \
1351 __ALIGNED(__alignof__(struct {__VA_ARGS__}));
1352
1353# define ARM_PROTECTED(...) \
1354 struct { \
1355 __VA_ARGS__ \
1356 } __ALIGNED(__alignof__(struct {__VA_ARGS__}));
1357
1358#else
1359# define ARM_PRIVATE(...) \
1360 uint8_t ARM_CONNECT3(chMask,__LINE__,__COUNTER__) \
1361 [sizeof(struct {__VA_ARGS__})] \
1362 __ALIGNED(__alignof__(struct {__VA_ARGS__}));
1363
1364# define ARM_PROTECTED(...) \
1365 uint8_t ARM_CONNECT3(chMask,__LINE__,__COUNTER__) \
1366 [sizeof(struct {__VA_ARGS__})] \
1367 __ALIGNED(__alignof__(struct {__VA_ARGS__}));
1368#endif
1369
1370
1371#undef ARM_PRIVATE_METHOD
1372#undef ARM_PROTECTED_METHOD
1373#undef ARM_PUBLIC_METHOD
1374
1375#if defined(__ARM_2D_IMPL__)
1376
1377# define ARM_PRIVATE_METHOD(...) __VA_ARGS__
1378# define ARM_PROTECTED_METHOD(...) __VA_ARGS__
1379# define ARM_PUBLIC_METHOD(...) __VA_ARGS__
1380
1381#elif defined(__ARM_2D_INHERIT__)
1382
1383# define ARM_PRIVATE_METHOD(...)
1384# define ARM_PROTECTED_METHOD(...) __VA_ARGS__
1385# define ARM_PUBLIC_METHOD(...) __VA_ARGS__
1386
1387#else
1388
1389# define ARM_PRIVATE_METHOD(...)
1390# define ARM_PROTECTED_METHOD(...)
1391# define ARM_PUBLIC_METHOD(...) __VA_ARGS__
1392
1393#endif
1394
1395
1396
1397/* post un-define macros */
1398
1399#undef __ARM_2D_IMPL__
1400#undef __ARM_2D_INHERIT__