Tareas en Un RTOS
Tareas en Un RTOS
Sistemas Embebidos
Reporte de práctica
PRÁCTICA 8: TAREAS EN UN SISTEMA OPERATIVO
Alumno:
MIGUEL ANGEL MÁRQUEZ HERNÁNDEZ
Registro:
18100170
Profesor:
MARISCAL GUTIÉRREZ LUIS ALEJANDRO
Fecha:
11 de junio de 2022
Resumen
En esta práctica se codificó un programa sobre el sistema operativo freeRTOS capaz de ejecutar dos tareas
simultáneas, asignándoles una prioridad, un tiempo y una función.
Objetivos Generales:
• Conocer las bases de los sistemas operativos en tiempo real.
• Comprender el funcionamiento de las tareas en sistemas operativos de tiempo real.
Objetivos Específicos:
• Utilizar FreeRTOS para realizar un proceso en la tarjeta de desarrollo KL25z.
• Implementar dos tareas en un programa de FreeRTOS.
Marco Teórico:
SISTEMAS OPERATIVOS:
El sistema operativo de una computadora es el programa que se encarga de administrar el hardware y el resto
de las aplicaciones que corren en el equipo. Sin un sistema operativo, cada aplicación tendría que incluir su GUI
propia, así como todo el código necesario para controlar las funciones de bajo nivel de la computadora, como
el uso de disco, interfaces de red, periféricos, etc.
En vez de hacer eso, muchas tareas comunes como enviar un paquete de red o mostrar texto en algún
dispositivo de salida pueden ser delegadas al sistema operativo que sirve como intermediario entre las
aplicaciones y el hardware. El sistema operativo provee un método consistente y repetible para que las
aplicaciones interactúen con el hardware.
KERNEL:
El kernel es el núcleo de un sistema operativo y la interfaz entre el software y el hardware. Controla todos los
accesos al procesador y a la memoria, es el responsable de los drivers y puede acceder directamente al
hardware.
SHELL:
El shell o intérprete de comandos es el programa informático que provee una interfaz de usuario para acceder
a los servicios del sistema operativo.
Dependiendo del tipo de interfaz que empleen, los shells pueden ser:
• De líneas texto (CLI, Command-Line Interface, interfaz de línea de comandos),
• Gráficos (GUI, Graphical User Interface, interfaz gráfica de usuario),
• De lenguaje natural (NUI, Natural User Interface, interfaz natural de usuario).
FREERTOS:
Es un sistema operativo de tiempo real para sistemas embebidos. FreeRTOS tiene un tamaño relativamente
pequeño. El núcleo mínimo de FreeRTOS consiste en tres archivos .c y un puñado de archivos .h. Que suman
aproximadamente 9000 líneas de código.
• Tareas: casi la mitad del núcleo de FreeRTOS está orientado al manejo de tareas.
• Comunicación: Las tareas e interrupciones utilizan colas para intercambiar información.
• Gestión del hardware: 6% del código núcleo de FreeRTOS permite que el sistema operativo interactúe
con el hardware.
REGISTROS UTILIZADOS:
GPIO-> PCOR
GPIO-> PSOR
FUNCIONES UTILIZADAS:
xTaskCreate();
Crea una nueva tarea y la añade a la lista de tareas que están listas para ejecutarse.
Ejemplo:
for( ;; )
{
/* Task code goes here. */
}
}
/* Function that creates a task. */
void vOtherFunction( void )
{
BaseType_t xReturned;
TaskHandle_t xHandle = NULL;
vTaskStartScheduler();
Habilita el secuenciador de tareas.
Ejemplo:
void vAFunction( void )
{
// Tasks can be created before or after starting the RTOS
scheduler
xTaskCreate( vTaskCode,
"NAME",
STACK_SIZE,
NULL,
tskIDLE_PRIORITY,
NULL );
// Start the real time scheduler.
vTaskStartScheduler();
// Will not get here unless there is insufficient RAM.
}
vTaskDelay();
Bloquea una tarea por el número de ticks especificado como parámetro.
Ejemplo:
void vTaskFunction( void * pvParameters )
{
/* Block for 500ms. */
const TickType_t xDelay = 500 / portTICK_PERIOD_MS;
for( ;; )
{
/* Simply toggle the LED every 500ms, blocking between each
toggle. */
vToggleLED();
vTaskDelay( xDelay );
}
}
Desarrollo Teórico:
FUNCIÓN PRINCIPAL:
DIAGRAMA DE FLUJO:
PSEUDOCÓDIGO:
FUNCION PRINCIPAL
CREAR TAREA 1
CREAR TAREA 2
INICIALIZAR SCHEDULER
FIN
TAREA 1 (MOSTRAR IMAGEN):
DIAGRAMA DE FLUJO:
PSEUDOCÓDIGO:
TAREA 1
INICIALIZAR MATRIZ
LIMPIAR MATRIZ
IMPRIMIR “ESTA ES MI PRIMER TAREA”
SI CONTADOR == 0
PARA I = 1; I<= 8; I++
ROW_DATA = 0
PARA j = 0; j< 8; j++
ROW_DATA = |= (mono2[i-1][j]<< j)
FIN PARA
ROW_SET(I)
COL_WRITE(ROW_DATA)
VTASKDELAY(2)
MATRIX_CLEAR()
FIN PARA
SI CONTADOR == 1
PARA I = 1; I<= 8; I++
ROW_DATA = 0
PARA j = 0; j< 8; j++
ROW_DATA = |= (mono1[i-1][j]<< j)
FIN PARA
ROW_SET(I)
COL_WRITE(ROW_DATA)
VTASKDELAY(2)
MATRIX_CLEAR()
FIN PARA
FIN TAREA 1
TAREA 2 (LEER PUSH BUTTON):
DIAGRAMA DE FLUJO:
PSEUDOCÓDIGO:
TAREA 2
INICIALIZAR SWITCH
IMPRIMIR “ESTA ES MI SEGUNDA TAREA”
PREV_SWITCHSTATE = CURR_SWITCHSTATE
CURR_SWITCHSTATE = PTE21
RISING_EDGE = 0
SI CURR_SWITCHSTATE != PREV_SWITCHSTATE && CURR_SWITCHSTATE == 1
RISING EDGE = 1
COUNTER++
SI COUNTER == 2
COUNTER = 0
FIN SI
FIN SI
VTASKDELAY(50)
FIN TAREA 2
Desarrollo Práctico:
CÓDIGO FUENTE:
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* o Redistributions of source code must retain the above copyright notice, this list
* of conditions and the following disclaimer.
*
* o Redistributions in binary form must reproduce the above copyright notice, this
* list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* o Neither the name of NXP Semiconductor, Inc. nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @file MKL25Z4_Task.c
* @brief Application entry point.
*/
#include <stdio.h>
#include "board.h"
#include "peripherals.h"
#include "pin_mux.h"
#include "clock_config.h"
#include "MKL25Z4.h"
#include "fsl_debug_console.h"
#include <stdbool.h>
#define F1 7
#define F2 6
#define F3 5
#define F4 4
#define F5 8
#define F6 4
#define F7 9
#define F8 2
void matrix_init(void);
void test_pixel(uint8_t row, uint8_t col);
void matrix_clear(void);
void matrix_set(void);
void row_set(uint8_t);
void row_clear(uint8_t data);
void col_write(uint8_t data);
void switch_init(void);
// filas, columnas
bool heart[8][8] = {
{0,1,1,0,0,1,1,0},
{1,1,1,1,1,1,1,1},
{1,1,1,1,1,1,1,1},
{1,1,1,1,1,1,1,1},
{0,1,1,1,1,1,1,0},
{0,0,1,1,1,1,0,0},
{0,0,0,1,1,0,0,0},
{0,0,0,0,0,0,0,0}
};
bool square[8][8] = {
{0,0,0,0,0,0,0,0},
{0,1,1,1,1,1,1,0},
{0,1,1,1,1,1,1,0},
{0,1,1,1,1,1,1,0},
{0,1,1,1,1,1,1,0},
{0,1,1,1,1,1,1,0},
{0,1,1,1,1,1,1,0},
{0,0,0,0,0,0,0,0}
};
bool weird[8][8] = {
{0,0,0,0,0,0,0,0},
{0,1,1,1,0,0,0,0},
{0,1,1,1,0,0,0,0},
{0,1,1,1,0,0,0,0},
{0,0,0,0,1,1,1,0},
{0,0,0,0,1,1,1,0},
{0,0,0,0,1,1,1,0},
{0,0,0,0,0,0,0,0}
};
bool diana[8][8] = {
{0,0,0,0,0,0,0,0},
{0,1,1,1,0,0,0,0},
{0,1,1,0,1,0,0,0},
{0,1,1,0,0,1,0,0},
{0,1,1,0,0,1,0,0},
{0,1,1,0,0,1,0,0},
{0,1,1,1,1,0,0,0},
{0,0,0,0,0,0,0,0}
};
bool mono1[8][8] = {
{0,0,1,1,1,0,0,0},
{0,0,1,1,1,0,0,0},
{0,0,0,1,0,0,0,0},
{0,0,1,1,1,0,0,0},
{0,1,0,1,0,1,0,0},
{0,0,0,1,0,0,0,0},
{0,0,1,0,1,0,0,0},
{0,0,1,0,1,0,0,0}
};
bool mono2[8][8] = {
{0,0,1,1,1,0,0,0},
{0,0,1,1,1,0,0,0},
{0,1,0,1,0,1,0,0},
{0,0,1,1,1,0,0,0},
{0,0,0,1,0,0,0,0},
{0,0,1,1,1,0,0,0},
{0,1,0,0,0,1,0,0},
{1,0,0,0,0,0,1,0}
};
bool pene[8][8] = {
{0,0,0,1,1,0,0,0},
{0,0,1,1,1,1,0,0},
{0,0,0,1,1,0,0,0},
{0,0,0,1,1,0,0,0},
{0,0,0,1,1,0,0,0},
{0,1,1,1,1,1,1,0},
{1,1,1,1,1,1,1,1},
{1,1,1,0,0,1,1,1}
};
bool switch_ispressed = 0;
bool curr_switchstate = 0;
bool prev_switchstate = 0;
bool rising_edge = 0;
int counter = 0;
/*
* @brief Application entry point.
*/
/* Task priorities. */
/***************************
* Prototypes
**************************/
static void my_First_task(void *pvParameters);
static void my_Second_task(void *pvParameters);
int main(void) {
int row_data = 0;
matrix_init();
matrix_clear();
if (counter == 0){
for(int i = 1; i <= 8; i++){
row_data = 0;
for(int j = 0; j < 8; j++){
row_data |= (mono2[i-1][j]) << (j);
}
row_set(i);
col_write(row_data);
vTaskDelay(2);
matrix_clear();
}
}
else if (counter == 1){
for(int i = 1; i <= 8; i++){
row_data = 0;
for(int j = 0; j < 8; j++){
row_data |= (mono1[i-1][j]) << (j);
}
row_set(i);
col_write(row_data);
vTaskDelay(2);
matrix_clear();
}
}
else if (counter == 2){
for(int i = 1; i <= 8; i++){
row_data = 0;
for(int j = 0; j < 8; j++){
row_data |= (pene[i-1][j]) << (j);
}
row_set(i);
col_write(row_data);
vTaskDelay(2);
matrix_clear();
}
}
else if (counter == 3){
for(int i = 1; i <= 8; i++){
row_data = 0;
for(int j = 0; j < 8; j++){
row_data |= (heart[i-1][j]) << (j);
}
row_set(i);
col_write(row_data);
vTaskDelay(2);
matrix_clear();
}
}
else if (counter == 4){
for(int i = 1; i <= 8; i++){
row_data = 0;
for(int j = 0; j < 8; j++){
row_data |= (square[i-1][j]) << (j);
}
row_set(i);
col_write(row_data);
vTaskDelay(2);
matrix_clear();
}
}
else if (counter == 5){
for(int i = 1; i <= 8; i++){
row_data = 0;
for(int j = 0; j < 8; j++){
row_data |= (weird[i-1][j]) << (j);
}
row_set(i);
col_write(row_data);
vTaskDelay(2);
matrix_clear();
}
}
prev_switchstate = curr_switchstate;
curr_switchstate = !(GPIOE -> PDIR & (1<<21));
rising_edge = 0;
// flanco de bajada
}
else if (curr_switchstate == prev_switchstate){
// no hay cambio
}
else if(curr_switchstate != prev_switchstate && curr_switchstate == 1){
rising_edge = 1;
counter++;
if (counter == 6){
counter = 0;
}
}
// if(switch_ispressed){
// PRINTF("Switch presionado\r\n");
// }
vTaskDelay(50);
}
}
//pte21
void matrix_init(void){
/*
* PTC
* 11 10 6 5 4 3 0 7
* C8 C7 F2 C1 F4 C6 C4 F1
*
* PTB
* 8 9 10 11
* F5 F7 C2 C3
*
* PTE
* 2 3 4 5
* F8 C5 F6 F3
*/
/*
*
* F1 F2 F3 F4 F5 F6 F7 F8
* PTC7 PTC6 PTE5 PTC4 PTB8 PTE4 PTB9 PTE2
*
* C1 C2 C3 C4 C5 C6 C7 C8
* PTC5 PTB10 PTB11 PTC0 PTE3 PTC3 PTC10 PTC11
*/
SIM->SCGC5 |= SIM_SCGC5_PORTC_MASK|SIM_SCGC5_PORTB_MASK|SIM_SCGC5_PORTE_MASK;
void matrix_clear(void){
// FILAS A 0
GPIOC-> PCOR |= (1<<F1)|(1<<F2)|
(1<<F4);
// COLUMNAS A 0
GPIOC-> PSOR |= (1<<C8)|(1<<C7)|(1<<C1)|(1<<C6)|(1<<C4);
void switch_init(void){
// HABILITAR PULL
PORTE -> PCR[21] |= (1<<1);
// SELECCIONAR PULL UP
PORTE -> PCR[21] |= (1<<0);
}
Ejecución:
MONO 1:
MONO 2:
CONSOLA:
Conclusiones:
Los datos obtenidos de la ejecución en físico y del log de la consola indican que la práctica fue realizada con
éxito ya que se pudo lograr que dos tareas corrieran de manera simultánea en la KL25Z. En la práctica se
utilizaron conocimientos adquiridos a lo largo de la carrera como lo son el manejo de arreglos, pines de gpio,
configuración de registros, así como conocimientos nuevos (RTOS, tareas) para codificar un programa que
realizara dos tareas simultáneas. La tarea 1 se encarga de mostrar un arreglo de 8x8 en la matriz de leds,
mientras que la tarea 2 se encarga de detectar los flancos de subida de un interruptor conectado a PTE21. Cada
que la tarea 2 detecta que se presiona el switch, la tarea 1 cambia la imagen que se muestra en la matriz de
leds.
Al finalizar la práctica aprendí a configurar el entorno de desarrollo para trabajar con freeRTOS, así como a crear
tareas y asignarles una prioridad y un proceso.
REFERENCIAS:
FREERTOS. (s.f.). Real time operating system for microcontrollers. Obtenido de
https://www.freertos.org/index.html
Apéndice:
FIRMA: