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: 08. Dec 2024
25 * $Revision: V.1.4.9
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 * \brief access each items in a given array
547 * \param __type the type of the array
548 * \param __array the target array
549 * \note you can use "_" as the current object (iterator)
550 */
551#define ARM_FOREACH2(__type, __array) \
552 arm_using(__type *_ = __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 * \param __item a name for the current item (iterator)
563 */
564#define ARM_FOREACH3(__type, __array, __item) \
565 arm_using(__type *_ = __array, *__item = _, (void)_, (void)0 ) \
566 for ( uint_fast32_t ARM_CONNECT2(count,__LINE__) = dimof(__array);\
567 ARM_CONNECT2(count,__LINE__) > 0; \
568 _++, __item = _, 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 or the pointer of an memory block
575 * \param __count number of items in the array/memory block
576 * \param __item a name for the current item (iterator)
577 */
578#define ARM_FOREACH4(__type, __array, __count, __item) \
579 arm_using(__type *_ = __array, *__item = _, (void)_, (void)0) \
580 for ( uint_fast32_t ARM_CONNECT2(count,__LINE__) = (__count); \
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 * \note there are 3 prototypes, please refer to ARM_FOREACH1/2/3 for details
588 */
589#define arm_foreach(...) \
590 ARM_CONNECT2(ARM_FOREACH, __ARM_VA_NUM_ARGS(__VA_ARGS__))(__VA_ARGS__)
591
592
593/*!
594 * \brief a wrapper for __attribute__((nonnull))
595 */
596#ifndef ARM_NONNULL
597# if defined(__IS_COMPILER_ARM_COMPILER_5__) ||\
598 defined(__IS_COMPILER_ARM_COMPILER_6__) ||\
599 defined(__IS_COMPILER_GCC__) ||\
600 defined(__IS_COMPILER_LLVM__)
601# define ARM_NONNULL(...) __attribute__((nonnull(__VA_ARGS__)))
602# else
603# define ARM_NONNULL(...)
604# endif
605#endif
606
607/*!
608 * \note do NOT use this macro directly
609 */
610#define __ARM_SECTION(__X) __attribute__((section(__X)))
611
612/*!
613 * \brief an attribute to specify the section
614 * \note it works for both functions and static/global variables
615 */
616#ifndef ARM_SECTION
617# define ARM_SECTION(__X) __ARM_SECTION(__X)
618#endif
619
620/*!
621 * \brief an attribute for static variables that no initialisation is required
622 * in the C startup process.
623 */
624#ifndef ARM_NOINIT
625# if defined(__IS_COMPILER_ARM_COMPILER_5__)
626# define ARM_NOINIT __attribute__(( section( ".bss.noinit"),zero_init))
627# elif defined(__IS_COMPILER_ARM_COMPILER_6__)
628# define ARM_NOINIT __attribute__(( section( ".bss.noinit")))
629# elif defined(__IS_COMPILER_IAR__)
630# define ARM_NOINIT __no_init
631# elif (defined(__IS_COMPILER_GCC__) || defined(__IS_COMPILER_LLVM__)) && !defined(__APPLE__)
632# define ARM_NOINIT __attribute__(( section( ".bss.noinit")))
633# else
634# define ARM_NOINIT
635# endif
636#endif
637
638#undef __ARM_ALIGN
639
640/*!
641 * \note do NOT use this macro directly
642 */
643#define __ARM_ALIGN(__N) __attribute__((aligned(__N)))
644
645/*!
646 * \brief an attribute to specify aligment requirement
647 * \note it works for both functions and static/global variables
648 */
649#ifndef ARM_ALIGN
650# define ARM_ALIGN(__N) __ARM_ALIGN(__N)
651#endif
652
653
654
655/*!
656 * \brief local variable decoration for pointers: restrict
657 */
658#ifndef __RESTRICT
659# define __RESTRICT __restrict
660#endif
661
662/*!
663 * \brief an decoration for claiming that the immediate following symbol
664 * (variable / function) is not WEAK. If there is an __WEAK symbol, the
665 * __OVERRIDE_WEAK one can override it.
666 *
667 */
668#ifndef __OVERRIDE_WEAK
669# define __OVERRIDE_WEAK
670#endif
671
672/*!
673 * \brief A macro to generate a safe name, usually used in macro template as the
674 * name of local variables
675 *
676 */
677#define ARM_2D_SAFE_NAME(...) ARM_CONNECT(__,__LINE__,##__VA_ARGS__)
678
679/*!
680 * \brief A macro to generate a safe name, usually used in macro template as the
681 * name of local variables
682 *
683 */
684#define arm_2d_safe_name(...) ARM_2D_SAFE_NAME(__VA_ARGS__)
685
686/*!
687 * \brief a decoration to make the immediate following code irq-safe
688 *
689 * \code
690 arm_irq_safe {
691 // code inside the brackets are IRQ safe
692 ...
693 }
694
695 // the printf is IRQ safe
696 arm_irq_safe printf("IRQ safe printf\n");
697
698 \endcode
699 */
700#if __IS_SUPPORTED_ARM_ARCH__
701# undef arm_irq_safe
702# undef arm_exit_irq_safe
703# define arm_irq_safe \
704 arm_using( uint32_t ARM_2D_SAFE_NAME(temp) = \
705 ({uint32_t temp=__get_PRIMASK();__disable_irq();temp;}),\
706 __set_PRIMASK(ARM_2D_SAFE_NAME(temp)))
707# define arm_exit_irq_safe continue
708#endif
709
710
711#undef ARM_2D_WRAP_FUNC
712#undef __ARM_2D_WRAP_FUNC
713#undef ARM_2D_ORIG_FUNC
714#undef __ARM_2D_ORIG_FUNC
715
716#if defined(__IS_COMPILER_ARM_COMPILER_6__)
717
718/*!
719 * \note do NOT use this macro directly
720 */
721# define __ARM_2D_WRAP_FUNC(__FUNC) $Sub$$##__FUNC
722
723/*!
724 * \note do NOT use this macro directly
725 */
726# define __ARM_2D_ORIG_FUNC(__FUNC) $Super$$## __FUNC
727#else
728
729/*!
730 * \note do NOT use this macro directly
731 */
732# define __ARM_2D_WRAP_FUNC(x) __wrap_ ## x
733
734/*!
735 * \note do NOT use this macro directly
736 */
737# define __ARM_2D_ORIG_FUNC(x) __real_ ## x
738#endif
739
740/*!
741 * \brief a symbol wrapper to override a specified function
742 */
743#define ARM_2D_WRAP_FUNC(__FUNC) __ARM_2D_WRAP_FUNC(__FUNC)
744
745/*!
746 * \brief a symbol wrapper to refer the original function with a given name
747 */
748#define ARM_2D_ORIG_FUNC(__FUNC) __ARM_2D_ORIG_FUNC(__FUNC)
749
750/*----------------------------------------------------------------------------*
751 * List Operations *
752 *----------------------------------------------------------------------------*/
753
754/* ALL the parameters passed to following macros must be pointer variables. */
755
756/*!
757 * \note do NOT use this macro directly
758 */
759#define __ARM_LIST_STACK_PUSH(__P_TOP, __P_NODE) \
760 do { \
761 ((__arm_slist_node_t *)(__P_NODE))->ptNext = \
762 (__arm_slist_node_t *)(__P_TOP); \
763 (*(__arm_slist_node_t **)&(__P_TOP)) = \
764 (__arm_slist_node_t *)(__P_NODE); \
765 } while(0)
766
767/*!
768 * \brief push a item to a list
769 * \param[in] __P_TOP a pointer points to the first item of a list
770 * \param[in] __P_NODE a pointer points to the new item
771 */
772#define ARM_LIST_STACK_PUSH(__P_TOP, __P_NODE) \
773 __ARM_LIST_STACK_PUSH((__P_TOP), (__P_NODE))
774
775/*!
776 * \brief insert a item after a specified node
777 * \param[in] __P_TARGET a pointer points to the target node
778 * \param[in] __P_NODE a pointer points to the new item
779 */
780#define ARM_LIST_INSERT_AFTER(__P_TARGET, __P_NODE) \
781 __ARM_LIST_STACK_PUSH((__P_TARGET), (__P_NODE))
782
783/*!
784 * \note do NOT use this macro directly
785 */
786#define __ARM_LIST_STACK_POP(__P_TOP, __P_NODE) \
787 do { \
788 (*(__arm_slist_node_t **)&(__P_NODE)) = \
789 (__arm_slist_node_t *)(__P_TOP); \
790 if (NULL != (__P_TOP)) { \
791 (*(__arm_slist_node_t **)&(__P_TOP)) = \
792 ((__arm_slist_node_t *)(__P_NODE))->ptNext; \
793 ((__arm_slist_node_t *)(__P_NODE))->ptNext = NULL; \
794 } \
795 } while(0)
796
797/*!
798 * \brief pop a item from a list
799 * \param[in] __P_TOP a pointer points to the first item of a list
800 * \param[out] __P_NODE a pointer variable for the node
801 */
802#define ARM_LIST_STACK_POP(__P_TOP, __P_NODE) \
803 __ARM_LIST_STACK_POP((__P_TOP), (__P_NODE))
804
805/*!
806 * \brief remove a item after a specified node
807 * \param[in] __P_TARGET a pointer points to the target node
808 * \param[out] __P_NODE a pointer variable for the node
809 */
810#define ARM_LIST_REMOVE_AFTER(__P_TARGET, __P_NODE) \
811 ARM_LIST_STACK_POP((__P_TARGET), (__P_NODE))
812
813/*!
814 * \note do NOT use this macro directly
815 */
816#define __ARM_LIST_QUEUE_ENQUEUE(__HEAD, __TAIL, __ITEM) \
817 do { \
818 if (NULL == (__TAIL)) { \
819 (*((__arm_slist_node_t **)&(__TAIL))) = \
820 (__arm_slist_node_t *)(__ITEM); \
821 (*((__arm_slist_node_t **)&(__HEAD))) = \
822 (__arm_slist_node_t *)(__ITEM); \
823 } else { \
824 ((__arm_slist_node_t *)(__TAIL))->ptNext = \
825 (__arm_slist_node_t *)(__ITEM); \
826 (*(__arm_slist_node_t **)&(__TAIL)) = \
827 (__arm_slist_node_t *)(__ITEM); \
828 } \
829 ((__arm_slist_node_t *)(__ITEM))->ptNext = NULL; \
830 } while(0)
831
832/*!
833 * \brief enter a node to a queue
834 * \param[in] __HEAD a pointer points to the queue head
835 * \param[in] __TAIL a pointer points to the queue tail
836 * \param[in] __ITEM a pointer variable for the new node
837 */
838#define ARM_LIST_QUEUE_ENQUEUE(__HEAD, __TAIL, __ITEM) \
839 __ARM_LIST_QUEUE_ENQUEUE((__HEAD), (__TAIL), (__ITEM))
840
841/*!
842 * \note do NOT use this macro directly
843 */
844#define __ARM_LIST_QUEUE_DEQUEUE(__HEAD, __TAIL, __ITEM) \
845 do { \
846 (*(__arm_slist_node_t **)&(__ITEM)) = (__arm_slist_node_t *)(__HEAD); \
847 if (NULL != (__HEAD)) { \
848 (*(__arm_slist_node_t **)&(__HEAD)) = \
849 ((__arm_slist_node_t *)(__HEAD))->ptNext; \
850 if (NULL == (__HEAD)) { \
851 (__TAIL) = NULL; \
852 } \
853 } \
854 if (NULL != (__ITEM)) { \
855 ((__arm_slist_node_t *)(__ITEM))->ptNext = NULL; \
856 } \
857 } while(0)
858
859/*!
860 * \brief fetch a node from a queue
861 * \param[in] __HEAD a pointer points to the queue head
862 * \param[in] __TAIL a pointer points to the queue tail
863 * \param[out] __ITEM a pointer variable for the node
864 */
865#define ARM_LIST_QUEUE_DEQUEUE(__HEAD, __TAIL, __ITEM) \
866 __ARM_LIST_QUEUE_DEQUEUE((__HEAD), (__TAIL), (__ITEM))
867
868/*!
869 * \note do NOT use this macro directly
870 */
871#define __ARM_LIST_QUEUE_PEEK(__HEAD, __TAIL, __ITEM) \
872 do { \
873 (*(__arm_slist_node_t **)&(__ITEM)) = (__arm_slist_node_t *)(__HEAD); \
874 } while(0)
875
876/*!
877 * \brief peek a node from a queue
878 * \param[in] __HEAD a pointer points to the queue head
879 * \param[in] __TAIL a pointer points to the queue tail
880 * \param[out] __ITEM a pointer variable for the node
881 */
882#define ARM_LIST_QUEUE_PEEK(__HEAD, __TAIL, __ITEM) \
883 __ARM_LIST_QUEUE_PEEK((__HEAD), (__TAIL), (__ITEM)) \
884
885/*!
886 * \note do NOT use this macro directly
887 */
888#define __ARM_LIST_QUEUE_IS_EMPTY(__HEAD, __TAIL) \
889 ((__HEAD) == NULL)
890
891
892/*!
893 * \brief check whether a list FIFO is empty or not
894 * \param[in] __HEAD a pointer points to the queue head
895 * \param[in] __TAIL a pointer points to the queue tail
896 * \retval true the list FIFO is empty
897 * \retval false the list FIFO is not empty
898 */
899#define ARM_LIST_QUEUE_IS_EMPTY(__HEAD, __TAIL) \
900 __ARM_LIST_QUEUE_IS_EMPTY((__HEAD), (__TAIL))
901/*----------------------------------------------------------------------------*
902 * PT Operations *
903 *----------------------------------------------------------------------------*/
904/*
905Protothreads open source BSD-style license
906The protothreads library is released under an open source license that allows
907both commercial and non-commercial use without restrictions. The only
908requirement is that credits is given in the source code and in the documentation
909for your product.
910
911The full license text follows.
912
913Copyright (c) 2004-2005, Swedish Institute of Computer Science.
914All rights reserved.
915
916Redistribution and use in source and binary forms, with or without
917modification, are permitted provided that the following conditions
918are met:
9191. Redistributions of source code must retain the above copyright
920notice, this list of conditions and the following disclaimer.
9212. Redistributions in binary form must reproduce the above copyright
922notice, this list of conditions and the following disclaimer in the
923documentation and/or other materials provided with the distribution.
9243. Neither the name of the Institute nor the names of its contributors
925may be used to endorse or promote products derived from this software
926without specific prior written permission.
927
928THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS `AS IS' AND
929ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
930IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
931ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
932FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
933DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
934OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
935HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
936LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
937OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
938SUCH DAMAGE.
939
940Author: Adam Dunkels
941*/
942
943#define ARM_PT_BEGIN(__STATE) \
944 enum { \
945 count_offset = __COUNTER__ + 1, \
946 }; \
947 uint8_t *ptPTState = &(__STATE); \
948 switch (__STATE) { \
949 case __COUNTER__ - count_offset:
950
951#define ARM_PT_ENTRY(...) \
952 (*ptPTState) = (__COUNTER__ - count_offset + 1) >> 1; \
953 __VA_ARGS__ \
954 case (__COUNTER__ - count_offset) >> 1: (void)(*ptPTState);
955
956#define ARM_PT_YIELD(...) \
957 ARM_PT_ENTRY(return __VA_ARGS__;)
958
959#define ARM_PT_END() \
960 (*ptPTState) = 0; \
961 break;}
962
963#define ARM_PT_GOTO_PREV_ENTRY(...) return __VA_ARGS__;
964
965#define ARM_PT_WAIT_UNTIL(__CONDITION, ...) \
966 ARM_PT_ENTRY() \
967 __VA_ARGS__; \
968 if (!(__CONDITION)) { \
969 ARM_PT_GOTO_PREV_ENTRY(arm_fsm_rt_on_going); \
970 }
971
972#define ARM_PT_WAIT_OBJ_UNTIL(__CONDITION, ...) \
973 ARM_PT_ENTRY() \
974 __VA_ARGS__; \
975 if (!(__CONDITION)) { \
976 ARM_PT_GOTO_PREV_ENTRY(arm_fsm_rt_wait_for_obj); \
977 }
978
979#define ARM_PT_WAIT_RESOURCE_UNTIL(__CONDITION, ...) \
980 ARM_PT_ENTRY() \
981 __VA_ARGS__; \
982 if (!(__CONDITION)) { \
983 ARM_PT_GOTO_PREV_ENTRY(arm_fsm_rt_wait_for_res); \
984 }
985
986#define ARM_PT_DELAY_MS(__MS, ...) \
987 ARM_PT_ENTRY( \
988 static int64_t ARM_2D_SAFE_NAME(s_lTimestamp); \
989 int64_t *ARM_2D_SAFE_NAME(plTimestamp) \
990 = (&ARM_2D_SAFE_NAME(s_lTimestamp), ##__VA_ARGS__); \
991 *ARM_2D_SAFE_NAME(plTimestamp) = \
992 arm_2d_helper_get_system_timestamp(); \
993 ) \
994 do { \
995 ARM_2D_SAFE_NAME(plTimestamp) \
996 = (&ARM_2D_SAFE_NAME(s_lTimestamp), ##__VA_ARGS__); \
997 int64_t ARM_2D_SAFE_NAME(lElapsedMs) = \
998 arm_2d_helper_convert_ticks_to_ms( \
999 arm_2d_helper_get_system_timestamp() \
1000 - *ARM_2D_SAFE_NAME(plTimestamp)); \
1001 if (ARM_2D_SAFE_NAME(lElapsedMs) < (__MS)) { \
1002 ARM_PT_GOTO_PREV_ENTRY(arm_fsm_rt_on_going); \
1003 } \
1004 } while(0)
1005
1006
1007#define ARM_PT_REPORT_STATUS(...) \
1008 ARM_PT_ENTRY( \
1009 return __VA_ARGS__; \
1010 )
1011
1012#define ARM_PT_RETURN(...) \
1013 (*ptPTState) = 0; \
1014 return __VA_ARGS__;
1015
1016/*----------------------------------------------------------------------------*
1017 * Definition Template *
1018 *----------------------------------------------------------------------------*/
1019
1020/*!
1021 * \note do NOT use this macro directly
1022 */
1023#define __def_low_lv_io(__NAME, __SW, ...) \
1024const __arm_2d_low_level_io_t LOW_LEVEL_IO##__NAME = { \
1025 .SW = (__arm_2d_io_func_t *)&(__SW), \
1026 .HW = (NULL, ##__VA_ARGS__) \
1027}
1028
1029
1030/*!
1031 * \brief a template to implement a specified low-level io interface
1032 * \param __NAME the IO name
1033 * \param __SW the default c implementation
1034 * \param ... you can specify an optional implementation using some acceleration.
1035 */
1036#define def_low_lv_io(__NAME, __SW, ...) \
1037 __def_low_lv_io(__NAME, __SW, ##__VA_ARGS__)
1038
1039/*!
1040 * \note do NOT use this macro directly
1041 */
1042#define __ref_low_lv_io(__NAME) &LOW_LEVEL_IO##__NAME
1043
1044/*!
1045 * \brief a symbol wrapper for referencing a specified low-level IO
1046 */
1047#define ref_low_lv_io(__NAME) __ref_low_lv_io(__NAME)
1048
1049/*----------------------------------------------------------------------------*
1050 * LOG *
1051 *----------------------------------------------------------------------------*/
1052
1053/*!
1054 * \brief the bit-mask for log channels
1055 */
1056#define ARM_2D_LOG_CHN_TYPE_USER _BV(28) //!< the channel for user messages
1057#define ARM_2D_LOG_CHN_TYPE_INFO _BV(29) //!< the channel for generic information
1058#define ARM_2D_LOG_CHN_TYPE_WARNING _BV(30) //!< the channel for warnings messages
1059#define ARM_2D_LOG_CHN_TYPE_ERROR _BV(31) //!< the channel for error messages
1060
1061#define ARM_2D_LOG_CHN_PIPELINE _BV(0) //!< the channel dedicated to the pixel-pipeline
1062#define ARM_2D_LOG_CHN_OPCODE _BV(1) //!< the channel dedicated to OPCODEs and related algorithms
1063#define ARM_2D_LOG_CHN_HELPER _BV(2) //!< the channel dedicated to Helper services
1064#define ARM_2D_LOG_CHN_HELPER_PFB _BV(3) //!< the channel dedicated to the PFB helper service
1065#define ARM_2D_LOG_CHN_SCENE_PLAYER _BV(4) //!< the channel dedicated to the scene player service
1066#define ARM_2D_LOG_CHN_DIRTY_REGION_OPTIMISATION _BV(5) //!< the channel dedicated to the dirty region optimization services
1067#define ARM_2D_LOG_CHN_STATISTICS _BV(6) //!< the channel dedicated to show statistics
1068#define ARM_2D_LOG_CHN_CONTROLS _BV(7) //!< the channel dedicated to example controls
1069
1070#define ARM_2D_LOG_CHN_GUI_STACK _BV(16) //!< the channel dedicated to USER defined GUI stack
1071
1072#define ARM_2D_LOG_CHN_APP _BV(24) //!< the channel dedicated to applications and examples
1073
1074
1075#if defined(__ARM_2D_CFG_LOG_OUTPUT_SUPPORT_COLOUR__) && __ARM_2D_CFG_LOG_OUTPUT_SUPPORT_COLOUR__
1076# define ARM_2D_TERMINAL_COLOUR_DEFAULT "\x1b[0m"
1077# define ARM_2D_TERMINAL_COLOUR_GREEN "\x1b[32m"
1078# define ARM_2D_TERMINAL_COLOUR_RED "\x1b[31m"
1079# define ARM_2D_TERMINAL_COLOUR_YELLOW "\x1b[33m"
1080# define ARM_2D_TERMINAL_COLOUR_WHITE "\x1b[97m"
1081# define ARM_2D_TERMINAL_COLOUR_BRIGHT_BLACK "\x1b[90m"
1082#else
1083# define ARM_2D_TERMINAL_COLOUR_DEFAULT
1084# define ARM_2D_TERMINAL_COLOUR_GREEN
1085# define ARM_2D_TERMINAL_COLOUR_RED
1086# define ARM_2D_TERMINAL_COLOUR_YELLOW
1087# define ARM_2D_TERMINAL_COLOUR_WHITE
1088# define ARM_2D_TERMINAL_COLOUR_BRIGHT_BLACK
1089#endif
1090
1091/*!
1092 * \brief the filter to enable log channels
1093 */
1094#ifndef __ARM_2D_LOG_CHANNEL_MASK_FILTER__
1095# define __ARM_2D_LOG_CHANNEL_MASK_FILTER__ 0xFFFFFFFF
1096#endif
1097
1098#ifndef __ARM_2D_LOG_PRINTF_PIPELINE
1099
1100/*!
1101 * \brief the log printf entry dedicated to pixel pipeline
1102 */
1103# define __ARM_2D_LOG_PRINTF_PIPELINE __arm_2d_log_printf
1104#endif
1105
1106#ifndef __ARM_2D_LOG_PRINTF_OPCODE
1107/*!
1108 * \brief the log printf entry dedicated to OPCODEs and related algorithms
1109 */
1110# define __ARM_2D_LOG_PRINTF_OPCODE __arm_2d_log_printf
1111#endif
1112
1113#ifndef __ARM_2D_LOG_PRINTF_HELPER
1114/*!
1115 * \brief the log printf entry dedicated to Helper services
1116 */
1117# define __ARM_2D_LOG_PRINTF_HELPER __arm_2d_log_printf
1118#endif
1119
1120#ifndef __ARM_2D_LOG_PRINTF_HELPER_PFB
1121/*!
1122 * \brief the log printf entry dedicated to the PFB helper service
1123 */
1124# define __ARM_2D_LOG_PRINTF_HELPER_PFB __arm_2d_log_printf
1125#endif
1126
1127#ifndef __ARM_2D_LOG_PRINTF_SCENE_PLAYER
1128/*!
1129 * \brief the log printf entry dedicated to the scene player service
1130 */
1131# define __ARM_2D_LOG_PRINTF_SCENE_PLAYER __arm_2d_log_printf
1132#endif
1133
1134#ifndef __ARM_2D_LOG_PRINTF_DIRTY_REGION_OPTIMISATION
1135/*!
1136 * \brief the log printf entry dedicated to the dirty region optimization service
1137 */
1138# define __ARM_2D_LOG_PRINTF_DIRTY_REGION_OPTIMISATION \
1139 __arm_2d_log_printf
1140#endif
1141
1142#ifndef __ARM_2D_LOG_PRINTF_STATISTICS
1143/*!
1144 * \brief the log printf entry dedicated to show statistics
1145 */
1146# define __ARM_2D_LOG_PRINTF_STATISTICS __arm_2d_log_printf
1147#endif
1148
1149#ifndef __ARM_2D_LOG_PRINTF_CONTROLS
1150/*!
1151 * \brief the log printf entry dedicated to example controls
1152 */
1153# define __ARM_2D_LOG_PRINTF_CONTROLS __arm_2d_log_printf
1154#endif
1155
1156#ifndef __ARM_2D_LOG_PRINTF_GUI_STACK
1157/*!
1158 * \brief the log printf entry dedicated to applications and examples
1159 */
1160# define __ARM_2D_LOG_PRINTF_GUI_STACK __arm_2d_log_printf
1161#endif
1162
1163#ifndef __ARM_2D_LOG_PRINTF_APP
1164/*!
1165 * \brief the log printf entry dedicated to applications and examples
1166 */
1167# define __ARM_2D_LOG_PRINTF_APP __arm_2d_log_printf
1168#endif
1169
1170#if defined(__ARM_2D_CFG_ENABLE_LOG__) && __ARM_2D_CFG_ENABLE_LOG__
1171/*!
1172 * \brief the log entry for generic information
1173 * \param[in] __CHN the channel name, e.g. PIPELINE, OPCODE, HELPER, HELPER_PFB etc.
1174 * \param[in] __INDENT number of indents before print actual content
1175 * \param[in] __PREFIX a string used as prefix, we can use it to print content
1176 * like function name, service name etc.
1177 * \param[in] __FORMAT_STR the format string used in printf
1178 * \param[in] ... the optional parameters
1179 */
1180# define ARM_2D_LOG_INFO(__CHN, __INDENT, __PREFIX, __FORMAT_STR, ...) \
1181 __ARM_2D_LOG_PRINTF_##__CHN( \
1182 (__INDENT), \
1183 (ARM_2D_LOG_CHN_TYPE_INFO | ARM_2D_LOG_CHN_##__CHN), \
1184 (__PREFIX), \
1185 (__FORMAT_STR),##__VA_ARGS__)
1186
1187/*!
1188 * \brief the log entry for warning messages
1189 * \param[in] __CHN the channel name, e.g. PIPELINE, OPCODE, HELPER, HELPER_PFB etc.
1190 * \param[in] __INDENT number of indents before print actual content
1191 * \param[in] __PREFIX a string used as prefix, we can use it to print content
1192 * like function name, service name etc.
1193 * \param[in] __FORMAT_STR the format string used in printf
1194 * \param[in] ... the optional parameters
1195 */
1196# define ARM_2D_LOG_WARNING(__CHN, __INDENT, __PREFIX, __FORMAT_STR, ...) \
1197 __ARM_2D_LOG_PRINTF_##__CHN( \
1198 (__INDENT), \
1199 (ARM_2D_LOG_CHN_TYPE_WARNING | ARM_2D_LOG_CHN_##__CHN), \
1200 (__PREFIX), \
1201 (__FORMAT_STR),##__VA_ARGS__)
1202
1203/*!
1204 * \brief the log entry for error messages
1205 * \param[in] __CHN the channel name, e.g. PIPELINE, OPCODE, HELPER, HELPER_PFB etc.
1206 * \param[in] __INDENT number of indents before print actual content
1207 * \param[in] __PREFIX a string used as prefix, we can use it to print content
1208 * like function name, service name etc.
1209 * \param[in] __FORMAT_STR the format string used in printf
1210 * \param[in] ... the optional parameters
1211 */
1212# define ARM_2D_LOG_ERROR(__CHN, __INDENT, __PREFIX, __FORMAT_STR, ...) \
1213 __ARM_2D_LOG_PRINTF_##__CHN( \
1214 (__INDENT), \
1215 (ARM_2D_LOG_CHN_TYPE_ERROR | ARM_2D_LOG_CHN_##__CHN), \
1216 (__PREFIX), \
1217 (__FORMAT_STR),##__VA_ARGS__)
1218
1219/*!
1220 * \brief the log entry for user messages
1221 * \param[in] __CHN the channel name, e.g. PIPELINE, OPCODE, HELPER, HELPER_PFB etc.
1222 * \param[in] __INDENT number of indents before print actual content
1223 * \param[in] __PREFIX a string used as prefix, we can use it to print content
1224 * like function name, service name etc.
1225 * \param[in] __FORMAT_STR the format string used in printf
1226 * \param[in] ... the optional parameters
1227 */
1228# define ARM_2D_LOG_USER(__CHN, __INDENT, __PREFIX, __FORMAT_STR, ...) \
1229 __ARM_2D_LOG_PRINTF_##__CHN( \
1230 (__INDENT), \
1231 (ARM_2D_LOG_CHN_TYPE_USER | ARM_2D_LOG_CHN_##__CHN), \
1232 (__PREFIX), \
1233 (__FORMAT_STR),##__VA_ARGS__)
1234
1235#else
1236# define ARM_2D_LOG_INFO(__CHN, __INDENT, __PREFIX, __FORMAT_STR, ...)
1237# define ARM_2D_LOG_WARNING(__CHN, __INDENT, __PREFIX, __FORMAT_STR, ...)
1238# define ARM_2D_LOG_ERROR(__CHN, __INDENT, __PREFIX, __FORMAT_STR, ...)
1239# define ARM_2D_LOG_USER(__CHN, __INDENT, __PREFIX, __FORMAT_STR, ...)
1240#endif
1241
1242
1243#ifndef __ARM_2D_PORT_PRINTF__
1244/*!
1245 * \brief the low level entry for printf
1246 * \note you can define this macro for retargeting
1247 */
1248# define __ARM_2D_PORT_PRINTF__(__format, ...) printf((__format), ##__VA_ARGS__)
1249#endif
1250
1251#ifndef __ARM_2D_LOG_MAX_STRING_LEN__
1252/*!
1253 * \brief the maximum allowed string length. The log service requests the specified
1254 * number of bytes for storing string. default value is 256
1255 * \note please make sure there are sufficient memory in HEAP.
1256 */
1257# define __ARM_2D_LOG_MAX_STRING_LEN__ 256
1258#endif
1259
1260/*============================ TYPES =========================================*/
1261
1262/*!
1263 * \brief a type for generic list
1264 *
1265 * \note to avoid using container_of() operand, please put __arm_slist_node_t
1266 * at the beginning of a class/structure
1267 */
1270 __arm_slist_node_t *ptNext; //!< the next node
1271};
1272
1273
1274/*============================ GLOBAL VARIABLES ==============================*/
1275/*============================ PROTOTYPES ====================================*/
1276
1277/*!
1278 * \brief an entry for log printf
1279 * \param[in] nIndentLevel number of indents before print actual content
1280 * \param[in] wChannelMask a bit-mask to indicate the log channel
1281 * \param[in] pchPrefix a string used as prefix, we can use it to print content
1282 * like function name, service name etc.
1283 * \param[in] pchFormatString the format string used in printf
1284 * \param[in] ... the optional parameters
1285 */
1286extern
1287void __arm_2d_log_printf(int32_t nIndentLevel,
1288 uint32_t wChannelMask,
1289 const char *pchPrefix,
1290 const char *pchFormatString,
1291 ...);
1292
1293
1294#if defined(__clang__)
1295# pragma clang diagnostic pop
1296#elif __IS_COMPILER_ARM_COMPILER_5__
1297#elif __IS_COMPILER_GCC__
1298# pragma GCC diagnostic pop
1299#endif
1300
1301#ifdef __cplusplus
1302}
1303#endif
1304
1305
1306#endif /* end of __ARM_2D_UTILS_H__ */
1307
1308
1309/*! @} */
1310
1311/*============================ MACROS ========================================*/
1312/*----------------------------------------------------------------------------*
1313 * Reentrant Macros *
1314 *----------------------------------------------------------------------------*/
1315
1316/* un-define macros */
1317#undef ARM_PRIVATE
1318#undef ARM_PROTECTED
1319#undef ARM_PUBLIC
1320
1321#define ARM_PUBLIC(...) struct {__VA_ARGS__};
1322
1323/* redefine macros */
1324#if defined(__cplusplus)
1325# define ARM_PRIVATE(...) \
1326 struct { \
1327 __VA_ARGS__ \
1328 };
1329
1330# define ARM_PROTECTED(...) \
1331 struct { \
1332 __VA_ARGS__ \
1333 };
1334
1335#elif defined(__ARM_2D_IMPL__) || defined(__IS_COMPILER_IAR__)
1336
1337# define ARM_PRIVATE(...) \
1338 struct { \
1339 __VA_ARGS__ \
1340 } __ALIGNED(__alignof__(struct {__VA_ARGS__}));
1341
1342# define ARM_PROTECTED(...) \
1343 struct { \
1344 __VA_ARGS__ \
1345 } __ALIGNED(__alignof__(struct {__VA_ARGS__}));
1346
1347#elif defined(__ARM_2D_INHERIT__)
1348
1349# define ARM_PRIVATE(...) \
1350 uint8_t ARM_CONNECT3(chMask,__LINE__,__COUNTER__) \
1351 [sizeof(struct {__VA_ARGS__})] \
1352 __ALIGNED(__alignof__(struct {__VA_ARGS__}));
1353
1354# define ARM_PROTECTED(...) \
1355 struct { \
1356 __VA_ARGS__ \
1357 } __ALIGNED(__alignof__(struct {__VA_ARGS__}));
1358
1359#else
1360# define ARM_PRIVATE(...) \
1361 uint8_t ARM_CONNECT3(chMask,__LINE__,__COUNTER__) \
1362 [sizeof(struct {__VA_ARGS__})] \
1363 __ALIGNED(__alignof__(struct {__VA_ARGS__}));
1364
1365# define ARM_PROTECTED(...) \
1366 uint8_t ARM_CONNECT3(chMask,__LINE__,__COUNTER__) \
1367 [sizeof(struct {__VA_ARGS__})] \
1368 __ALIGNED(__alignof__(struct {__VA_ARGS__}));
1369#endif
1370
1371
1372#undef ARM_PRIVATE_METHOD
1373#undef ARM_PROTECTED_METHOD
1374#undef ARM_PUBLIC_METHOD
1375
1376#if defined(__ARM_2D_IMPL__)
1377
1378# define ARM_PRIVATE_METHOD(...) __VA_ARGS__
1379# define ARM_PROTECTED_METHOD(...) __VA_ARGS__
1380# define ARM_PUBLIC_METHOD(...) __VA_ARGS__
1381
1382#elif defined(__ARM_2D_INHERIT__)
1383
1384# define ARM_PRIVATE_METHOD(...)
1385# define ARM_PROTECTED_METHOD(...) __VA_ARGS__
1386# define ARM_PUBLIC_METHOD(...) __VA_ARGS__
1387
1388#else
1389
1390# define ARM_PRIVATE_METHOD(...)
1391# define ARM_PROTECTED_METHOD(...)
1392# define ARM_PUBLIC_METHOD(...) __VA_ARGS__
1393
1394#endif
1395
1396
1397
1398/* post un-define macros */
1399
1400#undef __ARM_2D_IMPL__
1401#undef __ARM_2D_INHERIT__