mirror of
https://github.com/FreeRTOS/FreeRTOS-Kernel.git
synced 2025-09-13 01:27:48 -04:00
Merge branch 'main' into pthread_crit
This commit is contained in:
commit
5b48df7a95
17 changed files with 1506 additions and 1380 deletions
6
.github/lexicon.txt
vendored
6
.github/lexicon.txt
vendored
|
@ -1529,6 +1529,7 @@ prvinitialisenewstreambuffer
|
||||||
prvinitialisenewtimer
|
prvinitialisenewtimer
|
||||||
prvinsertblockintofreelist
|
prvinsertblockintofreelist
|
||||||
prvlockqueue
|
prvlockqueue
|
||||||
|
prvnotifyqueuesetcontainer
|
||||||
prvportmalloc
|
prvportmalloc
|
||||||
prvportresetpic
|
prvportresetpic
|
||||||
prvprocesssimulatedinterrupts
|
prvprocesssimulatedinterrupts
|
||||||
|
@ -1631,7 +1632,6 @@ pvyieldevent
|
||||||
pwdtc
|
pwdtc
|
||||||
pwm
|
pwm
|
||||||
pwmc
|
pwmc
|
||||||
pxtaskcode
|
|
||||||
pxblock
|
pxblock
|
||||||
pxblocktoinsert
|
pxblocktoinsert
|
||||||
pxcallbackfunction
|
pxcallbackfunction
|
||||||
|
@ -1688,6 +1688,7 @@ pxprevious
|
||||||
pxpreviouswaketime
|
pxpreviouswaketime
|
||||||
pxqueue
|
pxqueue
|
||||||
pxqueuebuffer
|
pxqueuebuffer
|
||||||
|
pxqueuesetcontainer
|
||||||
pxramstack
|
pxramstack
|
||||||
pxreadycoroutinelists
|
pxreadycoroutinelists
|
||||||
pxreadytaskslists
|
pxreadytaskslists
|
||||||
|
@ -1707,6 +1708,7 @@ pxstreambuffercreatestatic
|
||||||
pxtagvalue
|
pxtagvalue
|
||||||
pxtask
|
pxtask
|
||||||
pxtaskbuffer
|
pxtaskbuffer
|
||||||
|
pxtaskcode
|
||||||
pxtaskdefinition
|
pxtaskdefinition
|
||||||
pxtaskstatus
|
pxtaskstatus
|
||||||
pxtaskstatusarray
|
pxtaskstatusarray
|
||||||
|
@ -2653,7 +2655,6 @@ wu
|
||||||
www
|
www
|
||||||
wwwfreertos
|
wwwfreertos
|
||||||
wxr
|
wxr
|
||||||
xtasktodelete
|
|
||||||
xa
|
xa
|
||||||
xaa
|
xaa
|
||||||
xaaaa
|
xaaaa
|
||||||
|
@ -3020,6 +3021,7 @@ xtaskswaitingforbits
|
||||||
xtaskswaitingtermination
|
xtaskswaitingtermination
|
||||||
xtaskswaitingtoreceive
|
xtaskswaitingtoreceive
|
||||||
xtaskswaitingtosend
|
xtaskswaitingtosend
|
||||||
|
xtasktodelete
|
||||||
xtasktonotify
|
xtasktonotify
|
||||||
xtasktoquery
|
xtasktoquery
|
||||||
xtasktoresume
|
xtasktoresume
|
||||||
|
|
1
.github/workflows/ci.yml
vendored
1
.github/workflows/ci.yml
vendored
|
@ -44,3 +44,4 @@ jobs:
|
||||||
- name: URL Checker
|
- name: URL Checker
|
||||||
run: |
|
run: |
|
||||||
bash kernel/.github/actions/url_verifier.sh kernel
|
bash kernel/.github/actions/url_verifier.sh kernel
|
||||||
|
|
||||||
|
|
24
.github/workflows/git-secrets.yml
vendored
Normal file
24
.github/workflows/git-secrets.yml
vendored
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
name: git-secrets Check
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
pull_request:
|
||||||
|
workflow_dispatch:
|
||||||
|
jobs:
|
||||||
|
git-secrets:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
with:
|
||||||
|
submodules: recursive
|
||||||
|
- name: Checkout awslabs/git-secrets
|
||||||
|
uses: actions/checkout@v2
|
||||||
|
with:
|
||||||
|
repository: awslabs/git-secrets
|
||||||
|
ref: master
|
||||||
|
path: git-secrets
|
||||||
|
- name: Install git-secrets
|
||||||
|
run: cd git-secrets && sudo make install && cd ..
|
||||||
|
- name: Run git-secrets
|
||||||
|
run: |
|
||||||
|
git-secrets --register-aws
|
||||||
|
git-secrets --scan
|
27
.github/workflows/kernel-checks.yml
vendored
27
.github/workflows/kernel-checks.yml
vendored
|
@ -1,6 +1,6 @@
|
||||||
name: Kernel-Checker
|
name: Kernel-Checker
|
||||||
|
|
||||||
on: [pull_request]
|
on: [push, pull_request]
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
kernel-checker:
|
kernel-checker:
|
||||||
|
@ -45,3 +45,28 @@ jobs:
|
||||||
cd inspect
|
cd inspect
|
||||||
.github/scripts/kernel_checker.py --json ${HOME}/files_modified.json ${HOME}/files_added.json ${HOME}/files_renamed.json
|
.github/scripts/kernel_checker.py --json ${HOME}/files_modified.json ${HOME}/files_added.json ${HOME}/files_renamed.json
|
||||||
exit $?
|
exit $?
|
||||||
|
build-checker:
|
||||||
|
name: FreeRTOS Posix Build Check
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Checkout the parent repository
|
||||||
|
uses: actions/checkout@v2
|
||||||
|
with:
|
||||||
|
ref: master
|
||||||
|
repository: FreeRTOS/FreeRTOS
|
||||||
|
submodules: 'recursive'
|
||||||
|
fetch-depth: 1
|
||||||
|
path: ./workspace
|
||||||
|
- name: Checkout the current repository
|
||||||
|
uses: actions/checkout@v2
|
||||||
|
with:
|
||||||
|
path: ./workspace/FreeRTOS/Source
|
||||||
|
- name: Posix Build Checker
|
||||||
|
run: |
|
||||||
|
bash workspace/.github/scripts/posix_build_checker.sh workspace
|
||||||
|
- name: Install lib pcap dev
|
||||||
|
run: |
|
||||||
|
sudo apt-get install libpcap-dev
|
||||||
|
- name: Posix Network Build Checker
|
||||||
|
run: |
|
||||||
|
bash workspace/.github/scripts/posix_network_build_checker.sh workspace
|
||||||
|
|
56
.github/workflows/unit-tests.yml
vendored
Normal file
56
.github/workflows/unit-tests.yml
vendored
Normal file
|
@ -0,0 +1,56 @@
|
||||||
|
name: CMock Unit Tests
|
||||||
|
on: [push, pull_request]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
run:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Checkout Parent Repository
|
||||||
|
uses: actions/checkout@v2
|
||||||
|
with:
|
||||||
|
ref: master
|
||||||
|
repository: FreeRTOS/FreeRTOS
|
||||||
|
submodules: 'recursive'
|
||||||
|
fetch-depth: 1
|
||||||
|
- name: Clone This Repo
|
||||||
|
uses: actions/checkout@v2
|
||||||
|
with:
|
||||||
|
path: ./FreeRTOS/Source
|
||||||
|
|
||||||
|
- name: Setup Python
|
||||||
|
uses: actions/setup-python@master
|
||||||
|
with:
|
||||||
|
python-version: 3.8
|
||||||
|
|
||||||
|
- name: Install packages
|
||||||
|
run: |
|
||||||
|
sudo apt-get install lcov cflow ruby doxygen build-essential
|
||||||
|
- name: Run Unit Tests with ENABLE_SANITIZER=1
|
||||||
|
run: |
|
||||||
|
make -C FreeRTOS/Test/CMock clean
|
||||||
|
make -C FreeRTOS/Test/CMock ENABLE_SANITIZER=1 run_col_formatted
|
||||||
|
- name: Run Unit Tests for coverage
|
||||||
|
run: |
|
||||||
|
make -C FreeRTOS/Test/CMock clean
|
||||||
|
make -C FreeRTOS/Test/CMock lcovhtml
|
||||||
|
lcov --config-file FreeRTOS/Test/CMock/lcovrc --summary FreeRTOS/Test/CMock/build/cmock_test.info > FreeRTOS/Test/CMock/build/cmock_test_summary.txt
|
||||||
|
- name: Upload coverage to Codecov
|
||||||
|
uses: codecov/codecov-action@v1
|
||||||
|
with:
|
||||||
|
files: FreeRTOS/Test/CMock/build/cmock_test.info
|
||||||
|
working-directory: .
|
||||||
|
root_dir: FreeRTOS/Source
|
||||||
|
flags: unittests
|
||||||
|
fail_ci_if_error: false
|
||||||
|
path_to_write_report: coverage/codecov_report.txt
|
||||||
|
verbose: false
|
||||||
|
- name: Archive code coverage data
|
||||||
|
uses: actions/upload-artifact@v2
|
||||||
|
with:
|
||||||
|
name: coverage-data
|
||||||
|
path: FreeRTOS/Test/CMock/build/cmock_test*
|
||||||
|
- name: Archive code coverage html report
|
||||||
|
uses: actions/upload-artifact@v2
|
||||||
|
with:
|
||||||
|
name: coverage-report
|
||||||
|
path: FreeRTOS/Test/CMock/build/coverage
|
|
@ -625,6 +625,8 @@ EventBits_t xEventGroupSetBits( EventGroupHandle_t xEventGroup,
|
||||||
|
|
||||||
void vEventGroupDelete( EventGroupHandle_t xEventGroup )
|
void vEventGroupDelete( EventGroupHandle_t xEventGroup )
|
||||||
{
|
{
|
||||||
|
configASSERT( xEventGroup );
|
||||||
|
|
||||||
EventGroup_t * pxEventBits = xEventGroup;
|
EventGroup_t * pxEventBits = xEventGroup;
|
||||||
const List_t * pxTasksWaitingForBits = &( pxEventBits->xTasksWaitingForBits );
|
const List_t * pxTasksWaitingForBits = &( pxEventBits->xTasksWaitingForBits );
|
||||||
|
|
||||||
|
|
|
@ -1059,6 +1059,11 @@
|
||||||
#define configRUN_FREERTOS_SECURE_ONLY 0
|
#define configRUN_FREERTOS_SECURE_ONLY 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef configRUN_ADDITIONAL_TESTS
|
||||||
|
#define configRUN_ADDITIONAL_TESTS 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/* Sometimes the FreeRTOSConfig.h settings only allow a task to be created using
|
/* Sometimes the FreeRTOSConfig.h settings only allow a task to be created using
|
||||||
* dynamically allocated RAM, in which case when any task is deleted it is known
|
* dynamically allocated RAM, in which case when any task is deleted it is known
|
||||||
* that both the task's stack and TCB need to be freed. Sometimes the
|
* that both the task's stack and TCB need to be freed. Sometimes the
|
||||||
|
|
|
@ -31,7 +31,7 @@
|
||||||
*
|
*
|
||||||
* list_ts can only store pointers to list_item_ts. Each ListItem_t contains a
|
* list_ts can only store pointers to list_item_ts. Each ListItem_t contains a
|
||||||
* numeric value (xItemValue). Most of the time the lists are sorted in
|
* numeric value (xItemValue). Most of the time the lists are sorted in
|
||||||
* descending item value order.
|
* ascending item value order.
|
||||||
*
|
*
|
||||||
* Lists are created already containing one list item. The value of this
|
* Lists are created already containing one list item. The value of this
|
||||||
* item is the maximum possible that can be stored, it is therefore always at
|
* item is the maximum possible that can be stored, it is therefore always at
|
||||||
|
@ -141,19 +141,19 @@
|
||||||
struct xLIST;
|
struct xLIST;
|
||||||
struct xLIST_ITEM
|
struct xLIST_ITEM
|
||||||
{
|
{
|
||||||
listFIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE /*< Set to a known value if configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */
|
listFIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE /*< Set to a known value if configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */
|
||||||
configLIST_VOLATILE TickType_t xItemValue; /*< The value being listed. In most cases this is used to sort the list in descending order. */
|
configLIST_VOLATILE TickType_t xItemValue; /*< The value being listed. In most cases this is used to sort the list in ascending order. */
|
||||||
struct xLIST_ITEM * configLIST_VOLATILE pxNext; /*< Pointer to the next ListItem_t in the list. */
|
struct xLIST_ITEM * configLIST_VOLATILE pxNext; /*< Pointer to the next ListItem_t in the list. */
|
||||||
struct xLIST_ITEM * configLIST_VOLATILE pxPrevious; /*< Pointer to the previous ListItem_t in the list. */
|
struct xLIST_ITEM * configLIST_VOLATILE pxPrevious; /*< Pointer to the previous ListItem_t in the list. */
|
||||||
void * pvOwner; /*< Pointer to the object (normally a TCB) that contains the list item. There is therefore a two way link between the object containing the list item and the list item itself. */
|
void * pvOwner; /*< Pointer to the object (normally a TCB) that contains the list item. There is therefore a two way link between the object containing the list item and the list item itself. */
|
||||||
struct xLIST * configLIST_VOLATILE pxContainer; /*< Pointer to the list in which this list item is placed (if any). */
|
struct xLIST * configLIST_VOLATILE pxContainer; /*< Pointer to the list in which this list item is placed (if any). */
|
||||||
listSECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE /*< Set to a known value if configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */
|
listSECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE /*< Set to a known value if configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */
|
||||||
};
|
};
|
||||||
typedef struct xLIST_ITEM ListItem_t; /* For some reason lint wants this as two separate definitions. */
|
typedef struct xLIST_ITEM ListItem_t; /* For some reason lint wants this as two separate definitions. */
|
||||||
|
|
||||||
struct xMINI_LIST_ITEM
|
struct xMINI_LIST_ITEM
|
||||||
{
|
{
|
||||||
listFIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE /*< Set to a known value if configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */
|
listFIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE /*< Set to a known value if configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */
|
||||||
configLIST_VOLATILE TickType_t xItemValue;
|
configLIST_VOLATILE TickType_t xItemValue;
|
||||||
struct xLIST_ITEM * configLIST_VOLATILE pxNext;
|
struct xLIST_ITEM * configLIST_VOLATILE pxNext;
|
||||||
struct xLIST_ITEM * configLIST_VOLATILE pxPrevious;
|
struct xLIST_ITEM * configLIST_VOLATILE pxPrevious;
|
||||||
|
@ -165,11 +165,11 @@ typedef struct xMINI_LIST_ITEM MiniListItem_t;
|
||||||
*/
|
*/
|
||||||
typedef struct xLIST
|
typedef struct xLIST
|
||||||
{
|
{
|
||||||
listFIRST_LIST_INTEGRITY_CHECK_VALUE /*< Set to a known value if configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */
|
listFIRST_LIST_INTEGRITY_CHECK_VALUE /*< Set to a known value if configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */
|
||||||
volatile UBaseType_t uxNumberOfItems;
|
volatile UBaseType_t uxNumberOfItems;
|
||||||
ListItem_t * configLIST_VOLATILE pxIndex; /*< Used to walk through the list. Points to the last item returned by a call to listGET_OWNER_OF_NEXT_ENTRY (). */
|
ListItem_t * configLIST_VOLATILE pxIndex; /*< Used to walk through the list. Points to the last item returned by a call to listGET_OWNER_OF_NEXT_ENTRY (). */
|
||||||
MiniListItem_t xListEnd; /*< List item that contains the maximum possible item value meaning it is always at the end of the list and is therefore used as a marker. */
|
MiniListItem_t xListEnd; /*< List item that contains the maximum possible item value meaning it is always at the end of the list and is therefore used as a marker. */
|
||||||
listSECOND_LIST_INTEGRITY_CHECK_VALUE /*< Set to a known value if configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */
|
listSECOND_LIST_INTEGRITY_CHECK_VALUE /*< Set to a known value if configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */
|
||||||
} List_t;
|
} List_t;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -192,7 +192,7 @@ typedef struct xLIST
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Access macro to set the value of the list item. In most cases the value is
|
* Access macro to set the value of the list item. In most cases the value is
|
||||||
* used to sort the list in descending order.
|
* used to sort the list in ascending order.
|
||||||
*
|
*
|
||||||
* \page listSET_LIST_ITEM_VALUE listSET_LIST_ITEM_VALUE
|
* \page listSET_LIST_ITEM_VALUE listSET_LIST_ITEM_VALUE
|
||||||
* \ingroup LinkedList
|
* \ingroup LinkedList
|
||||||
|
@ -359,7 +359,7 @@ void vListInitialiseItem( ListItem_t * const pxItem ) PRIVILEGED_FUNCTION;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Insert a list item into a list. The item will be inserted into the list in
|
* Insert a list item into a list. The item will be inserted into the list in
|
||||||
* a position determined by its item value (descending item value order).
|
* a position determined by its item value (ascending item value order).
|
||||||
*
|
*
|
||||||
* @param pxList The list into which the item is to be inserted.
|
* @param pxList The list into which the item is to be inserted.
|
||||||
*
|
*
|
||||||
|
|
|
@ -29,7 +29,7 @@
|
||||||
|
|
||||||
/* This file redefines API functions to be called through a wrapper macro, but
|
/* This file redefines API functions to be called through a wrapper macro, but
|
||||||
* only for ports that are using the MPU. */
|
* only for ports that are using the MPU. */
|
||||||
#ifdef portUSING_MPU_WRAPPERS
|
#if ( portUSING_MPU_WRAPPERS == 1 )
|
||||||
|
|
||||||
/* MPU_WRAPPERS_INCLUDED_FROM_API_FILE will be defined when this file is
|
/* MPU_WRAPPERS_INCLUDED_FROM_API_FILE will be defined when this file is
|
||||||
* included from queue.c or task.c to prevent it from having an effect within
|
* included from queue.c or task.c to prevent it from having an effect within
|
||||||
|
|
|
@ -1934,9 +1934,8 @@ uint32_t ulTaskGetIdleRunTimeCounter( void ) PRIVILEGED_FUNCTION;
|
||||||
* that way task notifications can be used to send data to a task, or be used as
|
* that way task notifications can be used to send data to a task, or be used as
|
||||||
* light weight and fast binary or counting semaphores.
|
* light weight and fast binary or counting semaphores.
|
||||||
*
|
*
|
||||||
* A task can use xTaskNotifyWaitIndexed() to [optionally] block to wait for a
|
* A task can use xTaskNotifyWaitIndexed() or ulTaskNotifyTakeIndexed() to
|
||||||
* notification to be pending, or ulTaskNotifyTakeIndexed() to [optionally] block
|
* [optionally] block to wait for a notification to be pending. The task does
|
||||||
* to wait for a notification value to have a non-zero value. The task does
|
|
||||||
* not consume any CPU time while it is in the Blocked state.
|
* not consume any CPU time while it is in the Blocked state.
|
||||||
*
|
*
|
||||||
* A notification sent to a task will remain pending until it is cleared by the
|
* A notification sent to a task will remain pending until it is cleared by the
|
||||||
|
@ -2522,8 +2521,8 @@ void vTaskGenericNotifyGiveFromISR( TaskHandle_t xTaskToNotify,
|
||||||
* value acts like a counting semaphore.
|
* value acts like a counting semaphore.
|
||||||
*
|
*
|
||||||
* A task can use ulTaskNotifyTakeIndexed() to [optionally] block to wait for
|
* A task can use ulTaskNotifyTakeIndexed() to [optionally] block to wait for
|
||||||
* the task's notification value to be non-zero. The task does not consume any
|
* a notification. The task does not consume any CPU time while it is in the
|
||||||
* CPU time while it is in the Blocked state.
|
* Blocked state.
|
||||||
*
|
*
|
||||||
* Where as xTaskNotifyWaitIndexed() will return when a notification is pending,
|
* Where as xTaskNotifyWaitIndexed() will return when a notification is pending,
|
||||||
* ulTaskNotifyTakeIndexed() will return when the task's notification value is
|
* ulTaskNotifyTakeIndexed() will return when the task's notification value is
|
||||||
|
|
3
list.c
3
list.c
|
@ -158,6 +158,9 @@ void vListInsert( List_t * const pxList,
|
||||||
* 4) Using a queue or semaphore before it has been initialised or
|
* 4) Using a queue or semaphore before it has been initialised or
|
||||||
* before the scheduler has been started (are interrupts firing
|
* before the scheduler has been started (are interrupts firing
|
||||||
* before vTaskStartScheduler() has been called?).
|
* before vTaskStartScheduler() has been called?).
|
||||||
|
* 5) If the FreeRTOS port supports interrupt nesting then ensure that
|
||||||
|
* the priority of the tick interrupt is at or below
|
||||||
|
* configMAX_SYSCALL_INTERRUPT_PRIORITY.
|
||||||
**********************************************************************/
|
**********************************************************************/
|
||||||
|
|
||||||
for( pxIterator = ( ListItem_t * ) &( pxList->xListEnd ); pxIterator->pxNext->xItemValue <= xValueOfInsertion; pxIterator = pxIterator->pxNext ) /*lint !e826 !e740 !e9087 The mini list structure is used as the list end to save RAM. This is checked and valid. *//*lint !e440 The iterator moves to a different value, not xValueOfInsertion. */
|
for( pxIterator = ( ListItem_t * ) &( pxList->xListEnd ); pxIterator->pxNext->xItemValue <= xValueOfInsertion; pxIterator = pxIterator->pxNext ) /*lint !e826 !e740 !e9087 The mini list structure is used as the list end to save RAM. This is checked and valid. *//*lint !e440 The iterator moves to a different value, not xValueOfInsertion. */
|
||||||
|
|
|
@ -22,7 +22,6 @@
|
||||||
* https://www.FreeRTOS.org
|
* https://www.FreeRTOS.org
|
||||||
* https://github.com/FreeRTOS
|
* https://github.com/FreeRTOS
|
||||||
*
|
*
|
||||||
* 1 tab == 4 spaces!
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -58,6 +57,8 @@ extern "C" {
|
||||||
#define portSTACK_TYPE uint8_t
|
#define portSTACK_TYPE uint8_t
|
||||||
#define portBASE_TYPE char
|
#define portBASE_TYPE char
|
||||||
|
|
||||||
|
#define portPOINTER_SIZE_TYPE uint16_t
|
||||||
|
|
||||||
typedef portSTACK_TYPE StackType_t;
|
typedef portSTACK_TYPE StackType_t;
|
||||||
typedef signed char BaseType_t;
|
typedef signed char BaseType_t;
|
||||||
typedef unsigned char UBaseType_t;
|
typedef unsigned char UBaseType_t;
|
||||||
|
|
|
@ -762,10 +762,10 @@ __asm uint32_t vPortGetIPSR( void )
|
||||||
* be set to a value equal to or numerically *higher* than
|
* be set to a value equal to or numerically *higher* than
|
||||||
* configMAX_SYSCALL_INTERRUPT_PRIORITY.
|
* configMAX_SYSCALL_INTERRUPT_PRIORITY.
|
||||||
*
|
*
|
||||||
* Interrupts that use the FreeRTOS API must not be left at their
|
* Interrupts that use the FreeRTOS API must not be left at their
|
||||||
* default priority of zero as that is the highest possible priority,
|
* default priority of zero as that is the highest possible priority,
|
||||||
* which is guaranteed to be above configMAX_SYSCALL_INTERRUPT_PRIORITY,
|
* which is guaranteed to be above configMAX_SYSCALL_INTERRUPT_PRIORITY,
|
||||||
* and therefore also guaranteed to be invalid.
|
* and therefore also guaranteed to be invalid.
|
||||||
*
|
*
|
||||||
* FreeRTOS maintains separate thread and ISR API functions to ensure
|
* FreeRTOS maintains separate thread and ISR API functions to ensure
|
||||||
* interrupt entry is as fast and simple as possible.
|
* interrupt entry is as fast and simple as possible.
|
||||||
|
|
30
queue.c
30
queue.c
|
@ -342,8 +342,10 @@ BaseType_t xQueueGenericReset( QueueHandle_t xQueue,
|
||||||
* variable of type StaticQueue_t or StaticSemaphore_t equals the size of
|
* variable of type StaticQueue_t or StaticSemaphore_t equals the size of
|
||||||
* the real queue and semaphore structures. */
|
* the real queue and semaphore structures. */
|
||||||
volatile size_t xSize = sizeof( StaticQueue_t );
|
volatile size_t xSize = sizeof( StaticQueue_t );
|
||||||
configASSERT( xSize == sizeof( Queue_t ) );
|
|
||||||
( void ) xSize; /* Keeps lint quiet when configASSERT() is not defined. */
|
/* This assertion cannot be branch covered in unit tests */
|
||||||
|
configASSERT( xSize == sizeof( Queue_t ) ); /* LCOV_EXCL_BR_LINE */
|
||||||
|
( void ) xSize; /* Keeps lint quiet when configASSERT() is not defined. */
|
||||||
}
|
}
|
||||||
#endif /* configASSERT_DEFINED */
|
#endif /* configASSERT_DEFINED */
|
||||||
|
|
||||||
|
@ -398,7 +400,7 @@ BaseType_t xQueueGenericReset( QueueHandle_t xQueue,
|
||||||
configASSERT( ( uxItemSize == 0 ) || ( uxQueueLength == ( xQueueSizeInBytes / uxItemSize ) ) );
|
configASSERT( ( uxItemSize == 0 ) || ( uxQueueLength == ( xQueueSizeInBytes / uxItemSize ) ) );
|
||||||
|
|
||||||
/* Check for addition overflow. */
|
/* Check for addition overflow. */
|
||||||
configASSERT( ( sizeof( Queue_t ) + xQueueSizeInBytes ) > xQueueSizeInBytes );
|
configASSERT( ( sizeof( Queue_t ) + xQueueSizeInBytes ) > xQueueSizeInBytes );
|
||||||
|
|
||||||
/* Allocate the queue and storage area. Justification for MISRA
|
/* Allocate the queue and storage area. Justification for MISRA
|
||||||
* deviation as follows: pvPortMalloc() always ensures returned memory
|
* deviation as follows: pvPortMalloc() always ensures returned memory
|
||||||
|
@ -561,6 +563,8 @@ static void prvInitialiseNewQueue( const UBaseType_t uxQueueLength,
|
||||||
TaskHandle_t pxReturn;
|
TaskHandle_t pxReturn;
|
||||||
Queue_t * const pxSemaphore = ( Queue_t * ) xSemaphore;
|
Queue_t * const pxSemaphore = ( Queue_t * ) xSemaphore;
|
||||||
|
|
||||||
|
configASSERT( xSemaphore );
|
||||||
|
|
||||||
/* This function is called by xSemaphoreGetMutexHolder(), and should not
|
/* This function is called by xSemaphoreGetMutexHolder(), and should not
|
||||||
* be called directly. Note: This is a good way of determining if the
|
* be called directly. Note: This is a good way of determining if the
|
||||||
* calling task is the mutex holder, but not a good way of determining the
|
* calling task is the mutex holder, but not a good way of determining the
|
||||||
|
@ -944,15 +948,15 @@ BaseType_t xQueueGenericSend( QueueHandle_t xQueue,
|
||||||
vTaskPlaceOnEventList( &( pxQueue->xTasksWaitingToSend ), xTicksToWait );
|
vTaskPlaceOnEventList( &( pxQueue->xTasksWaitingToSend ), xTicksToWait );
|
||||||
|
|
||||||
/* Unlocking the queue means queue events can effect the
|
/* Unlocking the queue means queue events can effect the
|
||||||
* event list. It is possible that interrupts occurring now
|
* event list. It is possible that interrupts occurring now
|
||||||
* remove this task from the event list again - but as the
|
* remove this task from the event list again - but as the
|
||||||
* scheduler is suspended the task will go onto the pending
|
* scheduler is suspended the task will go onto the pending
|
||||||
* ready last instead of the actual ready list. */
|
* ready list instead of the actual ready list. */
|
||||||
prvUnlockQueue( pxQueue );
|
prvUnlockQueue( pxQueue );
|
||||||
|
|
||||||
/* Resuming the scheduler will move tasks from the pending
|
/* Resuming the scheduler will move tasks from the pending
|
||||||
* ready list into the ready list - so it is feasible that this
|
* ready list into the ready list - so it is feasible that this
|
||||||
* task is already in a ready list before it yields - in which
|
* task is already in the ready list before it yields - in which
|
||||||
* case the yield will not cause a context switch unless there
|
* case the yield will not cause a context switch unless there
|
||||||
* is also a higher priority task in the pending ready list. */
|
* is also a higher priority task in the pending ready list. */
|
||||||
if( xTaskResumeAll() == pdFALSE )
|
if( xTaskResumeAll() == pdFALSE )
|
||||||
|
@ -1774,7 +1778,7 @@ BaseType_t xQueuePeek( QueueHandle_t xQueue,
|
||||||
taskEXIT_CRITICAL();
|
taskEXIT_CRITICAL();
|
||||||
|
|
||||||
/* Interrupts and other tasks can send to and receive from the queue
|
/* Interrupts and other tasks can send to and receive from the queue
|
||||||
* now the critical section has been exited. */
|
* now that the critical section has been exited. */
|
||||||
|
|
||||||
vTaskSuspendAll();
|
vTaskSuspendAll();
|
||||||
prvLockQueue( pxQueue );
|
prvLockQueue( pxQueue );
|
||||||
|
@ -2723,6 +2727,9 @@ BaseType_t xQueueIsQueueFullFromISR( const QueueHandle_t xQueue )
|
||||||
{
|
{
|
||||||
UBaseType_t ux;
|
UBaseType_t ux;
|
||||||
|
|
||||||
|
configASSERT( xQueue );
|
||||||
|
configASSERT( pcQueueName );
|
||||||
|
|
||||||
/* See if there is an empty space in the registry. A NULL name denotes
|
/* See if there is an empty space in the registry. A NULL name denotes
|
||||||
* a free slot. */
|
* a free slot. */
|
||||||
for( ux = ( UBaseType_t ) 0U; ux < ( UBaseType_t ) configQUEUE_REGISTRY_SIZE; ux++ )
|
for( ux = ( UBaseType_t ) 0U; ux < ( UBaseType_t ) configQUEUE_REGISTRY_SIZE; ux++ )
|
||||||
|
@ -2753,6 +2760,8 @@ BaseType_t xQueueIsQueueFullFromISR( const QueueHandle_t xQueue )
|
||||||
UBaseType_t ux;
|
UBaseType_t ux;
|
||||||
const char * pcReturn = NULL; /*lint !e971 Unqualified char types are allowed for strings and single characters only. */
|
const char * pcReturn = NULL; /*lint !e971 Unqualified char types are allowed for strings and single characters only. */
|
||||||
|
|
||||||
|
configASSERT( xQueue );
|
||||||
|
|
||||||
/* Note there is nothing here to protect against another task adding or
|
/* Note there is nothing here to protect against another task adding or
|
||||||
* removing entries from the registry while it is being searched. */
|
* removing entries from the registry while it is being searched. */
|
||||||
|
|
||||||
|
@ -2781,6 +2790,8 @@ BaseType_t xQueueIsQueueFullFromISR( const QueueHandle_t xQueue )
|
||||||
{
|
{
|
||||||
UBaseType_t ux;
|
UBaseType_t ux;
|
||||||
|
|
||||||
|
configASSERT( xQueue );
|
||||||
|
|
||||||
/* See if the handle of the queue being unregistered in actually in the
|
/* See if the handle of the queue being unregistered in actually in the
|
||||||
* registry. */
|
* registry. */
|
||||||
for( ux = ( UBaseType_t ) 0U; ux < ( UBaseType_t ) configQUEUE_REGISTRY_SIZE; ux++ )
|
for( ux = ( UBaseType_t ) 0U; ux < ( UBaseType_t ) configQUEUE_REGISTRY_SIZE; ux++ )
|
||||||
|
@ -2967,7 +2978,10 @@ BaseType_t xQueueIsQueueFullFromISR( const QueueHandle_t xQueue )
|
||||||
|
|
||||||
/* This function must be called form a critical section. */
|
/* This function must be called form a critical section. */
|
||||||
|
|
||||||
configASSERT( pxQueueSetContainer );
|
/* The following line is not reachable in unit tests because every call
|
||||||
|
* to prvNotifyQueueSetContainer is preceded by a check that
|
||||||
|
* pxQueueSetContainer != NULL */
|
||||||
|
configASSERT( pxQueueSetContainer ); /* LCOV_EXCL_BR_LINE */
|
||||||
configASSERT( pxQueueSetContainer->uxMessagesWaiting < pxQueueSetContainer->uxLength );
|
configASSERT( pxQueueSetContainer->uxMessagesWaiting < pxQueueSetContainer->uxLength );
|
||||||
|
|
||||||
if( pxQueueSetContainer->uxMessagesWaiting < pxQueueSetContainer->uxLength )
|
if( pxQueueSetContainer->uxMessagesWaiting < pxQueueSetContainer->uxLength )
|
||||||
|
|
265
stream_buffer.c
265
stream_buffer.c
|
@ -49,7 +49,7 @@
|
||||||
#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE /*lint !e961 !e750 !e9021. */
|
#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE /*lint !e961 !e750 !e9021. */
|
||||||
|
|
||||||
/* If the user has not provided application specific Rx notification macros,
|
/* If the user has not provided application specific Rx notification macros,
|
||||||
* or #defined the notification macros away, them provide default implementations
|
* or #defined the notification macros away, then provide default implementations
|
||||||
* that uses task notifications. */
|
* that uses task notifications. */
|
||||||
/*lint -save -e9026 Function like macros allowed and needed here so they can be overridden. */
|
/*lint -save -e9026 Function like macros allowed and needed here so they can be overridden. */
|
||||||
#ifndef sbRECEIVE_COMPLETED
|
#ifndef sbRECEIVE_COMPLETED
|
||||||
|
@ -159,14 +159,20 @@ typedef struct StreamBufferDef_t /*lint !e9058 Style convention
|
||||||
static size_t prvBytesInBuffer( const StreamBuffer_t * const pxStreamBuffer ) PRIVILEGED_FUNCTION;
|
static size_t prvBytesInBuffer( const StreamBuffer_t * const pxStreamBuffer ) PRIVILEGED_FUNCTION;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Add xCount bytes from pucData into the pxStreamBuffer message buffer.
|
* Add xCount bytes from pucData into the pxStreamBuffer's data storage area.
|
||||||
* Returns the number of bytes written, which will either equal xCount in the
|
* This function does not update the buffer's xHead pointer, so multiple writes
|
||||||
* success case, or 0 if there was not enough space in the buffer (in which case
|
* may be chained together "atomically". This is useful for Message Buffers where
|
||||||
* no data is written into the buffer).
|
* the length and data bytes are written in two separate chunks, and we don't want
|
||||||
|
* the reader to see the buffer as having grown until after all data is copied over.
|
||||||
|
* This function takes a custom xHead value to indicate where to write to (necessary
|
||||||
|
* for chaining) and returns the the resulting xHead position.
|
||||||
|
* To mark the write as complete, manually set the buffer's xHead field with the
|
||||||
|
* returned xHead from this function.
|
||||||
*/
|
*/
|
||||||
static size_t prvWriteBytesToBuffer( StreamBuffer_t * const pxStreamBuffer,
|
static size_t prvWriteBytesToBuffer( StreamBuffer_t * const pxStreamBuffer,
|
||||||
const uint8_t * pucData,
|
const uint8_t * pucData,
|
||||||
size_t xCount ) PRIVILEGED_FUNCTION;
|
size_t xCount,
|
||||||
|
size_t xHead ) PRIVILEGED_FUNCTION;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If the stream buffer is being used as a message buffer, then reads an entire
|
* If the stream buffer is being used as a message buffer, then reads an entire
|
||||||
|
@ -178,8 +184,7 @@ static size_t prvWriteBytesToBuffer( StreamBuffer_t * const pxStreamBuffer,
|
||||||
static size_t prvReadMessageFromBuffer( StreamBuffer_t * pxStreamBuffer,
|
static size_t prvReadMessageFromBuffer( StreamBuffer_t * pxStreamBuffer,
|
||||||
void * pvRxData,
|
void * pvRxData,
|
||||||
size_t xBufferLengthBytes,
|
size_t xBufferLengthBytes,
|
||||||
size_t xBytesAvailable,
|
size_t xBytesAvailable ) PRIVILEGED_FUNCTION;
|
||||||
size_t xBytesToStoreMessageLength ) PRIVILEGED_FUNCTION;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If the stream buffer is being used as a message buffer, then writes an entire
|
* If the stream buffer is being used as a message buffer, then writes an entire
|
||||||
|
@ -195,13 +200,21 @@ static size_t prvWriteMessageToBuffer( StreamBuffer_t * const pxStreamBuffer,
|
||||||
size_t xRequiredSpace ) PRIVILEGED_FUNCTION;
|
size_t xRequiredSpace ) PRIVILEGED_FUNCTION;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Read xMaxCount bytes from the pxStreamBuffer message buffer and write them
|
* Copies xCount bytes from the pxStreamBuffer's data storage area to pucData.
|
||||||
* to pucData.
|
* This function does not update the buffer's xTail pointer, so multiple reads
|
||||||
|
* may be chained together "atomically". This is useful for Message Buffers where
|
||||||
|
* the length and data bytes are read in two separate chunks, and we don't want
|
||||||
|
* the writer to see the buffer as having more free space until after all data is
|
||||||
|
* copied over, especially if we have to abort the read due to insufficient receiving space.
|
||||||
|
* This function takes a custom xTail value to indicate where to read from (necessary
|
||||||
|
* for chaining) and returns the the resulting xTail position.
|
||||||
|
* To mark the read as complete, manually set the buffer's xTail field with the
|
||||||
|
* returned xTail from this function.
|
||||||
*/
|
*/
|
||||||
static size_t prvReadBytesFromBuffer( StreamBuffer_t * pxStreamBuffer,
|
static size_t prvReadBytesFromBuffer( StreamBuffer_t * pxStreamBuffer,
|
||||||
uint8_t * pucData,
|
uint8_t * pucData,
|
||||||
size_t xMaxCount,
|
size_t xCount,
|
||||||
size_t xBytesAvailable ) PRIVILEGED_FUNCTION;
|
size_t xTail ) PRIVILEGED_FUNCTION;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Called by both pxStreamBufferCreate() and pxStreamBufferCreateStatic() to
|
* Called by both pxStreamBufferCreate() and pxStreamBufferCreateStatic() to
|
||||||
|
@ -268,7 +281,6 @@ static void prvInitialiseNewStreamBuffer( StreamBuffer_t * const pxStreamBuffer,
|
||||||
pucAllocatedMemory = NULL;
|
pucAllocatedMemory = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if( pucAllocatedMemory != NULL )
|
if( pucAllocatedMemory != NULL )
|
||||||
{
|
{
|
||||||
prvInitialiseNewStreamBuffer( ( StreamBuffer_t * ) pucAllocatedMemory, /* Structure at the start of the allocated memory. */ /*lint !e9087 Safe cast as allocated memory is aligned. */ /*lint !e826 Area is not too small and alignment is guaranteed provided malloc() behaves as expected and returns aligned buffer. */
|
prvInitialiseNewStreamBuffer( ( StreamBuffer_t * ) pucAllocatedMemory, /* Structure at the start of the allocated memory. */ /*lint !e9087 Safe cast as allocated memory is aligned. */ /*lint !e826 Area is not too small and alignment is guaranteed provided malloc() behaves as expected and returns aligned buffer. */
|
||||||
|
@ -466,7 +478,7 @@ BaseType_t xStreamBufferSetTriggerLevel( StreamBufferHandle_t xStreamBuffer,
|
||||||
|
|
||||||
/* The trigger level is the number of bytes that must be in the stream
|
/* The trigger level is the number of bytes that must be in the stream
|
||||||
* buffer before a task that is waiting for data is unblocked. */
|
* buffer before a task that is waiting for data is unblocked. */
|
||||||
if( xTriggerLevel <= pxStreamBuffer->xLength )
|
if( xTriggerLevel < pxStreamBuffer->xLength )
|
||||||
{
|
{
|
||||||
pxStreamBuffer->xTriggerLevelBytes = xTriggerLevel;
|
pxStreamBuffer->xTriggerLevelBytes = xTriggerLevel;
|
||||||
xReturn = pdPASS;
|
xReturn = pdPASS;
|
||||||
|
@ -484,11 +496,19 @@ size_t xStreamBufferSpacesAvailable( StreamBufferHandle_t xStreamBuffer )
|
||||||
{
|
{
|
||||||
const StreamBuffer_t * const pxStreamBuffer = xStreamBuffer;
|
const StreamBuffer_t * const pxStreamBuffer = xStreamBuffer;
|
||||||
size_t xSpace;
|
size_t xSpace;
|
||||||
|
size_t xOriginalTail;
|
||||||
|
|
||||||
configASSERT( pxStreamBuffer );
|
configASSERT( pxStreamBuffer );
|
||||||
|
|
||||||
xSpace = pxStreamBuffer->xLength + pxStreamBuffer->xTail;
|
/* The code below reads xTail and then xHead. This is safe if the stream
|
||||||
xSpace -= pxStreamBuffer->xHead;
|
buffer is updated once between the two reads - but not if the stream buffer
|
||||||
|
is updated more than once between the two reads - hence the loop. */
|
||||||
|
do
|
||||||
|
{
|
||||||
|
xOriginalTail = pxStreamBuffer->xTail;
|
||||||
|
xSpace = pxStreamBuffer->xLength + pxStreamBuffer->xTail;
|
||||||
|
xSpace -= pxStreamBuffer->xHead;
|
||||||
|
} while( xOriginalTail != pxStreamBuffer->xTail );
|
||||||
xSpace -= ( size_t ) 1;
|
xSpace -= ( size_t ) 1;
|
||||||
|
|
||||||
if( xSpace >= pxStreamBuffer->xLength )
|
if( xSpace >= pxStreamBuffer->xLength )
|
||||||
|
@ -525,14 +545,15 @@ size_t xStreamBufferSend( StreamBufferHandle_t xStreamBuffer,
|
||||||
size_t xReturn, xSpace = 0;
|
size_t xReturn, xSpace = 0;
|
||||||
size_t xRequiredSpace = xDataLengthBytes;
|
size_t xRequiredSpace = xDataLengthBytes;
|
||||||
TimeOut_t xTimeOut;
|
TimeOut_t xTimeOut;
|
||||||
|
size_t xMaxReportedSpace = 0;
|
||||||
/* The maximum amount of space a stream buffer will ever report is its length
|
|
||||||
* minus 1. */
|
|
||||||
const size_t xMaxReportedSpace = pxStreamBuffer->xLength - ( size_t ) 1;
|
|
||||||
|
|
||||||
configASSERT( pvTxData );
|
configASSERT( pvTxData );
|
||||||
configASSERT( pxStreamBuffer );
|
configASSERT( pxStreamBuffer );
|
||||||
|
|
||||||
|
/* The maximum amount of space a stream buffer will ever report is its length
|
||||||
|
* minus 1. */
|
||||||
|
xMaxReportedSpace = pxStreamBuffer->xLength - ( size_t ) 1;
|
||||||
|
|
||||||
/* This send function is used to write to both message buffers and stream
|
/* This send function is used to write to both message buffers and stream
|
||||||
* buffers. If this is a message buffer then the space needed must be
|
* buffers. If this is a message buffer then the space needed must be
|
||||||
* increased by the amount of bytes needed to store the length of the
|
* increased by the amount of bytes needed to store the length of the
|
||||||
|
@ -703,49 +724,40 @@ static size_t prvWriteMessageToBuffer( StreamBuffer_t * const pxStreamBuffer,
|
||||||
size_t xSpace,
|
size_t xSpace,
|
||||||
size_t xRequiredSpace )
|
size_t xRequiredSpace )
|
||||||
{
|
{
|
||||||
BaseType_t xShouldWrite;
|
size_t xNextHead = pxStreamBuffer->xHead;
|
||||||
size_t xReturn;
|
|
||||||
|
|
||||||
if( xSpace == ( size_t ) 0 )
|
if( ( pxStreamBuffer->ucFlags & sbFLAGS_IS_MESSAGE_BUFFER ) != ( uint8_t ) 0 )
|
||||||
{
|
{
|
||||||
/* Doesn't matter if this is a stream buffer or a message buffer, there
|
/* This is a message buffer, as opposed to a stream buffer. */
|
||||||
* is no space to write. */
|
|
||||||
xShouldWrite = pdFALSE;
|
if( xSpace >= xRequiredSpace )
|
||||||
|
{
|
||||||
|
/* There is enough space to write both the message length and the message
|
||||||
|
* itself into the buffer. Start by writing the length of the data, the data
|
||||||
|
* itself will be written later in this function. */
|
||||||
|
xNextHead = prvWriteBytesToBuffer( pxStreamBuffer, ( const uint8_t * ) &( xDataLengthBytes ), sbBYTES_TO_STORE_MESSAGE_LENGTH, xNextHead );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Not enough space, so do not write data to the buffer. */
|
||||||
|
xDataLengthBytes = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if( ( pxStreamBuffer->ucFlags & sbFLAGS_IS_MESSAGE_BUFFER ) == ( uint8_t ) 0 )
|
else
|
||||||
{
|
{
|
||||||
/* This is a stream buffer, as opposed to a message buffer, so writing a
|
/* This is a stream buffer, as opposed to a message buffer, so writing a
|
||||||
* stream of bytes rather than discrete messages. Write as many bytes as
|
* stream of bytes rather than discrete messages. Plan to write as many
|
||||||
* possible. */
|
* bytes as possible. */
|
||||||
xShouldWrite = pdTRUE;
|
|
||||||
xDataLengthBytes = configMIN( xDataLengthBytes, xSpace );
|
xDataLengthBytes = configMIN( xDataLengthBytes, xSpace );
|
||||||
}
|
}
|
||||||
else if( xSpace >= xRequiredSpace )
|
|
||||||
|
if( xDataLengthBytes != ( size_t ) 0 )
|
||||||
{
|
{
|
||||||
/* This is a message buffer, as opposed to a stream buffer, and there
|
/* Write the data to the buffer. */
|
||||||
* is enough space to write both the message length and the message itself
|
pxStreamBuffer->xHead = prvWriteBytesToBuffer( pxStreamBuffer, ( const uint8_t * ) pvTxData, xDataLengthBytes, xNextHead ); /*lint !e9079 Storage buffer is implemented as uint8_t for ease of sizing, alignment and access. */
|
||||||
* into the buffer. Start by writing the length of the data, the data
|
|
||||||
* itself will be written later in this function. */
|
|
||||||
xShouldWrite = pdTRUE;
|
|
||||||
( void ) prvWriteBytesToBuffer( pxStreamBuffer, ( const uint8_t * ) &( xDataLengthBytes ), sbBYTES_TO_STORE_MESSAGE_LENGTH );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* There is space available, but not enough space. */
|
|
||||||
xShouldWrite = pdFALSE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if( xShouldWrite != pdFALSE )
|
return xDataLengthBytes;
|
||||||
{
|
|
||||||
/* Writes the data itself. */
|
|
||||||
xReturn = prvWriteBytesToBuffer( pxStreamBuffer, ( const uint8_t * ) pvTxData, xDataLengthBytes ); /*lint !e9079 Storage buffer is implemented as uint8_t for ease of sizing, alignment and access. */
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
xReturn = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return xReturn;
|
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
@ -830,7 +842,7 @@ size_t xStreamBufferReceive( StreamBufferHandle_t xStreamBuffer,
|
||||||
* read bytes from the buffer. */
|
* read bytes from the buffer. */
|
||||||
if( xBytesAvailable > xBytesToStoreMessageLength )
|
if( xBytesAvailable > xBytesToStoreMessageLength )
|
||||||
{
|
{
|
||||||
xReceivedLength = prvReadMessageFromBuffer( pxStreamBuffer, pvRxData, xBufferLengthBytes, xBytesAvailable, xBytesToStoreMessageLength );
|
xReceivedLength = prvReadMessageFromBuffer( pxStreamBuffer, pvRxData, xBufferLengthBytes, xBytesAvailable );
|
||||||
|
|
||||||
/* Was a task waiting for space in the buffer? */
|
/* Was a task waiting for space in the buffer? */
|
||||||
if( xReceivedLength != ( size_t ) 0 )
|
if( xReceivedLength != ( size_t ) 0 )
|
||||||
|
@ -856,7 +868,7 @@ size_t xStreamBufferReceive( StreamBufferHandle_t xStreamBuffer,
|
||||||
size_t xStreamBufferNextMessageLengthBytes( StreamBufferHandle_t xStreamBuffer )
|
size_t xStreamBufferNextMessageLengthBytes( StreamBufferHandle_t xStreamBuffer )
|
||||||
{
|
{
|
||||||
StreamBuffer_t * const pxStreamBuffer = xStreamBuffer;
|
StreamBuffer_t * const pxStreamBuffer = xStreamBuffer;
|
||||||
size_t xReturn, xBytesAvailable, xOriginalTail;
|
size_t xReturn, xBytesAvailable;
|
||||||
configMESSAGE_BUFFER_LENGTH_TYPE xTempReturn;
|
configMESSAGE_BUFFER_LENGTH_TYPE xTempReturn;
|
||||||
|
|
||||||
configASSERT( pxStreamBuffer );
|
configASSERT( pxStreamBuffer );
|
||||||
|
@ -870,14 +882,9 @@ size_t xStreamBufferNextMessageLengthBytes( StreamBufferHandle_t xStreamBuffer )
|
||||||
{
|
{
|
||||||
/* The number of bytes available is greater than the number of bytes
|
/* The number of bytes available is greater than the number of bytes
|
||||||
* required to hold the length of the next message, so another message
|
* required to hold the length of the next message, so another message
|
||||||
* is available. Return its length without removing the length bytes
|
* is available. */
|
||||||
* from the buffer. A copy of the tail is stored so the buffer can be
|
( void ) prvReadBytesFromBuffer( pxStreamBuffer, ( uint8_t * ) &xTempReturn, sbBYTES_TO_STORE_MESSAGE_LENGTH, pxStreamBuffer->xTail );
|
||||||
* returned to its prior state as the message is not actually being
|
xReturn = ( size_t ) xTempReturn;
|
||||||
* removed from the buffer. */
|
|
||||||
xOriginalTail = pxStreamBuffer->xTail;
|
|
||||||
( void ) prvReadBytesFromBuffer( pxStreamBuffer, ( uint8_t * ) &xTempReturn, sbBYTES_TO_STORE_MESSAGE_LENGTH, xBytesAvailable );
|
|
||||||
xReturn = ( size_t ) xTempReturn;
|
|
||||||
pxStreamBuffer->xTail = xOriginalTail;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -932,7 +939,7 @@ size_t xStreamBufferReceiveFromISR( StreamBufferHandle_t xStreamBuffer,
|
||||||
* read bytes from the buffer. */
|
* read bytes from the buffer. */
|
||||||
if( xBytesAvailable > xBytesToStoreMessageLength )
|
if( xBytesAvailable > xBytesToStoreMessageLength )
|
||||||
{
|
{
|
||||||
xReceivedLength = prvReadMessageFromBuffer( pxStreamBuffer, pvRxData, xBufferLengthBytes, xBytesAvailable, xBytesToStoreMessageLength );
|
xReceivedLength = prvReadMessageFromBuffer( pxStreamBuffer, pvRxData, xBufferLengthBytes, xBytesAvailable );
|
||||||
|
|
||||||
/* Was a task waiting for space in the buffer? */
|
/* Was a task waiting for space in the buffer? */
|
||||||
if( xReceivedLength != ( size_t ) 0 )
|
if( xReceivedLength != ( size_t ) 0 )
|
||||||
|
@ -958,34 +965,28 @@ size_t xStreamBufferReceiveFromISR( StreamBufferHandle_t xStreamBuffer,
|
||||||
static size_t prvReadMessageFromBuffer( StreamBuffer_t * pxStreamBuffer,
|
static size_t prvReadMessageFromBuffer( StreamBuffer_t * pxStreamBuffer,
|
||||||
void * pvRxData,
|
void * pvRxData,
|
||||||
size_t xBufferLengthBytes,
|
size_t xBufferLengthBytes,
|
||||||
size_t xBytesAvailable,
|
size_t xBytesAvailable )
|
||||||
size_t xBytesToStoreMessageLength )
|
|
||||||
{
|
{
|
||||||
size_t xOriginalTail, xReceivedLength, xNextMessageLength;
|
size_t xCount, xNextMessageLength;
|
||||||
configMESSAGE_BUFFER_LENGTH_TYPE xTempNextMessageLength;
|
configMESSAGE_BUFFER_LENGTH_TYPE xTempNextMessageLength;
|
||||||
|
size_t xNextTail = pxStreamBuffer->xTail;
|
||||||
|
|
||||||
if( xBytesToStoreMessageLength != ( size_t ) 0 )
|
if( ( pxStreamBuffer->ucFlags & sbFLAGS_IS_MESSAGE_BUFFER ) != ( uint8_t ) 0 )
|
||||||
{
|
{
|
||||||
/* A discrete message is being received. First receive the length
|
/* A discrete message is being received. First receive the length
|
||||||
* of the message. A copy of the tail is stored so the buffer can be
|
* of the message. */
|
||||||
* returned to its prior state if the length of the message is too
|
xNextTail = prvReadBytesFromBuffer( pxStreamBuffer, ( uint8_t * ) &xTempNextMessageLength, sbBYTES_TO_STORE_MESSAGE_LENGTH, xNextTail );
|
||||||
* large for the provided buffer. */
|
|
||||||
xOriginalTail = pxStreamBuffer->xTail;
|
|
||||||
( void ) prvReadBytesFromBuffer( pxStreamBuffer, ( uint8_t * ) &xTempNextMessageLength, xBytesToStoreMessageLength, xBytesAvailable );
|
|
||||||
xNextMessageLength = ( size_t ) xTempNextMessageLength;
|
xNextMessageLength = ( size_t ) xTempNextMessageLength;
|
||||||
|
|
||||||
/* Reduce the number of bytes available by the number of bytes just
|
/* Reduce the number of bytes available by the number of bytes just
|
||||||
* read out. */
|
* read out. */
|
||||||
xBytesAvailable -= xBytesToStoreMessageLength;
|
xBytesAvailable -= sbBYTES_TO_STORE_MESSAGE_LENGTH;
|
||||||
|
|
||||||
/* Check there is enough space in the buffer provided by the
|
/* Check there is enough space in the buffer provided by the
|
||||||
* user. */
|
* user. */
|
||||||
if( xNextMessageLength > xBufferLengthBytes )
|
if( xNextMessageLength > xBufferLengthBytes )
|
||||||
{
|
{
|
||||||
/* The user has provided insufficient space to read the message
|
/* The user has provided insufficient space to read the message. */
|
||||||
* so return the buffer to its previous state (so the length of
|
|
||||||
* the message is in the buffer again). */
|
|
||||||
pxStreamBuffer->xTail = xOriginalTail;
|
|
||||||
xNextMessageLength = 0;
|
xNextMessageLength = 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -1000,10 +1001,16 @@ static size_t prvReadMessageFromBuffer( StreamBuffer_t * pxStreamBuffer,
|
||||||
xNextMessageLength = xBufferLengthBytes;
|
xNextMessageLength = xBufferLengthBytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Read the actual data. */
|
/* Use the minimum of the wanted bytes and the available bytes. */
|
||||||
xReceivedLength = prvReadBytesFromBuffer( pxStreamBuffer, ( uint8_t * ) pvRxData, xNextMessageLength, xBytesAvailable ); /*lint !e9079 Data storage area is implemented as uint8_t array for ease of sizing, indexing and alignment. */
|
xCount = configMIN( xNextMessageLength, xBytesAvailable );
|
||||||
|
|
||||||
return xReceivedLength;
|
if( xCount != ( size_t ) 0 )
|
||||||
|
{
|
||||||
|
/* Read the actual data and update the tail to mark the data as officially consumed. */
|
||||||
|
pxStreamBuffer->xTail = prvReadBytesFromBuffer( pxStreamBuffer, ( uint8_t * ) pvRxData, xCount, xNextTail); /*lint !e9079 Data storage area is implemented as uint8_t array for ease of sizing, indexing and alignment. */
|
||||||
|
}
|
||||||
|
|
||||||
|
return xCount;
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
@ -1130,22 +1137,21 @@ BaseType_t xStreamBufferReceiveCompletedFromISR( StreamBufferHandle_t xStreamBuf
|
||||||
|
|
||||||
static size_t prvWriteBytesToBuffer( StreamBuffer_t * const pxStreamBuffer,
|
static size_t prvWriteBytesToBuffer( StreamBuffer_t * const pxStreamBuffer,
|
||||||
const uint8_t * pucData,
|
const uint8_t * pucData,
|
||||||
size_t xCount )
|
size_t xCount,
|
||||||
|
size_t xHead )
|
||||||
{
|
{
|
||||||
size_t xNextHead, xFirstLength;
|
size_t xFirstLength;
|
||||||
|
|
||||||
configASSERT( xCount > ( size_t ) 0 );
|
configASSERT( xCount > ( size_t ) 0 );
|
||||||
|
|
||||||
xNextHead = pxStreamBuffer->xHead;
|
|
||||||
|
|
||||||
/* Calculate the number of bytes that can be added in the first write -
|
/* Calculate the number of bytes that can be added in the first write -
|
||||||
* which may be less than the total number of bytes that need to be added if
|
* which may be less than the total number of bytes that need to be added if
|
||||||
* the buffer will wrap back to the beginning. */
|
* the buffer will wrap back to the beginning. */
|
||||||
xFirstLength = configMIN( pxStreamBuffer->xLength - xNextHead, xCount );
|
xFirstLength = configMIN( pxStreamBuffer->xLength - xHead, xCount );
|
||||||
|
|
||||||
/* Write as many bytes as can be written in the first write. */
|
/* Write as many bytes as can be written in the first write. */
|
||||||
configASSERT( ( xNextHead + xFirstLength ) <= pxStreamBuffer->xLength );
|
configASSERT( ( xHead + xFirstLength ) <= pxStreamBuffer->xLength );
|
||||||
( void ) memcpy( ( void * ) ( &( pxStreamBuffer->pucBuffer[ xNextHead ] ) ), ( const void * ) pucData, xFirstLength ); /*lint !e9087 memcpy() requires void *. */
|
( void ) memcpy( ( void * ) ( &( pxStreamBuffer->pucBuffer[ xHead ] ) ), ( const void * ) pucData, xFirstLength ); /*lint !e9087 memcpy() requires void *. */
|
||||||
|
|
||||||
/* If the number of bytes written was less than the number that could be
|
/* If the number of bytes written was less than the number that could be
|
||||||
* written in the first write... */
|
* written in the first write... */
|
||||||
|
@ -1160,78 +1166,63 @@ static size_t prvWriteBytesToBuffer( StreamBuffer_t * const pxStreamBuffer,
|
||||||
mtCOVERAGE_TEST_MARKER();
|
mtCOVERAGE_TEST_MARKER();
|
||||||
}
|
}
|
||||||
|
|
||||||
xNextHead += xCount;
|
xHead += xCount;
|
||||||
|
|
||||||
if( xNextHead >= pxStreamBuffer->xLength )
|
if( xHead >= pxStreamBuffer->xLength )
|
||||||
{
|
{
|
||||||
xNextHead -= pxStreamBuffer->xLength;
|
xHead -= pxStreamBuffer->xLength;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
mtCOVERAGE_TEST_MARKER();
|
mtCOVERAGE_TEST_MARKER();
|
||||||
}
|
}
|
||||||
|
|
||||||
pxStreamBuffer->xHead = xNextHead;
|
return xHead;
|
||||||
|
|
||||||
return xCount;
|
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
static size_t prvReadBytesFromBuffer( StreamBuffer_t * pxStreamBuffer,
|
static size_t prvReadBytesFromBuffer( StreamBuffer_t * pxStreamBuffer,
|
||||||
uint8_t * pucData,
|
uint8_t * pucData,
|
||||||
size_t xMaxCount,
|
size_t xCount,
|
||||||
size_t xBytesAvailable )
|
size_t xTail )
|
||||||
{
|
{
|
||||||
size_t xCount, xFirstLength, xNextTail;
|
size_t xFirstLength;
|
||||||
|
|
||||||
/* Use the minimum of the wanted bytes and the available bytes. */
|
configASSERT( xCount != ( size_t ) 0 );
|
||||||
xCount = configMIN( xBytesAvailable, xMaxCount );
|
|
||||||
|
|
||||||
if( xCount > ( size_t ) 0 )
|
/* Calculate the number of bytes that can be read - which may be
|
||||||
|
* less than the number wanted if the data wraps around to the start of
|
||||||
|
* the buffer. */
|
||||||
|
xFirstLength = configMIN( pxStreamBuffer->xLength - xTail, xCount );
|
||||||
|
|
||||||
|
/* Obtain the number of bytes it is possible to obtain in the first
|
||||||
|
* read. Asserts check bounds of read and write. */
|
||||||
|
configASSERT( xFirstLength <= xCount );
|
||||||
|
configASSERT( ( xTail + xFirstLength ) <= pxStreamBuffer->xLength );
|
||||||
|
( void ) memcpy( ( void * ) pucData, ( const void * ) &( pxStreamBuffer->pucBuffer[ xTail ] ), xFirstLength ); /*lint !e9087 memcpy() requires void *. */
|
||||||
|
|
||||||
|
/* If the total number of wanted bytes is greater than the number
|
||||||
|
* that could be read in the first read... */
|
||||||
|
if( xCount > xFirstLength )
|
||||||
{
|
{
|
||||||
xNextTail = pxStreamBuffer->xTail;
|
/* ...then read the remaining bytes from the start of the buffer. */
|
||||||
|
configASSERT( xCount <= xCount );
|
||||||
/* Calculate the number of bytes that can be read - which may be
|
( void ) memcpy( ( void * ) &( pucData[ xFirstLength ] ), ( void * ) ( pxStreamBuffer->pucBuffer ), xCount - xFirstLength ); /*lint !e9087 memcpy() requires void *. */
|
||||||
* less than the number wanted if the data wraps around to the start of
|
|
||||||
* the buffer. */
|
|
||||||
xFirstLength = configMIN( pxStreamBuffer->xLength - xNextTail, xCount );
|
|
||||||
|
|
||||||
/* Obtain the number of bytes it is possible to obtain in the first
|
|
||||||
* read. Asserts check bounds of read and write. */
|
|
||||||
configASSERT( xFirstLength <= xMaxCount );
|
|
||||||
configASSERT( ( xNextTail + xFirstLength ) <= pxStreamBuffer->xLength );
|
|
||||||
( void ) memcpy( ( void * ) pucData, ( const void * ) &( pxStreamBuffer->pucBuffer[ xNextTail ] ), xFirstLength ); /*lint !e9087 memcpy() requires void *. */
|
|
||||||
|
|
||||||
/* If the total number of wanted bytes is greater than the number
|
|
||||||
* that could be read in the first read... */
|
|
||||||
if( xCount > xFirstLength )
|
|
||||||
{
|
|
||||||
/*...then read the remaining bytes from the start of the buffer. */
|
|
||||||
configASSERT( xCount <= xMaxCount );
|
|
||||||
( void ) memcpy( ( void * ) &( pucData[ xFirstLength ] ), ( void * ) ( pxStreamBuffer->pucBuffer ), xCount - xFirstLength ); /*lint !e9087 memcpy() requires void *. */
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
mtCOVERAGE_TEST_MARKER();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Move the tail pointer to effectively remove the data read from
|
|
||||||
* the buffer. */
|
|
||||||
xNextTail += xCount;
|
|
||||||
|
|
||||||
if( xNextTail >= pxStreamBuffer->xLength )
|
|
||||||
{
|
|
||||||
xNextTail -= pxStreamBuffer->xLength;
|
|
||||||
}
|
|
||||||
|
|
||||||
pxStreamBuffer->xTail = xNextTail;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
mtCOVERAGE_TEST_MARKER();
|
mtCOVERAGE_TEST_MARKER();
|
||||||
}
|
}
|
||||||
|
|
||||||
return xCount;
|
/* Move the tail pointer to effectively remove the data read from the buffer. */
|
||||||
|
xTail += xCount;
|
||||||
|
|
||||||
|
if( xTail >= pxStreamBuffer->xLength )
|
||||||
|
{
|
||||||
|
xTail -= pxStreamBuffer->xLength;
|
||||||
|
}
|
||||||
|
|
||||||
|
return xTail;
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
26
tasks.c
26
tasks.c
|
@ -295,7 +295,6 @@ typedef struct tskTaskControlBlock /* The old naming convention is used to
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if ( configUSE_NEWLIB_REENTRANT == 1 )
|
#if ( configUSE_NEWLIB_REENTRANT == 1 )
|
||||||
|
|
||||||
/* Allocate a Newlib reent structure that is specific to this task.
|
/* Allocate a Newlib reent structure that is specific to this task.
|
||||||
* Note Newlib support has been included by popular demand, but is not
|
* Note Newlib support has been included by popular demand, but is not
|
||||||
* used by the FreeRTOS maintainers themselves. FreeRTOS is not
|
* used by the FreeRTOS maintainers themselves. FreeRTOS is not
|
||||||
|
@ -913,8 +912,8 @@ static void prvInitialiseNewTask( TaskFunction_t pxTaskCode,
|
||||||
pxNewTCB->pcTaskName[ 0 ] = 0x00;
|
pxNewTCB->pcTaskName[ 0 ] = 0x00;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This is used as an array index so must ensure it's not too large. First
|
/* This is used as an array index so must ensure it's not too large. */
|
||||||
* remove the privilege bit if one is present. */
|
configASSERT( uxPriority < configMAX_PRIORITIES );
|
||||||
if( uxPriority >= ( UBaseType_t ) configMAX_PRIORITIES )
|
if( uxPriority >= ( UBaseType_t ) configMAX_PRIORITIES )
|
||||||
{
|
{
|
||||||
uxPriority = ( UBaseType_t ) configMAX_PRIORITIES - ( UBaseType_t ) 1U;
|
uxPriority = ( UBaseType_t ) configMAX_PRIORITIES - ( UBaseType_t ) 1U;
|
||||||
|
@ -1544,7 +1543,7 @@ static void prvAddNewTaskToReadyList( TCB_t * pxNewTCB )
|
||||||
UBaseType_t uxCurrentBasePriority, uxPriorityUsedOnEntry;
|
UBaseType_t uxCurrentBasePriority, uxPriorityUsedOnEntry;
|
||||||
BaseType_t xYieldRequired = pdFALSE;
|
BaseType_t xYieldRequired = pdFALSE;
|
||||||
|
|
||||||
configASSERT( ( uxNewPriority < configMAX_PRIORITIES ) );
|
configASSERT( uxNewPriority < configMAX_PRIORITIES );
|
||||||
|
|
||||||
/* Ensure the new priority is valid. */
|
/* Ensure the new priority is valid. */
|
||||||
if( uxNewPriority >= ( UBaseType_t ) configMAX_PRIORITIES )
|
if( uxNewPriority >= ( UBaseType_t ) configMAX_PRIORITIES )
|
||||||
|
@ -2238,8 +2237,8 @@ BaseType_t xTaskResumeAll( void )
|
||||||
( void ) uxListRemove( &( pxTCB->xStateListItem ) );
|
( void ) uxListRemove( &( pxTCB->xStateListItem ) );
|
||||||
prvAddTaskToReadyList( pxTCB );
|
prvAddTaskToReadyList( pxTCB );
|
||||||
|
|
||||||
/* If the moved task has a priority higher than the current
|
/* If the moved task has a priority higher than or equal to
|
||||||
* task then a yield must be performed. */
|
* the current task then a yield must be performed. */
|
||||||
if( pxTCB->uxPriority >= pxCurrentTCB->uxPriority )
|
if( pxTCB->uxPriority >= pxCurrentTCB->uxPriority )
|
||||||
{
|
{
|
||||||
xYieldPending = pdTRUE;
|
xYieldPending = pdTRUE;
|
||||||
|
@ -2694,8 +2693,8 @@ BaseType_t xTaskCatchUpTicks( TickType_t xTicksToCatchUp )
|
||||||
#if ( configUSE_PREEMPTION == 1 )
|
#if ( configUSE_PREEMPTION == 1 )
|
||||||
{
|
{
|
||||||
/* Preemption is on, but a context switch should only be
|
/* Preemption is on, but a context switch should only be
|
||||||
* performed if the unblocked task has a priority that is
|
* performed if the unblocked task has a priority that is
|
||||||
* equal to or higher than the currently executing task. */
|
* higher than the currently executing task. */
|
||||||
if( pxTCB->uxPriority > pxCurrentTCB->uxPriority )
|
if( pxTCB->uxPriority > pxCurrentTCB->uxPriority )
|
||||||
{
|
{
|
||||||
/* Pend the yield to be performed when the scheduler
|
/* Pend the yield to be performed when the scheduler
|
||||||
|
@ -3093,8 +3092,15 @@ void vTaskPlaceOnEventList( List_t * const pxEventList,
|
||||||
|
|
||||||
/* Place the event list item of the TCB in the appropriate event list.
|
/* Place the event list item of the TCB in the appropriate event list.
|
||||||
* This is placed in the list in priority order so the highest priority task
|
* This is placed in the list in priority order so the highest priority task
|
||||||
* is the first to be woken by the event. The queue that contains the event
|
* is the first to be woken by the event.
|
||||||
* list is locked, preventing simultaneous access from interrupts. */
|
*
|
||||||
|
* Note: Lists are sorted in ascending order by ListItem_t.xItemValue.
|
||||||
|
* Normally, the xItemValue of a TCB's ListItem_t members is:
|
||||||
|
* xItemValue = ( configMAX_PRIORITIES - uxPriority )
|
||||||
|
* Therefore, the event list is sorted in descending priority order.
|
||||||
|
*
|
||||||
|
* The queue that contains the event list is locked, preventing
|
||||||
|
* simultaneous access from interrupts. */
|
||||||
vListInsert( pxEventList, &( pxCurrentTCB->xEventListItem ) );
|
vListInsert( pxEventList, &( pxCurrentTCB->xEventListItem ) );
|
||||||
|
|
||||||
prvAddCurrentTaskToDelayedList( xTicksToWait, pdTRUE );
|
prvAddCurrentTaskToDelayedList( xTicksToWait, pdTRUE );
|
||||||
|
|
35
timers.c
35
timers.c
|
@ -350,27 +350,24 @@
|
||||||
/* 0 is not a valid value for xTimerPeriodInTicks. */
|
/* 0 is not a valid value for xTimerPeriodInTicks. */
|
||||||
configASSERT( ( xTimerPeriodInTicks > 0 ) );
|
configASSERT( ( xTimerPeriodInTicks > 0 ) );
|
||||||
|
|
||||||
if( pxNewTimer != NULL )
|
/* Ensure the infrastructure used by the timer service task has been
|
||||||
|
* created/initialised. */
|
||||||
|
prvCheckForValidListAndQueue();
|
||||||
|
|
||||||
|
/* Initialise the timer structure members using the function
|
||||||
|
* parameters. */
|
||||||
|
pxNewTimer->pcTimerName = pcTimerName;
|
||||||
|
pxNewTimer->xTimerPeriodInTicks = xTimerPeriodInTicks;
|
||||||
|
pxNewTimer->pvTimerID = pvTimerID;
|
||||||
|
pxNewTimer->pxCallbackFunction = pxCallbackFunction;
|
||||||
|
vListInitialiseItem( &( pxNewTimer->xTimerListItem ) );
|
||||||
|
|
||||||
|
if( uxAutoReload != pdFALSE )
|
||||||
{
|
{
|
||||||
/* Ensure the infrastructure used by the timer service task has been
|
pxNewTimer->ucStatus |= tmrSTATUS_IS_AUTORELOAD;
|
||||||
* created/initialised. */
|
|
||||||
prvCheckForValidListAndQueue();
|
|
||||||
|
|
||||||
/* Initialise the timer structure members using the function
|
|
||||||
* parameters. */
|
|
||||||
pxNewTimer->pcTimerName = pcTimerName;
|
|
||||||
pxNewTimer->xTimerPeriodInTicks = xTimerPeriodInTicks;
|
|
||||||
pxNewTimer->pvTimerID = pvTimerID;
|
|
||||||
pxNewTimer->pxCallbackFunction = pxCallbackFunction;
|
|
||||||
vListInitialiseItem( &( pxNewTimer->xTimerListItem ) );
|
|
||||||
|
|
||||||
if( uxAutoReload != pdFALSE )
|
|
||||||
{
|
|
||||||
pxNewTimer->ucStatus |= tmrSTATUS_IS_AUTORELOAD;
|
|
||||||
}
|
|
||||||
|
|
||||||
traceTIMER_CREATE( pxNewTimer );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
traceTIMER_CREATE( pxNewTimer );
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue