doc: remove obsolete v1 changes/porting docs

doc/kernel/overview/changes.rst contains information about changes from
kernel release 1.5 ("Version 1 Kernel") to the combined "Version 2
Kernel" and doc/porting/application.rst talked about how to change
applications using Version 1 interfaces to the Version 2 interface.
This information remains in the online tagged versions of the
documentation, but it's time to remove this from the current
documentation set. (Also removing example porting code.)

Fixes issue #1524

Signed-off-by: David B. Kinder <david.b.kinder@intel.com>
This commit is contained in:
David B. Kinder 2017-10-02 14:46:37 -07:00 committed by Anas Nashif
parent c1930ed346
commit 37340c7353
8 changed files with 0 additions and 533 deletions

View file

@ -1,161 +0,0 @@
.. _changes_v2:
Changes from Version 1 Kernel
#############################
The current Zephyr kernel incorporates numerous changes from
kernels found in the 1.5 and earlier releases, and improves
ease of use for developers.
Some of the benefits of these changes are:
* elimination of separate microkernel and nanokernel build types,
* elimination of the MDEF in microkernel-based applications,
* simplifying and streamlining the kernel API,
* easing restrictions on the use of kernel objects,
* reducing memory footprint by merging duplicated services, and
* improving performance by reducing context switching.
The most significant changes are discussed below.
Application Design
******************
The earlier microkernel and nanokernel portions of Zephyr have been merged into
a single entity, which is simply referred to as "the kernel". Consequently,
there is now only a single way to design and build Zephyr applications.
The task and fiber context types have been merged into a single type,
known as a "thread". Setting a thread's priority to a negative priority
makes it a "cooperative thread", which operates in a fiber-like manner;
setting it to a non-negative priority makes it a "preemptive thread",
which operates in a task-like manner.
Kernel objects can now be used by both task-like threads and fiber-like
threads. (The previous kernel did not permit fibers to use microkernel
objects, and could result in undesirable busy-waiting when nanokernel
objects were used by tasks.)
Kernel objects now typically allow multiple threads to wait on a given
object. (The previous kernel restricted waiting on certain types of
kernel object to a single thread.)
Kernel object APIs now always execute in the context of the invoking thread.
(The previous kernel required microkernel object APIs to context switch
the thread to the microkernel server fiber, followed by another context
switch back to the invoking thread.)
The MDEF has been eliminated. Consequently, all kernel objects are now defined
directly in code.
.. _kernel_api_changes:
Kernel APIs
***********
Most kernel APIs have been renamed or have had changes to their arguments
(or both) to make them more intuitive, and to improve consistency.
The **k_** and **K_** prefixes are now used by most kernel APIs.
A previous kernel operation that can be invoked from a task, a fiber,
or an ISR using distinct APIs is now invoked from a thread or an ISR
using a single common API.
Many kernel APIs now return 0 to indicate success and a non-zero error code
to indicate the reason for failure. (The previous kernel supported only
two error codes, rather than an unlimited number of them.)
Threads
*******
A task-like thread can now make itself temporarily non-preemptible
by locking the kernel's scheduler (rather than by locking interrupts).
It is now possible to pass up to 3 arguments to a thread's entry point.
(The previous kernel allowed 2 arguments to be passed to a fiber
and allowed no arguments to be passed to a task.)
It is now possible to delay the start of a statically-defined threads.
(The previous kernel only permitted delaying of fibers spawned at run time.)
A task can no longer specify an "task abort handler" function
that is invoked automatically when the task terminates or aborts.
An application can no longer use "task groups" to alter the operation
of a set of related tasks by invoking a single kernel API.
However, applications can provide their own APIs to achieve a similar effect.
The kernel now spawns both a "main thread" and an "idle thread" during
startup. (The previous kernel spawned only a single thread.)
The kernel's main thread performs system initialization and then invokes
:cpp:func:`main()`. If no :cpp:func:`main()` is defined by the application,
the main thread terminates.
System initialization code can now perform blocking operations,
during which time the kernel's idle thread executes.
Timing
******
Most kernel APIs now specify timeout intervals in milliseconds, rather than
in system clock ticks. This change makes things more intuitive for most
developers. However, the kernel still implements timeouts using the
tick-based system clock.
The previous nanokernel timer and microkernel timer object types have been
merged into a single type.
Memory Allocation
*****************
The microkernel memory map object has been renamed to "memory slab", to better
reflect its management of equal-size memory blocks.
It is now possible to specify the alignment used by the memory blocks
belonging to a memory slab or a memory pool.
It is now possible to define a memory pool directly in code.
It is now possible to allocate and free memory in a malloc()-like manner
from a heap data pool.
Synchronization
***************
The previous nanokernel semaphore and microkernel semaphore object types have been
merged into a single type. The new type can now be used as a binary semaphore,
as well as a counting semaphore.
An application can no longer use a "semaphore group" to allow a thread to wait
on multiple semaphores simultaneously. Until the kernel incorporates a
:cpp:func:`select()` or :cpp:func:`poll()` capability an application wishing
to wait on multiple semaphores must either test them individually in a
non-blocking manner or use an additional mechanism, such as an event object,
to signal the application that one of the semaphores is available.
The previous microkernel event object type is renamed to "alert" and is now presented as
a relative to Unix-style signaling. Due to improvements to the implementation
of semaphores, alerts are now less efficient to use for basic synchronization
than semaphores; consequently, alerts should now be reserved for scenarios
requiring the use of a callback function.
Data Passing
************
The previous microkernel FIFO object type has been renamed to "message queue",
to avoid confusion with the nanokernel FIFO object type.
It is now possible to specify the alignment used by the data items
stored in a message queue (aka microkernel FIFO).
The previous microkernel mailbox object type no longer supports the explicit message
priority concept. Messages are now implicitly ordered based on the priority
of the sending thread.
The mailbox object type now supports sending asynchronous
messages using a message buffer. (The previous kernel only supported
asynchronous messages using a message block.)
It is now possible to specify the alignment used by a pipe object's
buffer.

