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