You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
FreeRTOS-Kernel/portable/ThirdParty/GCC/Posix/port.c

624 lines
18 KiB
C

portable/GCC/Posix: add new port for Posix (Linux) applications This is similar to the Windows port, allowing FreeRTOS kernel applications to run as regular applications on Posix (Linux) systems. You can use this in a 32-bit or 64-bit application (although there are dynamic memory allocation trace points that do not support 64-bit addresses). Many of the same caveats of running an RTOS on a non-real-time system apply, but this is still very useful for easy debugging/testing applications in a simulated environment. In particular, it allows easy use of tools such as valgrind. You can call standard library functions from tasks but care must be taken with any that internally take mutexes or block. This includes malloc()/free() and many stdio functions (e.g., printf()). Replacement malloc(), free(), realloc(), and calloc() functions are provided which are safe. printf() needs to be called with a FreeRTOS mutex help (or called from only a single task). Each task is run in its own pthread, which makes debugging with standard tools (such as GDB) easier backtraces for individual tasks are available. Threads for non-running tasks are blocked in sigwait(). The stack for each task (thread) is allocated when the thread is created, and the stack provided during task creation is not used. This is so the stack has guard pages, to help with detecting stack overflows. Task switch is done by resuming the thread for the next task by sending it the resume signal (SIGUSR1) and then suspending the current thread. The timer interrupt uses SIGALRM and care is taken to ensure that the signal handler runs only on the thread for the current task. The additional data needed per-thread is stored at the top on the task's stack. When a running task is being deleted, its thread is marked it as dying so when we switch away from it it exits instead of suspending. This ensures that even if the idle task doesn't run, threads are deleted which allows for more threads to be created (if many tasks are being created and deleted in rapid succession). To further aid debugging, SIGINT (^C) is not blocked inside critical sections. This allows it to be used break into GDB while in a critical section. This means that care must be taken with any custom SIGINT handlers as these are like NMIs. This is somewhat inspired by an existing port by William Davy (https://www.freertos.org/FreeRTOS-simulator-for-Linux.html) but it takes a number of different approaches to make it switch tasks reliableand there's little similarly with the original implementation. - Critical sections block scheduling/"interrupts" by blocking signals using pthread_sigmask(). This is more expensive than attempting to use flags but works reliably and is analogous to the interrupt enable/disable on real hardware. - Care is take to ensure that the SIGALRM handler (for the timer tick) is runnable only on the pthread for the running task. This makes tasks switches more straight-forward and reliable as we can suspend the thread while in the signal handler. - Task switches save/restore the critical nesting on the stack. - Only uses a single (SIGUSR1) signal which is ignored and thus GDB's default signal handling options won't trap/print on this signal. - Extra per-thread data is stored on the task's stack, making it accessible in O(1) instead of performing a O(n) lookup of the array. - Uses the task create/delete hooks in a similar way to the Windows port, rather than overloading trace points.
5 years ago
/*
* FreeRTOS Kernel V10.3.0
* Copyright (C) 2020 Cambridge Consultants Ltd.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* http://www.FreeRTOS.org
* http://aws.amazon.com/freertos
*
*/
/*-----------------------------------------------------------
* Implementation of functions defined in portable.h for the Posix port.
*
* Each task has a pthread which eases use of standard debuggers
* (allowing backtraces of tasks etc). Threads for tasks that are not
* running are blocked in sigwait().
*
* Task switch is done by resuming the thread for the next task by
* sending it the resume signal (SIGUSR1) and then suspending the
* current thread.
*
* The timer interrupt uses SIGALRM and care is taken to ensure that
* the signal handler runs only on the thread for the current task.
*
* Use of part of the standard C library requires care as some
* functions can take pthread mutexes internally which can result in
* deadlocks as the FreeRTOS kernel can switch tasks while they're
* holding a pthread mutex.
*
* Replacement malloc(), free(), calloc(), and realloc() are provided
* for glibc (see below for more information).
*
* stdio (printf() and friends) should be called from a single task
* only or serialized with a FreeRTOS primitive such as a binary
* semaphore or mutex.
*----------------------------------------------------------*/
portable/GCC/Posix: add new port for Posix (Linux) applications This is similar to the Windows port, allowing FreeRTOS kernel applications to run as regular applications on Posix (Linux) systems. You can use this in a 32-bit or 64-bit application (although there are dynamic memory allocation trace points that do not support 64-bit addresses). Many of the same caveats of running an RTOS on a non-real-time system apply, but this is still very useful for easy debugging/testing applications in a simulated environment. In particular, it allows easy use of tools such as valgrind. You can call standard library functions from tasks but care must be taken with any that internally take mutexes or block. This includes malloc()/free() and many stdio functions (e.g., printf()). Replacement malloc(), free(), realloc(), and calloc() functions are provided which are safe. printf() needs to be called with a FreeRTOS mutex help (or called from only a single task). Each task is run in its own pthread, which makes debugging with standard tools (such as GDB) easier backtraces for individual tasks are available. Threads for non-running tasks are blocked in sigwait(). The stack for each task (thread) is allocated when the thread is created, and the stack provided during task creation is not used. This is so the stack has guard pages, to help with detecting stack overflows. Task switch is done by resuming the thread for the next task by sending it the resume signal (SIGUSR1) and then suspending the current thread. The timer interrupt uses SIGALRM and care is taken to ensure that the signal handler runs only on the thread for the current task. The additional data needed per-thread is stored at the top on the task's stack. When a running task is being deleted, its thread is marked it as dying so when we switch away from it it exits instead of suspending. This ensures that even if the idle task doesn't run, threads are deleted which allows for more threads to be created (if many tasks are being created and deleted in rapid succession). To further aid debugging, SIGINT (^C) is not blocked inside critical sections. This allows it to be used break into GDB while in a critical section. This means that care must be taken with any custom SIGINT handlers as these are like NMIs. This is somewhat inspired by an existing port by William Davy (https://www.freertos.org/FreeRTOS-simulator-for-Linux.html) but it takes a number of different approaches to make it switch tasks reliableand there's little similarly with the original implementation. - Critical sections block scheduling/"interrupts" by blocking signals using pthread_sigmask(). This is more expensive than attempting to use flags but works reliably and is analogous to the interrupt enable/disable on real hardware. - Care is take to ensure that the SIGALRM handler (for the timer tick) is runnable only on the pthread for the running task. This makes tasks switches more straight-forward and reliable as we can suspend the thread while in the signal handler. - Task switches save/restore the critical nesting on the stack. - Only uses a single (SIGUSR1) signal which is ignored and thus GDB's default signal handling options won't trap/print on this signal. - Extra per-thread data is stored on the task's stack, making it accessible in O(1) instead of performing a O(n) lookup of the array. - Uses the task create/delete hooks in a similar way to the Windows port, rather than overloading trace points.
5 years ago
#include <errno.h>
#include <pthread.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/time.h>
#include <sys/times.h>
#include <time.h>
/* Scheduler includes. */
#include "FreeRTOS.h"
#include "task.h"
/*-----------------------------------------------------------*/
#define SIG_RESUME SIGUSR1
portable/GCC/Posix: add new port for Posix (Linux) applications This is similar to the Windows port, allowing FreeRTOS kernel applications to run as regular applications on Posix (Linux) systems. You can use this in a 32-bit or 64-bit application (although there are dynamic memory allocation trace points that do not support 64-bit addresses). Many of the same caveats of running an RTOS on a non-real-time system apply, but this is still very useful for easy debugging/testing applications in a simulated environment. In particular, it allows easy use of tools such as valgrind. You can call standard library functions from tasks but care must be taken with any that internally take mutexes or block. This includes malloc()/free() and many stdio functions (e.g., printf()). Replacement malloc(), free(), realloc(), and calloc() functions are provided which are safe. printf() needs to be called with a FreeRTOS mutex help (or called from only a single task). Each task is run in its own pthread, which makes debugging with standard tools (such as GDB) easier backtraces for individual tasks are available. Threads for non-running tasks are blocked in sigwait(). The stack for each task (thread) is allocated when the thread is created, and the stack provided during task creation is not used. This is so the stack has guard pages, to help with detecting stack overflows. Task switch is done by resuming the thread for the next task by sending it the resume signal (SIGUSR1) and then suspending the current thread. The timer interrupt uses SIGALRM and care is taken to ensure that the signal handler runs only on the thread for the current task. The additional data needed per-thread is stored at the top on the task's stack. When a running task is being deleted, its thread is marked it as dying so when we switch away from it it exits instead of suspending. This ensures that even if the idle task doesn't run, threads are deleted which allows for more threads to be created (if many tasks are being created and deleted in rapid succession). To further aid debugging, SIGINT (^C) is not blocked inside critical sections. This allows it to be used break into GDB while in a critical section. This means that care must be taken with any custom SIGINT handlers as these are like NMIs. This is somewhat inspired by an existing port by William Davy (https://www.freertos.org/FreeRTOS-simulator-for-Linux.html) but it takes a number of different approaches to make it switch tasks reliableand there's little similarly with the original implementation. - Critical sections block scheduling/"interrupts" by blocking signals using pthread_sigmask(). This is more expensive than attempting to use flags but works reliably and is analogous to the interrupt enable/disable on real hardware. - Care is take to ensure that the SIGALRM handler (for the timer tick) is runnable only on the pthread for the running task. This makes tasks switches more straight-forward and reliable as we can suspend the thread while in the signal handler. - Task switches save/restore the critical nesting on the stack. - Only uses a single (SIGUSR1) signal which is ignored and thus GDB's default signal handling options won't trap/print on this signal. - Extra per-thread data is stored on the task's stack, making it accessible in O(1) instead of performing a O(n) lookup of the array. - Uses the task create/delete hooks in a similar way to the Windows port, rather than overloading trace points.
5 years ago
typedef struct THREAD
{
pthread_t pthread;
pdTASK_CODE pxCode;
void * pvParams;
BaseType_t xDying;
portable/GCC/Posix: add new port for Posix (Linux) applications This is similar to the Windows port, allowing FreeRTOS kernel applications to run as regular applications on Posix (Linux) systems. You can use this in a 32-bit or 64-bit application (although there are dynamic memory allocation trace points that do not support 64-bit addresses). Many of the same caveats of running an RTOS on a non-real-time system apply, but this is still very useful for easy debugging/testing applications in a simulated environment. In particular, it allows easy use of tools such as valgrind. You can call standard library functions from tasks but care must be taken with any that internally take mutexes or block. This includes malloc()/free() and many stdio functions (e.g., printf()). Replacement malloc(), free(), realloc(), and calloc() functions are provided which are safe. printf() needs to be called with a FreeRTOS mutex help (or called from only a single task). Each task is run in its own pthread, which makes debugging with standard tools (such as GDB) easier backtraces for individual tasks are available. Threads for non-running tasks are blocked in sigwait(). The stack for each task (thread) is allocated when the thread is created, and the stack provided during task creation is not used. This is so the stack has guard pages, to help with detecting stack overflows. Task switch is done by resuming the thread for the next task by sending it the resume signal (SIGUSR1) and then suspending the current thread. The timer interrupt uses SIGALRM and care is taken to ensure that the signal handler runs only on the thread for the current task. The additional data needed per-thread is stored at the top on the task's stack. When a running task is being deleted, its thread is marked it as dying so when we switch away from it it exits instead of suspending. This ensures that even if the idle task doesn't run, threads are deleted which allows for more threads to be created (if many tasks are being created and deleted in rapid succession). To further aid debugging, SIGINT (^C) is not blocked inside critical sections. This allows it to be used break into GDB while in a critical section. This means that care must be taken with any custom SIGINT handlers as these are like NMIs. This is somewhat inspired by an existing port by William Davy (https://www.freertos.org/FreeRTOS-simulator-for-Linux.html) but it takes a number of different approaches to make it switch tasks reliableand there's little similarly with the original implementation. - Critical sections block scheduling/"interrupts" by blocking signals using pthread_sigmask(). This is more expensive than attempting to use flags but works reliably and is analogous to the interrupt enable/disable on real hardware. - Care is take to ensure that the SIGALRM handler (for the timer tick) is runnable only on the pthread for the running task. This makes tasks switches more straight-forward and reliable as we can suspend the thread while in the signal handler. - Task switches save/restore the critical nesting on the stack. - Only uses a single (SIGUSR1) signal which is ignored and thus GDB's default signal handling options won't trap/print on this signal. - Extra per-thread data is stored on the task's stack, making it accessible in O(1) instead of performing a O(n) lookup of the array. - Uses the task create/delete hooks in a similar way to the Windows port, rather than overloading trace points.
5 years ago
} Thread_t;
/*
* The additional per-thread data is stored at the beginning of the
* task's stack.
*/
static inline Thread_t * prvGetThreadFromTask( TaskHandle_t xTask )
portable/GCC/Posix: add new port for Posix (Linux) applications This is similar to the Windows port, allowing FreeRTOS kernel applications to run as regular applications on Posix (Linux) systems. You can use this in a 32-bit or 64-bit application (although there are dynamic memory allocation trace points that do not support 64-bit addresses). Many of the same caveats of running an RTOS on a non-real-time system apply, but this is still very useful for easy debugging/testing applications in a simulated environment. In particular, it allows easy use of tools such as valgrind. You can call standard library functions from tasks but care must be taken with any that internally take mutexes or block. This includes malloc()/free() and many stdio functions (e.g., printf()). Replacement malloc(), free(), realloc(), and calloc() functions are provided which are safe. printf() needs to be called with a FreeRTOS mutex help (or called from only a single task). Each task is run in its own pthread, which makes debugging with standard tools (such as GDB) easier backtraces for individual tasks are available. Threads for non-running tasks are blocked in sigwait(). The stack for each task (thread) is allocated when the thread is created, and the stack provided during task creation is not used. This is so the stack has guard pages, to help with detecting stack overflows. Task switch is done by resuming the thread for the next task by sending it the resume signal (SIGUSR1) and then suspending the current thread. The timer interrupt uses SIGALRM and care is taken to ensure that the signal handler runs only on the thread for the current task. The additional data needed per-thread is stored at the top on the task's stack. When a running task is being deleted, its thread is marked it as dying so when we switch away from it it exits instead of suspending. This ensures that even if the idle task doesn't run, threads are deleted which allows for more threads to be created (if many tasks are being created and deleted in rapid succession). To further aid debugging, SIGINT (^C) is not blocked inside critical sections. This allows it to be used break into GDB while in a critical section. This means that care must be taken with any custom SIGINT handlers as these are like NMIs. This is somewhat inspired by an existing port by William Davy (https://www.freertos.org/FreeRTOS-simulator-for-Linux.html) but it takes a number of different approaches to make it switch tasks reliableand there's little similarly with the original implementation. - Critical sections block scheduling/"interrupts" by blocking signals using pthread_sigmask(). This is more expensive than attempting to use flags but works reliably and is analogous to the interrupt enable/disable on real hardware. - Care is take to ensure that the SIGALRM handler (for the timer tick) is runnable only on the pthread for the running task. This makes tasks switches more straight-forward and reliable as we can suspend the thread while in the signal handler. - Task switches save/restore the critical nesting on the stack. - Only uses a single (SIGUSR1) signal which is ignored and thus GDB's default signal handling options won't trap/print on this signal. - Extra per-thread data is stored on the task's stack, making it accessible in O(1) instead of performing a O(n) lookup of the array. - Uses the task create/delete hooks in a similar way to the Windows port, rather than overloading trace points.
5 years ago
{
StackType_t * pxTopOfStack = *( StackType_t ** ) xTask;
portable/GCC/Posix: add new port for Posix (Linux) applications This is similar to the Windows port, allowing FreeRTOS kernel applications to run as regular applications on Posix (Linux) systems. You can use this in a 32-bit or 64-bit application (although there are dynamic memory allocation trace points that do not support 64-bit addresses). Many of the same caveats of running an RTOS on a non-real-time system apply, but this is still very useful for easy debugging/testing applications in a simulated environment. In particular, it allows easy use of tools such as valgrind. You can call standard library functions from tasks but care must be taken with any that internally take mutexes or block. This includes malloc()/free() and many stdio functions (e.g., printf()). Replacement malloc(), free(), realloc(), and calloc() functions are provided which are safe. printf() needs to be called with a FreeRTOS mutex help (or called from only a single task). Each task is run in its own pthread, which makes debugging with standard tools (such as GDB) easier backtraces for individual tasks are available. Threads for non-running tasks are blocked in sigwait(). The stack for each task (thread) is allocated when the thread is created, and the stack provided during task creation is not used. This is so the stack has guard pages, to help with detecting stack overflows. Task switch is done by resuming the thread for the next task by sending it the resume signal (SIGUSR1) and then suspending the current thread. The timer interrupt uses SIGALRM and care is taken to ensure that the signal handler runs only on the thread for the current task. The additional data needed per-thread is stored at the top on the task's stack. When a running task is being deleted, its thread is marked it as dying so when we switch away from it it exits instead of suspending. This ensures that even if the idle task doesn't run, threads are deleted which allows for more threads to be created (if many tasks are being created and deleted in rapid succession). To further aid debugging, SIGINT (^C) is not blocked inside critical sections. This allows it to be used break into GDB while in a critical section. This means that care must be taken with any custom SIGINT handlers as these are like NMIs. This is somewhat inspired by an existing port by William Davy (https://www.freertos.org/FreeRTOS-simulator-for-Linux.html) but it takes a number of different approaches to make it switch tasks reliableand there's little similarly with the original implementation. - Critical sections block scheduling/"interrupts" by blocking signals using pthread_sigmask(). This is more expensive than attempting to use flags but works reliably and is analogous to the interrupt enable/disable on real hardware. - Care is take to ensure that the SIGALRM handler (for the timer tick) is runnable only on the pthread for the running task. This makes tasks switches more straight-forward and reliable as we can suspend the thread while in the signal handler. - Task switches save/restore the critical nesting on the stack. - Only uses a single (SIGUSR1) signal which is ignored and thus GDB's default signal handling options won't trap/print on this signal. - Extra per-thread data is stored on the task's stack, making it accessible in O(1) instead of performing a O(n) lookup of the array. - Uses the task create/delete hooks in a similar way to the Windows port, rather than overloading trace points.
5 years ago
return ( Thread_t * ) ( pxTopOfStack + 1 );
portable/GCC/Posix: add new port for Posix (Linux) applications This is similar to the Windows port, allowing FreeRTOS kernel applications to run as regular applications on Posix (Linux) systems. You can use this in a 32-bit or 64-bit application (although there are dynamic memory allocation trace points that do not support 64-bit addresses). Many of the same caveats of running an RTOS on a non-real-time system apply, but this is still very useful for easy debugging/testing applications in a simulated environment. In particular, it allows easy use of tools such as valgrind. You can call standard library functions from tasks but care must be taken with any that internally take mutexes or block. This includes malloc()/free() and many stdio functions (e.g., printf()). Replacement malloc(), free(), realloc(), and calloc() functions are provided which are safe. printf() needs to be called with a FreeRTOS mutex help (or called from only a single task). Each task is run in its own pthread, which makes debugging with standard tools (such as GDB) easier backtraces for individual tasks are available. Threads for non-running tasks are blocked in sigwait(). The stack for each task (thread) is allocated when the thread is created, and the stack provided during task creation is not used. This is so the stack has guard pages, to help with detecting stack overflows. Task switch is done by resuming the thread for the next task by sending it the resume signal (SIGUSR1) and then suspending the current thread. The timer interrupt uses SIGALRM and care is taken to ensure that the signal handler runs only on the thread for the current task. The additional data needed per-thread is stored at the top on the task's stack. When a running task is being deleted, its thread is marked it as dying so when we switch away from it it exits instead of suspending. This ensures that even if the idle task doesn't run, threads are deleted which allows for more threads to be created (if many tasks are being created and deleted in rapid succession). To further aid debugging, SIGINT (^C) is not blocked inside critical sections. This allows it to be used break into GDB while in a critical section. This means that care must be taken with any custom SIGINT handlers as these are like NMIs. This is somewhat inspired by an existing port by William Davy (https://www.freertos.org/FreeRTOS-simulator-for-Linux.html) but it takes a number of different approaches to make it switch tasks reliableand there's little similarly with the original implementation. - Critical sections block scheduling/"interrupts" by blocking signals using pthread_sigmask(). This is more expensive than attempting to use flags but works reliably and is analogous to the interrupt enable/disable on real hardware. - Care is take to ensure that the SIGALRM handler (for the timer tick) is runnable only on the pthread for the running task. This makes tasks switches more straight-forward and reliable as we can suspend the thread while in the signal handler. - Task switches save/restore the critical nesting on the stack. - Only uses a single (SIGUSR1) signal which is ignored and thus GDB's default signal handling options won't trap/print on this signal. - Extra per-thread data is stored on the task's stack, making it accessible in O(1) instead of performing a O(n) lookup of the array. - Uses the task create/delete hooks in a similar way to the Windows port, rather than overloading trace points.
5 years ago
}
/*-----------------------------------------------------------*/
static pthread_once_t hSigSetupThread = PTHREAD_ONCE_INIT;
static sigset_t xResumeSignals;
static sigset_t xAllSignals;
static sigset_t xSchedulerOriginalSignalMask;
static pthread_t hMainThread = ( pthread_t ) NULL;
portable/GCC/Posix: add new port for Posix (Linux) applications This is similar to the Windows port, allowing FreeRTOS kernel applications to run as regular applications on Posix (Linux) systems. You can use this in a 32-bit or 64-bit application (although there are dynamic memory allocation trace points that do not support 64-bit addresses). Many of the same caveats of running an RTOS on a non-real-time system apply, but this is still very useful for easy debugging/testing applications in a simulated environment. In particular, it allows easy use of tools such as valgrind. You can call standard library functions from tasks but care must be taken with any that internally take mutexes or block. This includes malloc()/free() and many stdio functions (e.g., printf()). Replacement malloc(), free(), realloc(), and calloc() functions are provided which are safe. printf() needs to be called with a FreeRTOS mutex help (or called from only a single task). Each task is run in its own pthread, which makes debugging with standard tools (such as GDB) easier backtraces for individual tasks are available. Threads for non-running tasks are blocked in sigwait(). The stack for each task (thread) is allocated when the thread is created, and the stack provided during task creation is not used. This is so the stack has guard pages, to help with detecting stack overflows. Task switch is done by resuming the thread for the next task by sending it the resume signal (SIGUSR1) and then suspending the current thread. The timer interrupt uses SIGALRM and care is taken to ensure that the signal handler runs only on the thread for the current task. The additional data needed per-thread is stored at the top on the task's stack. When a running task is being deleted, its thread is marked it as dying so when we switch away from it it exits instead of suspending. This ensures that even if the idle task doesn't run, threads are deleted which allows for more threads to be created (if many tasks are being created and deleted in rapid succession). To further aid debugging, SIGINT (^C) is not blocked inside critical sections. This allows it to be used break into GDB while in a critical section. This means that care must be taken with any custom SIGINT handlers as these are like NMIs. This is somewhat inspired by an existing port by William Davy (https://www.freertos.org/FreeRTOS-simulator-for-Linux.html) but it takes a number of different approaches to make it switch tasks reliableand there's little similarly with the original implementation. - Critical sections block scheduling/"interrupts" by blocking signals using pthread_sigmask(). This is more expensive than attempting to use flags but works reliably and is analogous to the interrupt enable/disable on real hardware. - Care is take to ensure that the SIGALRM handler (for the timer tick) is runnable only on the pthread for the running task. This makes tasks switches more straight-forward and reliable as we can suspend the thread while in the signal handler. - Task switches save/restore the critical nesting on the stack. - Only uses a single (SIGUSR1) signal which is ignored and thus GDB's default signal handling options won't trap/print on this signal. - Extra per-thread data is stored on the task's stack, making it accessible in O(1) instead of performing a O(n) lookup of the array. - Uses the task create/delete hooks in a similar way to the Windows port, rather than overloading trace points.
5 years ago
static volatile portBASE_TYPE uxCriticalNesting;
/*-----------------------------------------------------------*/
static portBASE_TYPE xSchedulerEnd = pdFALSE;
portable/GCC/Posix: add new port for Posix (Linux) applications This is similar to the Windows port, allowing FreeRTOS kernel applications to run as regular applications on Posix (Linux) systems. You can use this in a 32-bit or 64-bit application (although there are dynamic memory allocation trace points that do not support 64-bit addresses). Many of the same caveats of running an RTOS on a non-real-time system apply, but this is still very useful for easy debugging/testing applications in a simulated environment. In particular, it allows easy use of tools such as valgrind. You can call standard library functions from tasks but care must be taken with any that internally take mutexes or block. This includes malloc()/free() and many stdio functions (e.g., printf()). Replacement malloc(), free(), realloc(), and calloc() functions are provided which are safe. printf() needs to be called with a FreeRTOS mutex help (or called from only a single task). Each task is run in its own pthread, which makes debugging with standard tools (such as GDB) easier backtraces for individual tasks are available. Threads for non-running tasks are blocked in sigwait(). The stack for each task (thread) is allocated when the thread is created, and the stack provided during task creation is not used. This is so the stack has guard pages, to help with detecting stack overflows. Task switch is done by resuming the thread for the next task by sending it the resume signal (SIGUSR1) and then suspending the current thread. The timer interrupt uses SIGALRM and care is taken to ensure that the signal handler runs only on the thread for the current task. The additional data needed per-thread is stored at the top on the task's stack. When a running task is being deleted, its thread is marked it as dying so when we switch away from it it exits instead of suspending. This ensures that even if the idle task doesn't run, threads are deleted which allows for more threads to be created (if many tasks are being created and deleted in rapid succession). To further aid debugging, SIGINT (^C) is not blocked inside critical sections. This allows it to be used break into GDB while in a critical section. This means that care must be taken with any custom SIGINT handlers as these are like NMIs. This is somewhat inspired by an existing port by William Davy (https://www.freertos.org/FreeRTOS-simulator-for-Linux.html) but it takes a number of different approaches to make it switch tasks reliableand there's little similarly with the original implementation. - Critical sections block scheduling/"interrupts" by blocking signals using pthread_sigmask(). This is more expensive than attempting to use flags but works reliably and is analogous to the interrupt enable/disable on real hardware. - Care is take to ensure that the SIGALRM handler (for the timer tick) is runnable only on the pthread for the running task. This makes tasks switches more straight-forward and reliable as we can suspend the thread while in the signal handler. - Task switches save/restore the critical nesting on the stack. - Only uses a single (SIGUSR1) signal which is ignored and thus GDB's default signal handling options won't trap/print on this signal. - Extra per-thread data is stored on the task's stack, making it accessible in O(1) instead of performing a O(n) lookup of the array. - Uses the task create/delete hooks in a similar way to the Windows port, rather than overloading trace points.
5 years ago
/*-----------------------------------------------------------*/
static void prvSetupSignalsAndSchedulerPolicy( void );
static void prvSetupTimerInterrupt( void );
static void * prvWaitForStart( void * pvParams );
static void prvSwitchThread( Thread_t * xThreadToResume,
Thread_t * xThreadToSuspend );
portable/GCC/Posix: add new port for Posix (Linux) applications This is similar to the Windows port, allowing FreeRTOS kernel applications to run as regular applications on Posix (Linux) systems. You can use this in a 32-bit or 64-bit application (although there are dynamic memory allocation trace points that do not support 64-bit addresses). Many of the same caveats of running an RTOS on a non-real-time system apply, but this is still very useful for easy debugging/testing applications in a simulated environment. In particular, it allows easy use of tools such as valgrind. You can call standard library functions from tasks but care must be taken with any that internally take mutexes or block. This includes malloc()/free() and many stdio functions (e.g., printf()). Replacement malloc(), free(), realloc(), and calloc() functions are provided which are safe. printf() needs to be called with a FreeRTOS mutex help (or called from only a single task). Each task is run in its own pthread, which makes debugging with standard tools (such as GDB) easier backtraces for individual tasks are available. Threads for non-running tasks are blocked in sigwait(). The stack for each task (thread) is allocated when the thread is created, and the stack provided during task creation is not used. This is so the stack has guard pages, to help with detecting stack overflows. Task switch is done by resuming the thread for the next task by sending it the resume signal (SIGUSR1) and then suspending the current thread. The timer interrupt uses SIGALRM and care is taken to ensure that the signal handler runs only on the thread for the current task. The additional data needed per-thread is stored at the top on the task's stack. When a running task is being deleted, its thread is marked it as dying so when we switch away from it it exits instead of suspending. This ensures that even if the idle task doesn't run, threads are deleted which allows for more threads to be created (if many tasks are being created and deleted in rapid succession). To further aid debugging, SIGINT (^C) is not blocked inside critical sections. This allows it to be used break into GDB while in a critical section. This means that care must be taken with any custom SIGINT handlers as these are like NMIs. This is somewhat inspired by an existing port by William Davy (https://www.freertos.org/FreeRTOS-simulator-for-Linux.html) but it takes a number of different approaches to make it switch tasks reliableand there's little similarly with the original implementation. - Critical sections block scheduling/"interrupts" by blocking signals using pthread_sigmask(). This is more expensive than attempting to use flags but works reliably and is analogous to the interrupt enable/disable on real hardware. - Care is take to ensure that the SIGALRM handler (for the timer tick) is runnable only on the pthread for the running task. This makes tasks switches more straight-forward and reliable as we can suspend the thread while in the signal handler. - Task switches save/restore the critical nesting on the stack. - Only uses a single (SIGUSR1) signal which is ignored and thus GDB's default signal handling options won't trap/print on this signal. - Extra per-thread data is stored on the task's stack, making it accessible in O(1) instead of performing a O(n) lookup of the array. - Uses the task create/delete hooks in a similar way to the Windows port, rather than overloading trace points.
5 years ago
static void prvSuspendSelf( void );
static void prvResumeThread( pthread_t xThreadId );
static void vPortSystemTickHandler( int sig );
static void vPortStartFirstTask( void );
/*-----------------------------------------------------------*/
/*
* The standard glibc malloc(), free() etc. take an internal lock so
* it is not safe to switch tasks while calling them.
*
* Requiring the application use the safe xPortMalloc() and
* vPortFree() is not sufficient as malloc() is used internally by
* glibc (e.g., by strdup() and the pthread library.)
*
* To further complicate things malloc() and free() may be called
* outside of task context during pthread destruction so using
* vTaskSuspend() and xTaskResumeAll() cannot be used.
* vPortEnterCritical() and vPortExitCritical() cannot be used either
* as they use global state for the critical section nesting (this
* cannot be fixed by using TLS as pthread destruction needs to free
* the TLS).
*
* Explicitly save/disable and restore the signal mask to block the
* timer (SIGALRM) and other signals.
*/
extern void * __libc_malloc( size_t );
extern void __libc_free( void * );
extern void * __libc_calloc( size_t,
size_t );
extern void * __libc_realloc( void * ptr,
size_t );
portable/GCC/Posix: add new port for Posix (Linux) applications This is similar to the Windows port, allowing FreeRTOS kernel applications to run as regular applications on Posix (Linux) systems. You can use this in a 32-bit or 64-bit application (although there are dynamic memory allocation trace points that do not support 64-bit addresses). Many of the same caveats of running an RTOS on a non-real-time system apply, but this is still very useful for easy debugging/testing applications in a simulated environment. In particular, it allows easy use of tools such as valgrind. You can call standard library functions from tasks but care must be taken with any that internally take mutexes or block. This includes malloc()/free() and many stdio functions (e.g., printf()). Replacement malloc(), free(), realloc(), and calloc() functions are provided which are safe. printf() needs to be called with a FreeRTOS mutex help (or called from only a single task). Each task is run in its own pthread, which makes debugging with standard tools (such as GDB) easier backtraces for individual tasks are available. Threads for non-running tasks are blocked in sigwait(). The stack for each task (thread) is allocated when the thread is created, and the stack provided during task creation is not used. This is so the stack has guard pages, to help with detecting stack overflows. Task switch is done by resuming the thread for the next task by sending it the resume signal (SIGUSR1) and then suspending the current thread. The timer interrupt uses SIGALRM and care is taken to ensure that the signal handler runs only on the thread for the current task. The additional data needed per-thread is stored at the top on the task's stack. When a running task is being deleted, its thread is marked it as dying so when we switch away from it it exits instead of suspending. This ensures that even if the idle task doesn't run, threads are deleted which allows for more threads to be created (if many tasks are being created and deleted in rapid succession). To further aid debugging, SIGINT (^C) is not blocked inside critical sections. This allows it to be used break into GDB while in a critical section. This means that care must be taken with any custom SIGINT handlers as these are like NMIs. This is somewhat inspired by an existing port by William Davy (https://www.freertos.org/FreeRTOS-simulator-for-Linux.html) but it takes a number of different approaches to make it switch tasks reliableand there's little similarly with the original implementation. - Critical sections block scheduling/"interrupts" by blocking signals using pthread_sigmask(). This is more expensive than attempting to use flags but works reliably and is analogous to the interrupt enable/disable on real hardware. - Care is take to ensure that the SIGALRM handler (for the timer tick) is runnable only on the pthread for the running task. This makes tasks switches more straight-forward and reliable as we can suspend the thread while in the signal handler. - Task switches save/restore the critical nesting on the stack. - Only uses a single (SIGUSR1) signal which is ignored and thus GDB's default signal handling options won't trap/print on this signal. - Extra per-thread data is stored on the task's stack, making it accessible in O(1) instead of performing a O(n) lookup of the array. - Uses the task create/delete hooks in a similar way to the Windows port, rather than overloading trace points.
5 years ago
void * malloc( size_t size )
portable/GCC/Posix: add new port for Posix (Linux) applications This is similar to the Windows port, allowing FreeRTOS kernel applications to run as regular applications on Posix (Linux) systems. You can use this in a 32-bit or 64-bit application (although there are dynamic memory allocation trace points that do not support 64-bit addresses). Many of the same caveats of running an RTOS on a non-real-time system apply, but this is still very useful for easy debugging/testing applications in a simulated environment. In particular, it allows easy use of tools such as valgrind. You can call standard library functions from tasks but care must be taken with any that internally take mutexes or block. This includes malloc()/free() and many stdio functions (e.g., printf()). Replacement malloc(), free(), realloc(), and calloc() functions are provided which are safe. printf() needs to be called with a FreeRTOS mutex help (or called from only a single task). Each task is run in its own pthread, which makes debugging with standard tools (such as GDB) easier backtraces for individual tasks are available. Threads for non-running tasks are blocked in sigwait(). The stack for each task (thread) is allocated when the thread is created, and the stack provided during task creation is not used. This is so the stack has guard pages, to help with detecting stack overflows. Task switch is done by resuming the thread for the next task by sending it the resume signal (SIGUSR1) and then suspending the current thread. The timer interrupt uses SIGALRM and care is taken to ensure that the signal handler runs only on the thread for the current task. The additional data needed per-thread is stored at the top on the task's stack. When a running task is being deleted, its thread is marked it as dying so when we switch away from it it exits instead of suspending. This ensures that even if the idle task doesn't run, threads are deleted which allows for more threads to be created (if many tasks are being created and deleted in rapid succession). To further aid debugging, SIGINT (^C) is not blocked inside critical sections. This allows it to be used break into GDB while in a critical section. This means that care must be taken with any custom SIGINT handlers as these are like NMIs. This is somewhat inspired by an existing port by William Davy (https://www.freertos.org/FreeRTOS-simulator-for-Linux.html) but it takes a number of different approaches to make it switch tasks reliableand there's little similarly with the original implementation. - Critical sections block scheduling/"interrupts" by blocking signals using pthread_sigmask(). This is more expensive than attempting to use flags but works reliably and is analogous to the interrupt enable/disable on real hardware. - Care is take to ensure that the SIGALRM handler (for the timer tick) is runnable only on the pthread for the running task. This makes tasks switches more straight-forward and reliable as we can suspend the thread while in the signal handler. - Task switches save/restore the critical nesting on the stack. - Only uses a single (SIGUSR1) signal which is ignored and thus GDB's default signal handling options won't trap/print on this signal. - Extra per-thread data is stored on the task's stack, making it accessible in O(1) instead of performing a O(n) lookup of the array. - Uses the task create/delete hooks in a similar way to the Windows port, rather than overloading trace points.
5 years ago
{
sigset_t xSavedSignals;
void * ptr;
portable/GCC/Posix: add new port for Posix (Linux) applications This is similar to the Windows port, allowing FreeRTOS kernel applications to run as regular applications on Posix (Linux) systems. You can use this in a 32-bit or 64-bit application (although there are dynamic memory allocation trace points that do not support 64-bit addresses). Many of the same caveats of running an RTOS on a non-real-time system apply, but this is still very useful for easy debugging/testing applications in a simulated environment. In particular, it allows easy use of tools such as valgrind. You can call standard library functions from tasks but care must be taken with any that internally take mutexes or block. This includes malloc()/free() and many stdio functions (e.g., printf()). Replacement malloc(), free(), realloc(), and calloc() functions are provided which are safe. printf() needs to be called with a FreeRTOS mutex help (or called from only a single task). Each task is run in its own pthread, which makes debugging with standard tools (such as GDB) easier backtraces for individual tasks are available. Threads for non-running tasks are blocked in sigwait(). The stack for each task (thread) is allocated when the thread is created, and the stack provided during task creation is not used. This is so the stack has guard pages, to help with detecting stack overflows. Task switch is done by resuming the thread for the next task by sending it the resume signal (SIGUSR1) and then suspending the current thread. The timer interrupt uses SIGALRM and care is taken to ensure that the signal handler runs only on the thread for the current task. The additional data needed per-thread is stored at the top on the task's stack. When a running task is being deleted, its thread is marked it as dying so when we switch away from it it exits instead of suspending. This ensures that even if the idle task doesn't run, threads are deleted which allows for more threads to be created (if many tasks are being created and deleted in rapid succession). To further aid debugging, SIGINT (^C) is not blocked inside critical sections. This allows it to be used break into GDB while in a critical section. This means that care must be taken with any custom SIGINT handlers as these are like NMIs. This is somewhat inspired by an existing port by William Davy (https://www.freertos.org/FreeRTOS-simulator-for-Linux.html) but it takes a number of different approaches to make it switch tasks reliableand there's little similarly with the original implementation. - Critical sections block scheduling/"interrupts" by blocking signals using pthread_sigmask(). This is more expensive than attempting to use flags but works reliably and is analogous to the interrupt enable/disable on real hardware. - Care is take to ensure that the SIGALRM handler (for the timer tick) is runnable only on the pthread for the running task. This makes tasks switches more straight-forward and reliable as we can suspend the thread while in the signal handler. - Task switches save/restore the critical nesting on the stack. - Only uses a single (SIGUSR1) signal which is ignored and thus GDB's default signal handling options won't trap/print on this signal. - Extra per-thread data is stored on the task's stack, making it accessible in O(1) instead of performing a O(n) lookup of the array. - Uses the task create/delete hooks in a similar way to the Windows port, rather than overloading trace points.
5 years ago
pthread_sigmask( SIG_BLOCK, &xAllSignals, &xSavedSignals );
ptr = __libc_malloc( size );
pthread_sigmask( SIG_SETMASK, &xSavedSignals, NULL );
portable/GCC/Posix: add new port for Posix (Linux) applications This is similar to the Windows port, allowing FreeRTOS kernel applications to run as regular applications on Posix (Linux) systems. You can use this in a 32-bit or 64-bit application (although there are dynamic memory allocation trace points that do not support 64-bit addresses). Many of the same caveats of running an RTOS on a non-real-time system apply, but this is still very useful for easy debugging/testing applications in a simulated environment. In particular, it allows easy use of tools such as valgrind. You can call standard library functions from tasks but care must be taken with any that internally take mutexes or block. This includes malloc()/free() and many stdio functions (e.g., printf()). Replacement malloc(), free(), realloc(), and calloc() functions are provided which are safe. printf() needs to be called with a FreeRTOS mutex help (or called from only a single task). Each task is run in its own pthread, which makes debugging with standard tools (such as GDB) easier backtraces for individual tasks are available. Threads for non-running tasks are blocked in sigwait(). The stack for each task (thread) is allocated when the thread is created, and the stack provided during task creation is not used. This is so the stack has guard pages, to help with detecting stack overflows. Task switch is done by resuming the thread for the next task by sending it the resume signal (SIGUSR1) and then suspending the current thread. The timer interrupt uses SIGALRM and care is taken to ensure that the signal handler runs only on the thread for the current task. The additional data needed per-thread is stored at the top on the task's stack. When a running task is being deleted, its thread is marked it as dying so when we switch away from it it exits instead of suspending. This ensures that even if the idle task doesn't run, threads are deleted which allows for more threads to be created (if many tasks are being created and deleted in rapid succession). To further aid debugging, SIGINT (^C) is not blocked inside critical sections. This allows it to be used break into GDB while in a critical section. This means that care must be taken with any custom SIGINT handlers as these are like NMIs. This is somewhat inspired by an existing port by William Davy (https://www.freertos.org/FreeRTOS-simulator-for-Linux.html) but it takes a number of different approaches to make it switch tasks reliableand there's little similarly with the original implementation. - Critical sections block scheduling/"interrupts" by blocking signals using pthread_sigmask(). This is more expensive than attempting to use flags but works reliably and is analogous to the interrupt enable/disable on real hardware. - Care is take to ensure that the SIGALRM handler (for the timer tick) is runnable only on the pthread for the running task. This makes tasks switches more straight-forward and reliable as we can suspend the thread while in the signal handler. - Task switches save/restore the critical nesting on the stack. - Only uses a single (SIGUSR1) signal which is ignored and thus GDB's default signal handling options won't trap/print on this signal. - Extra per-thread data is stored on the task's stack, making it accessible in O(1) instead of performing a O(n) lookup of the array. - Uses the task create/delete hooks in a similar way to the Windows port, rather than overloading trace points.
5 years ago
return ptr;
portable/GCC/Posix: add new port for Posix (Linux) applications This is similar to the Windows port, allowing FreeRTOS kernel applications to run as regular applications on Posix (Linux) systems. You can use this in a 32-bit or 64-bit application (although there are dynamic memory allocation trace points that do not support 64-bit addresses). Many of the same caveats of running an RTOS on a non-real-time system apply, but this is still very useful for easy debugging/testing applications in a simulated environment. In particular, it allows easy use of tools such as valgrind. You can call standard library functions from tasks but care must be taken with any that internally take mutexes or block. This includes malloc()/free() and many stdio functions (e.g., printf()). Replacement malloc(), free(), realloc(), and calloc() functions are provided which are safe. printf() needs to be called with a FreeRTOS mutex help (or called from only a single task). Each task is run in its own pthread, which makes debugging with standard tools (such as GDB) easier backtraces for individual tasks are available. Threads for non-running tasks are blocked in sigwait(). The stack for each task (thread) is allocated when the thread is created, and the stack provided during task creation is not used. This is so the stack has guard pages, to help with detecting stack overflows. Task switch is done by resuming the thread for the next task by sending it the resume signal (SIGUSR1) and then suspending the current thread. The timer interrupt uses SIGALRM and care is taken to ensure that the signal handler runs only on the thread for the current task. The additional data needed per-thread is stored at the top on the task's stack. When a running task is being deleted, its thread is marked it as dying so when we switch away from it it exits instead of suspending. This ensures that even if the idle task doesn't run, threads are deleted which allows for more threads to be created (if many tasks are being created and deleted in rapid succession). To further aid debugging, SIGINT (^C) is not blocked inside critical sections. This allows it to be used break into GDB while in a critical section. This means that care must be taken with any custom SIGINT handlers as these are like NMIs. This is somewhat inspired by an existing port by William Davy (https://www.freertos.org/FreeRTOS-simulator-for-Linux.html) but it takes a number of different approaches to make it switch tasks reliableand there's little similarly with the original implementation. - Critical sections block scheduling/"interrupts" by blocking signals using pthread_sigmask(). This is more expensive than attempting to use flags but works reliably and is analogous to the interrupt enable/disable on real hardware. - Care is take to ensure that the SIGALRM handler (for the timer tick) is runnable only on the pthread for the running task. This makes tasks switches more straight-forward and reliable as we can suspend the thread while in the signal handler. - Task switches save/restore the critical nesting on the stack. - Only uses a single (SIGUSR1) signal which is ignored and thus GDB's default signal handling options won't trap/print on this signal. - Extra per-thread data is stored on the task's stack, making it accessible in O(1) instead of performing a O(n) lookup of the array. - Uses the task create/delete hooks in a similar way to the Windows port, rather than overloading trace points.
5 years ago
}
void free( void * ptr )
portable/GCC/Posix: add new port for Posix (Linux) applications This is similar to the Windows port, allowing FreeRTOS kernel applications to run as regular applications on Posix (Linux) systems. You can use this in a 32-bit or 64-bit application (although there are dynamic memory allocation trace points that do not support 64-bit addresses). Many of the same caveats of running an RTOS on a non-real-time system apply, but this is still very useful for easy debugging/testing applications in a simulated environment. In particular, it allows easy use of tools such as valgrind. You can call standard library functions from tasks but care must be taken with any that internally take mutexes or block. This includes malloc()/free() and many stdio functions (e.g., printf()). Replacement malloc(), free(), realloc(), and calloc() functions are provided which are safe. printf() needs to be called with a FreeRTOS mutex help (or called from only a single task). Each task is run in its own pthread, which makes debugging with standard tools (such as GDB) easier backtraces for individual tasks are available. Threads for non-running tasks are blocked in sigwait(). The stack for each task (thread) is allocated when the thread is created, and the stack provided during task creation is not used. This is so the stack has guard pages, to help with detecting stack overflows. Task switch is done by resuming the thread for the next task by sending it the resume signal (SIGUSR1) and then suspending the current thread. The timer interrupt uses SIGALRM and care is taken to ensure that the signal handler runs only on the thread for the current task. The additional data needed per-thread is stored at the top on the task's stack. When a running task is being deleted, its thread is marked it as dying so when we switch away from it it exits instead of suspending. This ensures that even if the idle task doesn't run, threads are deleted which allows for more threads to be created (if many tasks are being created and deleted in rapid succession). To further aid debugging, SIGINT (^C) is not blocked inside critical sections. This allows it to be used break into GDB while in a critical section. This means that care must be taken with any custom SIGINT handlers as these are like NMIs. This is somewhat inspired by an existing port by William Davy (https://www.freertos.org/FreeRTOS-simulator-for-Linux.html) but it takes a number of different approaches to make it switch tasks reliableand there's little similarly with the original implementation. - Critical sections block scheduling/"interrupts" by blocking signals using pthread_sigmask(). This is more expensive than attempting to use flags but works reliably and is analogous to the interrupt enable/disable on real hardware. - Care is take to ensure that the SIGALRM handler (for the timer tick) is runnable only on the pthread for the running task. This makes tasks switches more straight-forward and reliable as we can suspend the thread while in the signal handler. - Task switches save/restore the critical nesting on the stack. - Only uses a single (SIGUSR1) signal which is ignored and thus GDB's default signal handling options won't trap/print on this signal. - Extra per-thread data is stored on the task's stack, making it accessible in O(1) instead of performing a O(n) lookup of the array. - Uses the task create/delete hooks in a similar way to the Windows port, rather than overloading trace points.
5 years ago
{
sigset_t xSavedSignals;
portable/GCC/Posix: add new port for Posix (Linux) applications This is similar to the Windows port, allowing FreeRTOS kernel applications to run as regular applications on Posix (Linux) systems. You can use this in a 32-bit or 64-bit application (although there are dynamic memory allocation trace points that do not support 64-bit addresses). Many of the same caveats of running an RTOS on a non-real-time system apply, but this is still very useful for easy debugging/testing applications in a simulated environment. In particular, it allows easy use of tools such as valgrind. You can call standard library functions from tasks but care must be taken with any that internally take mutexes or block. This includes malloc()/free() and many stdio functions (e.g., printf()). Replacement malloc(), free(), realloc(), and calloc() functions are provided which are safe. printf() needs to be called with a FreeRTOS mutex help (or called from only a single task). Each task is run in its own pthread, which makes debugging with standard tools (such as GDB) easier backtraces for individual tasks are available. Threads for non-running tasks are blocked in sigwait(). The stack for each task (thread) is allocated when the thread is created, and the stack provided during task creation is not used. This is so the stack has guard pages, to help with detecting stack overflows. Task switch is done by resuming the thread for the next task by sending it the resume signal (SIGUSR1) and then suspending the current thread. The timer interrupt uses SIGALRM and care is taken to ensure that the signal handler runs only on the thread for the current task. The additional data needed per-thread is stored at the top on the task's stack. When a running task is being deleted, its thread is marked it as dying so when we switch away from it it exits instead of suspending. This ensures that even if the idle task doesn't run, threads are deleted which allows for more threads to be created (if many tasks are being created and deleted in rapid succession). To further aid debugging, SIGINT (^C) is not blocked inside critical sections. This allows it to be used break into GDB while in a critical section. This means that care must be taken with any custom SIGINT handlers as these are like NMIs. This is somewhat inspired by an existing port by William Davy (https://www.freertos.org/FreeRTOS-simulator-for-Linux.html) but it takes a number of different approaches to make it switch tasks reliableand there's little similarly with the original implementation. - Critical sections block scheduling/"interrupts" by blocking signals using pthread_sigmask(). This is more expensive than attempting to use flags but works reliably and is analogous to the interrupt enable/disable on real hardware. - Care is take to ensure that the SIGALRM handler (for the timer tick) is runnable only on the pthread for the running task. This makes tasks switches more straight-forward and reliable as we can suspend the thread while in the signal handler. - Task switches save/restore the critical nesting on the stack. - Only uses a single (SIGUSR1) signal which is ignored and thus GDB's default signal handling options won't trap/print on this signal. - Extra per-thread data is stored on the task's stack, making it accessible in O(1) instead of performing a O(n) lookup of the array. - Uses the task create/delete hooks in a similar way to the Windows port, rather than overloading trace points.
5 years ago
pthread_sigmask( SIG_BLOCK, &xAllSignals, &xSavedSignals );
__libc_free( ptr );
pthread_sigmask( SIG_SETMASK, &xSavedSignals, NULL );
portable/GCC/Posix: add new port for Posix (Linux) applications This is similar to the Windows port, allowing FreeRTOS kernel applications to run as regular applications on Posix (Linux) systems. You can use this in a 32-bit or 64-bit application (although there are dynamic memory allocation trace points that do not support 64-bit addresses). Many of the same caveats of running an RTOS on a non-real-time system apply, but this is still very useful for easy debugging/testing applications in a simulated environment. In particular, it allows easy use of tools such as valgrind. You can call standard library functions from tasks but care must be taken with any that internally take mutexes or block. This includes malloc()/free() and many stdio functions (e.g., printf()). Replacement malloc(), free(), realloc(), and calloc() functions are provided which are safe. printf() needs to be called with a FreeRTOS mutex help (or called from only a single task). Each task is run in its own pthread, which makes debugging with standard tools (such as GDB) easier backtraces for individual tasks are available. Threads for non-running tasks are blocked in sigwait(). The stack for each task (thread) is allocated when the thread is created, and the stack provided during task creation is not used. This is so the stack has guard pages, to help with detecting stack overflows. Task switch is done by resuming the thread for the next task by sending it the resume signal (SIGUSR1) and then suspending the current thread. The timer interrupt uses SIGALRM and care is taken to ensure that the signal handler runs only on the thread for the current task. The additional data needed per-thread is stored at the top on the task's stack. When a running task is being deleted, its thread is marked it as dying so when we switch away from it it exits instead of suspending. This ensures that even if the idle task doesn't run, threads are deleted which allows for more threads to be created (if many tasks are being created and deleted in rapid succession). To further aid debugging, SIGINT (^C) is not blocked inside critical sections. This allows it to be used break into GDB while in a critical section. This means that care must be taken with any custom SIGINT handlers as these are like NMIs. This is somewhat inspired by an existing port by William Davy (https://www.freertos.org/FreeRTOS-simulator-for-Linux.html) but it takes a number of different approaches to make it switch tasks reliableand there's little similarly with the original implementation. - Critical sections block scheduling/"interrupts" by blocking signals using pthread_sigmask(). This is more expensive than attempting to use flags but works reliably and is analogous to the interrupt enable/disable on real hardware. - Care is take to ensure that the SIGALRM handler (for the timer tick) is runnable only on the pthread for the running task. This makes tasks switches more straight-forward and reliable as we can suspend the thread while in the signal handler. - Task switches save/restore the critical nesting on the stack. - Only uses a single (SIGUSR1) signal which is ignored and thus GDB's default signal handling options won't trap/print on this signal. - Extra per-thread data is stored on the task's stack, making it accessible in O(1) instead of performing a O(n) lookup of the array. - Uses the task create/delete hooks in a similar way to the Windows port, rather than overloading trace points.
5 years ago
}
void * calloc( size_t nmemb,
size_t size )
portable/GCC/Posix: add new port for Posix (Linux) applications This is similar to the Windows port, allowing FreeRTOS kernel applications to run as regular applications on Posix (Linux) systems. You can use this in a 32-bit or 64-bit application (although there are dynamic memory allocation trace points that do not support 64-bit addresses). Many of the same caveats of running an RTOS on a non-real-time system apply, but this is still very useful for easy debugging/testing applications in a simulated environment. In particular, it allows easy use of tools such as valgrind. You can call standard library functions from tasks but care must be taken with any that internally take mutexes or block. This includes malloc()/free() and many stdio functions (e.g., printf()). Replacement malloc(), free(), realloc(), and calloc() functions are provided which are safe. printf() needs to be called with a FreeRTOS mutex help (or called from only a single task). Each task is run in its own pthread, which makes debugging with standard tools (such as GDB) easier backtraces for individual tasks are available. Threads for non-running tasks are blocked in sigwait(). The stack for each task (thread) is allocated when the thread is created, and the stack provided during task creation is not used. This is so the stack has guard pages, to help with detecting stack overflows. Task switch is done by resuming the thread for the next task by sending it the resume signal (SIGUSR1) and then suspending the current thread. The timer interrupt uses SIGALRM and care is taken to ensure that the signal handler runs only on the thread for the current task. The additional data needed per-thread is stored at the top on the task's stack. When a running task is being deleted, its thread is marked it as dying so when we switch away from it it exits instead of suspending. This ensures that even if the idle task doesn't run, threads are deleted which allows for more threads to be created (if many tasks are being created and deleted in rapid succession). To further aid debugging, SIGINT (^C) is not blocked inside critical sections. This allows it to be used break into GDB while in a critical section. This means that care must be taken with any custom SIGINT handlers as these are like NMIs. This is somewhat inspired by an existing port by William Davy (https://www.freertos.org/FreeRTOS-simulator-for-Linux.html) but it takes a number of different approaches to make it switch tasks reliableand there's little similarly with the original implementation. - Critical sections block scheduling/"interrupts" by blocking signals using pthread_sigmask(). This is more expensive than attempting to use flags but works reliably and is analogous to the interrupt enable/disable on real hardware. - Care is take to ensure that the SIGALRM handler (for the timer tick) is runnable only on the pthread for the running task. This makes tasks switches more straight-forward and reliable as we can suspend the thread while in the signal handler. - Task switches save/restore the critical nesting on the stack. - Only uses a single (SIGUSR1) signal which is ignored and thus GDB's default signal handling options won't trap/print on this signal. - Extra per-thread data is stored on the task's stack, making it accessible in O(1) instead of performing a O(n) lookup of the array. - Uses the task create/delete hooks in a similar way to the Windows port, rather than overloading trace points.
5 years ago
{
sigset_t xSavedSignals;
void * ptr;
portable/GCC/Posix: add new port for Posix (Linux) applications This is similar to the Windows port, allowing FreeRTOS kernel applications to run as regular applications on Posix (Linux) systems. You can use this in a 32-bit or 64-bit application (although there are dynamic memory allocation trace points that do not support 64-bit addresses). Many of the same caveats of running an RTOS on a non-real-time system apply, but this is still very useful for easy debugging/testing applications in a simulated environment. In particular, it allows easy use of tools such as valgrind. You can call standard library functions from tasks but care must be taken with any that internally take mutexes or block. This includes malloc()/free() and many stdio functions (e.g., printf()). Replacement malloc(), free(), realloc(), and calloc() functions are provided which are safe. printf() needs to be called with a FreeRTOS mutex help (or called from only a single task). Each task is run in its own pthread, which makes debugging with standard tools (such as GDB) easier backtraces for individual tasks are available. Threads for non-running tasks are blocked in sigwait(). The stack for each task (thread) is allocated when the thread is created, and the stack provided during task creation is not used. This is so the stack has guard pages, to help with detecting stack overflows. Task switch is done by resuming the thread for the next task by sending it the resume signal (SIGUSR1) and then suspending the current thread. The timer interrupt uses SIGALRM and care is taken to ensure that the signal handler runs only on the thread for the current task. The additional data needed per-thread is stored at the top on the task's stack. When a running task is being deleted, its thread is marked it as dying so when we switch away from it it exits instead of suspending. This ensures that even if the idle task doesn't run, threads are deleted which allows for more threads to be created (if many tasks are being created and deleted in rapid succession). To further aid debugging, SIGINT (^C) is not blocked inside critical sections. This allows it to be used break into GDB while in a critical section. This means that care must be taken with any custom SIGINT handlers as these are like NMIs. This is somewhat inspired by an existing port by William Davy (https://www.freertos.org/FreeRTOS-simulator-for-Linux.html) but it takes a number of different approaches to make it switch tasks reliableand there's little similarly with the original implementation. - Critical sections block scheduling/"interrupts" by blocking signals using pthread_sigmask(). This is more expensive than attempting to use flags but works reliably and is analogous to the interrupt enable/disable on real hardware. - Care is take to ensure that the SIGALRM handler (for the timer tick) is runnable only on the pthread for the running task. This makes tasks switches more straight-forward and reliable as we can suspend the thread while in the signal handler. - Task switches save/restore the critical nesting on the stack. - Only uses a single (SIGUSR1) signal which is ignored and thus GDB's default signal handling options won't trap/print on this signal. - Extra per-thread data is stored on the task's stack, making it accessible in O(1) instead of performing a O(n) lookup of the array. - Uses the task create/delete hooks in a similar way to the Windows port, rather than overloading trace points.
5 years ago
pthread_sigmask( SIG_BLOCK, &xAllSignals, &xSavedSignals );
ptr = __libc_calloc( nmemb, size );
pthread_sigmask( SIG_SETMASK, &xSavedSignals, NULL );
portable/GCC/Posix: add new port for Posix (Linux) applications This is similar to the Windows port, allowing FreeRTOS kernel applications to run as regular applications on Posix (Linux) systems. You can use this in a 32-bit or 64-bit application (although there are dynamic memory allocation trace points that do not support 64-bit addresses). Many of the same caveats of running an RTOS on a non-real-time system apply, but this is still very useful for easy debugging/testing applications in a simulated environment. In particular, it allows easy use of tools such as valgrind. You can call standard library functions from tasks but care must be taken with any that internally take mutexes or block. This includes malloc()/free() and many stdio functions (e.g., printf()). Replacement malloc(), free(), realloc(), and calloc() functions are provided which are safe. printf() needs to be called with a FreeRTOS mutex help (or called from only a single task). Each task is run in its own pthread, which makes debugging with standard tools (such as GDB) easier backtraces for individual tasks are available. Threads for non-running tasks are blocked in sigwait(). The stack for each task (thread) is allocated when the thread is created, and the stack provided during task creation is not used. This is so the stack has guard pages, to help with detecting stack overflows. Task switch is done by resuming the thread for the next task by sending it the resume signal (SIGUSR1) and then suspending the current thread. The timer interrupt uses SIGALRM and care is taken to ensure that the signal handler runs only on the thread for the current task. The additional data needed per-thread is stored at the top on the task's stack. When a running task is being deleted, its thread is marked it as dying so when we switch away from it it exits instead of suspending. This ensures that even if the idle task doesn't run, threads are deleted which allows for more threads to be created (if many tasks are being created and deleted in rapid succession). To further aid debugging, SIGINT (^C) is not blocked inside critical sections. This allows it to be used break into GDB while in a critical section. This means that care must be taken with any custom SIGINT handlers as these are like NMIs. This is somewhat inspired by an existing port by William Davy (https://www.freertos.org/FreeRTOS-simulator-for-Linux.html) but it takes a number of different approaches to make it switch tasks reliableand there's little similarly with the original implementation. - Critical sections block scheduling/"interrupts" by blocking signals using pthread_sigmask(). This is more expensive than attempting to use flags but works reliably and is analogous to the interrupt enable/disable on real hardware. - Care is take to ensure that the SIGALRM handler (for the timer tick) is runnable only on the pthread for the running task. This makes tasks switches more straight-forward and reliable as we can suspend the thread while in the signal handler. - Task switches save/restore the critical nesting on the stack. - Only uses a single (SIGUSR1) signal which is ignored and thus GDB's default signal handling options won't trap/print on this signal. - Extra per-thread data is stored on the task's stack, making it accessible in O(1) instead of performing a O(n) lookup of the array. - Uses the task create/delete hooks in a similar way to the Windows port, rather than overloading trace points.
5 years ago
return ptr;
portable/GCC/Posix: add new port for Posix (Linux) applications This is similar to the Windows port, allowing FreeRTOS kernel applications to run as regular applications on Posix (Linux) systems. You can use this in a 32-bit or 64-bit application (although there are dynamic memory allocation trace points that do not support 64-bit addresses). Many of the same caveats of running an RTOS on a non-real-time system apply, but this is still very useful for easy debugging/testing applications in a simulated environment. In particular, it allows easy use of tools such as valgrind. You can call standard library functions from tasks but care must be taken with any that internally take mutexes or block. This includes malloc()/free() and many stdio functions (e.g., printf()). Replacement malloc(), free(), realloc(), and calloc() functions are provided which are safe. printf() needs to be called with a FreeRTOS mutex help (or called from only a single task). Each task is run in its own pthread, which makes debugging with standard tools (such as GDB) easier backtraces for individual tasks are available. Threads for non-running tasks are blocked in sigwait(). The stack for each task (thread) is allocated when the thread is created, and the stack provided during task creation is not used. This is so the stack has guard pages, to help with detecting stack overflows. Task switch is done by resuming the thread for the next task by sending it the resume signal (SIGUSR1) and then suspending the current thread. The timer interrupt uses SIGALRM and care is taken to ensure that the signal handler runs only on the thread for the current task. The additional data needed per-thread is stored at the top on the task's stack. When a running task is being deleted, its thread is marked it as dying so when we switch away from it it exits instead of suspending. This ensures that even if the idle task doesn't run, threads are deleted which allows for more threads to be created (if many tasks are being created and deleted in rapid succession). To further aid debugging, SIGINT (^C) is not blocked inside critical sections. This allows it to be used break into GDB while in a critical section. This means that care must be taken with any custom SIGINT handlers as these are like NMIs. This is somewhat inspired by an existing port by William Davy (https://www.freertos.org/FreeRTOS-simulator-for-Linux.html) but it takes a number of different approaches to make it switch tasks reliableand there's little similarly with the original implementation. - Critical sections block scheduling/"interrupts" by blocking signals using pthread_sigmask(). This is more expensive than attempting to use flags but works reliably and is analogous to the interrupt enable/disable on real hardware. - Care is take to ensure that the SIGALRM handler (for the timer tick) is runnable only on the pthread for the running task. This makes tasks switches more straight-forward and reliable as we can suspend the thread while in the signal handler. - Task switches save/restore the critical nesting on the stack. - Only uses a single (SIGUSR1) signal which is ignored and thus GDB's default signal handling options won't trap/print on this signal. - Extra per-thread data is stored on the task's stack, making it accessible in O(1) instead of performing a O(n) lookup of the array. - Uses the task create/delete hooks in a similar way to the Windows port, rather than overloading trace points.
5 years ago
}
void * realloc( void * ptr,
size_t size )
portable/GCC/Posix: add new port for Posix (Linux) applications This is similar to the Windows port, allowing FreeRTOS kernel applications to run as regular applications on Posix (Linux) systems. You can use this in a 32-bit or 64-bit application (although there are dynamic memory allocation trace points that do not support 64-bit addresses). Many of the same caveats of running an RTOS on a non-real-time system apply, but this is still very useful for easy debugging/testing applications in a simulated environment. In particular, it allows easy use of tools such as valgrind. You can call standard library functions from tasks but care must be taken with any that internally take mutexes or block. This includes malloc()/free() and many stdio functions (e.g., printf()). Replacement malloc(), free(), realloc(), and calloc() functions are provided which are safe. printf() needs to be called with a FreeRTOS mutex help (or called from only a single task). Each task is run in its own pthread, which makes debugging with standard tools (such as GDB) easier backtraces for individual tasks are available. Threads for non-running tasks are blocked in sigwait(). The stack for each task (thread) is allocated when the thread is created, and the stack provided during task creation is not used. This is so the stack has guard pages, to help with detecting stack overflows. Task switch is done by resuming the thread for the next task by sending it the resume signal (SIGUSR1) and then suspending the current thread. The timer interrupt uses SIGALRM and care is taken to ensure that the signal handler runs only on the thread for the current task. The additional data needed per-thread is stored at the top on the task's stack. When a running task is being deleted, its thread is marked it as dying so when we switch away from it it exits instead of suspending. This ensures that even if the idle task doesn't run, threads are deleted which allows for more threads to be created (if many tasks are being created and deleted in rapid succession). To further aid debugging, SIGINT (^C) is not blocked inside critical sections. This allows it to be used break into GDB while in a critical section. This means that care must be taken with any custom SIGINT handlers as these are like NMIs. This is somewhat inspired by an existing port by William Davy (https://www.freertos.org/FreeRTOS-simulator-for-Linux.html) but it takes a number of different approaches to make it switch tasks reliableand there's little similarly with the original implementation. - Critical sections block scheduling/"interrupts" by blocking signals using pthread_sigmask(). This is more expensive than attempting to use flags but works reliably and is analogous to the interrupt enable/disable on real hardware. - Care is take to ensure that the SIGALRM handler (for the timer tick) is runnable only on the pthread for the running task. This makes tasks switches more straight-forward and reliable as we can suspend the thread while in the signal handler. - Task switches save/restore the critical nesting on the stack. - Only uses a single (SIGUSR1) signal which is ignored and thus GDB's default signal handling options won't trap/print on this signal. - Extra per-thread data is stored on the task's stack, making it accessible in O(1) instead of performing a O(n) lookup of the array. - Uses the task create/delete hooks in a similar way to the Windows port, rather than overloading trace points.
5 years ago
{
sigset_t xSavedSignals;
portable/GCC/Posix: add new port for Posix (Linux) applications This is similar to the Windows port, allowing FreeRTOS kernel applications to run as regular applications on Posix (Linux) systems. You can use this in a 32-bit or 64-bit application (although there are dynamic memory allocation trace points that do not support 64-bit addresses). Many of the same caveats of running an RTOS on a non-real-time system apply, but this is still very useful for easy debugging/testing applications in a simulated environment. In particular, it allows easy use of tools such as valgrind. You can call standard library functions from tasks but care must be taken with any that internally take mutexes or block. This includes malloc()/free() and many stdio functions (e.g., printf()). Replacement malloc(), free(), realloc(), and calloc() functions are provided which are safe. printf() needs to be called with a FreeRTOS mutex help (or called from only a single task). Each task is run in its own pthread, which makes debugging with standard tools (such as GDB) easier backtraces for individual tasks are available. Threads for non-running tasks are blocked in sigwait(). The stack for each task (thread) is allocated when the thread is created, and the stack provided during task creation is not used. This is so the stack has guard pages, to help with detecting stack overflows. Task switch is done by resuming the thread for the next task by sending it the resume signal (SIGUSR1) and then suspending the current thread. The timer interrupt uses SIGALRM and care is taken to ensure that the signal handler runs only on the thread for the current task. The additional data needed per-thread is stored at the top on the task's stack. When a running task is being deleted, its thread is marked it as dying so when we switch away from it it exits instead of suspending. This ensures that even if the idle task doesn't run, threads are deleted which allows for more threads to be created (if many tasks are being created and deleted in rapid succession). To further aid debugging, SIGINT (^C) is not blocked inside critical sections. This allows it to be used break into GDB while in a critical section. This means that care must be taken with any custom SIGINT handlers as these are like NMIs. This is somewhat inspired by an existing port by William Davy (https://www.freertos.org/FreeRTOS-simulator-for-Linux.html) but it takes a number of different approaches to make it switch tasks reliableand there's little similarly with the original implementation. - Critical sections block scheduling/"interrupts" by blocking signals using pthread_sigmask(). This is more expensive than attempting to use flags but works reliably and is analogous to the interrupt enable/disable on real hardware. - Care is take to ensure that the SIGALRM handler (for the timer tick) is runnable only on the pthread for the running task. This makes tasks switches more straight-forward and reliable as we can suspend the thread while in the signal handler. - Task switches save/restore the critical nesting on the stack. - Only uses a single (SIGUSR1) signal which is ignored and thus GDB's default signal handling options won't trap/print on this signal. - Extra per-thread data is stored on the task's stack, making it accessible in O(1) instead of performing a O(n) lookup of the array. - Uses the task create/delete hooks in a similar way to the Windows port, rather than overloading trace points.
5 years ago
pthread_sigmask( SIG_BLOCK, &xAllSignals, &xSavedSignals );
ptr = __libc_realloc( ptr, size );
pthread_sigmask( SIG_SETMASK, &xSavedSignals, NULL );
portable/GCC/Posix: add new port for Posix (Linux) applications This is similar to the Windows port, allowing FreeRTOS kernel applications to run as regular applications on Posix (Linux) systems. You can use this in a 32-bit or 64-bit application (although there are dynamic memory allocation trace points that do not support 64-bit addresses). Many of the same caveats of running an RTOS on a non-real-time system apply, but this is still very useful for easy debugging/testing applications in a simulated environment. In particular, it allows easy use of tools such as valgrind. You can call standard library functions from tasks but care must be taken with any that internally take mutexes or block. This includes malloc()/free() and many stdio functions (e.g., printf()). Replacement malloc(), free(), realloc(), and calloc() functions are provided which are safe. printf() needs to be called with a FreeRTOS mutex help (or called from only a single task). Each task is run in its own pthread, which makes debugging with standard tools (such as GDB) easier backtraces for individual tasks are available. Threads for non-running tasks are blocked in sigwait(). The stack for each task (thread) is allocated when the thread is created, and the stack provided during task creation is not used. This is so the stack has guard pages, to help with detecting stack overflows. Task switch is done by resuming the thread for the next task by sending it the resume signal (SIGUSR1) and then suspending the current thread. The timer interrupt uses SIGALRM and care is taken to ensure that the signal handler runs only on the thread for the current task. The additional data needed per-thread is stored at the top on the task's stack. When a running task is being deleted, its thread is marked it as dying so when we switch away from it it exits instead of suspending. This ensures that even if the idle task doesn't run, threads are deleted which allows for more threads to be created (if many tasks are being created and deleted in rapid succession). To further aid debugging, SIGINT (^C) is not blocked inside critical sections. This allows it to be used break into GDB while in a critical section. This means that care must be taken with any custom SIGINT handlers as these are like NMIs. This is somewhat inspired by an existing port by William Davy (https://www.freertos.org/FreeRTOS-simulator-for-Linux.html) but it takes a number of different approaches to make it switch tasks reliableand there's little similarly with the original implementation. - Critical sections block scheduling/"interrupts" by blocking signals using pthread_sigmask(). This is more expensive than attempting to use flags but works reliably and is analogous to the interrupt enable/disable on real hardware. - Care is take to ensure that the SIGALRM handler (for the timer tick) is runnable only on the pthread for the running task. This makes tasks switches more straight-forward and reliable as we can suspend the thread while in the signal handler. - Task switches save/restore the critical nesting on the stack. - Only uses a single (SIGUSR1) signal which is ignored and thus GDB's default signal handling options won't trap/print on this signal. - Extra per-thread data is stored on the task's stack, making it accessible in O(1) instead of performing a O(n) lookup of the array. - Uses the task create/delete hooks in a similar way to the Windows port, rather than overloading trace points.
5 years ago
return ptr;
portable/GCC/Posix: add new port for Posix (Linux) applications This is similar to the Windows port, allowing FreeRTOS kernel applications to run as regular applications on Posix (Linux) systems. You can use this in a 32-bit or 64-bit application (although there are dynamic memory allocation trace points that do not support 64-bit addresses). Many of the same caveats of running an RTOS on a non-real-time system apply, but this is still very useful for easy debugging/testing applications in a simulated environment. In particular, it allows easy use of tools such as valgrind. You can call standard library functions from tasks but care must be taken with any that internally take mutexes or block. This includes malloc()/free() and many stdio functions (e.g., printf()). Replacement malloc(), free(), realloc(), and calloc() functions are provided which are safe. printf() needs to be called with a FreeRTOS mutex help (or called from only a single task). Each task is run in its own pthread, which makes debugging with standard tools (such as GDB) easier backtraces for individual tasks are available. Threads for non-running tasks are blocked in sigwait(). The stack for each task (thread) is allocated when the thread is created, and the stack provided during task creation is not used. This is so the stack has guard pages, to help with detecting stack overflows. Task switch is done by resuming the thread for the next task by sending it the resume signal (SIGUSR1) and then suspending the current thread. The timer interrupt uses SIGALRM and care is taken to ensure that the signal handler runs only on the thread for the current task. The additional data needed per-thread is stored at the top on the task's stack. When a running task is being deleted, its thread is marked it as dying so when we switch away from it it exits instead of suspending. This ensures that even if the idle task doesn't run, threads are deleted which allows for more threads to be created (if many tasks are being created and deleted in rapid succession). To further aid debugging, SIGINT (^C) is not blocked inside critical sections. This allows it to be used break into GDB while in a critical section. This means that care must be taken with any custom SIGINT handlers as these are like NMIs. This is somewhat inspired by an existing port by William Davy (https://www.freertos.org/FreeRTOS-simulator-for-Linux.html) but it takes a number of different approaches to make it switch tasks reliableand there's little similarly with the original implementation. - Critical sections block scheduling/"interrupts" by blocking signals using pthread_sigmask(). This is more expensive than attempting to use flags but works reliably and is analogous to the interrupt enable/disable on real hardware. - Care is take to ensure that the SIGALRM handler (for the timer tick) is runnable only on the pthread for the running task. This makes tasks switches more straight-forward and reliable as we can suspend the thread while in the signal handler. - Task switches save/restore the critical nesting on the stack. - Only uses a single (SIGUSR1) signal which is ignored and thus GDB's default signal handling options won't trap/print on this signal. - Extra per-thread data is stored on the task's stack, making it accessible in O(1) instead of performing a O(n) lookup of the array. - Uses the task create/delete hooks in a similar way to the Windows port, rather than overloading trace points.
5 years ago
}
static void prvFatalError( const char * pcCall,
int iErrno )
portable/GCC/Posix: add new port for Posix (Linux) applications This is similar to the Windows port, allowing FreeRTOS kernel applications to run as regular applications on Posix (Linux) systems. You can use this in a 32-bit or 64-bit application (although there are dynamic memory allocation trace points that do not support 64-bit addresses). Many of the same caveats of running an RTOS on a non-real-time system apply, but this is still very useful for easy debugging/testing applications in a simulated environment. In particular, it allows easy use of tools such as valgrind. You can call standard library functions from tasks but care must be taken with any that internally take mutexes or block. This includes malloc()/free() and many stdio functions (e.g., printf()). Replacement malloc(), free(), realloc(), and calloc() functions are provided which are safe. printf() needs to be called with a FreeRTOS mutex help (or called from only a single task). Each task is run in its own pthread, which makes debugging with standard tools (such as GDB) easier backtraces for individual tasks are available. Threads for non-running tasks are blocked in sigwait(). The stack for each task (thread) is allocated when the thread is created, and the stack provided during task creation is not used. This is so the stack has guard pages, to help with detecting stack overflows. Task switch is done by resuming the thread for the next task by sending it the resume signal (SIGUSR1) and then suspending the current thread. The timer interrupt uses SIGALRM and care is taken to ensure that the signal handler runs only on the thread for the current task. The additional data needed per-thread is stored at the top on the task's stack. When a running task is being deleted, its thread is marked it as dying so when we switch away from it it exits instead of suspending. This ensures that even if the idle task doesn't run, threads are deleted which allows for more threads to be created (if many tasks are being created and deleted in rapid succession). To further aid debugging, SIGINT (^C) is not blocked inside critical sections. This allows it to be used break into GDB while in a critical section. This means that care must be taken with any custom SIGINT handlers as these are like NMIs. This is somewhat inspired by an existing port by William Davy (https://www.freertos.org/FreeRTOS-simulator-for-Linux.html) but it takes a number of different approaches to make it switch tasks reliableand there's little similarly with the original implementation. - Critical sections block scheduling/"interrupts" by blocking signals using pthread_sigmask(). This is more expensive than attempting to use flags but works reliably and is analogous to the interrupt enable/disable on real hardware. - Care is take to ensure that the SIGALRM handler (for the timer tick) is runnable only on the pthread for the running task. This makes tasks switches more straight-forward and reliable as we can suspend the thread while in the signal handler. - Task switches save/restore the critical nesting on the stack. - Only uses a single (SIGUSR1) signal which is ignored and thus GDB's default signal handling options won't trap/print on this signal. - Extra per-thread data is stored on the task's stack, making it accessible in O(1) instead of performing a O(n) lookup of the array. - Uses the task create/delete hooks in a similar way to the Windows port, rather than overloading trace points.
5 years ago
{
fprintf( stderr, "%s: %s\n", pcCall, strerror( iErrno ) );
abort();
portable/GCC/Posix: add new port for Posix (Linux) applications This is similar to the Windows port, allowing FreeRTOS kernel applications to run as regular applications on Posix (Linux) systems. You can use this in a 32-bit or 64-bit application (although there are dynamic memory allocation trace points that do not support 64-bit addresses). Many of the same caveats of running an RTOS on a non-real-time system apply, but this is still very useful for easy debugging/testing applications in a simulated environment. In particular, it allows easy use of tools such as valgrind. You can call standard library functions from tasks but care must be taken with any that internally take mutexes or block. This includes malloc()/free() and many stdio functions (e.g., printf()). Replacement malloc(), free(), realloc(), and calloc() functions are provided which are safe. printf() needs to be called with a FreeRTOS mutex help (or called from only a single task). Each task is run in its own pthread, which makes debugging with standard tools (such as GDB) easier backtraces for individual tasks are available. Threads for non-running tasks are blocked in sigwait(). The stack for each task (thread) is allocated when the thread is created, and the stack provided during task creation is not used. This is so the stack has guard pages, to help with detecting stack overflows. Task switch is done by resuming the thread for the next task by sending it the resume signal (SIGUSR1) and then suspending the current thread. The timer interrupt uses SIGALRM and care is taken to ensure that the signal handler runs only on the thread for the current task. The additional data needed per-thread is stored at the top on the task's stack. When a running task is being deleted, its thread is marked it as dying so when we switch away from it it exits instead of suspending. This ensures that even if the idle task doesn't run, threads are deleted which allows for more threads to be created (if many tasks are being created and deleted in rapid succession). To further aid debugging, SIGINT (^C) is not blocked inside critical sections. This allows it to be used break into GDB while in a critical section. This means that care must be taken with any custom SIGINT handlers as these are like NMIs. This is somewhat inspired by an existing port by William Davy (https://www.freertos.org/FreeRTOS-simulator-for-Linux.html) but it takes a number of different approaches to make it switch tasks reliableand there's little similarly with the original implementation. - Critical sections block scheduling/"interrupts" by blocking signals using pthread_sigmask(). This is more expensive than attempting to use flags but works reliably and is analogous to the interrupt enable/disable on real hardware. - Care is take to ensure that the SIGALRM handler (for the timer tick) is runnable only on the pthread for the running task. This makes tasks switches more straight-forward and reliable as we can suspend the thread while in the signal handler. - Task switches save/restore the critical nesting on the stack. - Only uses a single (SIGUSR1) signal which is ignored and thus GDB's default signal handling options won't trap/print on this signal. - Extra per-thread data is stored on the task's stack, making it accessible in O(1) instead of performing a O(n) lookup of the array. - Uses the task create/delete hooks in a similar way to the Windows port, rather than overloading trace points.
5 years ago
}
/*
* See header file for description.
*/
portSTACK_TYPE * pxPortInitialiseStack( portSTACK_TYPE * pxTopOfStack,
portSTACK_TYPE * pxEndOfStack,
pdTASK_CODE pxCode,
void * pvParameters )
portable/GCC/Posix: add new port for Posix (Linux) applications This is similar to the Windows port, allowing FreeRTOS kernel applications to run as regular applications on Posix (Linux) systems. You can use this in a 32-bit or 64-bit application (although there are dynamic memory allocation trace points that do not support 64-bit addresses). Many of the same caveats of running an RTOS on a non-real-time system apply, but this is still very useful for easy debugging/testing applications in a simulated environment. In particular, it allows easy use of tools such as valgrind. You can call standard library functions from tasks but care must be taken with any that internally take mutexes or block. This includes malloc()/free() and many stdio functions (e.g., printf()). Replacement malloc(), free(), realloc(), and calloc() functions are provided which are safe. printf() needs to be called with a FreeRTOS mutex help (or called from only a single task). Each task is run in its own pthread, which makes debugging with standard tools (such as GDB) easier backtraces for individual tasks are available. Threads for non-running tasks are blocked in sigwait(). The stack for each task (thread) is allocated when the thread is created, and the stack provided during task creation is not used. This is so the stack has guard pages, to help with detecting stack overflows. Task switch is done by resuming the thread for the next task by sending it the resume signal (SIGUSR1) and then suspending the current thread. The timer interrupt uses SIGALRM and care is taken to ensure that the signal handler runs only on the thread for the current task. The additional data needed per-thread is stored at the top on the task's stack. When a running task is being deleted, its thread is marked it as dying so when we switch away from it it exits instead of suspending. This ensures that even if the idle task doesn't run, threads are deleted which allows for more threads to be created (if many tasks are being created and deleted in rapid succession). To further aid debugging, SIGINT (^C) is not blocked inside critical sections. This allows it to be used break into GDB while in a critical section. This means that care must be taken with any custom SIGINT handlers as these are like NMIs. This is somewhat inspired by an existing port by William Davy (https://www.freertos.org/FreeRTOS-simulator-for-Linux.html) but it takes a number of different approaches to make it switch tasks reliableand there's little similarly with the original implementation. - Critical sections block scheduling/"interrupts" by blocking signals using pthread_sigmask(). This is more expensive than attempting to use flags but works reliably and is analogous to the interrupt enable/disable on real hardware. - Care is take to ensure that the SIGALRM handler (for the timer tick) is runnable only on the pthread for the running task. This makes tasks switches more straight-forward and reliable as we can suspend the thread while in the signal handler. - Task switches save/restore the critical nesting on the stack. - Only uses a single (SIGUSR1) signal which is ignored and thus GDB's default signal handling options won't trap/print on this signal. - Extra per-thread data is stored on the task's stack, making it accessible in O(1) instead of performing a O(n) lookup of the array. - Uses the task create/delete hooks in a similar way to the Windows port, rather than overloading trace points.
5 years ago
{
Thread_t * thread;
pthread_attr_t xThreadAttributes;
size_t ulStackSize;
int iRet;
portable/GCC/Posix: add new port for Posix (Linux) applications This is similar to the Windows port, allowing FreeRTOS kernel applications to run as regular applications on Posix (Linux) systems. You can use this in a 32-bit or 64-bit application (although there are dynamic memory allocation trace points that do not support 64-bit addresses). Many of the same caveats of running an RTOS on a non-real-time system apply, but this is still very useful for easy debugging/testing applications in a simulated environment. In particular, it allows easy use of tools such as valgrind. You can call standard library functions from tasks but care must be taken with any that internally take mutexes or block. This includes malloc()/free() and many stdio functions (e.g., printf()). Replacement malloc(), free(), realloc(), and calloc() functions are provided which are safe. printf() needs to be called with a FreeRTOS mutex help (or called from only a single task). Each task is run in its own pthread, which makes debugging with standard tools (such as GDB) easier backtraces for individual tasks are available. Threads for non-running tasks are blocked in sigwait(). The stack for each task (thread) is allocated when the thread is created, and the stack provided during task creation is not used. This is so the stack has guard pages, to help with detecting stack overflows. Task switch is done by resuming the thread for the next task by sending it the resume signal (SIGUSR1) and then suspending the current thread. The timer interrupt uses SIGALRM and care is taken to ensure that the signal handler runs only on the thread for the current task. The additional data needed per-thread is stored at the top on the task's stack. When a running task is being deleted, its thread is marked it as dying so when we switch away from it it exits instead of suspending. This ensures that even if the idle task doesn't run, threads are deleted which allows for more threads to be created (if many tasks are being created and deleted in rapid succession). To further aid debugging, SIGINT (^C) is not blocked inside critical sections. This allows it to be used break into GDB while in a critical section. This means that care must be taken with any custom SIGINT handlers as these are like NMIs. This is somewhat inspired by an existing port by William Davy (https://www.freertos.org/FreeRTOS-simulator-for-Linux.html) but it takes a number of different approaches to make it switch tasks reliableand there's little similarly with the original implementation. - Critical sections block scheduling/"interrupts" by blocking signals using pthread_sigmask(). This is more expensive than attempting to use flags but works reliably and is analogous to the interrupt enable/disable on real hardware. - Care is take to ensure that the SIGALRM handler (for the timer tick) is runnable only on the pthread for the running task. This makes tasks switches more straight-forward and reliable as we can suspend the thread while in the signal handler. - Task switches save/restore the critical nesting on the stack. - Only uses a single (SIGUSR1) signal which is ignored and thus GDB's default signal handling options won't trap/print on this signal. - Extra per-thread data is stored on the task's stack, making it accessible in O(1) instead of performing a O(n) lookup of the array. - Uses the task create/delete hooks in a similar way to the Windows port, rather than overloading trace points.
5 years ago
( void ) pthread_once( &hSigSetupThread, prvSetupSignalsAndSchedulerPolicy );
portable/GCC/Posix: add new port for Posix (Linux) applications This is similar to the Windows port, allowing FreeRTOS kernel applications to run as regular applications on Posix (Linux) systems. You can use this in a 32-bit or 64-bit application (although there are dynamic memory allocation trace points that do not support 64-bit addresses). Many of the same caveats of running an RTOS on a non-real-time system apply, but this is still very useful for easy debugging/testing applications in a simulated environment. In particular, it allows easy use of tools such as valgrind. You can call standard library functions from tasks but care must be taken with any that internally take mutexes or block. This includes malloc()/free() and many stdio functions (e.g., printf()). Replacement malloc(), free(), realloc(), and calloc() functions are provided which are safe. printf() needs to be called with a FreeRTOS mutex help (or called from only a single task). Each task is run in its own pthread, which makes debugging with standard tools (such as GDB) easier backtraces for individual tasks are available. Threads for non-running tasks are blocked in sigwait(). The stack for each task (thread) is allocated when the thread is created, and the stack provided during task creation is not used. This is so the stack has guard pages, to help with detecting stack overflows. Task switch is done by resuming the thread for the next task by sending it the resume signal (SIGUSR1) and then suspending the current thread. The timer interrupt uses SIGALRM and care is taken to ensure that the signal handler runs only on the thread for the current task. The additional data needed per-thread is stored at the top on the task's stack. When a running task is being deleted, its thread is marked it as dying so when we switch away from it it exits instead of suspending. This ensures that even if the idle task doesn't run, threads are deleted which allows for more threads to be created (if many tasks are being created and deleted in rapid succession). To further aid debugging, SIGINT (^C) is not blocked inside critical sections. This allows it to be used break into GDB while in a critical section. This means that care must be taken with any custom SIGINT handlers as these are like NMIs. This is somewhat inspired by an existing port by William Davy (https://www.freertos.org/FreeRTOS-simulator-for-Linux.html) but it takes a number of different approaches to make it switch tasks reliableand there's little similarly with the original implementation. - Critical sections block scheduling/"interrupts" by blocking signals using pthread_sigmask(). This is more expensive than attempting to use flags but works reliably and is analogous to the interrupt enable/disable on real hardware. - Care is take to ensure that the SIGALRM handler (for the timer tick) is runnable only on the pthread for the running task. This makes tasks switches more straight-forward and reliable as we can suspend the thread while in the signal handler. - Task switches save/restore the critical nesting on the stack. - Only uses a single (SIGUSR1) signal which is ignored and thus GDB's default signal handling options won't trap/print on this signal. - Extra per-thread data is stored on the task's stack, making it accessible in O(1) instead of performing a O(n) lookup of the array. - Uses the task create/delete hooks in a similar way to the Windows port, rather than overloading trace points.
5 years ago
/*
* Store the additional thread data at the start of the stack.
*/
thread = ( Thread_t * ) ( pxTopOfStack + 1 ) - 1;
pxTopOfStack = ( portSTACK_TYPE * ) thread - 1;
ulStackSize = ( pxTopOfStack + 1 - pxEndOfStack ) * sizeof( *pxTopOfStack );
portable/GCC/Posix: add new port for Posix (Linux) applications This is similar to the Windows port, allowing FreeRTOS kernel applications to run as regular applications on Posix (Linux) systems. You can use this in a 32-bit or 64-bit application (although there are dynamic memory allocation trace points that do not support 64-bit addresses). Many of the same caveats of running an RTOS on a non-real-time system apply, but this is still very useful for easy debugging/testing applications in a simulated environment. In particular, it allows easy use of tools such as valgrind. You can call standard library functions from tasks but care must be taken with any that internally take mutexes or block. This includes malloc()/free() and many stdio functions (e.g., printf()). Replacement malloc(), free(), realloc(), and calloc() functions are provided which are safe. printf() needs to be called with a FreeRTOS mutex help (or called from only a single task). Each task is run in its own pthread, which makes debugging with standard tools (such as GDB) easier backtraces for individual tasks are available. Threads for non-running tasks are blocked in sigwait(). The stack for each task (thread) is allocated when the thread is created, and the stack provided during task creation is not used. This is so the stack has guard pages, to help with detecting stack overflows. Task switch is done by resuming the thread for the next task by sending it the resume signal (SIGUSR1) and then suspending the current thread. The timer interrupt uses SIGALRM and care is taken to ensure that the signal handler runs only on the thread for the current task. The additional data needed per-thread is stored at the top on the task's stack. When a running task is being deleted, its thread is marked it as dying so when we switch away from it it exits instead of suspending. This ensures that even if the idle task doesn't run, threads are deleted which allows for more threads to be created (if many tasks are being created and deleted in rapid succession). To further aid debugging, SIGINT (^C) is not blocked inside critical sections. This allows it to be used break into GDB while in a critical section. This means that care must be taken with any custom SIGINT handlers as these are like NMIs. This is somewhat inspired by an existing port by William Davy (https://www.freertos.org/FreeRTOS-simulator-for-Linux.html) but it takes a number of different approaches to make it switch tasks reliableand there's little similarly with the original implementation. - Critical sections block scheduling/"interrupts" by blocking signals using pthread_sigmask(). This is more expensive than attempting to use flags but works reliably and is analogous to the interrupt enable/disable on real hardware. - Care is take to ensure that the SIGALRM handler (for the timer tick) is runnable only on the pthread for the running task. This makes tasks switches more straight-forward and reliable as we can suspend the thread while in the signal handler. - Task switches save/restore the critical nesting on the stack. - Only uses a single (SIGUSR1) signal which is ignored and thus GDB's default signal handling options won't trap/print on this signal. - Extra per-thread data is stored on the task's stack, making it accessible in O(1) instead of performing a O(n) lookup of the array. - Uses the task create/delete hooks in a similar way to the Windows port, rather than overloading trace points.
5 years ago
thread->pxCode = pxCode;
thread->pvParams = pvParameters;
thread->xDying = pdFALSE;
portable/GCC/Posix: add new port for Posix (Linux) applications This is similar to the Windows port, allowing FreeRTOS kernel applications to run as regular applications on Posix (Linux) systems. You can use this in a 32-bit or 64-bit application (although there are dynamic memory allocation trace points that do not support 64-bit addresses). Many of the same caveats of running an RTOS on a non-real-time system apply, but this is still very useful for easy debugging/testing applications in a simulated environment. In particular, it allows easy use of tools such as valgrind. You can call standard library functions from tasks but care must be taken with any that internally take mutexes or block. This includes malloc()/free() and many stdio functions (e.g., printf()). Replacement malloc(), free(), realloc(), and calloc() functions are provided which are safe. printf() needs to be called with a FreeRTOS mutex help (or called from only a single task). Each task is run in its own pthread, which makes debugging with standard tools (such as GDB) easier backtraces for individual tasks are available. Threads for non-running tasks are blocked in sigwait(). The stack for each task (thread) is allocated when the thread is created, and the stack provided during task creation is not used. This is so the stack has guard pages, to help with detecting stack overflows. Task switch is done by resuming the thread for the next task by sending it the resume signal (SIGUSR1) and then suspending the current thread. The timer interrupt uses SIGALRM and care is taken to ensure that the signal handler runs only on the thread for the current task. The additional data needed per-thread is stored at the top on the task's stack. When a running task is being deleted, its thread is marked it as dying so when we switch away from it it exits instead of suspending. This ensures that even if the idle task doesn't run, threads are deleted which allows for more threads to be created (if many tasks are being created and deleted in rapid succession). To further aid debugging, SIGINT (^C) is not blocked inside critical sections. This allows it to be used break into GDB while in a critical section. This means that care must be taken with any custom SIGINT handlers as these are like NMIs. This is somewhat inspired by an existing port by William Davy (https://www.freertos.org/FreeRTOS-simulator-for-Linux.html) but it takes a number of different approaches to make it switch tasks reliableand there's little similarly with the original implementation. - Critical sections block scheduling/"interrupts" by blocking signals using pthread_sigmask(). This is more expensive than attempting to use flags but works reliably and is analogous to the interrupt enable/disable on real hardware. - Care is take to ensure that the SIGALRM handler (for the timer tick) is runnable only on the pthread for the running task. This makes tasks switches more straight-forward and reliable as we can suspend the thread while in the signal handler. - Task switches save/restore the critical nesting on the stack. - Only uses a single (SIGUSR1) signal which is ignored and thus GDB's default signal handling options won't trap/print on this signal. - Extra per-thread data is stored on the task's stack, making it accessible in O(1) instead of performing a O(n) lookup of the array. - Uses the task create/delete hooks in a similar way to the Windows port, rather than overloading trace points.
5 years ago
pthread_attr_init( &xThreadAttributes );
pthread_attr_setstack( &xThreadAttributes, pxEndOfStack, ulStackSize );
portable/GCC/Posix: add new port for Posix (Linux) applications This is similar to the Windows port, allowing FreeRTOS kernel applications to run as regular applications on Posix (Linux) systems. You can use this in a 32-bit or 64-bit application (although there are dynamic memory allocation trace points that do not support 64-bit addresses). Many of the same caveats of running an RTOS on a non-real-time system apply, but this is still very useful for easy debugging/testing applications in a simulated environment. In particular, it allows easy use of tools such as valgrind. You can call standard library functions from tasks but care must be taken with any that internally take mutexes or block. This includes malloc()/free() and many stdio functions (e.g., printf()). Replacement malloc(), free(), realloc(), and calloc() functions are provided which are safe. printf() needs to be called with a FreeRTOS mutex help (or called from only a single task). Each task is run in its own pthread, which makes debugging with standard tools (such as GDB) easier backtraces for individual tasks are available. Threads for non-running tasks are blocked in sigwait(). The stack for each task (thread) is allocated when the thread is created, and the stack provided during task creation is not used. This is so the stack has guard pages, to help with detecting stack overflows. Task switch is done by resuming the thread for the next task by sending it the resume signal (SIGUSR1) and then suspending the current thread. The timer interrupt uses SIGALRM and care is taken to ensure that the signal handler runs only on the thread for the current task. The additional data needed per-thread is stored at the top on the task's stack. When a running task is being deleted, its thread is marked it as dying so when we switch away from it it exits instead of suspending. This ensures that even if the idle task doesn't run, threads are deleted which allows for more threads to be created (if many tasks are being created and deleted in rapid succession). To further aid debugging, SIGINT (^C) is not blocked inside critical sections. This allows it to be used break into GDB while in a critical section. This means that care must be taken with any custom SIGINT handlers as these are like NMIs. This is somewhat inspired by an existing port by William Davy (https://www.freertos.org/FreeRTOS-simulator-for-Linux.html) but it takes a number of different approaches to make it switch tasks reliableand there's little similarly with the original implementation. - Critical sections block scheduling/"interrupts" by blocking signals using pthread_sigmask(). This is more expensive than attempting to use flags but works reliably and is analogous to the interrupt enable/disable on real hardware. - Care is take to ensure that the SIGALRM handler (for the timer tick) is runnable only on the pthread for the running task. This makes tasks switches more straight-forward and reliable as we can suspend the thread while in the signal handler. - Task switches save/restore the critical nesting on the stack. - Only uses a single (SIGUSR1) signal which is ignored and thus GDB's default signal handling options won't trap/print on this signal. - Extra per-thread data is stored on the task's stack, making it accessible in O(1) instead of performing a O(n) lookup of the array. - Uses the task create/delete hooks in a similar way to the Windows port, rather than overloading trace points.
5 years ago
vPortEnterCritical();
portable/GCC/Posix: add new port for Posix (Linux) applications This is similar to the Windows port, allowing FreeRTOS kernel applications to run as regular applications on Posix (Linux) systems. You can use this in a 32-bit or 64-bit application (although there are dynamic memory allocation trace points that do not support 64-bit addresses). Many of the same caveats of running an RTOS on a non-real-time system apply, but this is still very useful for easy debugging/testing applications in a simulated environment. In particular, it allows easy use of tools such as valgrind. You can call standard library functions from tasks but care must be taken with any that internally take mutexes or block. This includes malloc()/free() and many stdio functions (e.g., printf()). Replacement malloc(), free(), realloc(), and calloc() functions are provided which are safe. printf() needs to be called with a FreeRTOS mutex help (or called from only a single task). Each task is run in its own pthread, which makes debugging with standard tools (such as GDB) easier backtraces for individual tasks are available. Threads for non-running tasks are blocked in sigwait(). The stack for each task (thread) is allocated when the thread is created, and the stack provided during task creation is not used. This is so the stack has guard pages, to help with detecting stack overflows. Task switch is done by resuming the thread for the next task by sending it the resume signal (SIGUSR1) and then suspending the current thread. The timer interrupt uses SIGALRM and care is taken to ensure that the signal handler runs only on the thread for the current task. The additional data needed per-thread is stored at the top on the task's stack. When a running task is being deleted, its thread is marked it as dying so when we switch away from it it exits instead of suspending. This ensures that even if the idle task doesn't run, threads are deleted which allows for more threads to be created (if many tasks are being created and deleted in rapid succession). To further aid debugging, SIGINT (^C) is not blocked inside critical sections. This allows it to be used break into GDB while in a critical section. This means that care must be taken with any custom SIGINT handlers as these are like NMIs. This is somewhat inspired by an existing port by William Davy (https://www.freertos.org/FreeRTOS-simulator-for-Linux.html) but it takes a number of different approaches to make it switch tasks reliableand there's little similarly with the original implementation. - Critical sections block scheduling/"interrupts" by blocking signals using pthread_sigmask(). This is more expensive than attempting to use flags but works reliably and is analogous to the interrupt enable/disable on real hardware. - Care is take to ensure that the SIGALRM handler (for the timer tick) is runnable only on the pthread for the running task. This makes tasks switches more straight-forward and reliable as we can suspend the thread while in the signal handler. - Task switches save/restore the critical nesting on the stack. - Only uses a single (SIGUSR1) signal which is ignored and thus GDB's default signal handling options won't trap/print on this signal. - Extra per-thread data is stored on the task's stack, making it accessible in O(1) instead of performing a O(n) lookup of the array. - Uses the task create/delete hooks in a similar way to the Windows port, rather than overloading trace points.
5 years ago
iRet = pthread_create( &thread->pthread, &xThreadAttributes,
prvWaitForStart, thread );
portable/GCC/Posix: add new port for Posix (Linux) applications This is similar to the Windows port, allowing FreeRTOS kernel applications to run as regular applications on Posix (Linux) systems. You can use this in a 32-bit or 64-bit application (although there are dynamic memory allocation trace points that do not support 64-bit addresses). Many of the same caveats of running an RTOS on a non-real-time system apply, but this is still very useful for easy debugging/testing applications in a simulated environment. In particular, it allows easy use of tools such as valgrind. You can call standard library functions from tasks but care must be taken with any that internally take mutexes or block. This includes malloc()/free() and many stdio functions (e.g., printf()). Replacement malloc(), free(), realloc(), and calloc() functions are provided which are safe. printf() needs to be called with a FreeRTOS mutex help (or called from only a single task). Each task is run in its own pthread, which makes debugging with standard tools (such as GDB) easier backtraces for individual tasks are available. Threads for non-running tasks are blocked in sigwait(). The stack for each task (thread) is allocated when the thread is created, and the stack provided during task creation is not used. This is so the stack has guard pages, to help with detecting stack overflows. Task switch is done by resuming the thread for the next task by sending it the resume signal (SIGUSR1) and then suspending the current thread. The timer interrupt uses SIGALRM and care is taken to ensure that the signal handler runs only on the thread for the current task. The additional data needed per-thread is stored at the top on the task's stack. When a running task is being deleted, its thread is marked it as dying so when we switch away from it it exits instead of suspending. This ensures that even if the idle task doesn't run, threads are deleted which allows for more threads to be created (if many tasks are being created and deleted in rapid succession). To further aid debugging, SIGINT (^C) is not blocked inside critical sections. This allows it to be used break into GDB while in a critical section. This means that care must be taken with any custom SIGINT handlers as these are like NMIs. This is somewhat inspired by an existing port by William Davy (https://www.freertos.org/FreeRTOS-simulator-for-Linux.html) but it takes a number of different approaches to make it switch tasks reliableand there's little similarly with the original implementation. - Critical sections block scheduling/"interrupts" by blocking signals using pthread_sigmask(). This is more expensive than attempting to use flags but works reliably and is analogous to the interrupt enable/disable on real hardware. - Care is take to ensure that the SIGALRM handler (for the timer tick) is runnable only on the pthread for the running task. This makes tasks switches more straight-forward and reliable as we can suspend the thread while in the signal handler. - Task switches save/restore the critical nesting on the stack. - Only uses a single (SIGUSR1) signal which is ignored and thus GDB's default signal handling options won't trap/print on this signal. - Extra per-thread data is stored on the task's stack, making it accessible in O(1) instead of performing a O(n) lookup of the array. - Uses the task create/delete hooks in a similar way to the Windows port, rather than overloading trace points.
5 years ago
if( iRet )
{
prvFatalError( "pthread_create", iRet );
}
portable/GCC/Posix: add new port for Posix (Linux) applications This is similar to the Windows port, allowing FreeRTOS kernel applications to run as regular applications on Posix (Linux) systems. You can use this in a 32-bit or 64-bit application (although there are dynamic memory allocation trace points that do not support 64-bit addresses). Many of the same caveats of running an RTOS on a non-real-time system apply, but this is still very useful for easy debugging/testing applications in a simulated environment. In particular, it allows easy use of tools such as valgrind. You can call standard library functions from tasks but care must be taken with any that internally take mutexes or block. This includes malloc()/free() and many stdio functions (e.g., printf()). Replacement malloc(), free(), realloc(), and calloc() functions are provided which are safe. printf() needs to be called with a FreeRTOS mutex help (or called from only a single task). Each task is run in its own pthread, which makes debugging with standard tools (such as GDB) easier backtraces for individual tasks are available. Threads for non-running tasks are blocked in sigwait(). The stack for each task (thread) is allocated when the thread is created, and the stack provided during task creation is not used. This is so the stack has guard pages, to help with detecting stack overflows. Task switch is done by resuming the thread for the next task by sending it the resume signal (SIGUSR1) and then suspending the current thread. The timer interrupt uses SIGALRM and care is taken to ensure that the signal handler runs only on the thread for the current task. The additional data needed per-thread is stored at the top on the task's stack. When a running task is being deleted, its thread is marked it as dying so when we switch away from it it exits instead of suspending. This ensures that even if the idle task doesn't run, threads are deleted which allows for more threads to be created (if many tasks are being created and deleted in rapid succession). To further aid debugging, SIGINT (^C) is not blocked inside critical sections. This allows it to be used break into GDB while in a critical section. This means that care must be taken with any custom SIGINT handlers as these are like NMIs. This is somewhat inspired by an existing port by William Davy (https://www.freertos.org/FreeRTOS-simulator-for-Linux.html) but it takes a number of different approaches to make it switch tasks reliableand there's little similarly with the original implementation. - Critical sections block scheduling/"interrupts" by blocking signals using pthread_sigmask(). This is more expensive than attempting to use flags but works reliably and is analogous to the interrupt enable/disable on real hardware. - Care is take to ensure that the SIGALRM handler (for the timer tick) is runnable only on the pthread for the running task. This makes tasks switches more straight-forward and reliable as we can suspend the thread while in the signal handler. - Task switches save/restore the critical nesting on the stack. - Only uses a single (SIGUSR1) signal which is ignored and thus GDB's default signal handling options won't trap/print on this signal. - Extra per-thread data is stored on the task's stack, making it accessible in O(1) instead of performing a O(n) lookup of the array. - Uses the task create/delete hooks in a similar way to the Windows port, rather than overloading trace points.
5 years ago
vPortExitCritical();
return pxTopOfStack;
portable/GCC/Posix: add new port for Posix (Linux) applications This is similar to the Windows port, allowing FreeRTOS kernel applications to run as regular applications on Posix (Linux) systems. You can use this in a 32-bit or 64-bit application (although there are dynamic memory allocation trace points that do not support 64-bit addresses). Many of the same caveats of running an RTOS on a non-real-time system apply, but this is still very useful for easy debugging/testing applications in a simulated environment. In particular, it allows easy use of tools such as valgrind. You can call standard library functions from tasks but care must be taken with any that internally take mutexes or block. This includes malloc()/free() and many stdio functions (e.g., printf()). Replacement malloc(), free(), realloc(), and calloc() functions are provided which are safe. printf() needs to be called with a FreeRTOS mutex help (or called from only a single task). Each task is run in its own pthread, which makes debugging with standard tools (such as GDB) easier backtraces for individual tasks are available. Threads for non-running tasks are blocked in sigwait(). The stack for each task (thread) is allocated when the thread is created, and the stack provided during task creation is not used. This is so the stack has guard pages, to help with detecting stack overflows. Task switch is done by resuming the thread for the next task by sending it the resume signal (SIGUSR1) and then suspending the current thread. The timer interrupt uses SIGALRM and care is taken to ensure that the signal handler runs only on the thread for the current task. The additional data needed per-thread is stored at the top on the task's stack. When a running task is being deleted, its thread is marked it as dying so when we switch away from it it exits instead of suspending. This ensures that even if the idle task doesn't run, threads are deleted which allows for more threads to be created (if many tasks are being created and deleted in rapid succession). To further aid debugging, SIGINT (^C) is not blocked inside critical sections. This allows it to be used break into GDB while in a critical section. This means that care must be taken with any custom SIGINT handlers as these are like NMIs. This is somewhat inspired by an existing port by William Davy (https://www.freertos.org/FreeRTOS-simulator-for-Linux.html) but it takes a number of different approaches to make it switch tasks reliableand there's little similarly with the original implementation. - Critical sections block scheduling/"interrupts" by blocking signals using pthread_sigmask(). This is more expensive than attempting to use flags but works reliably and is analogous to the interrupt enable/disable on real hardware. - Care is take to ensure that the SIGALRM handler (for the timer tick) is runnable only on the pthread for the running task. This makes tasks switches more straight-forward and reliable as we can suspend the thread while in the signal handler. - Task switches save/restore the critical nesting on the stack. - Only uses a single (SIGUSR1) signal which is ignored and thus GDB's default signal handling options won't trap/print on this signal. - Extra per-thread data is stored on the task's stack, making it accessible in O(1) instead of performing a O(n) lookup of the array. - Uses the task create/delete hooks in a similar way to the Windows port, rather than overloading trace points.
5 years ago
}
/*-----------------------------------------------------------*/
void vPortStartFirstTask( void )
{
Thread_t * pxFirstThread = prvGetThreadFromTask( xTaskGetCurrentTaskHandle() );
portable/GCC/Posix: add new port for Posix (Linux) applications This is similar to the Windows port, allowing FreeRTOS kernel applications to run as regular applications on Posix (Linux) systems. You can use this in a 32-bit or 64-bit application (although there are dynamic memory allocation trace points that do not support 64-bit addresses). Many of the same caveats of running an RTOS on a non-real-time system apply, but this is still very useful for easy debugging/testing applications in a simulated environment. In particular, it allows easy use of tools such as valgrind. You can call standard library functions from tasks but care must be taken with any that internally take mutexes or block. This includes malloc()/free() and many stdio functions (e.g., printf()). Replacement malloc(), free(), realloc(), and calloc() functions are provided which are safe. printf() needs to be called with a FreeRTOS mutex help (or called from only a single task). Each task is run in its own pthread, which makes debugging with standard tools (such as GDB) easier backtraces for individual tasks are available. Threads for non-running tasks are blocked in sigwait(). The stack for each task (thread) is allocated when the thread is created, and the stack provided during task creation is not used. This is so the stack has guard pages, to help with detecting stack overflows. Task switch is done by resuming the thread for the next task by sending it the resume signal (SIGUSR1) and then suspending the current thread. The timer interrupt uses SIGALRM and care is taken to ensure that the signal handler runs only on the thread for the current task. The additional data needed per-thread is stored at the top on the task's stack. When a running task is being deleted, its thread is marked it as dying so when we switch away from it it exits instead of suspending. This ensures that even if the idle task doesn't run, threads are deleted which allows for more threads to be created (if many tasks are being created and deleted in rapid succession). To further aid debugging, SIGINT (^C) is not blocked inside critical sections. This allows it to be used break into GDB while in a critical section. This means that care must be taken with any custom SIGINT handlers as these are like NMIs. This is somewhat inspired by an existing port by William Davy (https://www.freertos.org/FreeRTOS-simulator-for-Linux.html) but it takes a number of different approaches to make it switch tasks reliableand there's little similarly with the original implementation. - Critical sections block scheduling/"interrupts" by blocking signals using pthread_sigmask(). This is more expensive than attempting to use flags but works reliably and is analogous to the interrupt enable/disable on real hardware. - Care is take to ensure that the SIGALRM handler (for the timer tick) is runnable only on the pthread for the running task. This makes tasks switches more straight-forward and reliable as we can suspend the thread while in the signal handler. - Task switches save/restore the critical nesting on the stack. - Only uses a single (SIGUSR1) signal which is ignored and thus GDB's default signal handling options won't trap/print on this signal. - Extra per-thread data is stored on the task's stack, making it accessible in O(1) instead of performing a O(n) lookup of the array. - Uses the task create/delete hooks in a similar way to the Windows port, rather than overloading trace points.
5 years ago
/* Start the first task. */
prvResumeThread( pxFirstThread->pthread );
portable/GCC/Posix: add new port for Posix (Linux) applications This is similar to the Windows port, allowing FreeRTOS kernel applications to run as regular applications on Posix (Linux) systems. You can use this in a 32-bit or 64-bit application (although there are dynamic memory allocation trace points that do not support 64-bit addresses). Many of the same caveats of running an RTOS on a non-real-time system apply, but this is still very useful for easy debugging/testing applications in a simulated environment. In particular, it allows easy use of tools such as valgrind. You can call standard library functions from tasks but care must be taken with any that internally take mutexes or block. This includes malloc()/free() and many stdio functions (e.g., printf()). Replacement malloc(), free(), realloc(), and calloc() functions are provided which are safe. printf() needs to be called with a FreeRTOS mutex help (or called from only a single task). Each task is run in its own pthread, which makes debugging with standard tools (such as GDB) easier backtraces for individual tasks are available. Threads for non-running tasks are blocked in sigwait(). The stack for each task (thread) is allocated when the thread is created, and the stack provided during task creation is not used. This is so the stack has guard pages, to help with detecting stack overflows. Task switch is done by resuming the thread for the next task by sending it the resume signal (SIGUSR1) and then suspending the current thread. The timer interrupt uses SIGALRM and care is taken to ensure that the signal handler runs only on the thread for the current task. The additional data needed per-thread is stored at the top on the task's stack. When a running task is being deleted, its thread is marked it as dying so when we switch away from it it exits instead of suspending. This ensures that even if the idle task doesn't run, threads are deleted which allows for more threads to be created (if many tasks are being created and deleted in rapid succession). To further aid debugging, SIGINT (^C) is not blocked inside critical sections. This allows it to be used break into GDB while in a critical section. This means that care must be taken with any custom SIGINT handlers as these are like NMIs. This is somewhat inspired by an existing port by William Davy (https://www.freertos.org/FreeRTOS-simulator-for-Linux.html) but it takes a number of different approaches to make it switch tasks reliableand there's little similarly with the original implementation. - Critical sections block scheduling/"interrupts" by blocking signals using pthread_sigmask(). This is more expensive than attempting to use flags but works reliably and is analogous to the interrupt enable/disable on real hardware. - Care is take to ensure that the SIGALRM handler (for the timer tick) is runnable only on the pthread for the running task. This makes tasks switches more straight-forward and reliable as we can suspend the thread while in the signal handler. - Task switches save/restore the critical nesting on the stack. - Only uses a single (SIGUSR1) signal which is ignored and thus GDB's default signal handling options won't trap/print on this signal. - Extra per-thread data is stored on the task's stack, making it accessible in O(1) instead of performing a O(n) lookup of the array. - Uses the task create/delete hooks in a similar way to the Windows port, rather than overloading trace points.
5 years ago
}
/*-----------------------------------------------------------*/
/*
* See header file for description.
*/
portBASE_TYPE xPortStartScheduler( void )
{
int iSignal;
sigset_t xSignals;
portable/GCC/Posix: add new port for Posix (Linux) applications This is similar to the Windows port, allowing FreeRTOS kernel applications to run as regular applications on Posix (Linux) systems. You can use this in a 32-bit or 64-bit application (although there are dynamic memory allocation trace points that do not support 64-bit addresses). Many of the same caveats of running an RTOS on a non-real-time system apply, but this is still very useful for easy debugging/testing applications in a simulated environment. In particular, it allows easy use of tools such as valgrind. You can call standard library functions from tasks but care must be taken with any that internally take mutexes or block. This includes malloc()/free() and many stdio functions (e.g., printf()). Replacement malloc(), free(), realloc(), and calloc() functions are provided which are safe. printf() needs to be called with a FreeRTOS mutex help (or called from only a single task). Each task is run in its own pthread, which makes debugging with standard tools (such as GDB) easier backtraces for individual tasks are available. Threads for non-running tasks are blocked in sigwait(). The stack for each task (thread) is allocated when the thread is created, and the stack provided during task creation is not used. This is so the stack has guard pages, to help with detecting stack overflows. Task switch is done by resuming the thread for the next task by sending it the resume signal (SIGUSR1) and then suspending the current thread. The timer interrupt uses SIGALRM and care is taken to ensure that the signal handler runs only on the thread for the current task. The additional data needed per-thread is stored at the top on the task's stack. When a running task is being deleted, its thread is marked it as dying so when we switch away from it it exits instead of suspending. This ensures that even if the idle task doesn't run, threads are deleted which allows for more threads to be created (if many tasks are being created and deleted in rapid succession). To further aid debugging, SIGINT (^C) is not blocked inside critical sections. This allows it to be used break into GDB while in a critical section. This means that care must be taken with any custom SIGINT handlers as these are like NMIs. This is somewhat inspired by an existing port by William Davy (https://www.freertos.org/FreeRTOS-simulator-for-Linux.html) but it takes a number of different approaches to make it switch tasks reliableand there's little similarly with the original implementation. - Critical sections block scheduling/"interrupts" by blocking signals using pthread_sigmask(). This is more expensive than attempting to use flags but works reliably and is analogous to the interrupt enable/disable on real hardware. - Care is take to ensure that the SIGALRM handler (for the timer tick) is runnable only on the pthread for the running task. This makes tasks switches more straight-forward and reliable as we can suspend the thread while in the signal handler. - Task switches save/restore the critical nesting on the stack. - Only uses a single (SIGUSR1) signal which is ignored and thus GDB's default signal handling options won't trap/print on this signal. - Extra per-thread data is stored on the task's stack, making it accessible in O(1) instead of performing a O(n) lookup of the array. - Uses the task create/delete hooks in a similar way to the Windows port, rather than overloading trace points.
5 years ago
hMainThread = pthread_self();
portable/GCC/Posix: add new port for Posix (Linux) applications This is similar to the Windows port, allowing FreeRTOS kernel applications to run as regular applications on Posix (Linux) systems. You can use this in a 32-bit or 64-bit application (although there are dynamic memory allocation trace points that do not support 64-bit addresses). Many of the same caveats of running an RTOS on a non-real-time system apply, but this is still very useful for easy debugging/testing applications in a simulated environment. In particular, it allows easy use of tools such as valgrind. You can call standard library functions from tasks but care must be taken with any that internally take mutexes or block. This includes malloc()/free() and many stdio functions (e.g., printf()). Replacement malloc(), free(), realloc(), and calloc() functions are provided which are safe. printf() needs to be called with a FreeRTOS mutex help (or called from only a single task). Each task is run in its own pthread, which makes debugging with standard tools (such as GDB) easier backtraces for individual tasks are available. Threads for non-running tasks are blocked in sigwait(). The stack for each task (thread) is allocated when the thread is created, and the stack provided during task creation is not used. This is so the stack has guard pages, to help with detecting stack overflows. Task switch is done by resuming the thread for the next task by sending it the resume signal (SIGUSR1) and then suspending the current thread. The timer interrupt uses SIGALRM and care is taken to ensure that the signal handler runs only on the thread for the current task. The additional data needed per-thread is stored at the top on the task's stack. When a running task is being deleted, its thread is marked it as dying so when we switch away from it it exits instead of suspending. This ensures that even if the idle task doesn't run, threads are deleted which allows for more threads to be created (if many tasks are being created and deleted in rapid succession). To further aid debugging, SIGINT (^C) is not blocked inside critical sections. This allows it to be used break into GDB while in a critical section. This means that care must be taken with any custom SIGINT handlers as these are like NMIs. This is somewhat inspired by an existing port by William Davy (https://www.freertos.org/FreeRTOS-simulator-for-Linux.html) but it takes a number of different approaches to make it switch tasks reliableand there's little similarly with the original implementation. - Critical sections block scheduling/"interrupts" by blocking signals using pthread_sigmask(). This is more expensive than attempting to use flags but works reliably and is analogous to the interrupt enable/disable on real hardware. - Care is take to ensure that the SIGALRM handler (for the timer tick) is runnable only on the pthread for the running task. This makes tasks switches more straight-forward and reliable as we can suspend the thread while in the signal handler. - Task switches save/restore the critical nesting on the stack. - Only uses a single (SIGUSR1) signal which is ignored and thus GDB's default signal handling options won't trap/print on this signal. - Extra per-thread data is stored on the task's stack, making it accessible in O(1) instead of performing a O(n) lookup of the array. - Uses the task create/delete hooks in a similar way to the Windows port, rather than overloading trace points.
5 years ago
/* Start the timer that generates the tick ISR. Interrupts are disabled
* here already. */
prvSetupTimerInterrupt();
portable/GCC/Posix: add new port for Posix (Linux) applications This is similar to the Windows port, allowing FreeRTOS kernel applications to run as regular applications on Posix (Linux) systems. You can use this in a 32-bit or 64-bit application (although there are dynamic memory allocation trace points that do not support 64-bit addresses). Many of the same caveats of running an RTOS on a non-real-time system apply, but this is still very useful for easy debugging/testing applications in a simulated environment. In particular, it allows easy use of tools such as valgrind. You can call standard library functions from tasks but care must be taken with any that internally take mutexes or block. This includes malloc()/free() and many stdio functions (e.g., printf()). Replacement malloc(), free(), realloc(), and calloc() functions are provided which are safe. printf() needs to be called with a FreeRTOS mutex help (or called from only a single task). Each task is run in its own pthread, which makes debugging with standard tools (such as GDB) easier backtraces for individual tasks are available. Threads for non-running tasks are blocked in sigwait(). The stack for each task (thread) is allocated when the thread is created, and the stack provided during task creation is not used. This is so the stack has guard pages, to help with detecting stack overflows. Task switch is done by resuming the thread for the next task by sending it the resume signal (SIGUSR1) and then suspending the current thread. The timer interrupt uses SIGALRM and care is taken to ensure that the signal handler runs only on the thread for the current task. The additional data needed per-thread is stored at the top on the task's stack. When a running task is being deleted, its thread is marked it as dying so when we switch away from it it exits instead of suspending. This ensures that even if the idle task doesn't run, threads are deleted which allows for more threads to be created (if many tasks are being created and deleted in rapid succession). To further aid debugging, SIGINT (^C) is not blocked inside critical sections. This allows it to be used break into GDB while in a critical section. This means that care must be taken with any custom SIGINT handlers as these are like NMIs. This is somewhat inspired by an existing port by William Davy (https://www.freertos.org/FreeRTOS-simulator-for-Linux.html) but it takes a number of different approaches to make it switch tasks reliableand there's little similarly with the original implementation. - Critical sections block scheduling/"interrupts" by blocking signals using pthread_sigmask(). This is more expensive than attempting to use flags but works reliably and is analogous to the interrupt enable/disable on real hardware. - Care is take to ensure that the SIGALRM handler (for the timer tick) is runnable only on the pthread for the running task. This makes tasks switches more straight-forward and reliable as we can suspend the thread while in the signal handler. - Task switches save/restore the critical nesting on the stack. - Only uses a single (SIGUSR1) signal which is ignored and thus GDB's default signal handling options won't trap/print on this signal. - Extra per-thread data is stored on the task's stack, making it accessible in O(1) instead of performing a O(n) lookup of the array. - Uses the task create/delete hooks in a similar way to the Windows port, rather than overloading trace points.
5 years ago
/* Start the first task. */
vPortStartFirstTask();
portable/GCC/Posix: add new port for Posix (Linux) applications This is similar to the Windows port, allowing FreeRTOS kernel applications to run as regular applications on Posix (Linux) systems. You can use this in a 32-bit or 64-bit application (although there are dynamic memory allocation trace points that do not support 64-bit addresses). Many of the same caveats of running an RTOS on a non-real-time system apply, but this is still very useful for easy debugging/testing applications in a simulated environment. In particular, it allows easy use of tools such as valgrind. You can call standard library functions from tasks but care must be taken with any that internally take mutexes or block. This includes malloc()/free() and many stdio functions (e.g., printf()). Replacement malloc(), free(), realloc(), and calloc() functions are provided which are safe. printf() needs to be called with a FreeRTOS mutex help (or called from only a single task). Each task is run in its own pthread, which makes debugging with standard tools (such as GDB) easier backtraces for individual tasks are available. Threads for non-running tasks are blocked in sigwait(). The stack for each task (thread) is allocated when the thread is created, and the stack provided during task creation is not used. This is so the stack has guard pages, to help with detecting stack overflows. Task switch is done by resuming the thread for the next task by sending it the resume signal (SIGUSR1) and then suspending the current thread. The timer interrupt uses SIGALRM and care is taken to ensure that the signal handler runs only on the thread for the current task. The additional data needed per-thread is stored at the top on the task's stack. When a running task is being deleted, its thread is marked it as dying so when we switch away from it it exits instead of suspending. This ensures that even if the idle task doesn't run, threads are deleted which allows for more threads to be created (if many tasks are being created and deleted in rapid succession). To further aid debugging, SIGINT (^C) is not blocked inside critical sections. This allows it to be used break into GDB while in a critical section. This means that care must be taken with any custom SIGINT handlers as these are like NMIs. This is somewhat inspired by an existing port by William Davy (https://www.freertos.org/FreeRTOS-simulator-for-Linux.html) but it takes a number of different approaches to make it switch tasks reliableand there's little similarly with the original implementation. - Critical sections block scheduling/"interrupts" by blocking signals using pthread_sigmask(). This is more expensive than attempting to use flags but works reliably and is analogous to the interrupt enable/disable on real hardware. - Care is take to ensure that the SIGALRM handler (for the timer tick) is runnable only on the pthread for the running task. This makes tasks switches more straight-forward and reliable as we can suspend the thread while in the signal handler. - Task switches save/restore the critical nesting on the stack. - Only uses a single (SIGUSR1) signal which is ignored and thus GDB's default signal handling options won't trap/print on this signal. - Extra per-thread data is stored on the task's stack, making it accessible in O(1) instead of performing a O(n) lookup of the array. - Uses the task create/delete hooks in a similar way to the Windows port, rather than overloading trace points.
5 years ago
/* Wait until signaled by vPortEndScheduler(). */
sigemptyset( &xSignals );
sigaddset( &xSignals, SIG_RESUME );
portable/GCC/Posix: add new port for Posix (Linux) applications This is similar to the Windows port, allowing FreeRTOS kernel applications to run as regular applications on Posix (Linux) systems. You can use this in a 32-bit or 64-bit application (although there are dynamic memory allocation trace points that do not support 64-bit addresses). Many of the same caveats of running an RTOS on a non-real-time system apply, but this is still very useful for easy debugging/testing applications in a simulated environment. In particular, it allows easy use of tools such as valgrind. You can call standard library functions from tasks but care must be taken with any that internally take mutexes or block. This includes malloc()/free() and many stdio functions (e.g., printf()). Replacement malloc(), free(), realloc(), and calloc() functions are provided which are safe. printf() needs to be called with a FreeRTOS mutex help (or called from only a single task). Each task is run in its own pthread, which makes debugging with standard tools (such as GDB) easier backtraces for individual tasks are available. Threads for non-running tasks are blocked in sigwait(). The stack for each task (thread) is allocated when the thread is created, and the stack provided during task creation is not used. This is so the stack has guard pages, to help with detecting stack overflows. Task switch is done by resuming the thread for the next task by sending it the resume signal (SIGUSR1) and then suspending the current thread. The timer interrupt uses SIGALRM and care is taken to ensure that the signal handler runs only on the thread for the current task. The additional data needed per-thread is stored at the top on the task's stack. When a running task is being deleted, its thread is marked it as dying so when we switch away from it it exits instead of suspending. This ensures that even if the idle task doesn't run, threads are deleted which allows for more threads to be created (if many tasks are being created and deleted in rapid succession). To further aid debugging, SIGINT (^C) is not blocked inside critical sections. This allows it to be used break into GDB while in a critical section. This means that care must be taken with any custom SIGINT handlers as these are like NMIs. This is somewhat inspired by an existing port by William Davy (https://www.freertos.org/FreeRTOS-simulator-for-Linux.html) but it takes a number of different approaches to make it switch tasks reliableand there's little similarly with the original implementation. - Critical sections block scheduling/"interrupts" by blocking signals using pthread_sigmask(). This is more expensive than attempting to use flags but works reliably and is analogous to the interrupt enable/disable on real hardware. - Care is take to ensure that the SIGALRM handler (for the timer tick) is runnable only on the pthread for the running task. This makes tasks switches more straight-forward and reliable as we can suspend the thread while in the signal handler. - Task switches save/restore the critical nesting on the stack. - Only uses a single (SIGUSR1) signal which is ignored and thus GDB's default signal handling options won't trap/print on this signal. - Extra per-thread data is stored on the task's stack, making it accessible in O(1) instead of performing a O(n) lookup of the array. - Uses the task create/delete hooks in a similar way to the Windows port, rather than overloading trace points.
5 years ago
while( !xSchedulerEnd )
{
sigwait( &xSignals, &iSignal );
}
portable/GCC/Posix: add new port for Posix (Linux) applications This is similar to the Windows port, allowing FreeRTOS kernel applications to run as regular applications on Posix (Linux) systems. You can use this in a 32-bit or 64-bit application (although there are dynamic memory allocation trace points that do not support 64-bit addresses). Many of the same caveats of running an RTOS on a non-real-time system apply, but this is still very useful for easy debugging/testing applications in a simulated environment. In particular, it allows easy use of tools such as valgrind. You can call standard library functions from tasks but care must be taken with any that internally take mutexes or block. This includes malloc()/free() and many stdio functions (e.g., printf()). Replacement malloc(), free(), realloc(), and calloc() functions are provided which are safe. printf() needs to be called with a FreeRTOS mutex help (or called from only a single task). Each task is run in its own pthread, which makes debugging with standard tools (such as GDB) easier backtraces for individual tasks are available. Threads for non-running tasks are blocked in sigwait(). The stack for each task (thread) is allocated when the thread is created, and the stack provided during task creation is not used. This is so the stack has guard pages, to help with detecting stack overflows. Task switch is done by resuming the thread for the next task by sending it the resume signal (SIGUSR1) and then suspending the current thread. The timer interrupt uses SIGALRM and care is taken to ensure that the signal handler runs only on the thread for the current task. The additional data needed per-thread is stored at the top on the task's stack. When a running task is being deleted, its thread is marked it as dying so when we switch away from it it exits instead of suspending. This ensures that even if the idle task doesn't run, threads are deleted which allows for more threads to be created (if many tasks are being created and deleted in rapid succession). To further aid debugging, SIGINT (^C) is not blocked inside critical sections. This allows it to be used break into GDB while in a critical section. This means that care must be taken with any custom SIGINT handlers as these are like NMIs. This is somewhat inspired by an existing port by William Davy (https://www.freertos.org/FreeRTOS-simulator-for-Linux.html) but it takes a number of different approaches to make it switch tasks reliableand there's little similarly with the original implementation. - Critical sections block scheduling/"interrupts" by blocking signals using pthread_sigmask(). This is more expensive than attempting to use flags but works reliably and is analogous to the interrupt enable/disable on real hardware. - Care is take to ensure that the SIGALRM handler (for the timer tick) is runnable only on the pthread for the running task. This makes tasks switches more straight-forward and reliable as we can suspend the thread while in the signal handler. - Task switches save/restore the critical nesting on the stack. - Only uses a single (SIGUSR1) signal which is ignored and thus GDB's default signal handling options won't trap/print on this signal. - Extra per-thread data is stored on the task's stack, making it accessible in O(1) instead of performing a O(n) lookup of the array. - Uses the task create/delete hooks in a similar way to the Windows port, rather than overloading trace points.
5 years ago
/* Restore original signal mask. */
( void ) pthread_sigmask( SIG_SETMASK, &xSchedulerOriginalSignalMask, NULL );
portable/GCC/Posix: add new port for Posix (Linux) applications This is similar to the Windows port, allowing FreeRTOS kernel applications to run as regular applications on Posix (Linux) systems. You can use this in a 32-bit or 64-bit application (although there are dynamic memory allocation trace points that do not support 64-bit addresses). Many of the same caveats of running an RTOS on a non-real-time system apply, but this is still very useful for easy debugging/testing applications in a simulated environment. In particular, it allows easy use of tools such as valgrind. You can call standard library functions from tasks but care must be taken with any that internally take mutexes or block. This includes malloc()/free() and many stdio functions (e.g., printf()). Replacement malloc(), free(), realloc(), and calloc() functions are provided which are safe. printf() needs to be called with a FreeRTOS mutex help (or called from only a single task). Each task is run in its own pthread, which makes debugging with standard tools (such as GDB) easier backtraces for individual tasks are available. Threads for non-running tasks are blocked in sigwait(). The stack for each task (thread) is allocated when the thread is created, and the stack provided during task creation is not used. This is so the stack has guard pages, to help with detecting stack overflows. Task switch is done by resuming the thread for the next task by sending it the resume signal (SIGUSR1) and then suspending the current thread. The timer interrupt uses SIGALRM and care is taken to ensure that the signal handler runs only on the thread for the current task. The additional data needed per-thread is stored at the top on the task's stack. When a running task is being deleted, its thread is marked it as dying so when we switch away from it it exits instead of suspending. This ensures that even if the idle task doesn't run, threads are deleted which allows for more threads to be created (if many tasks are being created and deleted in rapid succession). To further aid debugging, SIGINT (^C) is not blocked inside critical sections. This allows it to be used break into GDB while in a critical section. This means that care must be taken with any custom SIGINT handlers as these are like NMIs. This is somewhat inspired by an existing port by William Davy (https://www.freertos.org/FreeRTOS-simulator-for-Linux.html) but it takes a number of different approaches to make it switch tasks reliableand there's little similarly with the original implementation. - Critical sections block scheduling/"interrupts" by blocking signals using pthread_sigmask(). This is more expensive than attempting to use flags but works reliably and is analogous to the interrupt enable/disable on real hardware. - Care is take to ensure that the SIGALRM handler (for the timer tick) is runnable only on the pthread for the running task. This makes tasks switches more straight-forward and reliable as we can suspend the thread while in the signal handler. - Task switches save/restore the critical nesting on the stack. - Only uses a single (SIGUSR1) signal which is ignored and thus GDB's default signal handling options won't trap/print on this signal. - Extra per-thread data is stored on the task's stack, making it accessible in O(1) instead of performing a O(n) lookup of the array. - Uses the task create/delete hooks in a similar way to the Windows port, rather than overloading trace points.
5 years ago
return 0;
portable/GCC/Posix: add new port for Posix (Linux) applications This is similar to the Windows port, allowing FreeRTOS kernel applications to run as regular applications on Posix (Linux) systems. You can use this in a 32-bit or 64-bit application (although there are dynamic memory allocation trace points that do not support 64-bit addresses). Many of the same caveats of running an RTOS on a non-real-time system apply, but this is still very useful for easy debugging/testing applications in a simulated environment. In particular, it allows easy use of tools such as valgrind. You can call standard library functions from tasks but care must be taken with any that internally take mutexes or block. This includes malloc()/free() and many stdio functions (e.g., printf()). Replacement malloc(), free(), realloc(), and calloc() functions are provided which are safe. printf() needs to be called with a FreeRTOS mutex help (or called from only a single task). Each task is run in its own pthread, which makes debugging with standard tools (such as GDB) easier backtraces for individual tasks are available. Threads for non-running tasks are blocked in sigwait(). The stack for each task (thread) is allocated when the thread is created, and the stack provided during task creation is not used. This is so the stack has guard pages, to help with detecting stack overflows. Task switch is done by resuming the thread for the next task by sending it the resume signal (SIGUSR1) and then suspending the current thread. The timer interrupt uses SIGALRM and care is taken to ensure that the signal handler runs only on the thread for the current task. The additional data needed per-thread is stored at the top on the task's stack. When a running task is being deleted, its thread is marked it as dying so when we switch away from it it exits instead of suspending. This ensures that even if the idle task doesn't run, threads are deleted which allows for more threads to be created (if many tasks are being created and deleted in rapid succession). To further aid debugging, SIGINT (^C) is not blocked inside critical sections. This allows it to be used break into GDB while in a critical section. This means that care must be taken with any custom SIGINT handlers as these are like NMIs. This is somewhat inspired by an existing port by William Davy (https://www.freertos.org/FreeRTOS-simulator-for-Linux.html) but it takes a number of different approaches to make it switch tasks reliableand there's little similarly with the original implementation. - Critical sections block scheduling/"interrupts" by blocking signals using pthread_sigmask(). This is more expensive than attempting to use flags but works reliably and is analogous to the interrupt enable/disable on real hardware. - Care is take to ensure that the SIGALRM handler (for the timer tick) is runnable only on the pthread for the running task. This makes tasks switches more straight-forward and reliable as we can suspend the thread while in the signal handler. - Task switches save/restore the critical nesting on the stack. - Only uses a single (SIGUSR1) signal which is ignored and thus GDB's default signal handling options won't trap/print on this signal. - Extra per-thread data is stored on the task's stack, making it accessible in O(1) instead of performing a O(n) lookup of the array. - Uses the task create/delete hooks in a similar way to the Windows port, rather than overloading trace points.
5 years ago
}
/*-----------------------------------------------------------*/
void vPortEndScheduler( void )
{
struct itimerval itimer;
struct sigaction sigtick;
portable/GCC/Posix: add new port for Posix (Linux) applications This is similar to the Windows port, allowing FreeRTOS kernel applications to run as regular applications on Posix (Linux) systems. You can use this in a 32-bit or 64-bit application (although there are dynamic memory allocation trace points that do not support 64-bit addresses). Many of the same caveats of running an RTOS on a non-real-time system apply, but this is still very useful for easy debugging/testing applications in a simulated environment. In particular, it allows easy use of tools such as valgrind. You can call standard library functions from tasks but care must be taken with any that internally take mutexes or block. This includes malloc()/free() and many stdio functions (e.g., printf()). Replacement malloc(), free(), realloc(), and calloc() functions are provided which are safe. printf() needs to be called with a FreeRTOS mutex help (or called from only a single task). Each task is run in its own pthread, which makes debugging with standard tools (such as GDB) easier backtraces for individual tasks are available. Threads for non-running tasks are blocked in sigwait(). The stack for each task (thread) is allocated when the thread is created, and the stack provided during task creation is not used. This is so the stack has guard pages, to help with detecting stack overflows. Task switch is done by resuming the thread for the next task by sending it the resume signal (SIGUSR1) and then suspending the current thread. The timer interrupt uses SIGALRM and care is taken to ensure that the signal handler runs only on the thread for the current task. The additional data needed per-thread is stored at the top on the task's stack. When a running task is being deleted, its thread is marked it as dying so when we switch away from it it exits instead of suspending. This ensures that even if the idle task doesn't run, threads are deleted which allows for more threads to be created (if many tasks are being created and deleted in rapid succession). To further aid debugging, SIGINT (^C) is not blocked inside critical sections. This allows it to be used break into GDB while in a critical section. This means that care must be taken with any custom SIGINT handlers as these are like NMIs. This is somewhat inspired by an existing port by William Davy (https://www.freertos.org/FreeRTOS-simulator-for-Linux.html) but it takes a number of different approaches to make it switch tasks reliableand there's little similarly with the original implementation. - Critical sections block scheduling/"interrupts" by blocking signals using pthread_sigmask(). This is more expensive than attempting to use flags but works reliably and is analogous to the interrupt enable/disable on real hardware. - Care is take to ensure that the SIGALRM handler (for the timer tick) is runnable only on the pthread for the running task. This makes tasks switches more straight-forward and reliable as we can suspend the thread while in the signal handler. - Task switches save/restore the critical nesting on the stack. - Only uses a single (SIGUSR1) signal which is ignored and thus GDB's default signal handling options won't trap/print on this signal. - Extra per-thread data is stored on the task's stack, making it accessible in O(1) instead of performing a O(n) lookup of the array. - Uses the task create/delete hooks in a similar way to the Windows port, rather than overloading trace points.
5 years ago
/* Stop the timer and ignore any pending SIGALRMs that would end
* up running on the main thread when it is resumed. */
itimer.it_value.tv_sec = 0;
itimer.it_value.tv_usec = 0;
itimer.it_interval.tv_sec = 0;
itimer.it_interval.tv_usec = 0;
( void ) setitimer( ITIMER_REAL, &itimer, NULL );
portable/GCC/Posix: add new port for Posix (Linux) applications This is similar to the Windows port, allowing FreeRTOS kernel applications to run as regular applications on Posix (Linux) systems. You can use this in a 32-bit or 64-bit application (although there are dynamic memory allocation trace points that do not support 64-bit addresses). Many of the same caveats of running an RTOS on a non-real-time system apply, but this is still very useful for easy debugging/testing applications in a simulated environment. In particular, it allows easy use of tools such as valgrind. You can call standard library functions from tasks but care must be taken with any that internally take mutexes or block. This includes malloc()/free() and many stdio functions (e.g., printf()). Replacement malloc(), free(), realloc(), and calloc() functions are provided which are safe. printf() needs to be called with a FreeRTOS mutex help (or called from only a single task). Each task is run in its own pthread, which makes debugging with standard tools (such as GDB) easier backtraces for individual tasks are available. Threads for non-running tasks are blocked in sigwait(). The stack for each task (thread) is allocated when the thread is created, and the stack provided during task creation is not used. This is so the stack has guard pages, to help with detecting stack overflows. Task switch is done by resuming the thread for the next task by sending it the resume signal (SIGUSR1) and then suspending the current thread. The timer interrupt uses SIGALRM and care is taken to ensure that the signal handler runs only on the thread for the current task. The additional data needed per-thread is stored at the top on the task's stack. When a running task is being deleted, its thread is marked it as dying so when we switch away from it it exits instead of suspending. This ensures that even if the idle task doesn't run, threads are deleted which allows for more threads to be created (if many tasks are being created and deleted in rapid succession). To further aid debugging, SIGINT (^C) is not blocked inside critical sections. This allows it to be used break into GDB while in a critical section. This means that care must be taken with any custom SIGINT handlers as these are like NMIs. This is somewhat inspired by an existing port by William Davy (https://www.freertos.org/FreeRTOS-simulator-for-Linux.html) but it takes a number of different approaches to make it switch tasks reliableand there's little similarly with the original implementation. - Critical sections block scheduling/"interrupts" by blocking signals using pthread_sigmask(). This is more expensive than attempting to use flags but works reliably and is analogous to the interrupt enable/disable on real hardware. - Care is take to ensure that the SIGALRM handler (for the timer tick) is runnable only on the pthread for the running task. This makes tasks switches more straight-forward and reliable as we can suspend the thread while in the signal handler. - Task switches save/restore the critical nesting on the stack. - Only uses a single (SIGUSR1) signal which is ignored and thus GDB's default signal handling options won't trap/print on this signal. - Extra per-thread data is stored on the task's stack, making it accessible in O(1) instead of performing a O(n) lookup of the array. - Uses the task create/delete hooks in a similar way to the Windows port, rather than overloading trace points.
5 years ago
sigtick.sa_flags = 0;
sigtick.sa_handler = SIG_IGN;
sigemptyset( &sigtick.sa_mask );
sigaction( SIGALRM, &sigtick, NULL );
portable/GCC/Posix: add new port for Posix (Linux) applications This is similar to the Windows port, allowing FreeRTOS kernel applications to run as regular applications on Posix (Linux) systems. You can use this in a 32-bit or 64-bit application (although there are dynamic memory allocation trace points that do not support 64-bit addresses). Many of the same caveats of running an RTOS on a non-real-time system apply, but this is still very useful for easy debugging/testing applications in a simulated environment. In particular, it allows easy use of tools such as valgrind. You can call standard library functions from tasks but care must be taken with any that internally take mutexes or block. This includes malloc()/free() and many stdio functions (e.g., printf()). Replacement malloc(), free(), realloc(), and calloc() functions are provided which are safe. printf() needs to be called with a FreeRTOS mutex help (or called from only a single task). Each task is run in its own pthread, which makes debugging with standard tools (such as GDB) easier backtraces for individual tasks are available. Threads for non-running tasks are blocked in sigwait(). The stack for each task (thread) is allocated when the thread is created, and the stack provided during task creation is not used. This is so the stack has guard pages, to help with detecting stack overflows. Task switch is done by resuming the thread for the next task by sending it the resume signal (SIGUSR1) and then suspending the current thread. The timer interrupt uses SIGALRM and care is taken to ensure that the signal handler runs only on the thread for the current task. The additional data needed per-thread is stored at the top on the task's stack. When a running task is being deleted, its thread is marked it as dying so when we switch away from it it exits instead of suspending. This ensures that even if the idle task doesn't run, threads are deleted which allows for more threads to be created (if many tasks are being created and deleted in rapid succession). To further aid debugging, SIGINT (^C) is not blocked inside critical sections. This allows it to be used break into GDB while in a critical section. This means that care must be taken with any custom SIGINT handlers as these are like NMIs. This is somewhat inspired by an existing port by William Davy (https://www.freertos.org/FreeRTOS-simulator-for-Linux.html) but it takes a number of different approaches to make it switch tasks reliableand there's little similarly with the original implementation. - Critical sections block scheduling/"interrupts" by blocking signals using pthread_sigmask(). This is more expensive than attempting to use flags but works reliably and is analogous to the interrupt enable/disable on real hardware. - Care is take to ensure that the SIGALRM handler (for the timer tick) is runnable only on the pthread for the running task. This makes tasks switches more straight-forward and reliable as we can suspend the thread while in the signal handler. - Task switches save/restore the critical nesting on the stack. - Only uses a single (SIGUSR1) signal which is ignored and thus GDB's default signal handling options won't trap/print on this signal. - Extra per-thread data is stored on the task's stack, making it accessible in O(1) instead of performing a O(n) lookup of the array. - Uses the task create/delete hooks in a similar way to the Windows port, rather than overloading trace points.
5 years ago
/* Signal the scheduler to exit its loop. */
xSchedulerEnd = pdTRUE;
( void ) pthread_kill( hMainThread, SIG_RESUME );
portable/GCC/Posix: add new port for Posix (Linux) applications This is similar to the Windows port, allowing FreeRTOS kernel applications to run as regular applications on Posix (Linux) systems. You can use this in a 32-bit or 64-bit application (although there are dynamic memory allocation trace points that do not support 64-bit addresses). Many of the same caveats of running an RTOS on a non-real-time system apply, but this is still very useful for easy debugging/testing applications in a simulated environment. In particular, it allows easy use of tools such as valgrind. You can call standard library functions from tasks but care must be taken with any that internally take mutexes or block. This includes malloc()/free() and many stdio functions (e.g., printf()). Replacement malloc(), free(), realloc(), and calloc() functions are provided which are safe. printf() needs to be called with a FreeRTOS mutex help (or called from only a single task). Each task is run in its own pthread, which makes debugging with standard tools (such as GDB) easier backtraces for individual tasks are available. Threads for non-running tasks are blocked in sigwait(). The stack for each task (thread) is allocated when the thread is created, and the stack provided during task creation is not used. This is so the stack has guard pages, to help with detecting stack overflows. Task switch is done by resuming the thread for the next task by sending it the resume signal (SIGUSR1) and then suspending the current thread. The timer interrupt uses SIGALRM and care is taken to ensure that the signal handler runs only on the thread for the current task. The additional data needed per-thread is stored at the top on the task's stack. When a running task is being deleted, its thread is marked it as dying so when we switch away from it it exits instead of suspending. This ensures that even if the idle task doesn't run, threads are deleted which allows for more threads to be created (if many tasks are being created and deleted in rapid succession). To further aid debugging, SIGINT (^C) is not blocked inside critical sections. This allows it to be used break into GDB while in a critical section. This means that care must be taken with any custom SIGINT handlers as these are like NMIs. This is somewhat inspired by an existing port by William Davy (https://www.freertos.org/FreeRTOS-simulator-for-Linux.html) but it takes a number of different approaches to make it switch tasks reliableand there's little similarly with the original implementation. - Critical sections block scheduling/"interrupts" by blocking signals using pthread_sigmask(). This is more expensive than attempting to use flags but works reliably and is analogous to the interrupt enable/disable on real hardware. - Care is take to ensure that the SIGALRM handler (for the timer tick) is runnable only on the pthread for the running task. This makes tasks switches more straight-forward and reliable as we can suspend the thread while in the signal handler. - Task switches save/restore the critical nesting on the stack. - Only uses a single (SIGUSR1) signal which is ignored and thus GDB's default signal handling options won't trap/print on this signal. - Extra per-thread data is stored on the task's stack, making it accessible in O(1) instead of performing a O(n) lookup of the array. - Uses the task create/delete hooks in a similar way to the Windows port, rather than overloading trace points.
5 years ago
prvSuspendSelf();
portable/GCC/Posix: add new port for Posix (Linux) applications This is similar to the Windows port, allowing FreeRTOS kernel applications to run as regular applications on Posix (Linux) systems. You can use this in a 32-bit or 64-bit application (although there are dynamic memory allocation trace points that do not support 64-bit addresses). Many of the same caveats of running an RTOS on a non-real-time system apply, but this is still very useful for easy debugging/testing applications in a simulated environment. In particular, it allows easy use of tools such as valgrind. You can call standard library functions from tasks but care must be taken with any that internally take mutexes or block. This includes malloc()/free() and many stdio functions (e.g., printf()). Replacement malloc(), free(), realloc(), and calloc() functions are provided which are safe. printf() needs to be called with a FreeRTOS mutex help (or called from only a single task). Each task is run in its own pthread, which makes debugging with standard tools (such as GDB) easier backtraces for individual tasks are available. Threads for non-running tasks are blocked in sigwait(). The stack for each task (thread) is allocated when the thread is created, and the stack provided during task creation is not used. This is so the stack has guard pages, to help with detecting stack overflows. Task switch is done by resuming the thread for the next task by sending it the resume signal (SIGUSR1) and then suspending the current thread. The timer interrupt uses SIGALRM and care is taken to ensure that the signal handler runs only on the thread for the current task. The additional data needed per-thread is stored at the top on the task's stack. When a running task is being deleted, its thread is marked it as dying so when we switch away from it it exits instead of suspending. This ensures that even if the idle task doesn't run, threads are deleted which allows for more threads to be created (if many tasks are being created and deleted in rapid succession). To further aid debugging, SIGINT (^C) is not blocked inside critical sections. This allows it to be used break into GDB while in a critical section. This means that care must be taken with any custom SIGINT handlers as these are like NMIs. This is somewhat inspired by an existing port by William Davy (https://www.freertos.org/FreeRTOS-simulator-for-Linux.html) but it takes a number of different approaches to make it switch tasks reliableand there's little similarly with the original implementation. - Critical sections block scheduling/"interrupts" by blocking signals using pthread_sigmask(). This is more expensive than attempting to use flags but works reliably and is analogous to the interrupt enable/disable on real hardware. - Care is take to ensure that the SIGALRM handler (for the timer tick) is runnable only on the pthread for the running task. This makes tasks switches more straight-forward and reliable as we can suspend the thread while in the signal handler. - Task switches save/restore the critical nesting on the stack. - Only uses a single (SIGUSR1) signal which is ignored and thus GDB's default signal handling options won't trap/print on this signal. - Extra per-thread data is stored on the task's stack, making it accessible in O(1) instead of performing a O(n) lookup of the array. - Uses the task create/delete hooks in a similar way to the Windows port, rather than overloading trace points.
5 years ago
}
/*-----------------------------------------------------------*/
void vPortEnterCritical( void )
{
if( uxCriticalNesting == 0 )
{
vPortDisableInterrupts();
}
uxCriticalNesting++;
portable/GCC/Posix: add new port for Posix (Linux) applications This is similar to the Windows port, allowing FreeRTOS kernel applications to run as regular applications on Posix (Linux) systems. You can use this in a 32-bit or 64-bit application (although there are dynamic memory allocation trace points that do not support 64-bit addresses). Many of the same caveats of running an RTOS on a non-real-time system apply, but this is still very useful for easy debugging/testing applications in a simulated environment. In particular, it allows easy use of tools such as valgrind. You can call standard library functions from tasks but care must be taken with any that internally take mutexes or block. This includes malloc()/free() and many stdio functions (e.g., printf()). Replacement malloc(), free(), realloc(), and calloc() functions are provided which are safe. printf() needs to be called with a FreeRTOS mutex help (or called from only a single task). Each task is run in its own pthread, which makes debugging with standard tools (such as GDB) easier backtraces for individual tasks are available. Threads for non-running tasks are blocked in sigwait(). The stack for each task (thread) is allocated when the thread is created, and the stack provided during task creation is not used. This is so the stack has guard pages, to help with detecting stack overflows. Task switch is done by resuming the thread for the next task by sending it the resume signal (SIGUSR1) and then suspending the current thread. The timer interrupt uses SIGALRM and care is taken to ensure that the signal handler runs only on the thread for the current task. The additional data needed per-thread is stored at the top on the task's stack. When a running task is being deleted, its thread is marked it as dying so when we switch away from it it exits instead of suspending. This ensures that even if the idle task doesn't run, threads are deleted which allows for more threads to be created (if many tasks are being created and deleted in rapid succession). To further aid debugging, SIGINT (^C) is not blocked inside critical sections. This allows it to be used break into GDB while in a critical section. This means that care must be taken with any custom SIGINT handlers as these are like NMIs. This is somewhat inspired by an existing port by William Davy (https://www.freertos.org/FreeRTOS-simulator-for-Linux.html) but it takes a number of different approaches to make it switch tasks reliableand there's little similarly with the original implementation. - Critical sections block scheduling/"interrupts" by blocking signals using pthread_sigmask(). This is more expensive than attempting to use flags but works reliably and is analogous to the interrupt enable/disable on real hardware. - Care is take to ensure that the SIGALRM handler (for the timer tick) is runnable only on the pthread for the running task. This makes tasks switches more straight-forward and reliable as we can suspend the thread while in the signal handler. - Task switches save/restore the critical nesting on the stack. - Only uses a single (SIGUSR1) signal which is ignored and thus GDB's default signal handling options won't trap/print on this signal. - Extra per-thread data is stored on the task's stack, making it accessible in O(1) instead of performing a O(n) lookup of the array. - Uses the task create/delete hooks in a similar way to the Windows port, rather than overloading trace points.
5 years ago
}
/*-----------------------------------------------------------*/
void vPortExitCritical( void )
{
uxCriticalNesting--;
portable/GCC/Posix: add new port for Posix (Linux) applications This is similar to the Windows port, allowing FreeRTOS kernel applications to run as regular applications on Posix (Linux) systems. You can use this in a 32-bit or 64-bit application (although there are dynamic memory allocation trace points that do not support 64-bit addresses). Many of the same caveats of running an RTOS on a non-real-time system apply, but this is still very useful for easy debugging/testing applications in a simulated environment. In particular, it allows easy use of tools such as valgrind. You can call standard library functions from tasks but care must be taken with any that internally take mutexes or block. This includes malloc()/free() and many stdio functions (e.g., printf()). Replacement malloc(), free(), realloc(), and calloc() functions are provided which are safe. printf() needs to be called with a FreeRTOS mutex help (or called from only a single task). Each task is run in its own pthread, which makes debugging with standard tools (such as GDB) easier backtraces for individual tasks are available. Threads for non-running tasks are blocked in sigwait(). The stack for each task (thread) is allocated when the thread is created, and the stack provided during task creation is not used. This is so the stack has guard pages, to help with detecting stack overflows. Task switch is done by resuming the thread for the next task by sending it the resume signal (SIGUSR1) and then suspending the current thread. The timer interrupt uses SIGALRM and care is taken to ensure that the signal handler runs only on the thread for the current task. The additional data needed per-thread is stored at the top on the task's stack. When a running task is being deleted, its thread is marked it as dying so when we switch away from it it exits instead of suspending. This ensures that even if the idle task doesn't run, threads are deleted which allows for more threads to be created (if many tasks are being created and deleted in rapid succession). To further aid debugging, SIGINT (^C) is not blocked inside critical sections. This allows it to be used break into GDB while in a critical section. This means that care must be taken with any custom SIGINT handlers as these are like NMIs. This is somewhat inspired by an existing port by William Davy (https://www.freertos.org/FreeRTOS-simulator-for-Linux.html) but it takes a number of different approaches to make it switch tasks reliableand there's little similarly with the original implementation. - Critical sections block scheduling/"interrupts" by blocking signals using pthread_sigmask(). This is more expensive than attempting to use flags but works reliably and is analogous to the interrupt enable/disable on real hardware. - Care is take to ensure that the SIGALRM handler (for the timer tick) is runnable only on the pthread for the running task. This makes tasks switches more straight-forward and reliable as we can suspend the thread while in the signal handler. - Task switches save/restore the critical nesting on the stack. - Only uses a single (SIGUSR1) signal which is ignored and thus GDB's default signal handling options won't trap/print on this signal. - Extra per-thread data is stored on the task's stack, making it accessible in O(1) instead of performing a O(n) lookup of the array. - Uses the task create/delete hooks in a similar way to the Windows port, rather than overloading trace points.
5 years ago
/* If we have reached 0 then re-enable the interrupts. */
if( uxCriticalNesting == 0 )
{
vPortEnableInterrupts();
}
portable/GCC/Posix: add new port for Posix (Linux) applications This is similar to the Windows port, allowing FreeRTOS kernel applications to run as regular applications on Posix (Linux) systems. You can use this in a 32-bit or 64-bit application (although there are dynamic memory allocation trace points that do not support 64-bit addresses). Many of the same caveats of running an RTOS on a non-real-time system apply, but this is still very useful for easy debugging/testing applications in a simulated environment. In particular, it allows easy use of tools such as valgrind. You can call standard library functions from tasks but care must be taken with any that internally take mutexes or block. This includes malloc()/free() and many stdio functions (e.g., printf()). Replacement malloc(), free(), realloc(), and calloc() functions are provided which are safe. printf() needs to be called with a FreeRTOS mutex help (or called from only a single task). Each task is run in its own pthread, which makes debugging with standard tools (such as GDB) easier backtraces for individual tasks are available. Threads for non-running tasks are blocked in sigwait(). The stack for each task (thread) is allocated when the thread is created, and the stack provided during task creation is not used. This is so the stack has guard pages, to help with detecting stack overflows. Task switch is done by resuming the thread for the next task by sending it the resume signal (SIGUSR1) and then suspending the current thread. The timer interrupt uses SIGALRM and care is taken to ensure that the signal handler runs only on the thread for the current task. The additional data needed per-thread is stored at the top on the task's stack. When a running task is being deleted, its thread is marked it as dying so when we switch away from it it exits instead of suspending. This ensures that even if the idle task doesn't run, threads are deleted which allows for more threads to be created (if many tasks are being created and deleted in rapid succession). To further aid debugging, SIGINT (^C) is not blocked inside critical sections. This allows it to be used break into GDB while in a critical section. This means that care must be taken with any custom SIGINT handlers as these are like NMIs. This is somewhat inspired by an existing port by William Davy (https://www.freertos.org/FreeRTOS-simulator-for-Linux.html) but it takes a number of different approaches to make it switch tasks reliableand there's little similarly with the original implementation. - Critical sections block scheduling/"interrupts" by blocking signals using pthread_sigmask(). This is more expensive than attempting to use flags but works reliably and is analogous to the interrupt enable/disable on real hardware. - Care is take to ensure that the SIGALRM handler (for the timer tick) is runnable only on the pthread for the running task. This makes tasks switches more straight-forward and reliable as we can suspend the thread while in the signal handler. - Task switches save/restore the critical nesting on the stack. - Only uses a single (SIGUSR1) signal which is ignored and thus GDB's default signal handling options won't trap/print on this signal. - Extra per-thread data is stored on the task's stack, making it accessible in O(1) instead of performing a O(n) lookup of the array. - Uses the task create/delete hooks in a similar way to the Windows port, rather than overloading trace points.
5 years ago
}
/*-----------------------------------------------------------*/
void vPortYieldFromISR( void )
{
Thread_t * xThreadToSuspend;
Thread_t * xThreadToResume;
portable/GCC/Posix: add new port for Posix (Linux) applications This is similar to the Windows port, allowing FreeRTOS kernel applications to run as regular applications on Posix (Linux) systems. You can use this in a 32-bit or 64-bit application (although there are dynamic memory allocation trace points that do not support 64-bit addresses). Many of the same caveats of running an RTOS on a non-real-time system apply, but this is still very useful for easy debugging/testing applications in a simulated environment. In particular, it allows easy use of tools such as valgrind. You can call standard library functions from tasks but care must be taken with any that internally take mutexes or block. This includes malloc()/free() and many stdio functions (e.g., printf()). Replacement malloc(), free(), realloc(), and calloc() functions are provided which are safe. printf() needs to be called with a FreeRTOS mutex help (or called from only a single task). Each task is run in its own pthread, which makes debugging with standard tools (such as GDB) easier backtraces for individual tasks are available. Threads for non-running tasks are blocked in sigwait(). The stack for each task (thread) is allocated when the thread is created, and the stack provided during task creation is not used. This is so the stack has guard pages, to help with detecting stack overflows. Task switch is done by resuming the thread for the next task by sending it the resume signal (SIGUSR1) and then suspending the current thread. The timer interrupt uses SIGALRM and care is taken to ensure that the signal handler runs only on the thread for the current task. The additional data needed per-thread is stored at the top on the task's stack. When a running task is being deleted, its thread is marked it as dying so when we switch away from it it exits instead of suspending. This ensures that even if the idle task doesn't run, threads are deleted which allows for more threads to be created (if many tasks are being created and deleted in rapid succession). To further aid debugging, SIGINT (^C) is not blocked inside critical sections. This allows it to be used break into GDB while in a critical section. This means that care must be taken with any custom SIGINT handlers as these are like NMIs. This is somewhat inspired by an existing port by William Davy (https://www.freertos.org/FreeRTOS-simulator-for-Linux.html) but it takes a number of different approaches to make it switch tasks reliableand there's little similarly with the original implementation. - Critical sections block scheduling/"interrupts" by blocking signals using pthread_sigmask(). This is more expensive than attempting to use flags but works reliably and is analogous to the interrupt enable/disable on real hardware. - Care is take to ensure that the SIGALRM handler (for the timer tick) is runnable only on the pthread for the running task. This makes tasks switches more straight-forward and reliable as we can suspend the thread while in the signal handler. - Task switches save/restore the critical nesting on the stack. - Only uses a single (SIGUSR1) signal which is ignored and thus GDB's default signal handling options won't trap/print on this signal. - Extra per-thread data is stored on the task's stack, making it accessible in O(1) instead of performing a O(n) lookup of the array. - Uses the task create/delete hooks in a similar way to the Windows port, rather than overloading trace points.
5 years ago
xThreadToSuspend = prvGetThreadFromTask( xTaskGetCurrentTaskHandle() );
portable/GCC/Posix: add new port for Posix (Linux) applications This is similar to the Windows port, allowing FreeRTOS kernel applications to run as regular applications on Posix (Linux) systems. You can use this in a 32-bit or 64-bit application (although there are dynamic memory allocation trace points that do not support 64-bit addresses). Many of the same caveats of running an RTOS on a non-real-time system apply, but this is still very useful for easy debugging/testing applications in a simulated environment. In particular, it allows easy use of tools such as valgrind. You can call standard library functions from tasks but care must be taken with any that internally take mutexes or block. This includes malloc()/free() and many stdio functions (e.g., printf()). Replacement malloc(), free(), realloc(), and calloc() functions are provided which are safe. printf() needs to be called with a FreeRTOS mutex help (or called from only a single task). Each task is run in its own pthread, which makes debugging with standard tools (such as GDB) easier backtraces for individual tasks are available. Threads for non-running tasks are blocked in sigwait(). The stack for each task (thread) is allocated when the thread is created, and the stack provided during task creation is not used. This is so the stack has guard pages, to help with detecting stack overflows. Task switch is done by resuming the thread for the next task by sending it the resume signal (SIGUSR1) and then suspending the current thread. The timer interrupt uses SIGALRM and care is taken to ensure that the signal handler runs only on the thread for the current task. The additional data needed per-thread is stored at the top on the task's stack. When a running task is being deleted, its thread is marked it as dying so when we switch away from it it exits instead of suspending. This ensures that even if the idle task doesn't run, threads are deleted which allows for more threads to be created (if many tasks are being created and deleted in rapid succession). To further aid debugging, SIGINT (^C) is not blocked inside critical sections. This allows it to be used break into GDB while in a critical section. This means that care must be taken with any custom SIGINT handlers as these are like NMIs. This is somewhat inspired by an existing port by William Davy (https://www.freertos.org/FreeRTOS-simulator-for-Linux.html) but it takes a number of different approaches to make it switch tasks reliableand there's little similarly with the original implementation. - Critical sections block scheduling/"interrupts" by blocking signals using pthread_sigmask(). This is more expensive than attempting to use flags but works reliably and is analogous to the interrupt enable/disable on real hardware. - Care is take to ensure that the SIGALRM handler (for the timer tick) is runnable only on the pthread for the running task. This makes tasks switches more straight-forward and reliable as we can suspend the thread while in the signal handler. - Task switches save/restore the critical nesting on the stack. - Only uses a single (SIGUSR1) signal which is ignored and thus GDB's default signal handling options won't trap/print on this signal. - Extra per-thread data is stored on the task's stack, making it accessible in O(1) instead of performing a O(n) lookup of the array. - Uses the task create/delete hooks in a similar way to the Windows port, rather than overloading trace points.
5 years ago
vTaskSwitchContext();
portable/GCC/Posix: add new port for Posix (Linux) applications This is similar to the Windows port, allowing FreeRTOS kernel applications to run as regular applications on Posix (Linux) systems. You can use this in a 32-bit or 64-bit application (although there are dynamic memory allocation trace points that do not support 64-bit addresses). Many of the same caveats of running an RTOS on a non-real-time system apply, but this is still very useful for easy debugging/testing applications in a simulated environment. In particular, it allows easy use of tools such as valgrind. You can call standard library functions from tasks but care must be taken with any that internally take mutexes or block. This includes malloc()/free() and many stdio functions (e.g., printf()). Replacement malloc(), free(), realloc(), and calloc() functions are provided which are safe. printf() needs to be called with a FreeRTOS mutex help (or called from only a single task). Each task is run in its own pthread, which makes debugging with standard tools (such as GDB) easier backtraces for individual tasks are available. Threads for non-running tasks are blocked in sigwait(). The stack for each task (thread) is allocated when the thread is created, and the stack provided during task creation is not used. This is so the stack has guard pages, to help with detecting stack overflows. Task switch is done by resuming the thread for the next task by sending it the resume signal (SIGUSR1) and then suspending the current thread. The timer interrupt uses SIGALRM and care is taken to ensure that the signal handler runs only on the thread for the current task. The additional data needed per-thread is stored at the top on the task's stack. When a running task is being deleted, its thread is marked it as dying so when we switch away from it it exits instead of suspending. This ensures that even if the idle task doesn't run, threads are deleted which allows for more threads to be created (if many tasks are being created and deleted in rapid succession). To further aid debugging, SIGINT (^C) is not blocked inside critical sections. This allows it to be used break into GDB while in a critical section. This means that care must be taken with any custom SIGINT handlers as these are like NMIs. This is somewhat inspired by an existing port by William Davy (https://www.freertos.org/FreeRTOS-simulator-for-Linux.html) but it takes a number of different approaches to make it switch tasks reliableand there's little similarly with the original implementation. - Critical sections block scheduling/"interrupts" by blocking signals using pthread_sigmask(). This is more expensive than attempting to use flags but works reliably and is analogous to the interrupt enable/disable on real hardware. - Care is take to ensure that the SIGALRM handler (for the timer tick) is runnable only on the pthread for the running task. This makes tasks switches more straight-forward and reliable as we can suspend the thread while in the signal handler. - Task switches save/restore the critical nesting on the stack. - Only uses a single (SIGUSR1) signal which is ignored and thus GDB's default signal handling options won't trap/print on this signal. - Extra per-thread data is stored on the task's stack, making it accessible in O(1) instead of performing a O(n) lookup of the array. - Uses the task create/delete hooks in a similar way to the Windows port, rather than overloading trace points.
5 years ago
xThreadToResume = prvGetThreadFromTask( xTaskGetCurrentTaskHandle() );
portable/GCC/Posix: add new port for Posix (Linux) applications This is similar to the Windows port, allowing FreeRTOS kernel applications to run as regular applications on Posix (Linux) systems. You can use this in a 32-bit or 64-bit application (although there are dynamic memory allocation trace points that do not support 64-bit addresses). Many of the same caveats of running an RTOS on a non-real-time system apply, but this is still very useful for easy debugging/testing applications in a simulated environment. In particular, it allows easy use of tools such as valgrind. You can call standard library functions from tasks but care must be taken with any that internally take mutexes or block. This includes malloc()/free() and many stdio functions (e.g., printf()). Replacement malloc(), free(), realloc(), and calloc() functions are provided which are safe. printf() needs to be called with a FreeRTOS mutex help (or called from only a single task). Each task is run in its own pthread, which makes debugging with standard tools (such as GDB) easier backtraces for individual tasks are available. Threads for non-running tasks are blocked in sigwait(). The stack for each task (thread) is allocated when the thread is created, and the stack provided during task creation is not used. This is so the stack has guard pages, to help with detecting stack overflows. Task switch is done by resuming the thread for the next task by sending it the resume signal (SIGUSR1) and then suspending the current thread. The timer interrupt uses SIGALRM and care is taken to ensure that the signal handler runs only on the thread for the current task. The additional data needed per-thread is stored at the top on the task's stack. When a running task is being deleted, its thread is marked it as dying so when we switch away from it it exits instead of suspending. This ensures that even if the idle task doesn't run, threads are deleted which allows for more threads to be created (if many tasks are being created and deleted in rapid succession). To further aid debugging, SIGINT (^C) is not blocked inside critical sections. This allows it to be used break into GDB while in a critical section. This means that care must be taken with any custom SIGINT handlers as these are like NMIs. This is somewhat inspired by an existing port by William Davy (https://www.freertos.org/FreeRTOS-simulator-for-Linux.html) but it takes a number of different approaches to make it switch tasks reliableand there's little similarly with the original implementation. - Critical sections block scheduling/"interrupts" by blocking signals using pthread_sigmask(). This is more expensive than attempting to use flags but works reliably and is analogous to the interrupt enable/disable on real hardware. - Care is take to ensure that the SIGALRM handler (for the timer tick) is runnable only on the pthread for the running task. This makes tasks switches more straight-forward and reliable as we can suspend the thread while in the signal handler. - Task switches save/restore the critical nesting on the stack. - Only uses a single (SIGUSR1) signal which is ignored and thus GDB's default signal handling options won't trap/print on this signal. - Extra per-thread data is stored on the task's stack, making it accessible in O(1) instead of performing a O(n) lookup of the array. - Uses the task create/delete hooks in a similar way to the Windows port, rather than overloading trace points.
5 years ago
prvSwitchThread( xThreadToResume, xThreadToSuspend );
portable/GCC/Posix: add new port for Posix (Linux) applications This is similar to the Windows port, allowing FreeRTOS kernel applications to run as regular applications on Posix (Linux) systems. You can use this in a 32-bit or 64-bit application (although there are dynamic memory allocation trace points that do not support 64-bit addresses). Many of the same caveats of running an RTOS on a non-real-time system apply, but this is still very useful for easy debugging/testing applications in a simulated environment. In particular, it allows easy use of tools such as valgrind. You can call standard library functions from tasks but care must be taken with any that internally take mutexes or block. This includes malloc()/free() and many stdio functions (e.g., printf()). Replacement malloc(), free(), realloc(), and calloc() functions are provided which are safe. printf() needs to be called with a FreeRTOS mutex help (or called from only a single task). Each task is run in its own pthread, which makes debugging with standard tools (such as GDB) easier backtraces for individual tasks are available. Threads for non-running tasks are blocked in sigwait(). The stack for each task (thread) is allocated when the thread is created, and the stack provided during task creation is not used. This is so the stack has guard pages, to help with detecting stack overflows. Task switch is done by resuming the thread for the next task by sending it the resume signal (SIGUSR1) and then suspending the current thread. The timer interrupt uses SIGALRM and care is taken to ensure that the signal handler runs only on the thread for the current task. The additional data needed per-thread is stored at the top on the task's stack. When a running task is being deleted, its thread is marked it as dying so when we switch away from it it exits instead of suspending. This ensures that even if the idle task doesn't run, threads are deleted which allows for more threads to be created (if many tasks are being created and deleted in rapid succession). To further aid debugging, SIGINT (^C) is not blocked inside critical sections. This allows it to be used break into GDB while in a critical section. This means that care must be taken with any custom SIGINT handlers as these are like NMIs. This is somewhat inspired by an existing port by William Davy (https://www.freertos.org/FreeRTOS-simulator-for-Linux.html) but it takes a number of different approaches to make it switch tasks reliableand there's little similarly with the original implementation. - Critical sections block scheduling/"interrupts" by blocking signals using pthread_sigmask(). This is more expensive than attempting to use flags but works reliably and is analogous to the interrupt enable/disable on real hardware. - Care is take to ensure that the SIGALRM handler (for the timer tick) is runnable only on the pthread for the running task. This makes tasks switches more straight-forward and reliable as we can suspend the thread while in the signal handler. - Task switches save/restore the critical nesting on the stack. - Only uses a single (SIGUSR1) signal which is ignored and thus GDB's default signal handling options won't trap/print on this signal. - Extra per-thread data is stored on the task's stack, making it accessible in O(1) instead of performing a O(n) lookup of the array. - Uses the task create/delete hooks in a similar way to the Windows port, rather than overloading trace points.
5 years ago
}
/*-----------------------------------------------------------*/
void vPortYield( void )
{
vPortEnterCritical();
portable/GCC/Posix: add new port for Posix (Linux) applications This is similar to the Windows port, allowing FreeRTOS kernel applications to run as regular applications on Posix (Linux) systems. You can use this in a 32-bit or 64-bit application (although there are dynamic memory allocation trace points that do not support 64-bit addresses). Many of the same caveats of running an RTOS on a non-real-time system apply, but this is still very useful for easy debugging/testing applications in a simulated environment. In particular, it allows easy use of tools such as valgrind. You can call standard library functions from tasks but care must be taken with any that internally take mutexes or block. This includes malloc()/free() and many stdio functions (e.g., printf()). Replacement malloc(), free(), realloc(), and calloc() functions are provided which are safe. printf() needs to be called with a FreeRTOS mutex help (or called from only a single task). Each task is run in its own pthread, which makes debugging with standard tools (such as GDB) easier backtraces for individual tasks are available. Threads for non-running tasks are blocked in sigwait(). The stack for each task (thread) is allocated when the thread is created, and the stack provided during task creation is not used. This is so the stack has guard pages, to help with detecting stack overflows. Task switch is done by resuming the thread for the next task by sending it the resume signal (SIGUSR1) and then suspending the current thread. The timer interrupt uses SIGALRM and care is taken to ensure that the signal handler runs only on the thread for the current task. The additional data needed per-thread is stored at the top on the task's stack. When a running task is being deleted, its thread is marked it as dying so when we switch away from it it exits instead of suspending. This ensures that even if the idle task doesn't run, threads are deleted which allows for more threads to be created (if many tasks are being created and deleted in rapid succession). To further aid debugging, SIGINT (^C) is not blocked inside critical sections. This allows it to be used break into GDB while in a critical section. This means that care must be taken with any custom SIGINT handlers as these are like NMIs. This is somewhat inspired by an existing port by William Davy (https://www.freertos.org/FreeRTOS-simulator-for-Linux.html) but it takes a number of different approaches to make it switch tasks reliableand there's little similarly with the original implementation. - Critical sections block scheduling/"interrupts" by blocking signals using pthread_sigmask(). This is more expensive than attempting to use flags but works reliably and is analogous to the interrupt enable/disable on real hardware. - Care is take to ensure that the SIGALRM handler (for the timer tick) is runnable only on the pthread for the running task. This makes tasks switches more straight-forward and reliable as we can suspend the thread while in the signal handler. - Task switches save/restore the critical nesting on the stack. - Only uses a single (SIGUSR1) signal which is ignored and thus GDB's default signal handling options won't trap/print on this signal. - Extra per-thread data is stored on the task's stack, making it accessible in O(1) instead of performing a O(n) lookup of the array. - Uses the task create/delete hooks in a similar way to the Windows port, rather than overloading trace points.
5 years ago
vPortYieldFromISR();
portable/GCC/Posix: add new port for Posix (Linux) applications This is similar to the Windows port, allowing FreeRTOS kernel applications to run as regular applications on Posix (Linux) systems. You can use this in a 32-bit or 64-bit application (although there are dynamic memory allocation trace points that do not support 64-bit addresses). Many of the same caveats of running an RTOS on a non-real-time system apply, but this is still very useful for easy debugging/testing applications in a simulated environment. In particular, it allows easy use of tools such as valgrind. You can call standard library functions from tasks but care must be taken with any that internally take mutexes or block. This includes malloc()/free() and many stdio functions (e.g., printf()). Replacement malloc(), free(), realloc(), and calloc() functions are provided which are safe. printf() needs to be called with a FreeRTOS mutex help (or called from only a single task). Each task is run in its own pthread, which makes debugging with standard tools (such as GDB) easier backtraces for individual tasks are available. Threads for non-running tasks are blocked in sigwait(). The stack for each task (thread) is allocated when the thread is created, and the stack provided during task creation is not used. This is so the stack has guard pages, to help with detecting stack overflows. Task switch is done by resuming the thread for the next task by sending it the resume signal (SIGUSR1) and then suspending the current thread. The timer interrupt uses SIGALRM and care is taken to ensure that the signal handler runs only on the thread for the current task. The additional data needed per-thread is stored at the top on the task's stack. When a running task is being deleted, its thread is marked it as dying so when we switch away from it it exits instead of suspending. This ensures that even if the idle task doesn't run, threads are deleted which allows for more threads to be created (if many tasks are being created and deleted in rapid succession). To further aid debugging, SIGINT (^C) is not blocked inside critical sections. This allows it to be used break into GDB while in a critical section. This means that care must be taken with any custom SIGINT handlers as these are like NMIs. This is somewhat inspired by an existing port by William Davy (https://www.freertos.org/FreeRTOS-simulator-for-Linux.html) but it takes a number of different approaches to make it switch tasks reliableand there's little similarly with the original implementation. - Critical sections block scheduling/"interrupts" by blocking signals using pthread_sigmask(). This is more expensive than attempting to use flags but works reliably and is analogous to the interrupt enable/disable on real hardware. - Care is take to ensure that the SIGALRM handler (for the timer tick) is runnable only on the pthread for the running task. This makes tasks switches more straight-forward and reliable as we can suspend the thread while in the signal handler. - Task switches save/restore the critical nesting on the stack. - Only uses a single (SIGUSR1) signal which is ignored and thus GDB's default signal handling options won't trap/print on this signal. - Extra per-thread data is stored on the task's stack, making it accessible in O(1) instead of performing a O(n) lookup of the array. - Uses the task create/delete hooks in a similar way to the Windows port, rather than overloading trace points.
5 years ago
vPortExitCritical();
portable/GCC/Posix: add new port for Posix (Linux) applications This is similar to the Windows port, allowing FreeRTOS kernel applications to run as regular applications on Posix (Linux) systems. You can use this in a 32-bit or 64-bit application (although there are dynamic memory allocation trace points that do not support 64-bit addresses). Many of the same caveats of running an RTOS on a non-real-time system apply, but this is still very useful for easy debugging/testing applications in a simulated environment. In particular, it allows easy use of tools such as valgrind. You can call standard library functions from tasks but care must be taken with any that internally take mutexes or block. This includes malloc()/free() and many stdio functions (e.g., printf()). Replacement malloc(), free(), realloc(), and calloc() functions are provided which are safe. printf() needs to be called with a FreeRTOS mutex help (or called from only a single task). Each task is run in its own pthread, which makes debugging with standard tools (such as GDB) easier backtraces for individual tasks are available. Threads for non-running tasks are blocked in sigwait(). The stack for each task (thread) is allocated when the thread is created, and the stack provided during task creation is not used. This is so the stack has guard pages, to help with detecting stack overflows. Task switch is done by resuming the thread for the next task by sending it the resume signal (SIGUSR1) and then suspending the current thread. The timer interrupt uses SIGALRM and care is taken to ensure that the signal handler runs only on the thread for the current task. The additional data needed per-thread is stored at the top on the task's stack. When a running task is being deleted, its thread is marked it as dying so when we switch away from it it exits instead of suspending. This ensures that even if the idle task doesn't run, threads are deleted which allows for more threads to be created (if many tasks are being created and deleted in rapid succession). To further aid debugging, SIGINT (^C) is not blocked inside critical sections. This allows it to be used break into GDB while in a critical section. This means that care must be taken with any custom SIGINT handlers as these are like NMIs. This is somewhat inspired by an existing port by William Davy (https://www.freertos.org/FreeRTOS-simulator-for-Linux.html) but it takes a number of different approaches to make it switch tasks reliableand there's little similarly with the original implementation. - Critical sections block scheduling/"interrupts" by blocking signals using pthread_sigmask(). This is more expensive than attempting to use flags but works reliably and is analogous to the interrupt enable/disable on real hardware. - Care is take to ensure that the SIGALRM handler (for the timer tick) is runnable only on the pthread for the running task. This makes tasks switches more straight-forward and reliable as we can suspend the thread while in the signal handler. - Task switches save/restore the critical nesting on the stack. - Only uses a single (SIGUSR1) signal which is ignored and thus GDB's default signal handling options won't trap/print on this signal. - Extra per-thread data is stored on the task's stack, making it accessible in O(1) instead of performing a O(n) lookup of the array. - Uses the task create/delete hooks in a similar way to the Windows port, rather than overloading trace points.
5 years ago
}
/*-----------------------------------------------------------*/
void vPortDisableInterrupts( void )
{
pthread_sigmask( SIG_BLOCK, &xAllSignals, NULL );
portable/GCC/Posix: add new port for Posix (Linux) applications This is similar to the Windows port, allowing FreeRTOS kernel applications to run as regular applications on Posix (Linux) systems. You can use this in a 32-bit or 64-bit application (although there are dynamic memory allocation trace points that do not support 64-bit addresses). Many of the same caveats of running an RTOS on a non-real-time system apply, but this is still very useful for easy debugging/testing applications in a simulated environment. In particular, it allows easy use of tools such as valgrind. You can call standard library functions from tasks but care must be taken with any that internally take mutexes or block. This includes malloc()/free() and many stdio functions (e.g., printf()). Replacement malloc(), free(), realloc(), and calloc() functions are provided which are safe. printf() needs to be called with a FreeRTOS mutex help (or called from only a single task). Each task is run in its own pthread, which makes debugging with standard tools (such as GDB) easier backtraces for individual tasks are available. Threads for non-running tasks are blocked in sigwait(). The stack for each task (thread) is allocated when the thread is created, and the stack provided during task creation is not used. This is so the stack has guard pages, to help with detecting stack overflows. Task switch is done by resuming the thread for the next task by sending it the resume signal (SIGUSR1) and then suspending the current thread. The timer interrupt uses SIGALRM and care is taken to ensure that the signal handler runs only on the thread for the current task. The additional data needed per-thread is stored at the top on the task's stack. When a running task is being deleted, its thread is marked it as dying so when we switch away from it it exits instead of suspending. This ensures that even if the idle task doesn't run, threads are deleted which allows for more threads to be created (if many tasks are being created and deleted in rapid succession). To further aid debugging, SIGINT (^C) is not blocked inside critical sections. This allows it to be used break into GDB while in a critical section. This means that care must be taken with any custom SIGINT handlers as these are like NMIs. This is somewhat inspired by an existing port by William Davy (https://www.freertos.org/FreeRTOS-simulator-for-Linux.html) but it takes a number of different approaches to make it switch tasks reliableand there's little similarly with the original implementation. - Critical sections block scheduling/"interrupts" by blocking signals using pthread_sigmask(). This is more expensive than attempting to use flags but works reliably and is analogous to the interrupt enable/disable on real hardware. - Care is take to ensure that the SIGALRM handler (for the timer tick) is runnable only on the pthread for the running task. This makes tasks switches more straight-forward and reliable as we can suspend the thread while in the signal handler. - Task switches save/restore the critical nesting on the stack. - Only uses a single (SIGUSR1) signal which is ignored and thus GDB's default signal handling options won't trap/print on this signal. - Extra per-thread data is stored on the task's stack, making it accessible in O(1) instead of performing a O(n) lookup of the array. - Uses the task create/delete hooks in a similar way to the Windows port, rather than overloading trace points.
5 years ago
}
/*-----------------------------------------------------------*/
void vPortEnableInterrupts( void )
{
pthread_sigmask( SIG_UNBLOCK, &xAllSignals, NULL );
portable/GCC/Posix: add new port for Posix (Linux) applications This is similar to the Windows port, allowing FreeRTOS kernel applications to run as regular applications on Posix (Linux) systems. You can use this in a 32-bit or 64-bit application (although there are dynamic memory allocation trace points that do not support 64-bit addresses). Many of the same caveats of running an RTOS on a non-real-time system apply, but this is still very useful for easy debugging/testing applications in a simulated environment. In particular, it allows easy use of tools such as valgrind. You can call standard library functions from tasks but care must be taken with any that internally take mutexes or block. This includes malloc()/free() and many stdio functions (e.g., printf()). Replacement malloc(), free(), realloc(), and calloc() functions are provided which are safe. printf() needs to be called with a FreeRTOS mutex help (or called from only a single task). Each task is run in its own pthread, which makes debugging with standard tools (such as GDB) easier backtraces for individual tasks are available. Threads for non-running tasks are blocked in sigwait(). The stack for each task (thread) is allocated when the thread is created, and the stack provided during task creation is not used. This is so the stack has guard pages, to help with detecting stack overflows. Task switch is done by resuming the thread for the next task by sending it the resume signal (SIGUSR1) and then suspending the current thread. The timer interrupt uses SIGALRM and care is taken to ensure that the signal handler runs only on the thread for the current task. The additional data needed per-thread is stored at the top on the task's stack. When a running task is being deleted, its thread is marked it as dying so when we switch away from it it exits instead of suspending. This ensures that even if the idle task doesn't run, threads are deleted which allows for more threads to be created (if many tasks are being created and deleted in rapid succession). To further aid debugging, SIGINT (^C) is not blocked inside critical sections. This allows it to be used break into GDB while in a critical section. This means that care must be taken with any custom SIGINT handlers as these are like NMIs. This is somewhat inspired by an existing port by William Davy (https://www.freertos.org/FreeRTOS-simulator-for-Linux.html) but it takes a number of different approaches to make it switch tasks reliableand there's little similarly with the original implementation. - Critical sections block scheduling/"interrupts" by blocking signals using pthread_sigmask(). This is more expensive than attempting to use flags but works reliably and is analogous to the interrupt enable/disable on real hardware. - Care is take to ensure that the SIGALRM handler (for the timer tick) is runnable only on the pthread for the running task. This makes tasks switches more straight-forward and reliable as we can suspend the thread while in the signal handler. - Task switches save/restore the critical nesting on the stack. - Only uses a single (SIGUSR1) signal which is ignored and thus GDB's default signal handling options won't trap/print on this signal. - Extra per-thread data is stored on the task's stack, making it accessible in O(1) instead of performing a O(n) lookup of the array. - Uses the task create/delete hooks in a similar way to the Windows port, rather than overloading trace points.
5 years ago
}
/*-----------------------------------------------------------*/
portBASE_TYPE xPortSetInterruptMask( void )
{
/* Interrupts are always disabled inside ISRs (signals
* handlers). */
return pdTRUE;
portable/GCC/Posix: add new port for Posix (Linux) applications This is similar to the Windows port, allowing FreeRTOS kernel applications to run as regular applications on Posix (Linux) systems. You can use this in a 32-bit or 64-bit application (although there are dynamic memory allocation trace points that do not support 64-bit addresses). Many of the same caveats of running an RTOS on a non-real-time system apply, but this is still very useful for easy debugging/testing applications in a simulated environment. In particular, it allows easy use of tools such as valgrind. You can call standard library functions from tasks but care must be taken with any that internally take mutexes or block. This includes malloc()/free() and many stdio functions (e.g., printf()). Replacement malloc(), free(), realloc(), and calloc() functions are provided which are safe. printf() needs to be called with a FreeRTOS mutex help (or called from only a single task). Each task is run in its own pthread, which makes debugging with standard tools (such as GDB) easier backtraces for individual tasks are available. Threads for non-running tasks are blocked in sigwait(). The stack for each task (thread) is allocated when the thread is created, and the stack provided during task creation is not used. This is so the stack has guard pages, to help with detecting stack overflows. Task switch is done by resuming the thread for the next task by sending it the resume signal (SIGUSR1) and then suspending the current thread. The timer interrupt uses SIGALRM and care is taken to ensure that the signal handler runs only on the thread for the current task. The additional data needed per-thread is stored at the top on the task's stack. When a running task is being deleted, its thread is marked it as dying so when we switch away from it it exits instead of suspending. This ensures that even if the idle task doesn't run, threads are deleted which allows for more threads to be created (if many tasks are being created and deleted in rapid succession). To further aid debugging, SIGINT (^C) is not blocked inside critical sections. This allows it to be used break into GDB while in a critical section. This means that care must be taken with any custom SIGINT handlers as these are like NMIs. This is somewhat inspired by an existing port by William Davy (https://www.freertos.org/FreeRTOS-simulator-for-Linux.html) but it takes a number of different approaches to make it switch tasks reliableand there's little similarly with the original implementation. - Critical sections block scheduling/"interrupts" by blocking signals using pthread_sigmask(). This is more expensive than attempting to use flags but works reliably and is analogous to the interrupt enable/disable on real hardware. - Care is take to ensure that the SIGALRM handler (for the timer tick) is runnable only on the pthread for the running task. This makes tasks switches more straight-forward and reliable as we can suspend the thread while in the signal handler. - Task switches save/restore the critical nesting on the stack. - Only uses a single (SIGUSR1) signal which is ignored and thus GDB's default signal handling options won't trap/print on this signal. - Extra per-thread data is stored on the task's stack, making it accessible in O(1) instead of performing a O(n) lookup of the array. - Uses the task create/delete hooks in a similar way to the Windows port, rather than overloading trace points.
5 years ago
}
/*-----------------------------------------------------------*/
void vPortClearInterruptMask( portBASE_TYPE xMask )
{
}
/*-----------------------------------------------------------*/
static uint64_t prvGetTimeNs( void )
portable/GCC/Posix: add new port for Posix (Linux) applications This is similar to the Windows port, allowing FreeRTOS kernel applications to run as regular applications on Posix (Linux) systems. You can use this in a 32-bit or 64-bit application (although there are dynamic memory allocation trace points that do not support 64-bit addresses). Many of the same caveats of running an RTOS on a non-real-time system apply, but this is still very useful for easy debugging/testing applications in a simulated environment. In particular, it allows easy use of tools such as valgrind. You can call standard library functions from tasks but care must be taken with any that internally take mutexes or block. This includes malloc()/free() and many stdio functions (e.g., printf()). Replacement malloc(), free(), realloc(), and calloc() functions are provided which are safe. printf() needs to be called with a FreeRTOS mutex help (or called from only a single task). Each task is run in its own pthread, which makes debugging with standard tools (such as GDB) easier backtraces for individual tasks are available. Threads for non-running tasks are blocked in sigwait(). The stack for each task (thread) is allocated when the thread is created, and the stack provided during task creation is not used. This is so the stack has guard pages, to help with detecting stack overflows. Task switch is done by resuming the thread for the next task by sending it the resume signal (SIGUSR1) and then suspending the current thread. The timer interrupt uses SIGALRM and care is taken to ensure that the signal handler runs only on the thread for the current task. The additional data needed per-thread is stored at the top on the task's stack. When a running task is being deleted, its thread is marked it as dying so when we switch away from it it exits instead of suspending. This ensures that even if the idle task doesn't run, threads are deleted which allows for more threads to be created (if many tasks are being created and deleted in rapid succession). To further aid debugging, SIGINT (^C) is not blocked inside critical sections. This allows it to be used break into GDB while in a critical section. This means that care must be taken with any custom SIGINT handlers as these are like NMIs. This is somewhat inspired by an existing port by William Davy (https://www.freertos.org/FreeRTOS-simulator-for-Linux.html) but it takes a number of different approaches to make it switch tasks reliableand there's little similarly with the original implementation. - Critical sections block scheduling/"interrupts" by blocking signals using pthread_sigmask(). This is more expensive than attempting to use flags but works reliably and is analogous to the interrupt enable/disable on real hardware. - Care is take to ensure that the SIGALRM handler (for the timer tick) is runnable only on the pthread for the running task. This makes tasks switches more straight-forward and reliable as we can suspend the thread while in the signal handler. - Task switches save/restore the critical nesting on the stack. - Only uses a single (SIGUSR1) signal which is ignored and thus GDB's default signal handling options won't trap/print on this signal. - Extra per-thread data is stored on the task's stack, making it accessible in O(1) instead of performing a O(n) lookup of the array. - Uses the task create/delete hooks in a similar way to the Windows port, rather than overloading trace points.
5 years ago
{
struct timespec t;
portable/GCC/Posix: add new port for Posix (Linux) applications This is similar to the Windows port, allowing FreeRTOS kernel applications to run as regular applications on Posix (Linux) systems. You can use this in a 32-bit or 64-bit application (although there are dynamic memory allocation trace points that do not support 64-bit addresses). Many of the same caveats of running an RTOS on a non-real-time system apply, but this is still very useful for easy debugging/testing applications in a simulated environment. In particular, it allows easy use of tools such as valgrind. You can call standard library functions from tasks but care must be taken with any that internally take mutexes or block. This includes malloc()/free() and many stdio functions (e.g., printf()). Replacement malloc(), free(), realloc(), and calloc() functions are provided which are safe. printf() needs to be called with a FreeRTOS mutex help (or called from only a single task). Each task is run in its own pthread, which makes debugging with standard tools (such as GDB) easier backtraces for individual tasks are available. Threads for non-running tasks are blocked in sigwait(). The stack for each task (thread) is allocated when the thread is created, and the stack provided during task creation is not used. This is so the stack has guard pages, to help with detecting stack overflows. Task switch is done by resuming the thread for the next task by sending it the resume signal (SIGUSR1) and then suspending the current thread. The timer interrupt uses SIGALRM and care is taken to ensure that the signal handler runs only on the thread for the current task. The additional data needed per-thread is stored at the top on the task's stack. When a running task is being deleted, its thread is marked it as dying so when we switch away from it it exits instead of suspending. This ensures that even if the idle task doesn't run, threads are deleted which allows for more threads to be created (if many tasks are being created and deleted in rapid succession). To further aid debugging, SIGINT (^C) is not blocked inside critical sections. This allows it to be used break into GDB while in a critical section. This means that care must be taken with any custom SIGINT handlers as these are like NMIs. This is somewhat inspired by an existing port by William Davy (https://www.freertos.org/FreeRTOS-simulator-for-Linux.html) but it takes a number of different approaches to make it switch tasks reliableand there's little similarly with the original implementation. - Critical sections block scheduling/"interrupts" by blocking signals using pthread_sigmask(). This is more expensive than attempting to use flags but works reliably and is analogous to the interrupt enable/disable on real hardware. - Care is take to ensure that the SIGALRM handler (for the timer tick) is runnable only on the pthread for the running task. This makes tasks switches more straight-forward and reliable as we can suspend the thread while in the signal handler. - Task switches save/restore the critical nesting on the stack. - Only uses a single (SIGUSR1) signal which is ignored and thus GDB's default signal handling options won't trap/print on this signal. - Extra per-thread data is stored on the task's stack, making it accessible in O(1) instead of performing a O(n) lookup of the array. - Uses the task create/delete hooks in a similar way to the Windows port, rather than overloading trace points.
5 years ago
clock_gettime( CLOCK_MONOTONIC, &t );
portable/GCC/Posix: add new port for Posix (Linux) applications This is similar to the Windows port, allowing FreeRTOS kernel applications to run as regular applications on Posix (Linux) systems. You can use this in a 32-bit or 64-bit application (although there are dynamic memory allocation trace points that do not support 64-bit addresses). Many of the same caveats of running an RTOS on a non-real-time system apply, but this is still very useful for easy debugging/testing applications in a simulated environment. In particular, it allows easy use of tools such as valgrind. You can call standard library functions from tasks but care must be taken with any that internally take mutexes or block. This includes malloc()/free() and many stdio functions (e.g., printf()). Replacement malloc(), free(), realloc(), and calloc() functions are provided which are safe. printf() needs to be called with a FreeRTOS mutex help (or called from only a single task). Each task is run in its own pthread, which makes debugging with standard tools (such as GDB) easier backtraces for individual tasks are available. Threads for non-running tasks are blocked in sigwait(). The stack for each task (thread) is allocated when the thread is created, and the stack provided during task creation is not used. This is so the stack has guard pages, to help with detecting stack overflows. Task switch is done by resuming the thread for the next task by sending it the resume signal (SIGUSR1) and then suspending the current thread. The timer interrupt uses SIGALRM and care is taken to ensure that the signal handler runs only on the thread for the current task. The additional data needed per-thread is stored at the top on the task's stack. When a running task is being deleted, its thread is marked it as dying so when we switch away from it it exits instead of suspending. This ensures that even if the idle task doesn't run, threads are deleted which allows for more threads to be created (if many tasks are being created and deleted in rapid succession). To further aid debugging, SIGINT (^C) is not blocked inside critical sections. This allows it to be used break into GDB while in a critical section. This means that care must be taken with any custom SIGINT handlers as these are like NMIs. This is somewhat inspired by an existing port by William Davy (https://www.freertos.org/FreeRTOS-simulator-for-Linux.html) but it takes a number of different approaches to make it switch tasks reliableand there's little similarly with the original implementation. - Critical sections block scheduling/"interrupts" by blocking signals using pthread_sigmask(). This is more expensive than attempting to use flags but works reliably and is analogous to the interrupt enable/disable on real hardware. - Care is take to ensure that the SIGALRM handler (for the timer tick) is runnable only on the pthread for the running task. This makes tasks switches more straight-forward and reliable as we can suspend the thread while in the signal handler. - Task switches save/restore the critical nesting on the stack. - Only uses a single (SIGUSR1) signal which is ignored and thus GDB's default signal handling options won't trap/print on this signal. - Extra per-thread data is stored on the task's stack, making it accessible in O(1) instead of performing a O(n) lookup of the array. - Uses the task create/delete hooks in a similar way to the Windows port, rather than overloading trace points.
5 years ago
return t.tv_sec * 1000000000ull + t.tv_nsec;
portable/GCC/Posix: add new port for Posix (Linux) applications This is similar to the Windows port, allowing FreeRTOS kernel applications to run as regular applications on Posix (Linux) systems. You can use this in a 32-bit or 64-bit application (although there are dynamic memory allocation trace points that do not support 64-bit addresses). Many of the same caveats of running an RTOS on a non-real-time system apply, but this is still very useful for easy debugging/testing applications in a simulated environment. In particular, it allows easy use of tools such as valgrind. You can call standard library functions from tasks but care must be taken with any that internally take mutexes or block. This includes malloc()/free() and many stdio functions (e.g., printf()). Replacement malloc(), free(), realloc(), and calloc() functions are provided which are safe. printf() needs to be called with a FreeRTOS mutex help (or called from only a single task). Each task is run in its own pthread, which makes debugging with standard tools (such as GDB) easier backtraces for individual tasks are available. Threads for non-running tasks are blocked in sigwait(). The stack for each task (thread) is allocated when the thread is created, and the stack provided during task creation is not used. This is so the stack has guard pages, to help with detecting stack overflows. Task switch is done by resuming the thread for the next task by sending it the resume signal (SIGUSR1) and then suspending the current thread. The timer interrupt uses SIGALRM and care is taken to ensure that the signal handler runs only on the thread for the current task. The additional data needed per-thread is stored at the top on the task's stack. When a running task is being deleted, its thread is marked it as dying so when we switch away from it it exits instead of suspending. This ensures that even if the idle task doesn't run, threads are deleted which allows for more threads to be created (if many tasks are being created and deleted in rapid succession). To further aid debugging, SIGINT (^C) is not blocked inside critical sections. This allows it to be used break into GDB while in a critical section. This means that care must be taken with any custom SIGINT handlers as these are like NMIs. This is somewhat inspired by an existing port by William Davy (https://www.freertos.org/FreeRTOS-simulator-for-Linux.html) but it takes a number of different approaches to make it switch tasks reliableand there's little similarly with the original implementation. - Critical sections block scheduling/"interrupts" by blocking signals using pthread_sigmask(). This is more expensive than attempting to use flags but works reliably and is analogous to the interrupt enable/disable on real hardware. - Care is take to ensure that the SIGALRM handler (for the timer tick) is runnable only on the pthread for the running task. This makes tasks switches more straight-forward and reliable as we can suspend the thread while in the signal handler. - Task switches save/restore the critical nesting on the stack. - Only uses a single (SIGUSR1) signal which is ignored and thus GDB's default signal handling options won't trap/print on this signal. - Extra per-thread data is stored on the task's stack, making it accessible in O(1) instead of performing a O(n) lookup of the array. - Uses the task create/delete hooks in a similar way to the Windows port, rather than overloading trace points.
5 years ago
}
static uint64_t prvStartTimeNs;
static uint64_t prvTickCount;
/*
* Setup the systick timer to generate the tick interrupts at the required
* frequency.
*/
void prvSetupTimerInterrupt( void )
{
struct itimerval itimer;
int iRet;
/* Initialise the structure with the current timer information. */
iRet = getitimer( ITIMER_REAL, &itimer );
if( iRet )
{
prvFatalError( "getitimer", errno );
}
/* Set the interval between timer events. */
itimer.it_interval.tv_sec = 0;
itimer.it_interval.tv_usec = portTICK_RATE_MICROSECONDS;
/* Set the current count-down. */
itimer.it_value.tv_sec = 0;
itimer.it_value.tv_usec = portTICK_RATE_MICROSECONDS;
/* Set-up the timer interrupt. */
iRet = setitimer( ITIMER_REAL, &itimer, NULL );
if( iRet )
{
prvFatalError( "setitimer", errno );
}
prvStartTimeNs = prvGetTimeNs();
portable/GCC/Posix: add new port for Posix (Linux) applications This is similar to the Windows port, allowing FreeRTOS kernel applications to run as regular applications on Posix (Linux) systems. You can use this in a 32-bit or 64-bit application (although there are dynamic memory allocation trace points that do not support 64-bit addresses). Many of the same caveats of running an RTOS on a non-real-time system apply, but this is still very useful for easy debugging/testing applications in a simulated environment. In particular, it allows easy use of tools such as valgrind. You can call standard library functions from tasks but care must be taken with any that internally take mutexes or block. This includes malloc()/free() and many stdio functions (e.g., printf()). Replacement malloc(), free(), realloc(), and calloc() functions are provided which are safe. printf() needs to be called with a FreeRTOS mutex help (or called from only a single task). Each task is run in its own pthread, which makes debugging with standard tools (such as GDB) easier backtraces for individual tasks are available. Threads for non-running tasks are blocked in sigwait(). The stack for each task (thread) is allocated when the thread is created, and the stack provided during task creation is not used. This is so the stack has guard pages, to help with detecting stack overflows. Task switch is done by resuming the thread for the next task by sending it the resume signal (SIGUSR1) and then suspending the current thread. The timer interrupt uses SIGALRM and care is taken to ensure that the signal handler runs only on the thread for the current task. The additional data needed per-thread is stored at the top on the task's stack. When a running task is being deleted, its thread is marked it as dying so when we switch away from it it exits instead of suspending. This ensures that even if the idle task doesn't run, threads are deleted which allows for more threads to be created (if many tasks are being created and deleted in rapid succession). To further aid debugging, SIGINT (^C) is not blocked inside critical sections. This allows it to be used break into GDB while in a critical section. This means that care must be taken with any custom SIGINT handlers as these are like NMIs. This is somewhat inspired by an existing port by William Davy (https://www.freertos.org/FreeRTOS-simulator-for-Linux.html) but it takes a number of different approaches to make it switch tasks reliableand there's little similarly with the original implementation. - Critical sections block scheduling/"interrupts" by blocking signals using pthread_sigmask(). This is more expensive than attempting to use flags but works reliably and is analogous to the interrupt enable/disable on real hardware. - Care is take to ensure that the SIGALRM handler (for the timer tick) is runnable only on the pthread for the running task. This makes tasks switches more straight-forward and reliable as we can suspend the thread while in the signal handler. - Task switches save/restore the critical nesting on the stack. - Only uses a single (SIGUSR1) signal which is ignored and thus GDB's default signal handling options won't trap/print on this signal. - Extra per-thread data is stored on the task's stack, making it accessible in O(1) instead of performing a O(n) lookup of the array. - Uses the task create/delete hooks in a similar way to the Windows port, rather than overloading trace points.
5 years ago
}
/*-----------------------------------------------------------*/
static void vPortSystemTickHandler( int sig )
{
Thread_t * pxThreadToSuspend;
Thread_t * pxThreadToResume;
uint64_t xExpectedTicks;
uxCriticalNesting++; /* Signals are blocked in this signal handler. */
portable/GCC/Posix: add new port for Posix (Linux) applications This is similar to the Windows port, allowing FreeRTOS kernel applications to run as regular applications on Posix (Linux) systems. You can use this in a 32-bit or 64-bit application (although there are dynamic memory allocation trace points that do not support 64-bit addresses). Many of the same caveats of running an RTOS on a non-real-time system apply, but this is still very useful for easy debugging/testing applications in a simulated environment. In particular, it allows easy use of tools such as valgrind. You can call standard library functions from tasks but care must be taken with any that internally take mutexes or block. This includes malloc()/free() and many stdio functions (e.g., printf()). Replacement malloc(), free(), realloc(), and calloc() functions are provided which are safe. printf() needs to be called with a FreeRTOS mutex help (or called from only a single task). Each task is run in its own pthread, which makes debugging with standard tools (such as GDB) easier backtraces for individual tasks are available. Threads for non-running tasks are blocked in sigwait(). The stack for each task (thread) is allocated when the thread is created, and the stack provided during task creation is not used. This is so the stack has guard pages, to help with detecting stack overflows. Task switch is done by resuming the thread for the next task by sending it the resume signal (SIGUSR1) and then suspending the current thread. The timer interrupt uses SIGALRM and care is taken to ensure that the signal handler runs only on the thread for the current task. The additional data needed per-thread is stored at the top on the task's stack. When a running task is being deleted, its thread is marked it as dying so when we switch away from it it exits instead of suspending. This ensures that even if the idle task doesn't run, threads are deleted which allows for more threads to be created (if many tasks are being created and deleted in rapid succession). To further aid debugging, SIGINT (^C) is not blocked inside critical sections. This allows it to be used break into GDB while in a critical section. This means that care must be taken with any custom SIGINT handlers as these are like NMIs. This is somewhat inspired by an existing port by William Davy (https://www.freertos.org/FreeRTOS-simulator-for-Linux.html) but it takes a number of different approaches to make it switch tasks reliableand there's little similarly with the original implementation. - Critical sections block scheduling/"interrupts" by blocking signals using pthread_sigmask(). This is more expensive than attempting to use flags but works reliably and is analogous to the interrupt enable/disable on real hardware. - Care is take to ensure that the SIGALRM handler (for the timer tick) is runnable only on the pthread for the running task. This makes tasks switches more straight-forward and reliable as we can suspend the thread while in the signal handler. - Task switches save/restore the critical nesting on the stack. - Only uses a single (SIGUSR1) signal which is ignored and thus GDB's default signal handling options won't trap/print on this signal. - Extra per-thread data is stored on the task's stack, making it accessible in O(1) instead of performing a O(n) lookup of the array. - Uses the task create/delete hooks in a similar way to the Windows port, rather than overloading trace points.
5 years ago
pxThreadToSuspend = prvGetThreadFromTask( xTaskGetCurrentTaskHandle() );
portable/GCC/Posix: add new port for Posix (Linux) applications This is similar to the Windows port, allowing FreeRTOS kernel applications to run as regular applications on Posix (Linux) systems. You can use this in a 32-bit or 64-bit application (although there are dynamic memory allocation trace points that do not support 64-bit addresses). Many of the same caveats of running an RTOS on a non-real-time system apply, but this is still very useful for easy debugging/testing applications in a simulated environment. In particular, it allows easy use of tools such as valgrind. You can call standard library functions from tasks but care must be taken with any that internally take mutexes or block. This includes malloc()/free() and many stdio functions (e.g., printf()). Replacement malloc(), free(), realloc(), and calloc() functions are provided which are safe. printf() needs to be called with a FreeRTOS mutex help (or called from only a single task). Each task is run in its own pthread, which makes debugging with standard tools (such as GDB) easier backtraces for individual tasks are available. Threads for non-running tasks are blocked in sigwait(). The stack for each task (thread) is allocated when the thread is created, and the stack provided during task creation is not used. This is so the stack has guard pages, to help with detecting stack overflows. Task switch is done by resuming the thread for the next task by sending it the resume signal (SIGUSR1) and then suspending the current thread. The timer interrupt uses SIGALRM and care is taken to ensure that the signal handler runs only on the thread for the current task. The additional data needed per-thread is stored at the top on the task's stack. When a running task is being deleted, its thread is marked it as dying so when we switch away from it it exits instead of suspending. This ensures that even if the idle task doesn't run, threads are deleted which allows for more threads to be created (if many tasks are being created and deleted in rapid succession). To further aid debugging, SIGINT (^C) is not blocked inside critical sections. This allows it to be used break into GDB while in a critical section. This means that care must be taken with any custom SIGINT handlers as these are like NMIs. This is somewhat inspired by an existing port by William Davy (https://www.freertos.org/FreeRTOS-simulator-for-Linux.html) but it takes a number of different approaches to make it switch tasks reliableand there's little similarly with the original implementation. - Critical sections block scheduling/"interrupts" by blocking signals using pthread_sigmask(). This is more expensive than attempting to use flags but works reliably and is analogous to the interrupt enable/disable on real hardware. - Care is take to ensure that the SIGALRM handler (for the timer tick) is runnable only on the pthread for the running task. This makes tasks switches more straight-forward and reliable as we can suspend the thread while in the signal handler. - Task switches save/restore the critical nesting on the stack. - Only uses a single (SIGUSR1) signal which is ignored and thus GDB's default signal handling options won't trap/print on this signal. - Extra per-thread data is stored on the task's stack, making it accessible in O(1) instead of performing a O(n) lookup of the array. - Uses the task create/delete hooks in a similar way to the Windows port, rather than overloading trace points.
5 years ago
/* Tick Increment, accounting for any lost signals or drift in
* the timer. */
xExpectedTicks = ( prvGetTimeNs() - prvStartTimeNs )
/ ( portTICK_RATE_MICROSECONDS * 1000 );
portable/GCC/Posix: add new port for Posix (Linux) applications This is similar to the Windows port, allowing FreeRTOS kernel applications to run as regular applications on Posix (Linux) systems. You can use this in a 32-bit or 64-bit application (although there are dynamic memory allocation trace points that do not support 64-bit addresses). Many of the same caveats of running an RTOS on a non-real-time system apply, but this is still very useful for easy debugging/testing applications in a simulated environment. In particular, it allows easy use of tools such as valgrind. You can call standard library functions from tasks but care must be taken with any that internally take mutexes or block. This includes malloc()/free() and many stdio functions (e.g., printf()). Replacement malloc(), free(), realloc(), and calloc() functions are provided which are safe. printf() needs to be called with a FreeRTOS mutex help (or called from only a single task). Each task is run in its own pthread, which makes debugging with standard tools (such as GDB) easier backtraces for individual tasks are available. Threads for non-running tasks are blocked in sigwait(). The stack for each task (thread) is allocated when the thread is created, and the stack provided during task creation is not used. This is so the stack has guard pages, to help with detecting stack overflows. Task switch is done by resuming the thread for the next task by sending it the resume signal (SIGUSR1) and then suspending the current thread. The timer interrupt uses SIGALRM and care is taken to ensure that the signal handler runs only on the thread for the current task. The additional data needed per-thread is stored at the top on the task's stack. When a running task is being deleted, its thread is marked it as dying so when we switch away from it it exits instead of suspending. This ensures that even if the idle task doesn't run, threads are deleted which allows for more threads to be created (if many tasks are being created and deleted in rapid succession). To further aid debugging, SIGINT (^C) is not blocked inside critical sections. This allows it to be used break into GDB while in a critical section. This means that care must be taken with any custom SIGINT handlers as these are like NMIs. This is somewhat inspired by an existing port by William Davy (https://www.freertos.org/FreeRTOS-simulator-for-Linux.html) but it takes a number of different approaches to make it switch tasks reliableand there's little similarly with the original implementation. - Critical sections block scheduling/"interrupts" by blocking signals using pthread_sigmask(). This is more expensive than attempting to use flags but works reliably and is analogous to the interrupt enable/disable on real hardware. - Care is take to ensure that the SIGALRM handler (for the timer tick) is runnable only on the pthread for the running task. This makes tasks switches more straight-forward and reliable as we can suspend the thread while in the signal handler. - Task switches save/restore the critical nesting on the stack. - Only uses a single (SIGUSR1) signal which is ignored and thus GDB's default signal handling options won't trap/print on this signal. - Extra per-thread data is stored on the task's stack, making it accessible in O(1) instead of performing a O(n) lookup of the array. - Uses the task create/delete hooks in a similar way to the Windows port, rather than overloading trace points.
5 years ago
do
{
xTaskIncrementTick();
prvTickCount++;
} while( prvTickCount < xExpectedTicks );
portable/GCC/Posix: add new port for Posix (Linux) applications This is similar to the Windows port, allowing FreeRTOS kernel applications to run as regular applications on Posix (Linux) systems. You can use this in a 32-bit or 64-bit application (although there are dynamic memory allocation trace points that do not support 64-bit addresses). Many of the same caveats of running an RTOS on a non-real-time system apply, but this is still very useful for easy debugging/testing applications in a simulated environment. In particular, it allows easy use of tools such as valgrind. You can call standard library functions from tasks but care must be taken with any that internally take mutexes or block. This includes malloc()/free() and many stdio functions (e.g., printf()). Replacement malloc(), free(), realloc(), and calloc() functions are provided which are safe. printf() needs to be called with a FreeRTOS mutex help (or called from only a single task). Each task is run in its own pthread, which makes debugging with standard tools (such as GDB) easier backtraces for individual tasks are available. Threads for non-running tasks are blocked in sigwait(). The stack for each task (thread) is allocated when the thread is created, and the stack provided during task creation is not used. This is so the stack has guard pages, to help with detecting stack overflows. Task switch is done by resuming the thread for the next task by sending it the resume signal (SIGUSR1) and then suspending the current thread. The timer interrupt uses SIGALRM and care is taken to ensure that the signal handler runs only on the thread for the current task. The additional data needed per-thread is stored at the top on the task's stack. When a running task is being deleted, its thread is marked it as dying so when we switch away from it it exits instead of suspending. This ensures that even if the idle task doesn't run, threads are deleted which allows for more threads to be created (if many tasks are being created and deleted in rapid succession). To further aid debugging, SIGINT (^C) is not blocked inside critical sections. This allows it to be used break into GDB while in a critical section. This means that care must be taken with any custom SIGINT handlers as these are like NMIs. This is somewhat inspired by an existing port by William Davy (https://www.freertos.org/FreeRTOS-simulator-for-Linux.html) but it takes a number of different approaches to make it switch tasks reliableand there's little similarly with the original implementation. - Critical sections block scheduling/"interrupts" by blocking signals using pthread_sigmask(). This is more expensive than attempting to use flags but works reliably and is analogous to the interrupt enable/disable on real hardware. - Care is take to ensure that the SIGALRM handler (for the timer tick) is runnable only on the pthread for the running task. This makes tasks switches more straight-forward and reliable as we can suspend the thread while in the signal handler. - Task switches save/restore the critical nesting on the stack. - Only uses a single (SIGUSR1) signal which is ignored and thus GDB's default signal handling options won't trap/print on this signal. - Extra per-thread data is stored on the task's stack, making it accessible in O(1) instead of performing a O(n) lookup of the array. - Uses the task create/delete hooks in a similar way to the Windows port, rather than overloading trace points.
5 years ago
#if ( configUSE_PREEMPTION == 1 )
/* Select Next Task. */
vTaskSwitchContext();
portable/GCC/Posix: add new port for Posix (Linux) applications This is similar to the Windows port, allowing FreeRTOS kernel applications to run as regular applications on Posix (Linux) systems. You can use this in a 32-bit or 64-bit application (although there are dynamic memory allocation trace points that do not support 64-bit addresses). Many of the same caveats of running an RTOS on a non-real-time system apply, but this is still very useful for easy debugging/testing applications in a simulated environment. In particular, it allows easy use of tools such as valgrind. You can call standard library functions from tasks but care must be taken with any that internally take mutexes or block. This includes malloc()/free() and many stdio functions (e.g., printf()). Replacement malloc(), free(), realloc(), and calloc() functions are provided which are safe. printf() needs to be called with a FreeRTOS mutex help (or called from only a single task). Each task is run in its own pthread, which makes debugging with standard tools (such as GDB) easier backtraces for individual tasks are available. Threads for non-running tasks are blocked in sigwait(). The stack for each task (thread) is allocated when the thread is created, and the stack provided during task creation is not used. This is so the stack has guard pages, to help with detecting stack overflows. Task switch is done by resuming the thread for the next task by sending it the resume signal (SIGUSR1) and then suspending the current thread. The timer interrupt uses SIGALRM and care is taken to ensure that the signal handler runs only on the thread for the current task. The additional data needed per-thread is stored at the top on the task's stack. When a running task is being deleted, its thread is marked it as dying so when we switch away from it it exits instead of suspending. This ensures that even if the idle task doesn't run, threads are deleted which allows for more threads to be created (if many tasks are being created and deleted in rapid succession). To further aid debugging, SIGINT (^C) is not blocked inside critical sections. This allows it to be used break into GDB while in a critical section. This means that care must be taken with any custom SIGINT handlers as these are like NMIs. This is somewhat inspired by an existing port by William Davy (https://www.freertos.org/FreeRTOS-simulator-for-Linux.html) but it takes a number of different approaches to make it switch tasks reliableand there's little similarly with the original implementation. - Critical sections block scheduling/"interrupts" by blocking signals using pthread_sigmask(). This is more expensive than attempting to use flags but works reliably and is analogous to the interrupt enable/disable on real hardware. - Care is take to ensure that the SIGALRM handler (for the timer tick) is runnable only on the pthread for the running task. This makes tasks switches more straight-forward and reliable as we can suspend the thread while in the signal handler. - Task switches save/restore the critical nesting on the stack. - Only uses a single (SIGUSR1) signal which is ignored and thus GDB's default signal handling options won't trap/print on this signal. - Extra per-thread data is stored on the task's stack, making it accessible in O(1) instead of performing a O(n) lookup of the array. - Uses the task create/delete hooks in a similar way to the Windows port, rather than overloading trace points.
5 years ago
pxThreadToResume = prvGetThreadFromTask( xTaskGetCurrentTaskHandle() );
portable/GCC/Posix: add new port for Posix (Linux) applications This is similar to the Windows port, allowing FreeRTOS kernel applications to run as regular applications on Posix (Linux) systems. You can use this in a 32-bit or 64-bit application (although there are dynamic memory allocation trace points that do not support 64-bit addresses). Many of the same caveats of running an RTOS on a non-real-time system apply, but this is still very useful for easy debugging/testing applications in a simulated environment. In particular, it allows easy use of tools such as valgrind. You can call standard library functions from tasks but care must be taken with any that internally take mutexes or block. This includes malloc()/free() and many stdio functions (e.g., printf()). Replacement malloc(), free(), realloc(), and calloc() functions are provided which are safe. printf() needs to be called with a FreeRTOS mutex help (or called from only a single task). Each task is run in its own pthread, which makes debugging with standard tools (such as GDB) easier backtraces for individual tasks are available. Threads for non-running tasks are blocked in sigwait(). The stack for each task (thread) is allocated when the thread is created, and the stack provided during task creation is not used. This is so the stack has guard pages, to help with detecting stack overflows. Task switch is done by resuming the thread for the next task by sending it the resume signal (SIGUSR1) and then suspending the current thread. The timer interrupt uses SIGALRM and care is taken to ensure that the signal handler runs only on the thread for the current task. The additional data needed per-thread is stored at the top on the task's stack. When a running task is being deleted, its thread is marked it as dying so when we switch away from it it exits instead of suspending. This ensures that even if the idle task doesn't run, threads are deleted which allows for more threads to be created (if many tasks are being created and deleted in rapid succession). To further aid debugging, SIGINT (^C) is not blocked inside critical sections. This allows it to be used break into GDB while in a critical section. This means that care must be taken with any custom SIGINT handlers as these are like NMIs. This is somewhat inspired by an existing port by William Davy (https://www.freertos.org/FreeRTOS-simulator-for-Linux.html) but it takes a number of different approaches to make it switch tasks reliableand there's little similarly with the original implementation. - Critical sections block scheduling/"interrupts" by blocking signals using pthread_sigmask(). This is more expensive than attempting to use flags but works reliably and is analogous to the interrupt enable/disable on real hardware. - Care is take to ensure that the SIGALRM handler (for the timer tick) is runnable only on the pthread for the running task. This makes tasks switches more straight-forward and reliable as we can suspend the thread while in the signal handler. - Task switches save/restore the critical nesting on the stack. - Only uses a single (SIGUSR1) signal which is ignored and thus GDB's default signal handling options won't trap/print on this signal. - Extra per-thread data is stored on the task's stack, making it accessible in O(1) instead of performing a O(n) lookup of the array. - Uses the task create/delete hooks in a similar way to the Windows port, rather than overloading trace points.
5 years ago
prvSwitchThread( pxThreadToResume, pxThreadToSuspend );
#endif
portable/GCC/Posix: add new port for Posix (Linux) applications This is similar to the Windows port, allowing FreeRTOS kernel applications to run as regular applications on Posix (Linux) systems. You can use this in a 32-bit or 64-bit application (although there are dynamic memory allocation trace points that do not support 64-bit addresses). Many of the same caveats of running an RTOS on a non-real-time system apply, but this is still very useful for easy debugging/testing applications in a simulated environment. In particular, it allows easy use of tools such as valgrind. You can call standard library functions from tasks but care must be taken with any that internally take mutexes or block. This includes malloc()/free() and many stdio functions (e.g., printf()). Replacement malloc(), free(), realloc(), and calloc() functions are provided which are safe. printf() needs to be called with a FreeRTOS mutex help (or called from only a single task). Each task is run in its own pthread, which makes debugging with standard tools (such as GDB) easier backtraces for individual tasks are available. Threads for non-running tasks are blocked in sigwait(). The stack for each task (thread) is allocated when the thread is created, and the stack provided during task creation is not used. This is so the stack has guard pages, to help with detecting stack overflows. Task switch is done by resuming the thread for the next task by sending it the resume signal (SIGUSR1) and then suspending the current thread. The timer interrupt uses SIGALRM and care is taken to ensure that the signal handler runs only on the thread for the current task. The additional data needed per-thread is stored at the top on the task's stack. When a running task is being deleted, its thread is marked it as dying so when we switch away from it it exits instead of suspending. This ensures that even if the idle task doesn't run, threads are deleted which allows for more threads to be created (if many tasks are being created and deleted in rapid succession). To further aid debugging, SIGINT (^C) is not blocked inside critical sections. This allows it to be used break into GDB while in a critical section. This means that care must be taken with any custom SIGINT handlers as these are like NMIs. This is somewhat inspired by an existing port by William Davy (https://www.freertos.org/FreeRTOS-simulator-for-Linux.html) but it takes a number of different approaches to make it switch tasks reliableand there's little similarly with the original implementation. - Critical sections block scheduling/"interrupts" by blocking signals using pthread_sigmask(). This is more expensive than attempting to use flags but works reliably and is analogous to the interrupt enable/disable on real hardware. - Care is take to ensure that the SIGALRM handler (for the timer tick) is runnable only on the pthread for the running task. This makes tasks switches more straight-forward and reliable as we can suspend the thread while in the signal handler. - Task switches save/restore the critical nesting on the stack. - Only uses a single (SIGUSR1) signal which is ignored and thus GDB's default signal handling options won't trap/print on this signal. - Extra per-thread data is stored on the task's stack, making it accessible in O(1) instead of performing a O(n) lookup of the array. - Uses the task create/delete hooks in a similar way to the Windows port, rather than overloading trace points.
5 years ago
uxCriticalNesting--;
portable/GCC/Posix: add new port for Posix (Linux) applications This is similar to the Windows port, allowing FreeRTOS kernel applications to run as regular applications on Posix (Linux) systems. You can use this in a 32-bit or 64-bit application (although there are dynamic memory allocation trace points that do not support 64-bit addresses). Many of the same caveats of running an RTOS on a non-real-time system apply, but this is still very useful for easy debugging/testing applications in a simulated environment. In particular, it allows easy use of tools such as valgrind. You can call standard library functions from tasks but care must be taken with any that internally take mutexes or block. This includes malloc()/free() and many stdio functions (e.g., printf()). Replacement malloc(), free(), realloc(), and calloc() functions are provided which are safe. printf() needs to be called with a FreeRTOS mutex help (or called from only a single task). Each task is run in its own pthread, which makes debugging with standard tools (such as GDB) easier backtraces for individual tasks are available. Threads for non-running tasks are blocked in sigwait(). The stack for each task (thread) is allocated when the thread is created, and the stack provided during task creation is not used. This is so the stack has guard pages, to help with detecting stack overflows. Task switch is done by resuming the thread for the next task by sending it the resume signal (SIGUSR1) and then suspending the current thread. The timer interrupt uses SIGALRM and care is taken to ensure that the signal handler runs only on the thread for the current task. The additional data needed per-thread is stored at the top on the task's stack. When a running task is being deleted, its thread is marked it as dying so when we switch away from it it exits instead of suspending. This ensures that even if the idle task doesn't run, threads are deleted which allows for more threads to be created (if many tasks are being created and deleted in rapid succession). To further aid debugging, SIGINT (^C) is not blocked inside critical sections. This allows it to be used break into GDB while in a critical section. This means that care must be taken with any custom SIGINT handlers as these are like NMIs. This is somewhat inspired by an existing port by William Davy (https://www.freertos.org/FreeRTOS-simulator-for-Linux.html) but it takes a number of different approaches to make it switch tasks reliableand there's little similarly with the original implementation. - Critical sections block scheduling/"interrupts" by blocking signals using pthread_sigmask(). This is more expensive than attempting to use flags but works reliably and is analogous to the interrupt enable/disable on real hardware. - Care is take to ensure that the SIGALRM handler (for the timer tick) is runnable only on the pthread for the running task. This makes tasks switches more straight-forward and reliable as we can suspend the thread while in the signal handler. - Task switches save/restore the critical nesting on the stack. - Only uses a single (SIGUSR1) signal which is ignored and thus GDB's default signal handling options won't trap/print on this signal. - Extra per-thread data is stored on the task's stack, making it accessible in O(1) instead of performing a O(n) lookup of the array. - Uses the task create/delete hooks in a similar way to the Windows port, rather than overloading trace points.
5 years ago
}
/*-----------------------------------------------------------*/
void vPortThreadDying( void * pxTaskToDelete,
volatile BaseType_t * pxPendYield )
portable/GCC/Posix: add new port for Posix (Linux) applications This is similar to the Windows port, allowing FreeRTOS kernel applications to run as regular applications on Posix (Linux) systems. You can use this in a 32-bit or 64-bit application (although there are dynamic memory allocation trace points that do not support 64-bit addresses). Many of the same caveats of running an RTOS on a non-real-time system apply, but this is still very useful for easy debugging/testing applications in a simulated environment. In particular, it allows easy use of tools such as valgrind. You can call standard library functions from tasks but care must be taken with any that internally take mutexes or block. This includes malloc()/free() and many stdio functions (e.g., printf()). Replacement malloc(), free(), realloc(), and calloc() functions are provided which are safe. printf() needs to be called with a FreeRTOS mutex help (or called from only a single task). Each task is run in its own pthread, which makes debugging with standard tools (such as GDB) easier backtraces for individual tasks are available. Threads for non-running tasks are blocked in sigwait(). The stack for each task (thread) is allocated when the thread is created, and the stack provided during task creation is not used. This is so the stack has guard pages, to help with detecting stack overflows. Task switch is done by resuming the thread for the next task by sending it the resume signal (SIGUSR1) and then suspending the current thread. The timer interrupt uses SIGALRM and care is taken to ensure that the signal handler runs only on the thread for the current task. The additional data needed per-thread is stored at the top on the task's stack. When a running task is being deleted, its thread is marked it as dying so when we switch away from it it exits instead of suspending. This ensures that even if the idle task doesn't run, threads are deleted which allows for more threads to be created (if many tasks are being created and deleted in rapid succession). To further aid debugging, SIGINT (^C) is not blocked inside critical sections. This allows it to be used break into GDB while in a critical section. This means that care must be taken with any custom SIGINT handlers as these are like NMIs. This is somewhat inspired by an existing port by William Davy (https://www.freertos.org/FreeRTOS-simulator-for-Linux.html) but it takes a number of different approaches to make it switch tasks reliableand there's little similarly with the original implementation. - Critical sections block scheduling/"interrupts" by blocking signals using pthread_sigmask(). This is more expensive than attempting to use flags but works reliably and is analogous to the interrupt enable/disable on real hardware. - Care is take to ensure that the SIGALRM handler (for the timer tick) is runnable only on the pthread for the running task. This makes tasks switches more straight-forward and reliable as we can suspend the thread while in the signal handler. - Task switches save/restore the critical nesting on the stack. - Only uses a single (SIGUSR1) signal which is ignored and thus GDB's default signal handling options won't trap/print on this signal. - Extra per-thread data is stored on the task's stack, making it accessible in O(1) instead of performing a O(n) lookup of the array. - Uses the task create/delete hooks in a similar way to the Windows port, rather than overloading trace points.
5 years ago
{
Thread_t * pxThread = prvGetThreadFromTask( pxTaskToDelete );
portable/GCC/Posix: add new port for Posix (Linux) applications This is similar to the Windows port, allowing FreeRTOS kernel applications to run as regular applications on Posix (Linux) systems. You can use this in a 32-bit or 64-bit application (although there are dynamic memory allocation trace points that do not support 64-bit addresses). Many of the same caveats of running an RTOS on a non-real-time system apply, but this is still very useful for easy debugging/testing applications in a simulated environment. In particular, it allows easy use of tools such as valgrind. You can call standard library functions from tasks but care must be taken with any that internally take mutexes or block. This includes malloc()/free() and many stdio functions (e.g., printf()). Replacement malloc(), free(), realloc(), and calloc() functions are provided which are safe. printf() needs to be called with a FreeRTOS mutex help (or called from only a single task). Each task is run in its own pthread, which makes debugging with standard tools (such as GDB) easier backtraces for individual tasks are available. Threads for non-running tasks are blocked in sigwait(). The stack for each task (thread) is allocated when the thread is created, and the stack provided during task creation is not used. This is so the stack has guard pages, to help with detecting stack overflows. Task switch is done by resuming the thread for the next task by sending it the resume signal (SIGUSR1) and then suspending the current thread. The timer interrupt uses SIGALRM and care is taken to ensure that the signal handler runs only on the thread for the current task. The additional data needed per-thread is stored at the top on the task's stack. When a running task is being deleted, its thread is marked it as dying so when we switch away from it it exits instead of suspending. This ensures that even if the idle task doesn't run, threads are deleted which allows for more threads to be created (if many tasks are being created and deleted in rapid succession). To further aid debugging, SIGINT (^C) is not blocked inside critical sections. This allows it to be used break into GDB while in a critical section. This means that care must be taken with any custom SIGINT handlers as these are like NMIs. This is somewhat inspired by an existing port by William Davy (https://www.freertos.org/FreeRTOS-simulator-for-Linux.html) but it takes a number of different approaches to make it switch tasks reliableand there's little similarly with the original implementation. - Critical sections block scheduling/"interrupts" by blocking signals using pthread_sigmask(). This is more expensive than attempting to use flags but works reliably and is analogous to the interrupt enable/disable on real hardware. - Care is take to ensure that the SIGALRM handler (for the timer tick) is runnable only on the pthread for the running task. This makes tasks switches more straight-forward and reliable as we can suspend the thread while in the signal handler. - Task switches save/restore the critical nesting on the stack. - Only uses a single (SIGUSR1) signal which is ignored and thus GDB's default signal handling options won't trap/print on this signal. - Extra per-thread data is stored on the task's stack, making it accessible in O(1) instead of performing a O(n) lookup of the array. - Uses the task create/delete hooks in a similar way to the Windows port, rather than overloading trace points.
5 years ago
pxThread->xDying = pdTRUE;
portable/GCC/Posix: add new port for Posix (Linux) applications This is similar to the Windows port, allowing FreeRTOS kernel applications to run as regular applications on Posix (Linux) systems. You can use this in a 32-bit or 64-bit application (although there are dynamic memory allocation trace points that do not support 64-bit addresses). Many of the same caveats of running an RTOS on a non-real-time system apply, but this is still very useful for easy debugging/testing applications in a simulated environment. In particular, it allows easy use of tools such as valgrind. You can call standard library functions from tasks but care must be taken with any that internally take mutexes or block. This includes malloc()/free() and many stdio functions (e.g., printf()). Replacement malloc(), free(), realloc(), and calloc() functions are provided which are safe. printf() needs to be called with a FreeRTOS mutex help (or called from only a single task). Each task is run in its own pthread, which makes debugging with standard tools (such as GDB) easier backtraces for individual tasks are available. Threads for non-running tasks are blocked in sigwait(). The stack for each task (thread) is allocated when the thread is created, and the stack provided during task creation is not used. This is so the stack has guard pages, to help with detecting stack overflows. Task switch is done by resuming the thread for the next task by sending it the resume signal (SIGUSR1) and then suspending the current thread. The timer interrupt uses SIGALRM and care is taken to ensure that the signal handler runs only on the thread for the current task. The additional data needed per-thread is stored at the top on the task's stack. When a running task is being deleted, its thread is marked it as dying so when we switch away from it it exits instead of suspending. This ensures that even if the idle task doesn't run, threads are deleted which allows for more threads to be created (if many tasks are being created and deleted in rapid succession). To further aid debugging, SIGINT (^C) is not blocked inside critical sections. This allows it to be used break into GDB while in a critical section. This means that care must be taken with any custom SIGINT handlers as these are like NMIs. This is somewhat inspired by an existing port by William Davy (https://www.freertos.org/FreeRTOS-simulator-for-Linux.html) but it takes a number of different approaches to make it switch tasks reliableand there's little similarly with the original implementation. - Critical sections block scheduling/"interrupts" by blocking signals using pthread_sigmask(). This is more expensive than attempting to use flags but works reliably and is analogous to the interrupt enable/disable on real hardware. - Care is take to ensure that the SIGALRM handler (for the timer tick) is runnable only on the pthread for the running task. This makes tasks switches more straight-forward and reliable as we can suspend the thread while in the signal handler. - Task switches save/restore the critical nesting on the stack. - Only uses a single (SIGUSR1) signal which is ignored and thus GDB's default signal handling options won't trap/print on this signal. - Extra per-thread data is stored on the task's stack, making it accessible in O(1) instead of performing a O(n) lookup of the array. - Uses the task create/delete hooks in a similar way to the Windows port, rather than overloading trace points.
5 years ago
}
void vPortCancelThread( void * pxTaskToDelete )
portable/GCC/Posix: add new port for Posix (Linux) applications This is similar to the Windows port, allowing FreeRTOS kernel applications to run as regular applications on Posix (Linux) systems. You can use this in a 32-bit or 64-bit application (although there are dynamic memory allocation trace points that do not support 64-bit addresses). Many of the same caveats of running an RTOS on a non-real-time system apply, but this is still very useful for easy debugging/testing applications in a simulated environment. In particular, it allows easy use of tools such as valgrind. You can call standard library functions from tasks but care must be taken with any that internally take mutexes or block. This includes malloc()/free() and many stdio functions (e.g., printf()). Replacement malloc(), free(), realloc(), and calloc() functions are provided which are safe. printf() needs to be called with a FreeRTOS mutex help (or called from only a single task). Each task is run in its own pthread, which makes debugging with standard tools (such as GDB) easier backtraces for individual tasks are available. Threads for non-running tasks are blocked in sigwait(). The stack for each task (thread) is allocated when the thread is created, and the stack provided during task creation is not used. This is so the stack has guard pages, to help with detecting stack overflows. Task switch is done by resuming the thread for the next task by sending it the resume signal (SIGUSR1) and then suspending the current thread. The timer interrupt uses SIGALRM and care is taken to ensure that the signal handler runs only on the thread for the current task. The additional data needed per-thread is stored at the top on the task's stack. When a running task is being deleted, its thread is marked it as dying so when we switch away from it it exits instead of suspending. This ensures that even if the idle task doesn't run, threads are deleted which allows for more threads to be created (if many tasks are being created and deleted in rapid succession). To further aid debugging, SIGINT (^C) is not blocked inside critical sections. This allows it to be used break into GDB while in a critical section. This means that care must be taken with any custom SIGINT handlers as these are like NMIs. This is somewhat inspired by an existing port by William Davy (https://www.freertos.org/FreeRTOS-simulator-for-Linux.html) but it takes a number of different approaches to make it switch tasks reliableand there's little similarly with the original implementation. - Critical sections block scheduling/"interrupts" by blocking signals using pthread_sigmask(). This is more expensive than attempting to use flags but works reliably and is analogous to the interrupt enable/disable on real hardware. - Care is take to ensure that the SIGALRM handler (for the timer tick) is runnable only on the pthread for the running task. This makes tasks switches more straight-forward and reliable as we can suspend the thread while in the signal handler. - Task switches save/restore the critical nesting on the stack. - Only uses a single (SIGUSR1) signal which is ignored and thus GDB's default signal handling options won't trap/print on this signal. - Extra per-thread data is stored on the task's stack, making it accessible in O(1) instead of performing a O(n) lookup of the array. - Uses the task create/delete hooks in a similar way to the Windows port, rather than overloading trace points.
5 years ago
{
Thread_t * pxThreadToCancel = prvGetThreadFromTask( pxTaskToDelete );
/*
* The thread has already been suspended so it can be safely
* cancelled.
*/
pthread_cancel( pxThreadToCancel->pthread );
pthread_join( pxThreadToCancel->pthread, NULL );
portable/GCC/Posix: add new port for Posix (Linux) applications This is similar to the Windows port, allowing FreeRTOS kernel applications to run as regular applications on Posix (Linux) systems. You can use this in a 32-bit or 64-bit application (although there are dynamic memory allocation trace points that do not support 64-bit addresses). Many of the same caveats of running an RTOS on a non-real-time system apply, but this is still very useful for easy debugging/testing applications in a simulated environment. In particular, it allows easy use of tools such as valgrind. You can call standard library functions from tasks but care must be taken with any that internally take mutexes or block. This includes malloc()/free() and many stdio functions (e.g., printf()). Replacement malloc(), free(), realloc(), and calloc() functions are provided which are safe. printf() needs to be called with a FreeRTOS mutex help (or called from only a single task). Each task is run in its own pthread, which makes debugging with standard tools (such as GDB) easier backtraces for individual tasks are available. Threads for non-running tasks are blocked in sigwait(). The stack for each task (thread) is allocated when the thread is created, and the stack provided during task creation is not used. This is so the stack has guard pages, to help with detecting stack overflows. Task switch is done by resuming the thread for the next task by sending it the resume signal (SIGUSR1) and then suspending the current thread. The timer interrupt uses SIGALRM and care is taken to ensure that the signal handler runs only on the thread for the current task. The additional data needed per-thread is stored at the top on the task's stack. When a running task is being deleted, its thread is marked it as dying so when we switch away from it it exits instead of suspending. This ensures that even if the idle task doesn't run, threads are deleted which allows for more threads to be created (if many tasks are being created and deleted in rapid succession). To further aid debugging, SIGINT (^C) is not blocked inside critical sections. This allows it to be used break into GDB while in a critical section. This means that care must be taken with any custom SIGINT handlers as these are like NMIs. This is somewhat inspired by an existing port by William Davy (https://www.freertos.org/FreeRTOS-simulator-for-Linux.html) but it takes a number of different approaches to make it switch tasks reliableand there's little similarly with the original implementation. - Critical sections block scheduling/"interrupts" by blocking signals using pthread_sigmask(). This is more expensive than attempting to use flags but works reliably and is analogous to the interrupt enable/disable on real hardware. - Care is take to ensure that the SIGALRM handler (for the timer tick) is runnable only on the pthread for the running task. This makes tasks switches more straight-forward and reliable as we can suspend the thread while in the signal handler. - Task switches save/restore the critical nesting on the stack. - Only uses a single (SIGUSR1) signal which is ignored and thus GDB's default signal handling options won't trap/print on this signal. - Extra per-thread data is stored on the task's stack, making it accessible in O(1) instead of performing a O(n) lookup of the array. - Uses the task create/delete hooks in a similar way to the Windows port, rather than overloading trace points.
5 years ago
}
/*-----------------------------------------------------------*/
static void * prvWaitForStart( void * pvParams )
portable/GCC/Posix: add new port for Posix (Linux) applications This is similar to the Windows port, allowing FreeRTOS kernel applications to run as regular applications on Posix (Linux) systems. You can use this in a 32-bit or 64-bit application (although there are dynamic memory allocation trace points that do not support 64-bit addresses). Many of the same caveats of running an RTOS on a non-real-time system apply, but this is still very useful for easy debugging/testing applications in a simulated environment. In particular, it allows easy use of tools such as valgrind. You can call standard library functions from tasks but care must be taken with any that internally take mutexes or block. This includes malloc()/free() and many stdio functions (e.g., printf()). Replacement malloc(), free(), realloc(), and calloc() functions are provided which are safe. printf() needs to be called with a FreeRTOS mutex help (or called from only a single task). Each task is run in its own pthread, which makes debugging with standard tools (such as GDB) easier backtraces for individual tasks are available. Threads for non-running tasks are blocked in sigwait(). The stack for each task (thread) is allocated when the thread is created, and the stack provided during task creation is not used. This is so the stack has guard pages, to help with detecting stack overflows. Task switch is done by resuming the thread for the next task by sending it the resume signal (SIGUSR1) and then suspending the current thread. The timer interrupt uses SIGALRM and care is taken to ensure that the signal handler runs only on the thread for the current task. The additional data needed per-thread is stored at the top on the task's stack. When a running task is being deleted, its thread is marked it as dying so when we switch away from it it exits instead of suspending. This ensures that even if the idle task doesn't run, threads are deleted which allows for more threads to be created (if many tasks are being created and deleted in rapid succession). To further aid debugging, SIGINT (^C) is not blocked inside critical sections. This allows it to be used break into GDB while in a critical section. This means that care must be taken with any custom SIGINT handlers as these are like NMIs. This is somewhat inspired by an existing port by William Davy (https://www.freertos.org/FreeRTOS-simulator-for-Linux.html) but it takes a number of different approaches to make it switch tasks reliableand there's little similarly with the original implementation. - Critical sections block scheduling/"interrupts" by blocking signals using pthread_sigmask(). This is more expensive than attempting to use flags but works reliably and is analogous to the interrupt enable/disable on real hardware. - Care is take to ensure that the SIGALRM handler (for the timer tick) is runnable only on the pthread for the running task. This makes tasks switches more straight-forward and reliable as we can suspend the thread while in the signal handler. - Task switches save/restore the critical nesting on the stack. - Only uses a single (SIGUSR1) signal which is ignored and thus GDB's default signal handling options won't trap/print on this signal. - Extra per-thread data is stored on the task's stack, making it accessible in O(1) instead of performing a O(n) lookup of the array. - Uses the task create/delete hooks in a similar way to the Windows port, rather than overloading trace points.
5 years ago
{
Thread_t * pxThread = pvParams;
portable/GCC/Posix: add new port for Posix (Linux) applications This is similar to the Windows port, allowing FreeRTOS kernel applications to run as regular applications on Posix (Linux) systems. You can use this in a 32-bit or 64-bit application (although there are dynamic memory allocation trace points that do not support 64-bit addresses). Many of the same caveats of running an RTOS on a non-real-time system apply, but this is still very useful for easy debugging/testing applications in a simulated environment. In particular, it allows easy use of tools such as valgrind. You can call standard library functions from tasks but care must be taken with any that internally take mutexes or block. This includes malloc()/free() and many stdio functions (e.g., printf()). Replacement malloc(), free(), realloc(), and calloc() functions are provided which are safe. printf() needs to be called with a FreeRTOS mutex help (or called from only a single task). Each task is run in its own pthread, which makes debugging with standard tools (such as GDB) easier backtraces for individual tasks are available. Threads for non-running tasks are blocked in sigwait(). The stack for each task (thread) is allocated when the thread is created, and the stack provided during task creation is not used. This is so the stack has guard pages, to help with detecting stack overflows. Task switch is done by resuming the thread for the next task by sending it the resume signal (SIGUSR1) and then suspending the current thread. The timer interrupt uses SIGALRM and care is taken to ensure that the signal handler runs only on the thread for the current task. The additional data needed per-thread is stored at the top on the task's stack. When a running task is being deleted, its thread is marked it as dying so when we switch away from it it exits instead of suspending. This ensures that even if the idle task doesn't run, threads are deleted which allows for more threads to be created (if many tasks are being created and deleted in rapid succession). To further aid debugging, SIGINT (^C) is not blocked inside critical sections. This allows it to be used break into GDB while in a critical section. This means that care must be taken with any custom SIGINT handlers as these are like NMIs. This is somewhat inspired by an existing port by William Davy (https://www.freertos.org/FreeRTOS-simulator-for-Linux.html) but it takes a number of different approaches to make it switch tasks reliableand there's little similarly with the original implementation. - Critical sections block scheduling/"interrupts" by blocking signals using pthread_sigmask(). This is more expensive than attempting to use flags but works reliably and is analogous to the interrupt enable/disable on real hardware. - Care is take to ensure that the SIGALRM handler (for the timer tick) is runnable only on the pthread for the running task. This makes tasks switches more straight-forward and reliable as we can suspend the thread while in the signal handler. - Task switches save/restore the critical nesting on the stack. - Only uses a single (SIGUSR1) signal which is ignored and thus GDB's default signal handling options won't trap/print on this signal. - Extra per-thread data is stored on the task's stack, making it accessible in O(1) instead of performing a O(n) lookup of the array. - Uses the task create/delete hooks in a similar way to the Windows port, rather than overloading trace points.
5 years ago
prvSuspendSelf();
portable/GCC/Posix: add new port for Posix (Linux) applications This is similar to the Windows port, allowing FreeRTOS kernel applications to run as regular applications on Posix (Linux) systems. You can use this in a 32-bit or 64-bit application (although there are dynamic memory allocation trace points that do not support 64-bit addresses). Many of the same caveats of running an RTOS on a non-real-time system apply, but this is still very useful for easy debugging/testing applications in a simulated environment. In particular, it allows easy use of tools such as valgrind. You can call standard library functions from tasks but care must be taken with any that internally take mutexes or block. This includes malloc()/free() and many stdio functions (e.g., printf()). Replacement malloc(), free(), realloc(), and calloc() functions are provided which are safe. printf() needs to be called with a FreeRTOS mutex help (or called from only a single task). Each task is run in its own pthread, which makes debugging with standard tools (such as GDB) easier backtraces for individual tasks are available. Threads for non-running tasks are blocked in sigwait(). The stack for each task (thread) is allocated when the thread is created, and the stack provided during task creation is not used. This is so the stack has guard pages, to help with detecting stack overflows. Task switch is done by resuming the thread for the next task by sending it the resume signal (SIGUSR1) and then suspending the current thread. The timer interrupt uses SIGALRM and care is taken to ensure that the signal handler runs only on the thread for the current task. The additional data needed per-thread is stored at the top on the task's stack. When a running task is being deleted, its thread is marked it as dying so when we switch away from it it exits instead of suspending. This ensures that even if the idle task doesn't run, threads are deleted which allows for more threads to be created (if many tasks are being created and deleted in rapid succession). To further aid debugging, SIGINT (^C) is not blocked inside critical sections. This allows it to be used break into GDB while in a critical section. This means that care must be taken with any custom SIGINT handlers as these are like NMIs. This is somewhat inspired by an existing port by William Davy (https://www.freertos.org/FreeRTOS-simulator-for-Linux.html) but it takes a number of different approaches to make it switch tasks reliableand there's little similarly with the original implementation. - Critical sections block scheduling/"interrupts" by blocking signals using pthread_sigmask(). This is more expensive than attempting to use flags but works reliably and is analogous to the interrupt enable/disable on real hardware. - Care is take to ensure that the SIGALRM handler (for the timer tick) is runnable only on the pthread for the running task. This makes tasks switches more straight-forward and reliable as we can suspend the thread while in the signal handler. - Task switches save/restore the critical nesting on the stack. - Only uses a single (SIGUSR1) signal which is ignored and thus GDB's default signal handling options won't trap/print on this signal. - Extra per-thread data is stored on the task's stack, making it accessible in O(1) instead of performing a O(n) lookup of the array. - Uses the task create/delete hooks in a similar way to the Windows port, rather than overloading trace points.
5 years ago
/* Resumed for the first time, unblocks all signals. */
uxCriticalNesting = 0;
vPortEnableInterrupts();
portable/GCC/Posix: add new port for Posix (Linux) applications This is similar to the Windows port, allowing FreeRTOS kernel applications to run as regular applications on Posix (Linux) systems. You can use this in a 32-bit or 64-bit application (although there are dynamic memory allocation trace points that do not support 64-bit addresses). Many of the same caveats of running an RTOS on a non-real-time system apply, but this is still very useful for easy debugging/testing applications in a simulated environment. In particular, it allows easy use of tools such as valgrind. You can call standard library functions from tasks but care must be taken with any that internally take mutexes or block. This includes malloc()/free() and many stdio functions (e.g., printf()). Replacement malloc(), free(), realloc(), and calloc() functions are provided which are safe. printf() needs to be called with a FreeRTOS mutex help (or called from only a single task). Each task is run in its own pthread, which makes debugging with standard tools (such as GDB) easier backtraces for individual tasks are available. Threads for non-running tasks are blocked in sigwait(). The stack for each task (thread) is allocated when the thread is created, and the stack provided during task creation is not used. This is so the stack has guard pages, to help with detecting stack overflows. Task switch is done by resuming the thread for the next task by sending it the resume signal (SIGUSR1) and then suspending the current thread. The timer interrupt uses SIGALRM and care is taken to ensure that the signal handler runs only on the thread for the current task. The additional data needed per-thread is stored at the top on the task's stack. When a running task is being deleted, its thread is marked it as dying so when we switch away from it it exits instead of suspending. This ensures that even if the idle task doesn't run, threads are deleted which allows for more threads to be created (if many tasks are being created and deleted in rapid succession). To further aid debugging, SIGINT (^C) is not blocked inside critical sections. This allows it to be used break into GDB while in a critical section. This means that care must be taken with any custom SIGINT handlers as these are like NMIs. This is somewhat inspired by an existing port by William Davy (https://www.freertos.org/FreeRTOS-simulator-for-Linux.html) but it takes a number of different approaches to make it switch tasks reliableand there's little similarly with the original implementation. - Critical sections block scheduling/"interrupts" by blocking signals using pthread_sigmask(). This is more expensive than attempting to use flags but works reliably and is analogous to the interrupt enable/disable on real hardware. - Care is take to ensure that the SIGALRM handler (for the timer tick) is runnable only on the pthread for the running task. This makes tasks switches more straight-forward and reliable as we can suspend the thread while in the signal handler. - Task switches save/restore the critical nesting on the stack. - Only uses a single (SIGUSR1) signal which is ignored and thus GDB's default signal handling options won't trap/print on this signal. - Extra per-thread data is stored on the task's stack, making it accessible in O(1) instead of performing a O(n) lookup of the array. - Uses the task create/delete hooks in a similar way to the Windows port, rather than overloading trace points.
5 years ago
/* Call the task's entry point. */
pxThread->pxCode( pxThread->pvParams );
portable/GCC/Posix: add new port for Posix (Linux) applications This is similar to the Windows port, allowing FreeRTOS kernel applications to run as regular applications on Posix (Linux) systems. You can use this in a 32-bit or 64-bit application (although there are dynamic memory allocation trace points that do not support 64-bit addresses). Many of the same caveats of running an RTOS on a non-real-time system apply, but this is still very useful for easy debugging/testing applications in a simulated environment. In particular, it allows easy use of tools such as valgrind. You can call standard library functions from tasks but care must be taken with any that internally take mutexes or block. This includes malloc()/free() and many stdio functions (e.g., printf()). Replacement malloc(), free(), realloc(), and calloc() functions are provided which are safe. printf() needs to be called with a FreeRTOS mutex help (or called from only a single task). Each task is run in its own pthread, which makes debugging with standard tools (such as GDB) easier backtraces for individual tasks are available. Threads for non-running tasks are blocked in sigwait(). The stack for each task (thread) is allocated when the thread is created, and the stack provided during task creation is not used. This is so the stack has guard pages, to help with detecting stack overflows. Task switch is done by resuming the thread for the next task by sending it the resume signal (SIGUSR1) and then suspending the current thread. The timer interrupt uses SIGALRM and care is taken to ensure that the signal handler runs only on the thread for the current task. The additional data needed per-thread is stored at the top on the task's stack. When a running task is being deleted, its thread is marked it as dying so when we switch away from it it exits instead of suspending. This ensures that even if the idle task doesn't run, threads are deleted which allows for more threads to be created (if many tasks are being created and deleted in rapid succession). To further aid debugging, SIGINT (^C) is not blocked inside critical sections. This allows it to be used break into GDB while in a critical section. This means that care must be taken with any custom SIGINT handlers as these are like NMIs. This is somewhat inspired by an existing port by William Davy (https://www.freertos.org/FreeRTOS-simulator-for-Linux.html) but it takes a number of different approaches to make it switch tasks reliableand there's little similarly with the original implementation. - Critical sections block scheduling/"interrupts" by blocking signals using pthread_sigmask(). This is more expensive than attempting to use flags but works reliably and is analogous to the interrupt enable/disable on real hardware. - Care is take to ensure that the SIGALRM handler (for the timer tick) is runnable only on the pthread for the running task. This makes tasks switches more straight-forward and reliable as we can suspend the thread while in the signal handler. - Task switches save/restore the critical nesting on the stack. - Only uses a single (SIGUSR1) signal which is ignored and thus GDB's default signal handling options won't trap/print on this signal. - Extra per-thread data is stored on the task's stack, making it accessible in O(1) instead of performing a O(n) lookup of the array. - Uses the task create/delete hooks in a similar way to the Windows port, rather than overloading trace points.
5 years ago
return NULL;
portable/GCC/Posix: add new port for Posix (Linux) applications This is similar to the Windows port, allowing FreeRTOS kernel applications to run as regular applications on Posix (Linux) systems. You can use this in a 32-bit or 64-bit application (although there are dynamic memory allocation trace points that do not support 64-bit addresses). Many of the same caveats of running an RTOS on a non-real-time system apply, but this is still very useful for easy debugging/testing applications in a simulated environment. In particular, it allows easy use of tools such as valgrind. You can call standard library functions from tasks but care must be taken with any that internally take mutexes or block. This includes malloc()/free() and many stdio functions (e.g., printf()). Replacement malloc(), free(), realloc(), and calloc() functions are provided which are safe. printf() needs to be called with a FreeRTOS mutex help (or called from only a single task). Each task is run in its own pthread, which makes debugging with standard tools (such as GDB) easier backtraces for individual tasks are available. Threads for non-running tasks are blocked in sigwait(). The stack for each task (thread) is allocated when the thread is created, and the stack provided during task creation is not used. This is so the stack has guard pages, to help with detecting stack overflows. Task switch is done by resuming the thread for the next task by sending it the resume signal (SIGUSR1) and then suspending the current thread. The timer interrupt uses SIGALRM and care is taken to ensure that the signal handler runs only on the thread for the current task. The additional data needed per-thread is stored at the top on the task's stack. When a running task is being deleted, its thread is marked it as dying so when we switch away from it it exits instead of suspending. This ensures that even if the idle task doesn't run, threads are deleted which allows for more threads to be created (if many tasks are being created and deleted in rapid succession). To further aid debugging, SIGINT (^C) is not blocked inside critical sections. This allows it to be used break into GDB while in a critical section. This means that care must be taken with any custom SIGINT handlers as these are like NMIs. This is somewhat inspired by an existing port by William Davy (https://www.freertos.org/FreeRTOS-simulator-for-Linux.html) but it takes a number of different approaches to make it switch tasks reliableand there's little similarly with the original implementation. - Critical sections block scheduling/"interrupts" by blocking signals using pthread_sigmask(). This is more expensive than attempting to use flags but works reliably and is analogous to the interrupt enable/disable on real hardware. - Care is take to ensure that the SIGALRM handler (for the timer tick) is runnable only on the pthread for the running task. This makes tasks switches more straight-forward and reliable as we can suspend the thread while in the signal handler. - Task switches save/restore the critical nesting on the stack. - Only uses a single (SIGUSR1) signal which is ignored and thus GDB's default signal handling options won't trap/print on this signal. - Extra per-thread data is stored on the task's stack, making it accessible in O(1) instead of performing a O(n) lookup of the array. - Uses the task create/delete hooks in a similar way to the Windows port, rather than overloading trace points.
5 years ago
}
/*-----------------------------------------------------------*/
static void prvSwitchThread( Thread_t * pxThreadToResume,
Thread_t * pxThreadToSuspend )
portable/GCC/Posix: add new port for Posix (Linux) applications This is similar to the Windows port, allowing FreeRTOS kernel applications to run as regular applications on Posix (Linux) systems. You can use this in a 32-bit or 64-bit application (although there are dynamic memory allocation trace points that do not support 64-bit addresses). Many of the same caveats of running an RTOS on a non-real-time system apply, but this is still very useful for easy debugging/testing applications in a simulated environment. In particular, it allows easy use of tools such as valgrind. You can call standard library functions from tasks but care must be taken with any that internally take mutexes or block. This includes malloc()/free() and many stdio functions (e.g., printf()). Replacement malloc(), free(), realloc(), and calloc() functions are provided which are safe. printf() needs to be called with a FreeRTOS mutex help (or called from only a single task). Each task is run in its own pthread, which makes debugging with standard tools (such as GDB) easier backtraces for individual tasks are available. Threads for non-running tasks are blocked in sigwait(). The stack for each task (thread) is allocated when the thread is created, and the stack provided during task creation is not used. This is so the stack has guard pages, to help with detecting stack overflows. Task switch is done by resuming the thread for the next task by sending it the resume signal (SIGUSR1) and then suspending the current thread. The timer interrupt uses SIGALRM and care is taken to ensure that the signal handler runs only on the thread for the current task. The additional data needed per-thread is stored at the top on the task's stack. When a running task is being deleted, its thread is marked it as dying so when we switch away from it it exits instead of suspending. This ensures that even if the idle task doesn't run, threads are deleted which allows for more threads to be created (if many tasks are being created and deleted in rapid succession). To further aid debugging, SIGINT (^C) is not blocked inside critical sections. This allows it to be used break into GDB while in a critical section. This means that care must be taken with any custom SIGINT handlers as these are like NMIs. This is somewhat inspired by an existing port by William Davy (https://www.freertos.org/FreeRTOS-simulator-for-Linux.html) but it takes a number of different approaches to make it switch tasks reliableand there's little similarly with the original implementation. - Critical sections block scheduling/"interrupts" by blocking signals using pthread_sigmask(). This is more expensive than attempting to use flags but works reliably and is analogous to the interrupt enable/disable on real hardware. - Care is take to ensure that the SIGALRM handler (for the timer tick) is runnable only on the pthread for the running task. This makes tasks switches more straight-forward and reliable as we can suspend the thread while in the signal handler. - Task switches save/restore the critical nesting on the stack. - Only uses a single (SIGUSR1) signal which is ignored and thus GDB's default signal handling options won't trap/print on this signal. - Extra per-thread data is stored on the task's stack, making it accessible in O(1) instead of performing a O(n) lookup of the array. - Uses the task create/delete hooks in a similar way to the Windows port, rather than overloading trace points.
5 years ago
{
BaseType_t uxSavedCriticalNesting;
if( pxThreadToSuspend != pxThreadToResume )
{
/*
* Switch tasks.
*
* The critical section nesting is per-task, so save it on the
* stack of the current (suspending thread), restoring it when
* we switch back to this task.
*/
uxSavedCriticalNesting = uxCriticalNesting;
prvResumeThread( pxThreadToResume->pthread );
if( pxThreadToSuspend->xDying )
{
pthread_exit( NULL );
}
prvSuspendSelf();
uxCriticalNesting = uxSavedCriticalNesting;
}
portable/GCC/Posix: add new port for Posix (Linux) applications This is similar to the Windows port, allowing FreeRTOS kernel applications to run as regular applications on Posix (Linux) systems. You can use this in a 32-bit or 64-bit application (although there are dynamic memory allocation trace points that do not support 64-bit addresses). Many of the same caveats of running an RTOS on a non-real-time system apply, but this is still very useful for easy debugging/testing applications in a simulated environment. In particular, it allows easy use of tools such as valgrind. You can call standard library functions from tasks but care must be taken with any that internally take mutexes or block. This includes malloc()/free() and many stdio functions (e.g., printf()). Replacement malloc(), free(), realloc(), and calloc() functions are provided which are safe. printf() needs to be called with a FreeRTOS mutex help (or called from only a single task). Each task is run in its own pthread, which makes debugging with standard tools (such as GDB) easier backtraces for individual tasks are available. Threads for non-running tasks are blocked in sigwait(). The stack for each task (thread) is allocated when the thread is created, and the stack provided during task creation is not used. This is so the stack has guard pages, to help with detecting stack overflows. Task switch is done by resuming the thread for the next task by sending it the resume signal (SIGUSR1) and then suspending the current thread. The timer interrupt uses SIGALRM and care is taken to ensure that the signal handler runs only on the thread for the current task. The additional data needed per-thread is stored at the top on the task's stack. When a running task is being deleted, its thread is marked it as dying so when we switch away from it it exits instead of suspending. This ensures that even if the idle task doesn't run, threads are deleted which allows for more threads to be created (if many tasks are being created and deleted in rapid succession). To further aid debugging, SIGINT (^C) is not blocked inside critical sections. This allows it to be used break into GDB while in a critical section. This means that care must be taken with any custom SIGINT handlers as these are like NMIs. This is somewhat inspired by an existing port by William Davy (https://www.freertos.org/FreeRTOS-simulator-for-Linux.html) but it takes a number of different approaches to make it switch tasks reliableand there's little similarly with the original implementation. - Critical sections block scheduling/"interrupts" by blocking signals using pthread_sigmask(). This is more expensive than attempting to use flags but works reliably and is analogous to the interrupt enable/disable on real hardware. - Care is take to ensure that the SIGALRM handler (for the timer tick) is runnable only on the pthread for the running task. This makes tasks switches more straight-forward and reliable as we can suspend the thread while in the signal handler. - Task switches save/restore the critical nesting on the stack. - Only uses a single (SIGUSR1) signal which is ignored and thus GDB's default signal handling options won't trap/print on this signal. - Extra per-thread data is stored on the task's stack, making it accessible in O(1) instead of performing a O(n) lookup of the array. - Uses the task create/delete hooks in a similar way to the Windows port, rather than overloading trace points.
5 years ago
}
/*-----------------------------------------------------------*/
static void prvSuspendSelf( void )
{
int iSig;
/*
* Suspend this thread by waiting for a SIG_RESUME signal.
*
* A suspended thread must not handle signals (interrupts) so
* all signals must be blocked by calling this from:
*
* - Inside a critical section (vPortEnterCritical() /
* vPortExitCritical()).
*
* - From a signal handler that has all signals masked.
*
* - A thread with all signals blocked with pthread_sigmask().
*/
sigwait( &xResumeSignals, &iSig );
portable/GCC/Posix: add new port for Posix (Linux) applications This is similar to the Windows port, allowing FreeRTOS kernel applications to run as regular applications on Posix (Linux) systems. You can use this in a 32-bit or 64-bit application (although there are dynamic memory allocation trace points that do not support 64-bit addresses). Many of the same caveats of running an RTOS on a non-real-time system apply, but this is still very useful for easy debugging/testing applications in a simulated environment. In particular, it allows easy use of tools such as valgrind. You can call standard library functions from tasks but care must be taken with any that internally take mutexes or block. This includes malloc()/free() and many stdio functions (e.g., printf()). Replacement malloc(), free(), realloc(), and calloc() functions are provided which are safe. printf() needs to be called with a FreeRTOS mutex help (or called from only a single task). Each task is run in its own pthread, which makes debugging with standard tools (such as GDB) easier backtraces for individual tasks are available. Threads for non-running tasks are blocked in sigwait(). The stack for each task (thread) is allocated when the thread is created, and the stack provided during task creation is not used. This is so the stack has guard pages, to help with detecting stack overflows. Task switch is done by resuming the thread for the next task by sending it the resume signal (SIGUSR1) and then suspending the current thread. The timer interrupt uses SIGALRM and care is taken to ensure that the signal handler runs only on the thread for the current task. The additional data needed per-thread is stored at the top on the task's stack. When a running task is being deleted, its thread is marked it as dying so when we switch away from it it exits instead of suspending. This ensures that even if the idle task doesn't run, threads are deleted which allows for more threads to be created (if many tasks are being created and deleted in rapid succession). To further aid debugging, SIGINT (^C) is not blocked inside critical sections. This allows it to be used break into GDB while in a critical section. This means that care must be taken with any custom SIGINT handlers as these are like NMIs. This is somewhat inspired by an existing port by William Davy (https://www.freertos.org/FreeRTOS-simulator-for-Linux.html) but it takes a number of different approaches to make it switch tasks reliableand there's little similarly with the original implementation. - Critical sections block scheduling/"interrupts" by blocking signals using pthread_sigmask(). This is more expensive than attempting to use flags but works reliably and is analogous to the interrupt enable/disable on real hardware. - Care is take to ensure that the SIGALRM handler (for the timer tick) is runnable only on the pthread for the running task. This makes tasks switches more straight-forward and reliable as we can suspend the thread while in the signal handler. - Task switches save/restore the critical nesting on the stack. - Only uses a single (SIGUSR1) signal which is ignored and thus GDB's default signal handling options won't trap/print on this signal. - Extra per-thread data is stored on the task's stack, making it accessible in O(1) instead of performing a O(n) lookup of the array. - Uses the task create/delete hooks in a similar way to the Windows port, rather than overloading trace points.
5 years ago
}
/*-----------------------------------------------------------*/
static void prvResumeThread( pthread_t xThreadId )
{
if( pthread_self() != xThreadId )
{
pthread_kill( xThreadId, SIG_RESUME );
}
portable/GCC/Posix: add new port for Posix (Linux) applications This is similar to the Windows port, allowing FreeRTOS kernel applications to run as regular applications on Posix (Linux) systems. You can use this in a 32-bit or 64-bit application (although there are dynamic memory allocation trace points that do not support 64-bit addresses). Many of the same caveats of running an RTOS on a non-real-time system apply, but this is still very useful for easy debugging/testing applications in a simulated environment. In particular, it allows easy use of tools such as valgrind. You can call standard library functions from tasks but care must be taken with any that internally take mutexes or block. This includes malloc()/free() and many stdio functions (e.g., printf()). Replacement malloc(), free(), realloc(), and calloc() functions are provided which are safe. printf() needs to be called with a FreeRTOS mutex help (or called from only a single task). Each task is run in its own pthread, which makes debugging with standard tools (such as GDB) easier backtraces for individual tasks are available. Threads for non-running tasks are blocked in sigwait(). The stack for each task (thread) is allocated when the thread is created, and the stack provided during task creation is not used. This is so the stack has guard pages, to help with detecting stack overflows. Task switch is done by resuming the thread for the next task by sending it the resume signal (SIGUSR1) and then suspending the current thread. The timer interrupt uses SIGALRM and care is taken to ensure that the signal handler runs only on the thread for the current task. The additional data needed per-thread is stored at the top on the task's stack. When a running task is being deleted, its thread is marked it as dying so when we switch away from it it exits instead of suspending. This ensures that even if the idle task doesn't run, threads are deleted which allows for more threads to be created (if many tasks are being created and deleted in rapid succession). To further aid debugging, SIGINT (^C) is not blocked inside critical sections. This allows it to be used break into GDB while in a critical section. This means that care must be taken with any custom SIGINT handlers as these are like NMIs. This is somewhat inspired by an existing port by William Davy (https://www.freertos.org/FreeRTOS-simulator-for-Linux.html) but it takes a number of different approaches to make it switch tasks reliableand there's little similarly with the original implementation. - Critical sections block scheduling/"interrupts" by blocking signals using pthread_sigmask(). This is more expensive than attempting to use flags but works reliably and is analogous to the interrupt enable/disable on real hardware. - Care is take to ensure that the SIGALRM handler (for the timer tick) is runnable only on the pthread for the running task. This makes tasks switches more straight-forward and reliable as we can suspend the thread while in the signal handler. - Task switches save/restore the critical nesting on the stack. - Only uses a single (SIGUSR1) signal which is ignored and thus GDB's default signal handling options won't trap/print on this signal. - Extra per-thread data is stored on the task's stack, making it accessible in O(1) instead of performing a O(n) lookup of the array. - Uses the task create/delete hooks in a similar way to the Windows port, rather than overloading trace points.
5 years ago
}
/*-----------------------------------------------------------*/
static void prvSetupSignalsAndSchedulerPolicy( void )
{
struct sigaction sigresume, sigtick;
int iRet;
hMainThread = pthread_self();
/* Initialise common signal masks. */
sigemptyset( &xResumeSignals );
sigaddset( &xResumeSignals, SIG_RESUME );
sigfillset( &xAllSignals );
/* Don't block SIGINT so this can be used to break into GDB while
* in a critical section. */
sigdelset( &xAllSignals, SIGINT );
/*
* Block all signals in this thread so all new threads
* inherits this mask.
*
* When a thread is resumed for the first time, all signals
* will be unblocked.
*/
( void ) pthread_sigmask( SIG_SETMASK, &xAllSignals,
&xSchedulerOriginalSignalMask );
/* SIG_RESUME is only used with sigwait() so doesn't need a
* handler. */
sigresume.sa_flags = 0;
sigresume.sa_handler = SIG_IGN;
sigfillset( &sigresume.sa_mask );
sigtick.sa_flags = 0;
sigtick.sa_handler = vPortSystemTickHandler;
sigfillset( &sigtick.sa_mask );
iRet = sigaction( SIG_RESUME, &sigresume, NULL );
if( iRet )
{
prvFatalError( "sigaction", errno );
}
iRet = sigaction( SIGALRM, &sigtick, NULL );
if( iRet )
{
prvFatalError( "sigaction", errno );
}
portable/GCC/Posix: add new port for Posix (Linux) applications This is similar to the Windows port, allowing FreeRTOS kernel applications to run as regular applications on Posix (Linux) systems. You can use this in a 32-bit or 64-bit application (although there are dynamic memory allocation trace points that do not support 64-bit addresses). Many of the same caveats of running an RTOS on a non-real-time system apply, but this is still very useful for easy debugging/testing applications in a simulated environment. In particular, it allows easy use of tools such as valgrind. You can call standard library functions from tasks but care must be taken with any that internally take mutexes or block. This includes malloc()/free() and many stdio functions (e.g., printf()). Replacement malloc(), free(), realloc(), and calloc() functions are provided which are safe. printf() needs to be called with a FreeRTOS mutex help (or called from only a single task). Each task is run in its own pthread, which makes debugging with standard tools (such as GDB) easier backtraces for individual tasks are available. Threads for non-running tasks are blocked in sigwait(). The stack for each task (thread) is allocated when the thread is created, and the stack provided during task creation is not used. This is so the stack has guard pages, to help with detecting stack overflows. Task switch is done by resuming the thread for the next task by sending it the resume signal (SIGUSR1) and then suspending the current thread. The timer interrupt uses SIGALRM and care is taken to ensure that the signal handler runs only on the thread for the current task. The additional data needed per-thread is stored at the top on the task's stack. When a running task is being deleted, its thread is marked it as dying so when we switch away from it it exits instead of suspending. This ensures that even if the idle task doesn't run, threads are deleted which allows for more threads to be created (if many tasks are being created and deleted in rapid succession). To further aid debugging, SIGINT (^C) is not blocked inside critical sections. This allows it to be used break into GDB while in a critical section. This means that care must be taken with any custom SIGINT handlers as these are like NMIs. This is somewhat inspired by an existing port by William Davy (https://www.freertos.org/FreeRTOS-simulator-for-Linux.html) but it takes a number of different approaches to make it switch tasks reliableand there's little similarly with the original implementation. - Critical sections block scheduling/"interrupts" by blocking signals using pthread_sigmask(). This is more expensive than attempting to use flags but works reliably and is analogous to the interrupt enable/disable on real hardware. - Care is take to ensure that the SIGALRM handler (for the timer tick) is runnable only on the pthread for the running task. This makes tasks switches more straight-forward and reliable as we can suspend the thread while in the signal handler. - Task switches save/restore the critical nesting on the stack. - Only uses a single (SIGUSR1) signal which is ignored and thus GDB's default signal handling options won't trap/print on this signal. - Extra per-thread data is stored on the task's stack, making it accessible in O(1) instead of performing a O(n) lookup of the array. - Uses the task create/delete hooks in a similar way to the Windows port, rather than overloading trace points.
5 years ago
}
/*-----------------------------------------------------------*/
unsigned long ulPortGetRunTime( void )
{
struct tms xTimes;
portable/GCC/Posix: add new port for Posix (Linux) applications This is similar to the Windows port, allowing FreeRTOS kernel applications to run as regular applications on Posix (Linux) systems. You can use this in a 32-bit or 64-bit application (although there are dynamic memory allocation trace points that do not support 64-bit addresses). Many of the same caveats of running an RTOS on a non-real-time system apply, but this is still very useful for easy debugging/testing applications in a simulated environment. In particular, it allows easy use of tools such as valgrind. You can call standard library functions from tasks but care must be taken with any that internally take mutexes or block. This includes malloc()/free() and many stdio functions (e.g., printf()). Replacement malloc(), free(), realloc(), and calloc() functions are provided which are safe. printf() needs to be called with a FreeRTOS mutex help (or called from only a single task). Each task is run in its own pthread, which makes debugging with standard tools (such as GDB) easier backtraces for individual tasks are available. Threads for non-running tasks are blocked in sigwait(). The stack for each task (thread) is allocated when the thread is created, and the stack provided during task creation is not used. This is so the stack has guard pages, to help with detecting stack overflows. Task switch is done by resuming the thread for the next task by sending it the resume signal (SIGUSR1) and then suspending the current thread. The timer interrupt uses SIGALRM and care is taken to ensure that the signal handler runs only on the thread for the current task. The additional data needed per-thread is stored at the top on the task's stack. When a running task is being deleted, its thread is marked it as dying so when we switch away from it it exits instead of suspending. This ensures that even if the idle task doesn't run, threads are deleted which allows for more threads to be created (if many tasks are being created and deleted in rapid succession). To further aid debugging, SIGINT (^C) is not blocked inside critical sections. This allows it to be used break into GDB while in a critical section. This means that care must be taken with any custom SIGINT handlers as these are like NMIs. This is somewhat inspired by an existing port by William Davy (https://www.freertos.org/FreeRTOS-simulator-for-Linux.html) but it takes a number of different approaches to make it switch tasks reliableand there's little similarly with the original implementation. - Critical sections block scheduling/"interrupts" by blocking signals using pthread_sigmask(). This is more expensive than attempting to use flags but works reliably and is analogous to the interrupt enable/disable on real hardware. - Care is take to ensure that the SIGALRM handler (for the timer tick) is runnable only on the pthread for the running task. This makes tasks switches more straight-forward and reliable as we can suspend the thread while in the signal handler. - Task switches save/restore the critical nesting on the stack. - Only uses a single (SIGUSR1) signal which is ignored and thus GDB's default signal handling options won't trap/print on this signal. - Extra per-thread data is stored on the task's stack, making it accessible in O(1) instead of performing a O(n) lookup of the array. - Uses the task create/delete hooks in a similar way to the Windows port, rather than overloading trace points.
5 years ago
times( &xTimes );
portable/GCC/Posix: add new port for Posix (Linux) applications This is similar to the Windows port, allowing FreeRTOS kernel applications to run as regular applications on Posix (Linux) systems. You can use this in a 32-bit or 64-bit application (although there are dynamic memory allocation trace points that do not support 64-bit addresses). Many of the same caveats of running an RTOS on a non-real-time system apply, but this is still very useful for easy debugging/testing applications in a simulated environment. In particular, it allows easy use of tools such as valgrind. You can call standard library functions from tasks but care must be taken with any that internally take mutexes or block. This includes malloc()/free() and many stdio functions (e.g., printf()). Replacement malloc(), free(), realloc(), and calloc() functions are provided which are safe. printf() needs to be called with a FreeRTOS mutex help (or called from only a single task). Each task is run in its own pthread, which makes debugging with standard tools (such as GDB) easier backtraces for individual tasks are available. Threads for non-running tasks are blocked in sigwait(). The stack for each task (thread) is allocated when the thread is created, and the stack provided during task creation is not used. This is so the stack has guard pages, to help with detecting stack overflows. Task switch is done by resuming the thread for the next task by sending it the resume signal (SIGUSR1) and then suspending the current thread. The timer interrupt uses SIGALRM and care is taken to ensure that the signal handler runs only on the thread for the current task. The additional data needed per-thread is stored at the top on the task's stack. When a running task is being deleted, its thread is marked it as dying so when we switch away from it it exits instead of suspending. This ensures that even if the idle task doesn't run, threads are deleted which allows for more threads to be created (if many tasks are being created and deleted in rapid succession). To further aid debugging, SIGINT (^C) is not blocked inside critical sections. This allows it to be used break into GDB while in a critical section. This means that care must be taken with any custom SIGINT handlers as these are like NMIs. This is somewhat inspired by an existing port by William Davy (https://www.freertos.org/FreeRTOS-simulator-for-Linux.html) but it takes a number of different approaches to make it switch tasks reliableand there's little similarly with the original implementation. - Critical sections block scheduling/"interrupts" by blocking signals using pthread_sigmask(). This is more expensive than attempting to use flags but works reliably and is analogous to the interrupt enable/disable on real hardware. - Care is take to ensure that the SIGALRM handler (for the timer tick) is runnable only on the pthread for the running task. This makes tasks switches more straight-forward and reliable as we can suspend the thread while in the signal handler. - Task switches save/restore the critical nesting on the stack. - Only uses a single (SIGUSR1) signal which is ignored and thus GDB's default signal handling options won't trap/print on this signal. - Extra per-thread data is stored on the task's stack, making it accessible in O(1) instead of performing a O(n) lookup of the array. - Uses the task create/delete hooks in a similar way to the Windows port, rather than overloading trace points.
5 years ago
return ( unsigned long ) xTimes.tms_utime;
portable/GCC/Posix: add new port for Posix (Linux) applications This is similar to the Windows port, allowing FreeRTOS kernel applications to run as regular applications on Posix (Linux) systems. You can use this in a 32-bit or 64-bit application (although there are dynamic memory allocation trace points that do not support 64-bit addresses). Many of the same caveats of running an RTOS on a non-real-time system apply, but this is still very useful for easy debugging/testing applications in a simulated environment. In particular, it allows easy use of tools such as valgrind. You can call standard library functions from tasks but care must be taken with any that internally take mutexes or block. This includes malloc()/free() and many stdio functions (e.g., printf()). Replacement malloc(), free(), realloc(), and calloc() functions are provided which are safe. printf() needs to be called with a FreeRTOS mutex help (or called from only a single task). Each task is run in its own pthread, which makes debugging with standard tools (such as GDB) easier backtraces for individual tasks are available. Threads for non-running tasks are blocked in sigwait(). The stack for each task (thread) is allocated when the thread is created, and the stack provided during task creation is not used. This is so the stack has guard pages, to help with detecting stack overflows. Task switch is done by resuming the thread for the next task by sending it the resume signal (SIGUSR1) and then suspending the current thread. The timer interrupt uses SIGALRM and care is taken to ensure that the signal handler runs only on the thread for the current task. The additional data needed per-thread is stored at the top on the task's stack. When a running task is being deleted, its thread is marked it as dying so when we switch away from it it exits instead of suspending. This ensures that even if the idle task doesn't run, threads are deleted which allows for more threads to be created (if many tasks are being created and deleted in rapid succession). To further aid debugging, SIGINT (^C) is not blocked inside critical sections. This allows it to be used break into GDB while in a critical section. This means that care must be taken with any custom SIGINT handlers as these are like NMIs. This is somewhat inspired by an existing port by William Davy (https://www.freertos.org/FreeRTOS-simulator-for-Linux.html) but it takes a number of different approaches to make it switch tasks reliableand there's little similarly with the original implementation. - Critical sections block scheduling/"interrupts" by blocking signals using pthread_sigmask(). This is more expensive than attempting to use flags but works reliably and is analogous to the interrupt enable/disable on real hardware. - Care is take to ensure that the SIGALRM handler (for the timer tick) is runnable only on the pthread for the running task. This makes tasks switches more straight-forward and reliable as we can suspend the thread while in the signal handler. - Task switches save/restore the critical nesting on the stack. - Only uses a single (SIGUSR1) signal which is ignored and thus GDB's default signal handling options won't trap/print on this signal. - Extra per-thread data is stored on the task's stack, making it accessible in O(1) instead of performing a O(n) lookup of the array. - Uses the task create/delete hooks in a similar way to the Windows port, rather than overloading trace points.
5 years ago
}
/*-----------------------------------------------------------*/