View file

@ -25,4 +25,3 @@ include: fitness wearables, smart watches, and IoT wireless gateways.
:maxdepth: 1
source_tree.rst
changes.rst

View file

@ -1,133 +0,0 @@
.. _application_porting_guide:
Legacy Applications Porting Guide
##################################
.. note::
This document is still work in progress.
This guide will help you move your applications from the nanokernel/microkernel
model to the unified kernel. The unified kernel was introduced with
:ref:`zephyr_1.6` which was released late 2016.
A list of the major changes that came with the unified kernel can be found in
the section :ref:`changes_v2`.
API Changes
***********
As described in the section :ref:`kernel_api_changes` the kernel now has one
unified and consistent API with new naming.
Same Arguments
==============
In many cases, a simple search and replace is enough to move from the legacy to
the new APIs, for example:
* :cpp:func:`task_abort()` -> :cpp:func:`k_thread_abort()`
* :cpp:func:`task_sem_count_get()` -> :cpp:func:`k_sem_count_get()`
Additional Arguments
====================
The number of arguments to some APIs have changed,
* :cpp:func:`nano_sem_init()` -> :cpp:func:`k_sem_init()`
This function now accepts 2 additional arguments:
- Initial semaphore count
- Permitted semaphore count
When porting your application, make sure you have set the right arguments. For
example, calls to the old API:
.. code-block:: c
nano_sem_init(sem)
depending on the usage becomes in most cases:
.. code-block:: c
k_sem_init(sem, 0, UINT_MAX);
Return Codes
============
Many kernel APIs now return 0 to indicate success and a non-zero error code
to indicate the reason for failure. You should pay special attention to this
change when checking for return codes from kernel APIs, for example:
* :cpp:func:`k_sem_take()` now returns 0 on success, in the legacy API
:cpp:func:`nano_sem_take()` returned 1 when a semaphore is available.
Application Porting
*******************
The existing :ref:`synchronization_sample` from the Zephyr tree will be used to
guide you with porting a legacy application to the new kernel.
The code has been ported to the new kernel and is shown below:
.. literalinclude:: sync_v2.c
:linenos:
:language: c
:lines: 9-
Porting a Nanokernel Application
=================================
Below is the code for the application using the legacy kernel:
.. literalinclude:: sync_v1_nano.c
:linenos:
:language: c
:lines: 9-
Porting a Microkernel Application
=================================
The MDEF feature of the legacy kernel has been eliminated. Consequently, all
kernel objects are now defined directly in code.
Below is the code for the application using the legacy kernel:
.. literalinclude:: sync_v1.c
:linenos:
:language: c
:lines: 9-
A microkernel application defines the used objects in an MDEF file, for this
porting sample using the :ref:`synchronization_sample`, the file is shown below:
.. literalinclude:: v1.mdef
:linenos:
In the unified kernel the semaphore will be defined in the code as follows:
.. literalinclude:: sync_v2.c
:linenos:
:language: c
:lines: 51-54
The threads (previously named tasks) are defined in the code as follows, for
thread A:
.. literalinclude:: sync_v2.c
:linenos:
:language: c
:lines: 88-89
Thread B (taskB in the microkernel) will be spawned dynamically from thread A
(See :ref:`spawning_thread` section):
.. literalinclude:: sync_v2.c
:linenos:
:language: c
:lines: 80-82

