blob: fc59f31b352ea9fc5f51ae72daf9f418af7ebf11 [file] [log] [blame]
Enabling The Console and Shell for Blinky
-----------------------------------------
This tutorial shows you how to add the Console and Shell to the Blinky
application and interact with it over a serial line connection.
.. contents::
:local:
:depth: 2
Prerequisites
~~~~~~~~~~~~~
- Work through one of the :doc:`Blinky Tutorials <blinky>` to create and build a Blinky
application for one of the boards.
- Have a :doc:`serial setup <../../get_started/serial_access>`.
Use an Existing Project
~~~~~~~~~~~~~~~~~~~~~~~
Since all we're doing is adding the shell and console capability to
blinky, we assume that you have worked through at least some of the
other tutorials, and have an existing project. For this example, we'll
be modifying the :doc:`blinky on nRF52 <nRF52>` project to enable the
shell and console connectivity. You can use blinky on a different board.
Modify the Dependencies and Configuration
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Modify the package dependencies in your application target's ``pkg.yml``
file as follows:
- Add the shell package: ``@apache-mynewt-core/sys/shell``.
- Replace the ``@apache-mynewt-core/sys/console/stub`` package with the
``@apache-mynewt-core/sys/console/full`` package.
**Note**: If you are using version 1.1 or lower of blinky, the
``@apache-mynewt-core/sys/console/full`` package may be already
listed as a dependency.
The updated ``pkg.yml`` file should have the following two lines:
.. code-block:: yaml
pkg.deps:
- "@apache-mynewt-core/sys/console/full"
- "@apache-mynewt-core/sys/shell"
This lets the newt system know that it needs to pull in the code for the
console and the shell.
Modify the system configuration settings to enable Shell and Console
ticks and prompt. Add the following to your application target's
``syscfg.yml`` file:
.. code-block:: yaml
syscfg.vals:
# Enable the shell task.
SHELL_TASK: 1
SHELL_PROMPT_MODULE: 1
Use the OS Default Event Queue to Process Blinky Timer and Shell Events
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Mynewt creates a main task that executes the application ``main()``
function. It also creates an OS default event queue that packages can
use to queue their events. Shell uses the OS default event queue for
Shell events, and ``main()`` can process the events in the context of
the main task.
Blinky's main.c is very simple. It only has a ``main()`` function that
executes an infinite loop to toggle the LED and sleep for one second. We
will modify blinky:
- To use os_callout to generate a timer event every one second instead
of sleeping. The timer events are added to the OS default event
queue.
- To process events from the OS default event queue inside the infinite
loop in ``main()``.
This allows the main task to process both Shell events and the timer
events to toggle the LED from the OS default event queue.
Modify main.c
~~~~~~~~~~~~~
Initialize a os_callout timer and move the toggle code from the while
loop in ``main()`` to the event callback function. Add the following
code above the ``main()`` function:
.. code-block:: cpp
/* The timer callout */
static struct os_callout blinky_callout;
/*
* Event callback function for timer events. It toggles the led pin.
*/
static void
timer_ev_cb(struct os_event *ev)
{
assert(ev != NULL);
++g_task1_loops;
hal_gpio_toggle(g_led_pin);
os_callout_reset(&blinky_callout, OS_TICKS_PER_SEC);
}
static void
init_timer(void)
{
/*
* Initialize the callout for a timer event.
*/
os_callout_init(&blinky_callout, os_eventq_dflt_get(),
timer_ev_cb, NULL);
os_callout_reset(&blinky_callout, OS_TICKS_PER_SEC);
}
In ``main()``, add the call to the ``init_timer()`` function before the
while loop and modify the while loop to process events from the OS
default event queue:
.. code-block:: cpp
:emphasize-lines: 14,16
int
main(int argc, char **argv)
{
int rc;
#ifdef ARCH_sim
mcu_sim_parse_args(argc, argv);
#endif
sysinit();
g_led_pin = LED_BLINK_PIN;
hal_gpio_init_out(g_led_pin, 1);
init_timer();
while (1) {
os_eventq_run(os_eventq_dflt_get());
}
assert(0);
return rc;
}
Build, Run, and Upload the Blinky Application Target
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
We're not going to build the bootloader here since we are assuming that
you have already built and loaded it during previous tutorials.
We will use the ``newt run`` command to build and deploy our improved
blinky image. The run command performs the following tasks for us:
1. Builds a binary Mynewt executable
2. Wraps the executable in an image header and footer, turning it into a
Mynewt image.
3. Uploads the image to the target hardware.
4. Starts a gdb process to remotely debug the Mynewt device.
Run the ``newt run nrf52_blinky 0`` command. The ``0`` is the version
number that should be written to the image header. Any version will do,
so we choose 0.
.. code-block:: console
$ newt run nrf52_blinky 0
...
Archiving util_mem.a
Linking /home/me/dev/myproj/bin/targets/nrf52_blinky/app/apps/blinky/blinky.elf
App image succesfully generated: /home/me/dev/myproj/bin/targets/nrf52_blinky/app/apps/blinky/blinky.elf
Loading app image into slot 1
[/home/me/dev/myproj/repos/apache-mynewt-core/hw/bsp/nrf52dk/nrf52dk_debug.sh /home/me/dev/myproj/repos/apache-mynewt-core/hw/bsp/nrf52dk /home/me/dev/myproj/bin/targets/nrf52_blinky/app/apps/blinky]
Debugging /home/me/dev/myproj/bin/targets/nrf52_blinky/app/apps/blinky/blinky.elf
Set Up a Serial Connection
~~~~~~~~~~~~~~~~~~~~~~~~~~
You'll need a Serial connection to see the output of your program. You
can reference the :doc:`../../get_started/serial_access` Tutorial for more information
on setting up your serial communication.
Communicate with the Application
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Once you have a connection set up, you can connect to your device as
follows:
- On Mac OS and Linux platforms, you can run
``minicom -D /dev/tty.usbserial-<port> -b 115200`` to connect to the
console of your app. Note that on Linux, the format of the port name
is ``/dev/ttyUSB<N>``, where N is a number.
- On Windows, you can use a terminal application such as PuTTY to
connect to the device.
If you located your port from a MinGW terminal, the port name format is
``/dev/ttyS<N>``, where ``N`` is a number. You must map the port name to
a Windows COM port: ``/dev/ttyS<N>`` maps to ``COM<N+1>``. For example,
``/dev/ttyS2`` maps to ``COM3``.
You can also use the Windows Device Manager to locate the COM port.
To test and make sure that the Shell is running, first just hit :
.. code-block:: console
004543 shell>
You can try some commands:
.. code-block:: console
003005 shell> help
003137 Available modules:
003137 os
003138 prompt
003138 To select a module, enter 'select <module name>'.
003140 shell> prompt
003827 help
003827 ticks shell ticks command
004811 shell> prompt ticks off
005770 Console Ticks off
shell> prompt ticks on
006404 Console Ticks on
006404 shell>