Sunday, August 25, 2019

[Study FreeRTOS-Task API] 2.10 vTaskDelayUntil()

#include "FreeRTOS.h"
#include "task.h"

void vTaskDelayUntil(TickType_t *pxPreviousWakeTime,TickType_t xTimeIncrement);

Summary
Places  the  task  that  calls  vTaskDelayUntil()  into  the  Blocked  state  until  an  absolute  time  is
reached.
Periodic tasks can use vTaskDelayUntil() to achieve a constant execution frequency.
Differences Between vTaskDelay() and  vTaskDelayUntil()
vTaskDelay()  results in  the calling task  entering into the Blocked state, and then remaining in
the  Blocked  state,  for the  specified  number  of ticks from the  time  vTaskDelay()  was  called.
The time at which the task  that called vTaskDelay()  exits the Blocked state is  relative  to when
vTaskDelay() was called.
vTaskDelayUntil()  results  in  the  calling  task  entering  into  the  Blocked  state,  and  then
remaining in the Blocked state, until an  absolute  time has been reached. The task that called
vTaskDelayUntil()  exits  the  Blocked state  exactly  at  the  specified  time, not  at  a  time that  is
relative to when vTaskDelayUntil() was called.

Parameters
pxPreviousWakeTime - This parameter is named on the assumption that vTaskDelayUntil() is
being used to implement a task that executes periodically and with a fixed frequency. In this case pxPreviousWakeTime holds the time at which the task last left the Blocked state (was ‘woken’ up). This time is used as a reference point to calculate the time at which t he task should next leave the
Blocked state.
The variable pointed to by pxPreviousWakeTime is updated automatically within the vTaskDelayUntil() function; it would not normally be modified by the application code, other than when the variable is first initialized.  The example in this section demonstrates
how the initialization is performed.
xTimeIncrement  This parameter is also named on the assumption that
vTaskDelayUntil() is being used to implement a task that executes
periodically and with a fixed frequency – the frequency being set by
the xTimeIncrement value.
xTimeIncrement is specified in ‘ticks’. The pdMS_TO_TICKS() macro
can be used to convert milliseconds to ticks.

Return Values
None.

Notes
INCLUDE_vTaskDelayUntil  must be set to 1 in FreeRTOSConfig.h for the vTaskDelay() API
function to be available.


Example 
/* Define a task that performs an action every 50 milliseconds. */
void vCyclicTaskFunction( void * pvParameters )
{
TickType_t xLastWakeTime;
const TickType_t xPeriod = pdMS_TO_TICKS( 50 );
/* The xLastWakeTime variable needs to be initialized with the current tick count. Note that this is the only time the variable is written to explicitly.After this assignment, xLastWakeTime is updated automatically internally within vTaskDelayUntil(). */
xLastWakeTime = xTaskGetTickCount();

/* Enter the loop that defines the task behavior. */
for( ;; )
{
/* This task should execute every 50 milliseconds. Time is measured in ticks. The pdMS_TO_TICKS macro is used to convert milliseconds into ticks. xLastWakeTime is automatically updated within vTaskDelayUntil() so is not explicitly updated by the task. */
vTaskDelayUntil( &xLastWakeTime, xPeriod );

/* Perform the periodic actions here. */
}
}

[Study FreeRTOS-Task API] 2.11 vTaskDelete ( )

#include "FreeRTOS.h"
#include "task.h"

void vTaskDelete(TaskHandle_t pxTask);

Summary
Deletes  an  instance  of  a  task  that  was  previously  created  using  a  call  to  xTaskCreate()  or
xTaskCreateStatic().
Deleted tasks no longer exist so cannot enter the Running state.
Do not attempt to use a task handle to reference a task that has been deleted.
When a task is deleted, it is the responsibility of the idle task to free the memory that had been
used to hold the deleted task’s stack and data structures (task  control block).  Therefore, if an
application  makes  use  of  the  vTaskDelete()  API  function,  it  is  vital  that  the  application  also
ensures the idle task is not starved of processing time (the idle task must be allocated time in
the Running state).
Only memory that is allocated to a task by the kernel itself is automatically freed when a task is
deleted.  Memory,  or any other resource,  that the  application (rather than the kernel) allocates
to a task must be explicitly freed by the application when the task is deleted.