View file

@ -11,5 +11,4 @@ architectures, SoCs and boards.
arch.rst
board_porting.rst
application.rst
ip-stack-migrate.rst

View file

@ -1,59 +0,0 @@
/* hello.c - Hello World demo */
/*
* Copyright (c) 2012-2014 Wind River Systems, Inc.
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <zephyr.h>
#include <misc/printk.h>
/*
* Microkernel version of hello world demo has two tasks that utilize
* semaphores and sleeps to take turns printing a greeting message at
* a controlled rate.
*/
/* specify delay between greetings (in ms); compute equivalent in ticks */
#define SLEEPTIME 500
#define SLEEPTICKS (SLEEPTIME * sys_clock_ticks_per_sec / 1000)
/*
*
* @param taskname task identification string
* @param mySem task's own semaphore
* @param otherSem other task's semaphore
*
*/
void helloLoop(const char *taskname, ksem_t mySem, ksem_t otherSem)
{
while (1) {
task_sem_take(mySem, TICKS_UNLIMITED);
/* say "hello" */
printk("%s: Hello World from %s!\n", taskname, CONFIG_ARCH);
/* wait a while, then let other task have a turn */
task_sleep(SLEEPTICKS);
task_sem_give(otherSem);
}
}
void taskA(void)
{
/* taskA gives its own semaphore, allowing it to say hello right away */
task_sem_give(TASKASEM);
/* invoke routine that allows task to ping-pong hello messages with taskB */
helloLoop(__func__, TASKASEM, TASKBSEM);
}
void taskB(void)
{
/* invoke routine that allows task to ping-pong hello messages with taskA */
helloLoop(__func__, TASKBSEM, TASKASEM);
}

View file

