1 /*
2 * Copyright (c) 2015 Intel Corporation
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #include <zephyr/ztest.h>
8
9 #define BUF_SZ 1024
10
11 static int pos;
12 char pk_console[BUF_SZ];
13
14 void __printk_hook_install(int (*fn)(int));
15 void *__printk_get_hook(void);
16 int (*_old_char_out)(int);
17
18 #if defined(CONFIG_PICOLIBC)
19
20 #define ZEPHYR_PICOLIBC_VERSION (__PICOLIBC__ * 10000 + \
21 __PICOLIBC_MINOR__ * 100 + \
22 __PICOLIBC_PATCHLEVEL__)
23
24 #ifdef CONFIG_PICOLIBC_IO_MINIMAL
25 /*
26 * If picolibc is >= 1.8.4, then minimal printf is available. Otherwise,
27 * we're going to get the floating point version when the minimal one is
28 * selected.
29 */
30 #if ZEPHYR_PICOLIBC_VERSION >= 10804
31 #define HAS_PICOLIBC_IO_MINIMAL
32 #else
33 #define HAS_PICOLIBC_IO_FLOAT
34 #endif
35 #endif
36
37 #ifdef CONFIG_PICOLIBC_IO_LONG_LONG
38 /*
39 * If picolibc is >= 1.8.5, then long long printf is available. Otherwise,
40 * we're going to get the floating point version when the long long one is
41 * selected.
42 */
43 #if ZEPHYR_PICOLIBC_VERSION >= 10805
44 #define HAS_PICOLIBC_IO_LONG_LONG
45 #else
46 #define HAS_PICOLIBC_IO_FLOAT
47 #endif
48 #endif
49
50 #ifdef CONFIG_PICOLIBC_IO_FLOAT
51 #define HAS_PICOLIBC_IO_FLOAT
52 #endif
53
54 /*
55 * Picolibc long long support is present if Zephyr configuration has
56 * enabled long long or floating point support.
57 */
58
59 char expected_32[] = "22 113 10000 32768 40000 22\n"
60 "p 112 -10000 -32768 -40000 -22\n"
61 #if defined(HAS_PICOLIBC_IO_MINIMAL)
62 "0x1 0x1 0x1 0x1 0x1\n"
63 "0x1 0x1 0x1 0x1\n"
64 "42 42 42 42\n"
65 "-42 -42 -42 -42\n"
66 "42 42 42 42\n"
67 "42 42 42 42\n"
68 "25542abcdef 42\n"
69 #if defined(_WANT_MINIMAL_IO_LONG_LONG)
70 "68719476735 -1 18446744073709551615 ffffffffffffffff\n"
71 #else
72 "-1 -1 4294967295 ffffffff\n"
73 #endif
74 #else
75 "0x1 0x01 0x0001 0x00000001 0x0000000000000001\n"
76 "0x1 0x 1 0x 1 0x 1\n"
77 "42 42 0042 00000042\n"
78 "-42 -42 -042 -0000042\n"
79 "42 42 42 42\n"
80 "42 42 0042 00000042\n"
81 "255 42 abcdef 42\n"
82 #if defined(HAS_PICOLIBC_IO_LONG_LONG) || defined(HAS_PICOLIBC_IO_FLOAT)
83 "68719476735 -1 18446744073709551615 ffffffffffffffff\n"
84 #else
85 "-1 -1 4294967295 ffffffff\n"
86 #endif
87 #endif
88 "0xcafebabe 0xbeef 0x2a\n"
89 ;
90
91 char expected_64[] = "22 113 10000 32768 40000 22\n"
92 "p 112 -10000 -32768 -40000 -22\n"
93 #if defined(HAS_PICOLIBC_IO_MINIMAL)
94 "0x1 0x1 0x1 0x1 0x1\n"
95 "0x1 0x1 0x1 0x1\n"
96 "42 42 42 42\n"
97 "-42 -42 -42 -42\n"
98 "42 42 42 42\n"
99 "42 42 42 42\n"
100 "25542abcdef 42\n"
101 #else
102 "0x1 0x01 0x0001 0x00000001 0x0000000000000001\n"
103 "0x1 0x 1 0x 1 0x 1\n"
104 "42 42 0042 00000042\n"
105 "-42 -42 -042 -0000042\n"
106 "42 42 42 42\n"
107 "42 42 0042 00000042\n"
108 "255 42 abcdef 42\n"
109 #endif
110 "68719476735 -1 18446744073709551615 ffffffffffffffff\n"
111 "0xcafebabe 0xbeef 0x2a\n"
112 ;
113 char *expected = (sizeof(long) == sizeof(long long)) ? expected_64 : expected_32;
114 #else
115 #if defined(CONFIG_CBPRINTF_FULL_INTEGRAL)
116 char *expected = "22 113 10000 32768 40000 22\n"
117 "p 112 -10000 -32768 -40000 -22\n"
118 "0x1 0x01 0x0001 0x00000001 0x0000000000000001\n"
119 "0x1 0x 1 0x 1 0x 1\n"
120 "42 42 0042 00000042\n"
121 "-42 -42 -042 -0000042\n"
122 "42 42 42 42\n"
123 "42 42 0042 00000042\n"
124 "255 42 abcdef 42\n"
125 "68719476735 -1 18446744073709551615 ffffffffffffffff\n"
126 "0xcafebabe 0xbeef 0x2a\n"
127 ;
128 #elif defined(CONFIG_CBPRINTF_COMPLETE)
129 char *expected = "22 113 10000 32768 40000 %llu\n"
130 "p 112 -10000 -32768 -40000 %lld\n"
131 "0x1 0x01 0x0001 0x00000001 0x0000000000000001\n"
132 "0x1 0x 1 0x 1 0x 1\n"
133 "42 42 0042 00000042\n"
134 "-42 -42 -042 -0000042\n"
135 "42 42 42 42\n"
136 "42 42 0042 00000042\n"
137 "255 42 abcdef 42\n"
138 "%lld %lld %llu %llx\n"
139 "0xcafebabe 0xbeef 0x2a\n"
140 ;
141 #elif defined(CONFIG_CBPRINTF_NANO)
142 char *expected = "22 113 10000 32768 40000 22\n"
143 "p 112 -10000 -32768 -40000 -22\n"
144 "0x1 0x01 0x0001 0x00000001 0x0000000000000001\n"
145 "0x1 0x 1 0x 1 0x 1\n"
146 "42 42 0042 00000042\n"
147 "-42 -42 -042 -0000042\n"
148 "42 42 42 42\n"
149 "42 42 0042 00000042\n"
150 "255 42 abcdef 42\n"
151 "ERR -1 ERR ERR\n"
152 "0xcafebabe 0xbeef 0x2a\n"
153 ;
154 #endif
155 #endif
156
157 size_t stv = 22;
158 unsigned char uc = 'q';
159 unsigned short int usi = 10000U;
160 unsigned int ui = 32768U;
161 unsigned long ul = 40000;
162
163 /* FIXME
164 * we know printk doesn't have full support for 64-bit values.
165 * at least show it can print uint64_t values less than 32-bits wide
166 */
167 unsigned long long ull = 22;
168
169 char c = 'p';
170 signed short int ssi = -10000;
171 signed int si = -32768;
172 signed long sl = -40000;
173 signed long long sll = -22;
174
175 uint32_t hex = 0xCAFEBABE;
176
177 void *ptr = (void *)0xBEEF;
178
ram_console_out(int character)179 static int ram_console_out(int character)
180 {
181 pk_console[pos] = (char)character;
182 pos = (pos + 1) % BUF_SZ;
183 return _old_char_out(character);
184 }
185 /**
186 * @addtogroup kernel_common_tests
187 * @{
188 */
189
190 /**
191 * @brief Test printk() functionality
192 *
193 * @see printk(), __printk_get_hook(),
194 * __printk_hook_install(), snprintk()
195 *
196 */
ZTEST(printk,test_printk)197 ZTEST(printk, test_printk)
198 {
199 int count;
200
201 if (IS_ENABLED(CONFIG_LOG_PRINTK)) {
202 ztest_test_skip();
203 }
204
205 _old_char_out = __printk_get_hook();
206 __printk_hook_install(ram_console_out);
207
208 printk("%zu %hhu %hu %u %lu %llu\n", stv, uc, usi, ui, ul, ull);
209 printk("%c %hhd %hd %d %ld %lld\n", c, c, ssi, si, sl, sll);
210 printk("0x%x 0x%02x 0x%04x 0x%08x 0x%016x\n", 1, 1, 1, 1, 1);
211 printk("0x%x 0x%2x 0x%4x 0x%8x\n", 1, 1, 1, 1);
212 printk("%d %02d %04d %08d\n", 42, 42, 42, 42);
213 printk("%d %02d %04d %08d\n", -42, -42, -42, -42);
214 printk("%u %2u %4u %8u\n", 42, 42, 42, 42);
215 printk("%u %02u %04u %08u\n", 42, 42, 42, 42);
216 printk("%-8u%-6d%-4x %8d\n", 0xFF, 42, 0xABCDEF, 42);
217 printk("%lld %lld %llu %llx\n", 0xFFFFFFFFFULL, -1LL, -1ULL, -1ULL);
218 printk("0x%x %p %-2p\n", hex, ptr, (char *)42);
219
220 pk_console[pos] = '\0';
221 __printk_hook_install(_old_char_out);
222 printk("expected '%s'\n", expected);
223 zassert_true((strcmp(pk_console, expected) == 0), "printk failed");
224
225 (void)memset(pk_console, 0, sizeof(pk_console));
226 count = 0;
227
228 count += snprintk(pk_console + count, sizeof(pk_console) - count,
229 "%zu %hhu %hu %u %lu %llu\n",
230 stv, uc, usi, ui, ul, ull);
231 count += snprintk(pk_console + count, sizeof(pk_console) - count,
232 "%c %hhd %hd %d %ld %lld\n", c, c, ssi, si, sl, sll);
233 count += snprintk(pk_console + count, sizeof(pk_console) - count,
234 "0x%x 0x%02x 0x%04x 0x%08x 0x%016x\n", 1, 1, 1, 1, 1);
235 count += snprintk(pk_console + count, sizeof(pk_console) - count,
236 "0x%x 0x%2x 0x%4x 0x%8x\n", 1, 1, 1, 1);
237 count += snprintk(pk_console + count, sizeof(pk_console) - count,
238 "%d %02d %04d %08d\n", 42, 42, 42, 42);
239 count += snprintk(pk_console + count, sizeof(pk_console) - count,
240 "%d %02d %04d %08d\n", -42, -42, -42, -42);
241 count += snprintk(pk_console + count, sizeof(pk_console) - count,
242 "%u %2u %4u %8u\n", 42, 42, 42, 42);
243 count += snprintk(pk_console + count, sizeof(pk_console) - count,
244 "%u %02u %04u %08u\n", 42, 42, 42, 42);
245 count += snprintk(pk_console + count, sizeof(pk_console) - count,
246 "%-8u%-6d%-4x %8d\n",
247 0xFF, 42, 0xABCDEF, 42);
248 count += snprintk(pk_console + count, sizeof(pk_console) - count,
249 "%lld %lld %llu %llx\n",
250 0xFFFFFFFFFULL, -1LL, -1ULL, -1ULL);
251 count += snprintk(pk_console + count, sizeof(pk_console) - count,
252 "0x%x %p %-2p\n", hex, ptr, (char *)42);
253 pk_console[count] = '\0';
254 zassert_true((strcmp(pk_console, expected) == 0), "snprintk failed");
255 }
256
257 extern void *common_setup(void);
258 ZTEST_SUITE(printk, NULL, common_setup, NULL, NULL, NULL);
259
260 /**
261 * @}
262 */
263