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