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