@ -1,78 +0,0 @@
/* main.c - Synchronisation demo */
/*
* Copyright (c) 2012-2014 Wind River Systems, Inc.
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <zephyr.h>
#include <misc/printk.h>
/*
* Nanokernel version of hello world demo has a task and a fiber that utilize
* semaphores and timers to take turns printing a greeting message at
* a controlled rate.
*/
/* specify delay between greetings (in ms); compute equivalent in ticks */
#define SLEEPTIME 500
#define SLEEPTICKS (SLEEPTIME * sys_clock_ticks_per_sec / 1000)
#define STACKSIZE 2000
char __stack fiberStack[STACKSIZE];
struct nano_sem nanoSemTask;
struct nano_sem nanoSemFiber;
void fiberEntry(void)
{
struct nano_timer timer;
u32_t data[2] = {0, 0};
nano_sem_init(&nanoSemFiber);
nano_timer_init(&timer, data);
while (1) {
/* wait for task to let us have a turn */
nano_fiber_sem_take(&nanoSemFiber, TICKS_UNLIMITED);
/* say "hello" */
printk("%s: Hello World!\n", __func__);
/* wait a while, then let task have a turn */
nano_fiber_timer_start(&timer, SLEEPTICKS);
nano_fiber_timer_test(&timer, TICKS_UNLIMITED);
nano_fiber_sem_give(&nanoSemTask);
}
}
void main(void)
{
struct nano_timer timer;
u32_t data[2] = {0, 0};
task_fiber_start(&fiberStack[0], STACKSIZE,
(nano_fiber_entry_t) fiberEntry, 0, 0, 7, 0);
nano_sem_init(&nanoSemTask);
nano_timer_init(&timer, data);
while (1) {
/* say "hello" */
printk("%s: Hello World!\n", __func__);
/* wait a while, then let fiber have a turn */
nano_task_timer_start(&timer, SLEEPTICKS);
nano_task_timer_test(&timer, TICKS_UNLIMITED);
nano_task_sem_give(&nanoSemFiber);
/* now wait for fiber to let us have a turn */
nano_task_sem_take(&nanoSemTask, TICKS_UNLIMITED);
}
}

View file

@ -1,89 +0,0 @@
/* main.c - Hello World demo */
/*
* Copyright (c) 2012-2014 Wind River Systems, Inc.
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <zephyr.h>
#include <misc/printk.h>
/*
* The hello world demo has two threads that utilize semaphores and sleeping
* to take turns printing a greeting message at a controlled rate. The demo
* shows both the static and dynamic approaches for spawning a thread; a real
* world application would likely use the static approach for both threads.
*/
/* size of stack area used by each thread */
#define STACKSIZE 1024
/* scheduling priority used by each thread */
#define PRIORITY 7
/* delay between greetings (in ms) */
#define SLEEPTIME 500
/*
* @param my_name thread identification string
* @param my_sem thread's own semaphore
* @param other_sem other thread's semaphore
*/
void helloLoop(const char *my_name,
struct k_sem *my_sem, struct k_sem *other_sem)
{
while (1) {
/* take my semaphore */
k_sem_take(my_sem, K_FOREVER);
/* say "hello" */
printk("%s: Hello World from %s!\n", my_name, CONFIG_ARCH);
/* wait a while, then let other thread have a turn */
k_sleep(SLEEPTIME);
k_sem_give(other_sem);
}
}
/* define semaphores */
K_SEM_DEFINE(threadA_sem, 1, 1); /* starts off "available" */
K_SEM_DEFINE(threadB_sem, 0, 1); /* starts off "not available" */
/* threadB is a dynamic thread that is spawned by threadA */
void threadB(void *dummy1, void *dummy2, void *dummy3)
{
ARG_UNUSED(dummy1);
ARG_UNUSED(dummy2);
ARG_UNUSED(dummy3);
/* invoke routine to ping-pong hello messages with threadA */
helloLoop(__func__, &threadB_sem, &threadA_sem);
}
char __noinit __stack threadB_stack_area[STACKSIZE];
/* threadA is a static thread that is spawned automatically */
void threadA(void *dummy1, void *dummy2, void *dummy3)
{
ARG_UNUSED(dummy1);
ARG_UNUSED(dummy2);
ARG_UNUSED(dummy3);
/* spawn threadB */
k_thread_spawn(threadB_stack_area, STACKSIZE, threadB, NULL, NULL, NULL,
PRIORITY, 0, K_NO_WAIT);
/* invoke routine to ping-pong hello messages with threadB */
helloLoop(__func__, &threadA_sem, &threadB_sem);
}
K_THREAD_DEFINE(threadA_id, STACKSIZE, threadA, NULL, NULL, NULL,
PRIORITY, 0, K_NO_WAIT);

View file

@ -1,11 +0,0 @@
% Application : Hello demo
% TASK NAME PRIO ENTRY STACK GROUPS
% ==================================
TASK TASKA 7 taskA 1024 [EXE]
TASK TASKB 7 taskB 1024 [EXE]
% SEMA NAME
% =============
SEMA TASKASEM
SEMA TASKBSEM