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