Parameters
pxTask  The handle of the task being deleted (the subject task).
To obtain a task’s handle create the task using xTaskCreate() and make use of the pxCreatedTask parameter, or create the task using xTaskCreateStatic() and store the returned value, or use the task’s name in a call to xTaskGetHandle().
A task can delete itself by passing NULL in place of a valid task handle.

Return Values
None.


Example
void vAnotherFunction( void )
{
TaskHandle_t xHandle;
/* Create a task, storing the handle to the created task in xHandle. */
if(
xTaskCreate(
vTaskCode,
"Demo task",
STACK_SIZE,
NULL,
PRIORITY,
&xHandle /* The address of xHandle is passed in as the last parameter to xTaskCreate() to obtain a handle to the task being created. */
)
!= pdPASS )
{
/* The task could not be created because there was not enough FreeRTOS heap memory available for the task data structures and stack to be allocated. */
}
else
{
/* Delete the task just created. Use the handle passed out of xTaskCreate() to reference the subject task. */
vTaskDelete( xHandle );
}
/* Delete the task that called this function by passing NULL in as the vTaskDelete() parameter. The same task (this task) could also be deleted by passing in a valid handle to itself. */
vTaskDelete( NULL );
}

[Study FreeRTOS-Semaphore API] 4.1 vSemaphoreCreateBinary()

#include "FreeRTOS.h"
#include "semphr.h"

vSemaphoreCreateBinary(SemaphoreHandle_t xSemaphore);

Summary
NOTE: The vSemaphoreCreateBinary() macro remains in the source code to ensure backward
compatibility, but it should not be used in new designs. Use the xSemaphoreCreateBinary()
function instead.
A macro that creates a binary semaphore. A semaphore must be explicitly created before it
can be used.

Parameters
xSemaphore  Variable of type SemaphoreHandle_t that will store the handle of the semaphore being created.

Return Values
None.

If,  following  a  call  to  vSemaphoreCreateBinary(),  xSemaphore  is  equal  to  NULL,  then  the
semaphore  cannot  be  created  because  there  is  insufficient  heap  memory  available  for
FreeRTOS  to  allocate  the  semaphore  data  structures.   In  all  other  cases,  xSemaphore  will
hold the handle of the created semaphore.

Notes
Binary  semaphores  and  mutexes  are  very  similar,  but  do  have  some  subtle  differences.
Mutexes  include  a  priority  inheritance  mechanism,  binary  semaphores  do  not.  This  makes
binary  semaphores  the  better  choice  for  implementing  synchronization  (between  tasks  or
between  tasks  and  an  interrupt),  and  mutexes  the  better  choice  for  implementing  simple
mutual exclusion. 


Binary  Semaphores  –  A  binary  semaphore  used  for  synchronization  does  not  need  to  be
‘given’  back  after  it  has  been  successfully  ‘taken’  (obtained).   Task  synchronization  is
implemented by  having one task  or interrupt  ‘give’  the semaphore, and  another task  ‘take’  the
semaphore (see the xSemaphoreGiveFromISR() documentation).
Mutexes  –  The priority of a task that  holds  a mutex  will  be raised if another task of higher
priority attempts to obtain the same  mutex.    The task that  already holds  the mutex  is said to
‘inherit’  the  priority  of  the  task  that  is  attempting  to  ‘take’  the  same  mutex.   The  inherited
priority will be ‘disinherited’ when the mutex is returned (the task that inherited a higher priority
while it held a mutex will return to its original priority when the mutex is returned).
A task that obtains a mutex that is used for mutual exclusion must always give the mutex back
–  otherwise no other task will ever be able to obtain the same mutex.    An example of a mutex
being used to implement mutual exclusion is provided in the xSemaphoreTake() section of this
manual.
Mutexes  and  binary  semaphores  are  both  referenced  using  variables  that  have  an
SemaphoreHandle_t  type,  and can be used in any API function  that takes a parameter of  that
type.
Mutexes and binary semaphores  that were  created using the  old  vSemaphoreCreateBinary()
macro,  as  opposed  to  the  preferred  xSemaphoreCreateBinary()  function,  are  both  created
such  that  the  first  call  to  xSemaphoreTake()  on  the  semaphore  or  mutex  will  pass.  Note
vSemaphoreCreateBinary() is deprecated and must not be used in new applications.  Binary
semaphores created using the xSemaphoreCreateBinary() function are created ‘empty’, so the
semaphore must first be given before the semaphore can be taken (obtained) using a call to
xSemaphoreTake().


