This repository has been archived on 2023-11-05. You can view files and clone it, but cannot push or open issues or pull requests.
FreeRTOS-Kernel/portable/ThirdParty/GCC/Posix/portmacro.h

135 lines
4.8 KiB
C
Raw Normal View History

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.
2020-03-05 02:00:41 +08:00
/*
* FreeRTOS Kernel V10.3.0
* Copyright 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.
*
* https://www.FreeRTOS.org
* https://github.com/FreeRTOS
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.
2020-03-05 02:00:41 +08:00
*
2020-07-08 08:42:07 +08:00
* 1 tab == 4 spaces!
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.
2020-03-05 02:00:41 +08:00
*/
#ifndef PORTMACRO_H
#define PORTMACRO_H
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.
2020-03-05 02:00:41 +08:00
#ifdef __cplusplus
extern "C" {
#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.
2020-03-05 02:00:41 +08:00
#include <limits.h>
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.
2020-03-05 02:00:41 +08:00
/*-----------------------------------------------------------
* Port specific definitions.
*
* The settings in this file configure FreeRTOS correctly for the
* given hardware and compiler.
*
* These settings should not be altered.
*-----------------------------------------------------------
*/
/* Type definitions. */
#define portCHAR char
#define portFLOAT float
#define portDOUBLE double
#define portLONG long
#define portSHORT short
#define portSTACK_TYPE unsigned long
#define portBASE_TYPE long
#define portPOINTER_SIZE_TYPE intptr_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.
2020-03-05 02:00:41 +08:00
typedef portSTACK_TYPE StackType_t;
typedef long BaseType_t;
typedef unsigned long UBaseType_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.
2020-03-05 02:00:41 +08:00
typedef unsigned long TickType_t;
#define portMAX_DELAY ( TickType_t ) ULONG_MAX
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.
2020-03-05 02:00:41 +08:00
#define portTICK_TYPE_IS_ATOMIC 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.
2020-03-05 02:00:41 +08:00
/*-----------------------------------------------------------*/
/* Architecture specifics. */
#define portSTACK_GROWTH ( -1 )
#define portHAS_STACK_OVERFLOW_CHECKING ( 1 )
#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ )
#define portTICK_RATE_MICROSECONDS ( ( portTickType ) 1000000 / configTICK_RATE_HZ )
#define portBYTE_ALIGNMENT 8
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.
2020-03-05 02:00:41 +08:00
/*-----------------------------------------------------------*/
/* Scheduler utilities. */
extern void vPortYield( 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.
2020-03-05 02:00:41 +08:00
#define portYIELD() vPortYield()
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.
2020-03-05 02:00:41 +08:00
#define portEND_SWITCHING_ISR( xSwitchRequired ) if( xSwitchRequired != pdFALSE ) vPortYield()
#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x )
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.
2020-03-05 02:00:41 +08:00
/*-----------------------------------------------------------*/
/* Critical section management. */
extern void vPortDisableInterrupts( void );
extern void vPortEnableInterrupts( void );
#define portSET_INTERRUPT_MASK() ( vPortDisableInterrupts() )
#define portCLEAR_INTERRUPT_MASK() ( vPortEnableInterrupts() )
extern portBASE_TYPE xPortSetInterruptMask( void );
extern void vPortClearInterruptMask( portBASE_TYPE xMask );
extern void vPortEnterCritical( void );
extern void vPortExitCritical( void );
#define portSET_INTERRUPT_MASK_FROM_ISR() xPortSetInterruptMask()
#define portCLEAR_INTERRUPT_MASK_FROM_ISR(x) vPortClearInterruptMask(x)
#define portDISABLE_INTERRUPTS() portSET_INTERRUPT_MASK()
#define portENABLE_INTERRUPTS() portCLEAR_INTERRUPT_MASK()
#define portENTER_CRITICAL() vPortEnterCritical()
#define portEXIT_CRITICAL() 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.
2020-03-05 02:00:41 +08:00
/*-----------------------------------------------------------*/
extern void vPortThreadDying( void *pxTaskToDelete, volatile BaseType_t *pxPendYield );
extern void vPortCancelThread( void *pxTaskToDelete );
#define portPRE_TASK_DELETE_HOOK( pvTaskToDelete, pxPendYield ) vPortThreadDying( ( pvTaskToDelete ), ( pxPendYield ) )
#define portCLEAN_UP_TCB( pxTCB ) vPortCancelThread( pxTCB )
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.
2020-03-05 02:00:41 +08:00
/*-----------------------------------------------------------*/
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void *pvParameters )
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( 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.
2020-03-05 02:00:41 +08:00
/*-----------------------------------------------------------*/
/*
* Tasks run in their own pthreads and context switches between them
* are always a full memory barrier. ISRs are emulated as signals
* which also imply a full memory barrier.
*
* Thus, only a compilier barrier is needed to prevent the compiler
* reordering.
*/
#define portMEMORY_BARRIER() __asm volatile( "" ::: "memory" )
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.
2020-03-05 02:00:41 +08:00
extern unsigned long ulPortGetRunTime( void );
#define portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() /* no-op */
#define portGET_RUN_TIME_COUNTER_VALUE() ulPortGetRunTime()
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.
2020-03-05 02:00:41 +08:00
#ifdef __cplusplus
}
#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.
2020-03-05 02:00:41 +08:00
#endif /* PORTMACRO_H */