Skip to content

Commit 3587b0d

Browse files
committed
serial_dm
1 parent 195f94e commit 3587b0d

File tree

5 files changed

+229
-8
lines changed

5 files changed

+229
-8
lines changed

components/drivers/ofw/ofw.c

+26-1
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#include <rtdevice.h>
1313
#include <drivers/platform.h>
1414
#include <drivers/core/bus.h>
15+
#include "../serial/serial_dm.h"
1516

1617
#define DBG_TAG "rtdm.ofw"
1718
#define DBG_LVL DBG_INFO
@@ -168,7 +169,7 @@ static const char *ofw_console_tty_find(char *dst_con, const char *con)
168169
rt_err_t rt_ofw_console_setup(void)
169170
{
170171
rt_err_t err = -RT_ENOSYS;
171-
char con_name[RT_NAME_MAX];
172+
char con_name[RT_NAME_MAX], *options = RT_NULL;
172173
const char *ofw_name = RT_NULL, *stdout_path, *con;
173174

174175
/* chosen.console > chosen.stdout-path > RT_CONSOLE_DEVICE_NAME */
@@ -190,6 +191,18 @@ rt_err_t rt_ofw_console_setup(void)
190191

191192
if (ofw_name)
192193
{
194+
const char *ch = con;
195+
196+
while (*ch && *ch != ' ')
197+
{
198+
if (*ch++ == ',')
199+
{
200+
options = (char *)ch;
201+
202+
break;
203+
}
204+
}
205+
193206
err = RT_EOK;
194207
break;
195208
}
@@ -230,6 +243,18 @@ rt_err_t rt_ofw_console_setup(void)
230243

231244
rt_console_set_device(con);
232245

246+
if (options)
247+
{
248+
rt_device_t con_dev = rt_console_get_device();
249+
250+
if (con_dev)
251+
{
252+
struct serial_configure con_conf = serial_cfg_from_args(options);
253+
254+
rt_device_control(con_dev, RT_DEVICE_CTRL_CONFIG, &con_conf);
255+
}
256+
}
257+
233258
rt_fdt_earlycon_kick(FDT_EARLYCON_KICK_COMPLETED);
234259

235260
LOG_I("Console: %s (%s)", con, ofw_name ? ofw_name : "<unknown>");

components/drivers/serial/SConscript

+14-7
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,19 @@ from building import *
33
cwd = GetCurrentDir()
44
CPPPATH = [cwd + '/../include']
55
group = []
6-
if GetDepend(['RT_USING_SERIAL']):
7-
if GetDepend(['RT_USING_SERIAL_V2']):
8-
src = Glob('serial_v2.c')
9-
group = DefineGroup('DeviceDrivers', src, depend = ['RT_USING_SERIAL_V2'], CPPPATH = CPPPATH)
10-
else:
11-
src = Glob('serial.c')
12-
group = DefineGroup('DeviceDrivers', src, depend = ['RT_USING_SERIAL'], CPPPATH = CPPPATH)
6+
src = []
7+
8+
if not GetDepend(['RT_USING_SERIAL']):
9+
Return('group')
10+
11+
if GetDepend(['RT_USING_SERIAL_V2']):
12+
src += ['serial_v2.c']
13+
else:
14+
src += ['serial.c']
15+
16+
if GetDepend(['RT_USING_DM']):
17+
src += ['serial_dm.c']
18+
19+
group = DefineGroup('DeviceDrivers', src, depend = [''], CPPPATH = CPPPATH)
1320

1421
Return('group')

components/drivers/serial/serial_dm.c

+155
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,155 @@
1+
/*
2+
* Copyright (c) 2006-2022, RT-Thread Development Team
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*
6+
* Change Logs:
7+
* Date Author Notes
8+
* 2022-11-16 GuEe-GUI first version
9+
*/
10+
11+
#include <rtatomic.h>
12+
#include "serial_dm.h"
13+
14+
int serial_dev_set_name(struct rt_serial_device *sdev)
15+
{
16+
int id = -1;
17+
static int uid_min = -1;
18+
static volatile rt_atomic_t uid = 0;
19+
20+
RT_ASSERT(sdev != RT_NULL);
21+
22+
#ifdef RT_USING_OFW
23+
if (sdev->parent.ofw_node)
24+
{
25+
id = rt_ofw_get_alias_id(sdev->parent.ofw_node, "serial");
26+
27+
if (id < 0)
28+
{
29+
id = rt_ofw_get_alias_id(sdev->parent.ofw_node, "uart");
30+
}
31+
32+
if (uid_min < 0)
33+
{
34+
uid_min = rt_ofw_get_alias_last_id("serial");
35+
36+
if (uid_min < 0)
37+
{
38+
uid_min = rt_ofw_get_alias_last_id("uart");
39+
}
40+
41+
uid_min = uid_min < 0 ? 0 : (uid_min + 1);
42+
43+
rt_hw_atomic_store(&uid, uid_min);
44+
}
45+
}
46+
#endif
47+
48+
if (id < 0)
49+
{
50+
id = (int)rt_hw_atomic_add(&uid, 1);
51+
}
52+
53+
return rt_dm_dev_set_name(&sdev->parent, "uart%u", id);
54+
}
55+
56+
void *serial_base_from_args(char *str)
57+
{
58+
rt_ubase_t base = 0;
59+
60+
while (*str && !(*str == 'x' || *str == 'X'))
61+
{
62+
++str;
63+
}
64+
++str;
65+
66+
/* The str may get from bootargs that we need check it */
67+
while (*str && *str != ',' && *str != ' ')
68+
{
69+
base <<= 4;
70+
71+
if ((*str >= 'a' && *str <= 'f') || (*str >= 'A' && *str <= 'F'))
72+
{
73+
base += ((*str | ' ') - 'a') + 10;
74+
}
75+
else
76+
{
77+
base += *str - '0';
78+
}
79+
80+
++str;
81+
}
82+
83+
return (void *)base;
84+
}
85+
86+
struct serial_configure serial_cfg_from_args(char *str)
87+
{
88+
struct serial_configure cfg = RT_SERIAL_CONFIG_DEFAULT;
89+
90+
/* Format baudrate/parity/bits/flow (BBBBPNF), Default is 115200n8 */
91+
if (str && *str)
92+
{
93+
rt_uint32_t baudrate = 0;
94+
95+
/* BBBB is the speed */
96+
while (*str && (*str >= '0' && *str <= '9'))
97+
{
98+
baudrate *= 10;
99+
baudrate += *str - '0';
100+
++str;
101+
}
102+
103+
if (baudrate)
104+
{
105+
cfg.baud_rate = baudrate;
106+
}
107+
108+
/* P is parity (n/o/e) */
109+
switch (*str)
110+
{
111+
case 'n':
112+
cfg.parity = PARITY_NONE;
113+
break;
114+
case 'o':
115+
cfg.parity = PARITY_ODD;
116+
break;
117+
case 'e':
118+
cfg.parity = PARITY_EVEN;
119+
break;
120+
default:
121+
--str;
122+
break;
123+
}
124+
++str;
125+
126+
/* N is number of bits */
127+
if (*str && (*str >= '0' && *str <= '9'))
128+
{
129+
cfg.data_bits = *str;
130+
++str;
131+
}
132+
133+
/* F is flow ontrol ('r' for RTS) */
134+
if (*str)
135+
{
136+
cfg.flowcontrol = (*str == 'r' ? RT_SERIAL_FLOWCONTROL_CTSRTS : RT_SERIAL_FLOWCONTROL_NONE);
137+
++str;
138+
}
139+
140+
#ifdef RT_USING_OFW
141+
if (*str == '\0')
142+
{
143+
const char earlycon_magic[] = { 'O', 'F', 'W', '\0' };
144+
145+
if (!rt_strcmp(++str, earlycon_magic))
146+
{
147+
/* Is OFW earlycon, we should ACK it */
148+
rt_memset(str, 0, RT_ARRAY_SIZE(earlycon_magic));
149+
}
150+
}
151+
#endif
152+
}
153+
154+
return cfg;
155+
}

components/drivers/serial/serial_dm.h

+29
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
/*
2+
* Copyright (c) 2006-2022, RT-Thread Development Team
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*
6+
* Change Logs:
7+
* Date Author Notes
8+
* 2022-11-16 GuEe-GUI first version
9+
*/
10+
11+
#ifndef __SERIAL_DM_H__
12+
#define __SERIAL_DM_H__
13+
14+
#include <rtthread.h>
15+
#include <rtdevice.h>
16+
#include <string.h>
17+
18+
int serial_dev_set_name(struct rt_serial_device *sdev);
19+
20+
void *serial_base_from_args(char *str);
21+
struct serial_configure serial_cfg_from_args(char *str);
22+
23+
#define serial_for_each_args(arg, args) \
24+
for (char *context = (arg = (typeof(arg))args, (void *)RT_NULL), \
25+
*context_end = rt_strchrnul((char *)args, ' '); \
26+
(arg = strtok_r(arg, ",", &context)) && arg < context_end; \
27+
arg = RT_NULL)
28+
29+
#endif /* __SERIAL_DM_H__ */

libcpu/aarch64/common/setup.c

+5
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,11 @@ void rt_hw_fdt_install_early(void *fdt)
7373
}
7474
}
7575

76+
void rt_hw_console_output(const char *str)
77+
{
78+
rt_fdt_earlycon_output(str);
79+
}
80+
7681
rt_weak void rt_hw_idle_wfi(void)
7782
{
7883
__asm__ volatile ("wfi");

0 commit comments

Comments
 (0)