Px4控制台
控制台的入口
启动 rcS脚本中 :nshterm /dev/ttyACM0 &
int
nshterm_main(int argc, char *argv[]) ———>
int nsh_consolemain(int argc, char *argv[])
{
FAR struct console_stdio_s *pstate = nsh_newconsole();
int ret;
DEBUGASSERT(pstate);
/* Initialize any USB tracing options that were requested */
#ifdef CONFIG_NSH_USBDEV_TRACE
usbtrace_enable(TRACE_BITSET);
#endif
/* Initialize the USB serial driver */
#if defined(CONFIG_PL2303) || defined(CONFIG_CDCACM)
#ifdef CONFIG_CDCACM
ret = cdcacm_initialize(CONFIG_NSH_USBDEV_MINOR, NULL);
#else
ret = usbdev_serialinitialize(CONFIG_NSH_USBDEV_MINOR);
#endif
DEBUGASSERT(ret == OK);
#endif
/* Configure to use /dev/null if we do not have a valid console. */
#ifndef CONFIG_DEV_CONSOLE
(void)nsh_nullstdio();
#endif
/* Execute the one-time start-up script (output may go to /dev/null) */
#ifdef CONFIG_NSH_ROMFSETC
(void)nsh_initscript(&pstate->cn_vtbl);
#endif
/* Now loop, executing creating a session for each USB connection */
for (;;)
{
/* Wait for the USB to be connected to the host and switch
* standard I/O to the USB serial device.
*/
ret = nsh_waitusbready();
DEBUGASSERT(ret == OK);
/* Execute the session */
(void)nsh_session(pstate);
/* Switch to /dev/null because we probably no longer have a
* valid console device.
*/
(void)nsh_nullstdio();
}
}
分析:
1、 (void)nsh_initscript(&pstate->cn_vtbl);
该函数执行启动脚本;
2、ret = nsh_waitusbready();
#ifdef HAVE_USB_CONSOLE
static int nsh_waitusbready(void)
{
char inch;
ssize_t nbytes;
int nlc;
int fd;
/* Don't start the NSH console until the console device is ready. Chances
* are, we get here with no functional console. The USB console will not
* be available until the device is connected to the host and until the
* host-side application opens the connection.
*/
/* Open the USB serial device for read/write access */
do
{
/* Try to open the console */
fd = open(CONFIG_NSH_USBCONDEV, O_RDWR); //在这里代开和控制台关联的uart(usb转串口)
if (fd < 0)
{
/* ENOTCONN means that the USB device is not yet connected. Anything
* else is bad.
*/
DEBUGASSERT(errno == ENOTCONN);
/* Sleep a bit and try again */
sleep(2);
}
}
while (fd < 0);
/* Now wait until we successfully read a carriage return a few times.
* That is a sure way of know that there is something at the other end of
* the USB serial connection that is ready to talk with us. The user needs
* to hit ENTER a few times to get things started.
*/
nlc = 0;
do
{
/* Read one byte */
inch = 0;
nbytes = read(fd, &inch, 1); //从串口设备读数据
/* Is it a carriage return (or maybe a newline)? */
if (nbytes == 1 && (inch == '\n' || inch == '\r'))
{
/* Yes.. increment the count */
nlc++;
}
else
{
/* No.. Reset the count. We need to see 3 in a row to continue. */
nlc = 0;
}
}
while (nlc < 3);
/* Configure standard I/O */
nsh_configstdio(fd);
/* We can close the original file descriptor now (unless it was one of 0-2) */
if (fd > 2)
{
close(fd);
}
return OK;
}
#endif
3、(void)nsh_session(pstate); ——>
int nsh_parse(FAR struct nsh_vtbl_s *vtbl, char *cmdline)——>
int nsh_builtin(FAR struct nsh_vtbl_s *vtbl, FAR const char *cmd,
FAR char **argv, FAR const char *redirfile, int oflags) ——>
int exec_builtin(FAR const char *appname, FAR char * const *argv,
FAR const char *redirfile, int oflags) ——>
/* Start the built-in */
ret = task_spawn(&pid, builtin->name, builtin->main, &file_actions,
&attr, (argv) ? &argv[1] : (FAR char * const *)NULL,
(FAR char * const *)NULL);
执行控制台命令。