API  2.2
TSmarT Software Library
 All Data Structures Functions Variables Typedefs Enumerations Enumerator Groups Pages
freertos_advance.c

This is an example about how to manage the operating system FreeRTOS.

/* @file freertos_advance.c
* @author TST
* @version 0.1
* @date 17/09/2012
* @brief This is an example of how to manage the operating system FreeRTOS.
*
* FreeRTOS is a real-time operating system for embedded devices,
* being ported to 31 micro-controllers. This example shows the user how to create
* tasks (setting stack size and priorities) and queues mainly. In addition, it
* shows to the users how to start with TSmarT programming:
*
* - Filling the "Init()" function
* - Using the most easy device: DIO (digital input/output).
*
* User can learn more about FreeRTOS in http://www.freertos.org/
*
* API reference for FreeRTOS:
* - http://www.freertos.org/a00106.html
*
*/
/* Platform headers */
#include "tsmart.h"
/* Global variables to share between tasks: queue and mutex handlers */
xSemaphoreHandle led_mutex;
xQueueHandle task1_queue;
xQueueHandle task2_queue;
/* @brief vTASK1 task
*
* This task set DIO0a and send a value(1) to report to
* other task to reset DI0a.
* After that it wait for a value in a queue.
*
* @param pvParameters
*/
void vTASK1(void *pvParameters) {
/* Variables */
uint8_t value_received;
uint8_t value_sent = 1;
while(1){
/* Set DIO0a */
/* Wait 1 second */
vTaskDelay(1000/portTICK_RATE_MS);
/* Send value to task2(vTASK2) */
xQueueSend(task2_queue, &value_sent, portMAX_DELAY);
/* Wait for new value in queue from task2(vTASK2) */
xQueueReceive(task1_queue, &value_received, portMAX_DELAY);
}
}
/* @brief vTASK2 task
*
* This task is waiting for new value from the task1(vTASK1)
* and when the value is received it resets the DIO0a and
* send a value to task1.
*
* @param pvParameters
*/
void vTASK2(void *pvParameters) {
/* Variables */
uint8_t value_received;
uint8_t value_sent = 1;
while(1){
/* Wait for new value in queue from task1(vTASK1) */
xQueueReceive(task2_queue, &value_received, portMAX_DELAY);
/* Reset DIO0a */
/* Wait 1 second */
vTaskDelay(1000/portTICK_RATE_MS);
/* Send value to task1(vLED1) */
xQueueSend(task1_queue, &value_sent, portMAX_DELAY);
}
}
/* @brief vTASK3 task
*
* This task is waiting for an interrupt generated by a external
* button. When the DIO7 interruption happens this task release the mutex
* and wait for an interrupt again.
*
* @param pvParameters
*/
void vTASK3(void *pvParameters) {
for(;;){
/* Wait for interrupt */
TSMART_DIO_Wfi(&tsmart_dio7, portMAX_DELAY);
/* Give mutex */
xSemaphoreGive(led_mutex);
}
}
/* @brief vTASK4 task
*
* This task is waiting for the mutex is available to take it, then
* when that is possible, toggles the DIO1a and wait for the mutex again
*
* @param pvParameters
*/
void vTASK4(void *pvParameters) {
/* Take it to synchronize */
xSemaphoreTake(led_mutex, portMAX_DELAY);
for(;;){
/* Wait for mutex */
xSemaphoreTake(led_mutex, portMAX_DELAY);
/* Led */
}
}
/* @brief "Init()" function.
*
* This is the first thing that the user must do for using TSmarT.
* It initializes specific hardware resources (GPRS, GPS, AI, DIO, MODBUS, MSA...)
* and software resources (queues, mutex, tasks...) for the user application.
*
* The way to fill in this function properly is to initialize first
* hardware resources and after that software resources.
*
* This function must return: TSMART_PASS when every thing is OK or
* TSMART_FAIL when a failure happened.
*
* @return
* @arg TSMART_PASS
* @arg TSMART_FAIL
*/
int32_t init() {
tsmart_dio_config_t dio_config;
portBASE_TYPE xReturn;
/* ************************************************************************* */
/* Debug Mode */
/* ************************************************************************* */
/* Uncomment for Debug */
/* ************************************************************************* */
/* Initialize resources */
/* ************************************************************************* */
/* The specific hardware for this application are three digital input and output
* located in:
* - DIO0a
* - DIO1a
* - DIO7
*/
/* LED1 - DIO */
dio_config.mode = TSMART_DIO_OD;
TSMART_DIO_Init(&tsmart_dio0a, &dio_config);
/* LED2 - DIO */
dio_config.mode = TSMART_DIO_OD;
TSMART_DIO_Init(&tsmart_dio1a, &dio_config);
/* Button */
dio_config.mode = TSMART_DIO_IPU;
TSMART_DIO_Init(&tsmart_dio7, &dio_config);
/* ************************************************************************* */
/* Application task */
/* ************************************************************************* */
/* This examples will need four task:
*
* - TASK1 task: Set DIO0a and send a value using a queue to a TASK2
* to reset the same DIO.
*
* - TASK2 task: wait for value in a queue and when a value is received, reset
* DIO0a and send a value to a TASK1.
*
* - TASK3 task: wait for an interrupt (in DIO7) and release a mutex when that happens.
*
* - TASK4 task: wait for free mutex and toggles the DIO1a.
*
*
* Two queue to send values one task to another and vice versa:
* - task1_queue
* - task2_queue
*
* One mutex to wait for and interruption:
* - led_mutex
*
*/
/* Create task1 queue */
task1_queue = xQueueCreate(1, sizeof(uint8_t));
if (task1_queue == NULL) {
return TSMART_FAIL;
}
/* Create task2 queue */
task2_queue = xQueueCreate(1, sizeof(uint8_t));
if (task2_queue == NULL) {
return TSMART_FAIL;
}
/* Create mutex */
led_mutex = xSemaphoreCreateMutex();
if(led_mutex == NULL){
return TSMART_FAIL;
}
/* Create task 1 */
xReturn = xTaskCreate(vTASK1, "TASK1", 128, NULL, 6, NULL);
if (xReturn != pdPASS) {
return TSMART_FAIL;
}
/* Create task 2 */
xReturn = xTaskCreate(vTASK2, "TASK2", 128, NULL, 6, NULL);
if (xReturn != pdPASS) {
return TSMART_FAIL;
}
/* Create task3 */
xReturn = xTaskCreate(vTASK3, "TASK3", 128, NULL, 7, NULL);
if (xReturn != pdPASS) {
return TSMART_FAIL;
}
/* Create task4 */
xReturn = xTaskCreate(vTASK4, "TASK4", 128, NULL, 9, NULL);
if (xReturn != pdPASS) {
return TSMART_FAIL;
}
/* Everything OK */
return TSMART_PASS;
}