Example
SemaphoreHandle_t xSemaphore;
void vATask( void * pvParameters )
{
/* Attempt to create a semaphore.
NOTE: New designs should use the xSemaphoreCreateBinary() function, not the vSemaphoreCreateBinary() macro. */
vSemaphoreCreateBinary( xSemaphore );

if( xSemaphore == NULL )
{
/* There was insufficient FreeRTOS heap available for the semaphore to
be created successfully. */
}
else
{
/* The semaphore can now be used. Its handle is stored in the xSemaphore
variable. */
}

[Study FreeRTOS-API] 2.26 xTaskResumeAll ()

#include "FreeRTOS.h"
#include "task.h"

BaseType_t xTaskResumeAll(void);

Summary
Resumes  scheduler  activity,  following  a  previous  call  to  vTaskSuspendAll(),  by  transitioning
the scheduler into the Active state from the Suspended state.

Parameters
None.

Return Values
pdTRUE  The scheduler was transitioned into the Active state. The transition caused a
pending context switch to occur.
pdFALSE  Either the scheduler was transitioned into the Active state and the transition did not
cause a context switch to occur, or the scheduler was left in the Suspended state
due to nested calls to vTaskSuspendAll().


Notes
The  scheduler  can  be  suspended  by  calling  vTaskSuspendAll().   When  the  scheduler  is
suspended,  interrupts remain enabled, but a context switch  will not  occur. If a context switch
is requested while the scheduler is suspended, then the request will be held pending until such
time that the scheduler is resumed (un-suspended).
Calls  to  vTaskSuspendAll()  can  be  nested.   The  same  number  of  calls  must  be  made  to
xTaskResumeAll() as have previously been made to  vTaskSuspendAll() before the scheduler
will leave the Suspended state and re-enter the Active state.
xTaskResumeAll()  must  only  be  called  from  an  executing  task  and  therefore  must  not  be
called while the scheduler is in the Initialization state (prior to the scheduler being started).

Other FreeRTOS API functions should not be called while the scheduler is suspended.
Example
137
/* A function that suspends then resumes the scheduler. */
void vDemoFunction( void )
{
/* This function suspends the scheduler. When it is called from vTask1 the
scheduler is already suspended, so this call creates a nesting depth of 2. */
vTaskSuspendAll();
/* Perform an action here. */
/* As calls to vTaskSuspendAll() are now nested, resuming the scheduler here
does not cause the scheduler to re-enter the active state. */
xTaskResumeAll();
}
void vTask1( void * pvParameters )
{
for( ;; )
{
/* Perform some actions here. */
/* At some point the task wants to perform an operation during which it  does not want to get swapped out, or it wants to access data which is also accessed from another task (but not from an interrupt).  It cannot use taskENTER_CRITICAL()/taskEXIT_CRITICAL() as the length of the operation may cause interrupts to be missed. */

/* Prevent the scheduler from performing a context switch. */
vTaskSuspendAll();
/* Perform the operation here. There is no need to use critical sections as the task has all the processing time other than that utilized by interrupt service routines.*/
/* Calls to vTaskSuspendAll() can be nested, so it is safe to call a (nonAPI) function that also calls vTaskSuspendAll(). API functions should not be called while the scheduler is suspended. */
vDemoFunction();

/* The operation is complete. Set the scheduler back into the Active
state. */
if( xTaskResumeAll() == pdTRUE )
{
/* A context switch occurred within xTaskResumeAll(). */
}
else
{
/* A context switch did not occur within xTaskResumeAll(). */
}
}
}

[Study FreeRTOS-API] 2.25 vTaskResume( )

#include "FreeRTOS.h"
#include "task.h"

void vTaskResume(TaskHandle_t pxTaskToResume);

Summary
Transition a task from the Suspended state to the Ready state. The task must have previously
been placed into the Suspended state using a call to vTaskSuspend().

Parameters
pxTaskToResume  The handle of the task being resumed (transitioned out of the Suspended
state).  This is the subject task.
To obtain a task’s handle create the task using xTaskCreate() and make
use of the pxCreatedTask parameter, or create the task using xTaskCreateStatic() and store the returned value, or use the task’s name in a call to xTaskGetHandle().

Return Values
None.


Notes
A task can be blocked to wait for a queue event, specifying a timeout period. It is legitimate to
move such a Blocked task into the Suspended state using a call to vTaskSuspend(), then out
of the Suspended state and into the Ready state using a call to  vTaskResume(). Following
this scenario, the next time the task enters the Running state it will check whether or not its
timeout period has (in  the meantime) expired. If the timeout period has not expired,  the task
will once again enter the Blocked state to wait for the queue  event for the remainder of the
originally specified timeout period.


A  task  can  also  be  blocked  to  wait  for  a  temporal  event  using  the  vTaskDelay()  or
vTaskDelayUntil()  API  functions.   It  is  legitimate  to  move  such  a  Blocked  task  into  the
Suspended state using a call to vTaskSuspend(), then out of the Suspended state and into the
Ready state using a call to  vTaskResume(). Following this scenario, the next time the task
enters  the  Running state  it  will  exit  the  vTaskDelay()  or  vTaskDelayUntil() function  as  if the
specified delay period had expired, even if this is not actually the case.
vTaskResume() must only be called from an executing task and therefore must not be called
while the scheduler is in the Initialization state (prior to the scheduler being started).


Example 
void vAFunction( void )
{
TaskHandle_t xHandle;
/* Create a task, storing the handle to the created task in xHandle. */
if( xTaskCreate( vTaskCode,
"Demo task",
STACK_SIZE,
NULL,
PRIORITY,
&xHandle
) != pdPASS )
{
/* The task was not created successfully. */
}
else
{
/* Use the handle to suspend the created task. */
vTaskSuspend( xHandle );

/* The suspended task will not run during this period, unless another task
calls vTaskResume( xHandle ). */

/* Resume the suspended task again. */
vTaskResume( xHandle );

/* The created task is again available to the scheduler and can enter The Running state. */
}

[Study FreeRTOS-API] 2.24 vTaskPrioritySet ()

#include "FreeRTOS.h"
#include "task.h"

void vTaskPrioritySet(TaskHandle_t pxTask,UBaseType_t uxNewPriority);

Summary
Changes the priority of a task.

Parameters
pxTask  The handle of the task being modified (the subject task).
To obtain a task’s handle create the task using xTaskCreate() and make use of the pxCreatedTask parameter, or create the task using xTaskCreateStatic() and store the returned value, or use the task’s name in a call to xTaskGetHandle().
A task can change its own priority by passing NULL in place of a valid task
handle.
uxNewPriority  The priority to which the subject task will be set.  Priorities can be assigned
from 0, which is the lowest priority, to (configMAX_PRIORITIES – 1), which is the highest priority.
configMAX_PRIORITIES is defined in FreeRTOSConfig.h.  Passing a value above (configMAX_PRIORITIES – 1) will result in the priority assigned to the task being capped to the maximum legitimate value.


Return Values
None.

Notes
vTaskPrioritySet()  must  only  be  called  from  an  executing  task,  and  therefore  must  not  be
called while the scheduler is in the Initialization state (prior to the scheduler being started).
It  is  possible  to  have  a  set  of  tasks  that  are  all  blocked  waiting  for  the  same  queue  or
semaphore event.  These tasks will be ordered according to their priority  –  for example,  the
first event will unblock the highest priority task  that was waiting for the event, the second event
will  unblock  the  second  highest  priority  task  that  was  originally  waiting  for  the  event,  etc.
Using vTaskPrioritySet() to change the priority of  such a blocked task will not cause the  order
in which the blocked tasks are assessed to be re-evaluated.


Example
void vAFunction( void )
{
TaskHandle_t xHandle;
/* Create a task, storing the handle of the created task in xHandle. */
if( xTaskCreate( vTaskCode,
"Demo task",
STACK_SIZE,
NULL,
PRIORITY,
&xHandle
) != pdPASS )
{
/* The task was not created successfully. */
}
else
{
/* Use the handle to raise the priority of the created task. */
vTaskPrioritySet( xHandle, PRIORITY + 1 );

/* Use NULL in place of a valid task handle to set the priority of the
calling task to 1. */
vTaskPrioritySet( NULL, 1 );
}
}

[Study FreeRTOS-API] 2.23 uxTaskPriorityGet( )

#include "FreeRTOS.h"
#include "task.h"

UBaseType_t uxTaskPriorityGet(TaskHandle_t pxTask);

Summary
Queries the priority assigned to a task at the time uxTaskPriorityGet() is called.

Parameters
pxTask  The handle of the task being queried (the subject task). 
To obtain a task’s handle create the task using xTaskCreate() and make use of the 
pxCreatedTask parameter, or create the task using xTaskCreateStatic() and store 
the returned value, or use the task’s name in a call to xTaskGetHandle().
A task may query its own priority by passing NULL in place of a valid task handle.

Return Values
The value returned is the priority of the task being queried at the time uxTaskPriorityGet() is 
called. 


Example 
void vAFunction( void )
{
TaskHandle_t xHandle;
UBaseType_t uxCreatedPriority, uxOurPriority;

/* Create a task, storing the handle of the created task in xHandle. */
if( xTaskCreate( vTaskCode, 
"Demo task", 
STACK_SIZE, NULL, PRIORITY, 
&xHandle 
) != pdPASS )
{
/* The task was not created successfully. */
}
else
{
/* Use the handle to query the priority of the created task. */
uxCreatedPriority = uxTaskPriorityGet( xHandle );

/* Query the priority of the calling task by using NULL in place of a valid task handle. */
uxOurPriority = uxTaskPriorityGet( NULL );
/* Is the priority of this task higher than the priority of the task just created? */
if( uxOurPriority > uxCreatedPriority )
{
/* Yes. */
}
}

[Study FreeRTOS-API] 2.31 vTaskStartScheduler ()

#include "FreeRTOS.h"
#include "task.h"

void vTaskStartScheduler(void);

Summary
Starts the FreeRTOS scheduler running.
Typically, before the scheduler has been started, main() (or a function called by main()) will be
executing. After the scheduler has been started, only tasks and interrupts will ever execute.
Starting the scheduler causes the highest priority task that was created while the scheduler
was in the Initialization state to enter the Running state.

Parameters
None.

Return Values
The Idle task is created  automatically  when the scheduler is started. vTaskStartScheduler()
will only return if there is not enough FreeRTOS heap memory available for the Idle task to be
created.

Notes
Ports  that  execute  on  ARM7  and  ARM9  microcontrollers  require  the  processor  to  be  in
Supervisor mode before vTaskStartScheduler() is called.


Example
TaskHandle_t xHandle;
/* Define a task function. */
void vATask( void )
{
for( ;; )
{
/* Task code goes here. */
}
}
void main( void )
{
/* Create at least one task, in this case the task function defined above is created.  Calling vTaskStartScheduler() before any tasks have been created will cause the idle task to enter the Running state. */

xTaskCreate( vTaskCode, "task name", STACK_SIZE, NULL, TASK_PRIORITY, NULL );

/* Start the scheduler. */
vTaskStartScheduler();

/* This code will only be reached if the idle task could not be created inside
vTaskStartScheduler(). An infinite loop is used to assist debugging by
ensuring this scenario does not result in main() exiting. */

for( ;; );
}

[Study FreeRTOS-API] 2.33 vTaskSuspend ()

#include "FreeRTOS.h"
#include "task.h"

void vTaskSuspend(TaskHandle_t pxTaskToSuspend);

Summary
Places a task into the  Suspended state.  A task that is in the Suspended state will never be selected to enter the Running state.
The only way of removing a task from the Suspended state is to make it the subject of a call to
vTaskResume().


Parameters
pxTaskToSuspend  The handle of the task being suspended.
To obtain a task’s handle create the task using xTaskCreate() and make use of the pxCreatedTask parameter, or create the task using
xTaskCreateStatic() and store the returned value, or use the task’s name in a call to xTaskGetHandle().
A task may suspend itself by passing NULL in place of a valid task handle.


Return Values
None.

Notes
If FreeRTOS version 6.1.0 or later is being used, then  vTaskSuspend() can be  called to place
a  task  into  the  Suspended  state  before  the  scheduler  has  been  started  (before
vTaskStartScheduler() has been called). This will result in the task (effectively) starting in the
Suspended state.


Example 
void vAFunction( void )
{
TaskHandle_t xHandle;
/* Create a task, storing the handle of the created task in xHandle. */

if( xTaskCreate( vTaskCode, "Demo task", STACK_SIZE, NULL, PRIORITY, &xHandle ) != pdPASS )
{
/* The task was not created successfully. */
}
else
{
/* Use the handle of the created task to place the task in the Suspended state.  From FreeRTOS version 6.1.0, this can be done before the Scheduler has been started. */

vTaskSuspend( xHandle );
/* The created task will not run during this period, unless another task calls vTaskResume( xHandle ). */
/* Use a NULL parameter to suspend the calling task. */

vTaskSuspend( NULL );

/* This task can only execute past the call to vTaskSuspend( NULL ) if another task has resumed (un-suspended) it using a call to vTaskResume(). */
}

[Study FreeRTOS-API] 2.34 vTaskSuspendAll ()

#include "FreeRTOS.h"
#include "task.h"

void vTaskSuspendAll(void);


Summary
Suspends the scheduler.  Suspending the scheduler prevents a context switch from occurring
but leaves interrupts enabled. If an interrupt requests a context switch while the scheduler is
suspended,  then  the  request  is  held  pending  and  is  performed  only  when  the  scheduler  is
resumed (un-suspended). 


Parameters
None.


Return Values
None.


Notes
Calls  to  xTaskResumeAll()  transition  the  scheduler  out  of  the  Suspended  state  following  a
previous call to vTaskSuspendAll().
Calls  to  vTaskSuspendAll()  can  be  nested.   The  same  number  of  calls  must  be  made  to
xTaskResumeAll() as have previously been made to  vTaskSuspendAll() before the scheduler
will leave the Suspended state and re-enter the Active state.
xTaskResumeAll()  must  only  be  called  from  an  executing  task  and  therefore  must  not  be
called while the scheduler is in the Initialization state (prior to the scheduler being started).
Other FreeRTOS API functions must not be called while the scheduler is suspended.


Example 
/* A function that suspends then resumes the scheduler. */
void vDemoFunction( void )
{
/* This function suspends the scheduler. When it is called from vTask1 the scheduler is already suspended, so this call creates a nesting depth of 2. */

vTaskSuspendAll();

/* Perform an action here. */
/* As calls to vTaskSuspendAll() are nested, resuming the scheduler here will not cause the scheduler to re-enter the active state. */

xTaskResumeAll();
}
void vTask1( void * pvParameters )
{
for( ;; )
{
/* Perform some actions here. */
/* At some point the task wants to perform an operation during which it does not want to get swapped out, or it wants to access data which is also accessed from another task (but not from an interrupt). It cannot use taskENTER_CRITICAL()/taskEXIT_CRITICAL() as the length of the operation may
cause interrupts to be missed. */
/* Prevent the scheduler from performing a context switch. */

vTaskSuspendAll();

/* Perform the operation here. There is no need to use critical sections as the task has all the processing time other than that utilized by interrupt service routines.*/
/* Calls to vTaskSuspendAll() can be nested so it is safe to call a (non API) function which also contains calls to vTaskSuspendAll(). API functions should not be called while the scheduler is suspended. */

vDemoFunction(); // Non-API function

/* The operation is complete. Set the scheduler back into the Active
state. */

if( xTaskResumeAll() == pdTRUE )
{
/* A context switch occurred within xTaskResumeAll(). */
}
else
{
/* A context switch did not occur within xTaskResumeAll(). */
}
}

[Study FreeRTOS-API] 2.35 taskYIELD()

#include "FreeRTOS.h"
#include "task.h"

void taskYEILD(void);


Summary
Yield to another task of equal priority.
Yielding is where a task volunteers to leave the Running state,  without being pre-empted,  and
before its time slice has been fully utilized.


Parameters
None.

Return Values
None.


Notes
taskYIELD() must only be called from an executing task and therefore must not be called while
the scheduler is in the Initialization state (prior to the scheduler being started).
When  a  task  calls  taskYIELD(),  the  scheduler will  select  another  Ready  state  task  of  equal
priority to enter the Running state in its place. If there are no other Ready state tasks of equal
priority  then  the task that  called  taskYIELD()  will  itself  be transitioned  straight  back  into  the
Running state.
The scheduler will only ever select a task of equal priority to the task that called taskYIELD()
because, if there were any tasks of higher priority that were in the Ready state, the task that
called taskYIELD() would not have been executing in the first place.


Example 
void vATask( void * pvParameters)
{
for( ;; )
{
/* Perform some actions. */
/* If there are any tasks of equal priority to this task that are in the
Ready state then let them execute now - even though this task has not used
all of its time slice. */

taskYIELD();

/* If there were any tasks of equal priority to this task in the Ready state,
then they will have executed before this task reaches here. */
}

[Study FreeRTOS - API ] 2.3 xTaskAbortDelay()

#include "FreeRTOS.h"
#include "task.h"

BaseType_t xTaskAbortDelay(TaskHandle_t xTask);

Summary
Calling an API function that includes a timeout parameter can result in the calling task entering
the Blocked state. A task that is in the Blocked state is either waiting for a timeout period to
elapse, or waiting with a timeout for an event to occur, after which the task will automatically
leave  the  Blocked  state  and  enter  the  Ready  state.   There  are  many  examples  of  this
behavior, two of which are:

  If a task calls vTaskDelay() it will enter the Blocked state until the timeout specified by
the function’s parameter has elapsed, at which time the task will automatically leave
the Blocked state and enter the Ready state.

  If  a  task  calls  ulTaskNotifyTake()  when  its  notification  value  is  zero  it  will  enter  the
Blocked state until either it receives a notification or the timeout specified by one of the
function’s  parameters has elapsed, at which time the task will automatically leave the
Blocked state and enter the Ready state.

xTaskAbortDelay() will move a task from the Blocked state to the Ready state even if the event
the task is waiting for has not occurred, and the timeout specified when t he task entered the
Blocked state has not elapsed.
While a task is in the Blocked state it is not available to the scheduler, and will not consume
any processing time.


Parameters

xTask  The handle of the task that will be moved out of the Blocked state.
To obtain a task’s handle create the task using xTaskCreate() and make use of
the pxCreatedTask parameter, or create the task using xTaskCreateStatic() and store the returned value, or use the task’s name in a call to xTaskGetHandle().

Returned value
If the task referenced by xTask was removed from the Blocked state then
pdPASS is returned. If the task referenced by xTask was not removed from the
Blocked state because it was not in the Blocked state then pdFAIL is returned.


Notes
INCLUDE_xTaskAbortDelay must be set to 1 in FreeRTOSConfig.h for xTaskAbortDelay() to
be available.


Example
void vAFunction( TaskHandle_t xTask )
{
/* The task referenced by xTask is blocked to wait for something that the task calling
this function has determined will never happen. Force the task referenced by xTask
out of the Blocked state. */
if( xTaskAbortDelay( xTask ) == pdFAIL )
{
/* The task referenced by xTask was not in the Blocked state anyway. */
}
else
{
/* The task referenced by xTask was in the Blocked state, but is not now. */
}

Saturday, August 24, 2019

Kết nối WiFi cho ESP8266 sử dụng Arduino IDE



Viết chương trình kết nối wifi

Sau khi đã cài đặt thành công và hiển thị được hình như trên thì chúng ta sẽ bắt đầu viết chương trình đầu tiên, sau đó upload xuống ESP8266 để kết nối với mạng wifi ở nhà của mình.

Lập trình

Chương trình khá đơn giản, chỉ là kết nối với Wifi, in ra địa chỉ IP, nếu không kết nối được thì in ra dấu . (bạn thấy …….. hoài có nghĩa là sai tên wifi/password rồi nhé). Mình giải thích bằng comment trên code luôn cho các bạn dễ quan sát
// Them thu vien
#include <ESP8266WiFi.h>
// Thong so WiFi
const char* ssid = "ten_wifi"; //Thay ten_wifi bang ten wifi nha ban
const char* password = "mat_khau_wifi"; //Thay mat_khau_wifi bang mat khau cua ban
void setup(void)
{
// Khoi dong serial de debug
Serial.begin(115200);
// Ket noi voi WiFi
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) { //Kiem tra xem trang thai da ket noi chua neu chua thi in ra dau .
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.println("WiFi connected");
// Neu da ket noi duoc voi wifi se in ra dia chi IP
Serial.println(WiFi.localIP());
}
void loop() {
}
Quan trọng nhất là dòng 4,5 ví dụ wifi nhà bạn là Abcd pass 12345678 thì sẽ thay như sau
const char* ssid = "Abcd"; //Thay ten_wifi bang ten wifi nha ban
const char* password = "12345678"; //Thay mat_khau_wifi bang mat khau cua ban

Nạp chương trình

Coi như phần chương trình đã xong, giờ là nạp xuống ESP8266
  • Trước hết là phải chọn board cho chính xác bằng cách vào menu chọn Tool > Boards
    • Nếu dùng board ESP8266V1 thì chọn Generic ESP8266 Module
    • Nếu dùng board ESP8266V7 hoặc ESP8266V12, NodeMCU 0.9 thì chọn NodeMCU 0.9
    • Nếu dùng Wemos hay các board khác thì chọn theo danh sách.
  • Sau là chọn cổng COM (Tool > Port), ở đây của mình là COM2
esp8266_arduino_wifi_connect
Cuối cùng là biên dịch và nạp chương trình xuống,nếu có thông báo Done uploading như hình là thành công
esp8266_arduino_doneupload

Kết quả

esp8266_arduino_viewresult
Sau khi thực hiện theo các bước 1 mở terminal, bước 2 chọn baud (ở đây là 115200) thì sẽ có kết quả là thông báo kết nối và địa chỉ IP là 192.168.1.103. Cái dòng chữ rlrl… ở trên cùng là do tự ESP8266 sinh ra, chúng ta có thể bỏ qua không cần quan tâm tới nó làm gì.

Lập trình ESP8266 bằng Arduino IDE

Chuẩn bị:
Kit ESP8266.
Dây cáp micro USB để kết nối ESP8266 với COM của máy tính.

- Đầu tiên bạn phải cài đặt Driver cho chip chuyển đổi USB-TTL.
Bạn nhìn vào kit ESP để xem chip đang sử dụng.




Sau khi down bản mới nhất của Arduino IDE, các bạn tiến hành cài đặt như bình thường và mở chương trình

Để tiến hành cài đặt thư viện và chức năng nạp code cho IDE các bạn làm như sau:
Vào File→ Preferences, vào textbox Additional Board Manager URLs thêm đường link sau vào 
http://arduino.esp8266.com/stable/package_esp8266com_index.json
Click OK để chấp nhận. 
Tiếp theo vào ToolBoardBoards Manager
đợi một lát để chương trình tìm kiếm. Ta kéo xuống và click vào ESP8266 by ESP8266 Community, click vào Install. Chờ phần mềm tự động download và cài đặt.
Chọn Board để lập trình cho ESP8266:
Kết nối mudule USB-to-UART vào máy tính. Vào ToolBoardGeneric ESP8266 Module, chọn cổng COM tương ứng với module USB-to-UART tương ứng.

Chọn chế độ nạp Arduino as ISP. Vậy là ta đã có môi trường lập trình cho esp8266 rất thân thiện.
Sau khi kết nối UART vs ESP8266. các bạn có thể test code ESP8266 ở đây:
  1. int pin = 2;
  2. void setup() {
  3. pinMode(pin, OUTPUT);
  4. }
  5. void loop() {
  6. digitalWrite(pin, HIGH); //bật led
  7. delay(1000); //dừng 1s
  8. digitalWrite(pin, LOW); //tắt led
  9. delay(1000); //dừng 1s
  10. }
Back to Top