Hello i am new with the embedded programming. Now try to finish up a project for my university.
The project is that we need to create a production line which create tasks and give in the speed of the tasks.
Through a Display manager i will get so out puts on the 7 seg- 2 Digit - 5V - from mickroelektronika module.
I use the texas instrumen Tiva C series EK-TM4C1294XL evaluation kit with 32bit Arm Cortex M4 120MHz CPU wth floating point.
I use a code composer studio 8 and RTOS tirtos_tivac_2_16_00_08.
In my code now i achieved to create the tast on the terminal and with a certain speed that i can set when i create a task it prints on the terminal.
Also on the 7 segment first digit shows the speed of the task and the second digit shows the task ID.
I made the UART connection and SPI communation for the 7seg click.
Now i want to add a function which i start the task will blink the same speed with the task.
So down below you can find my code.
/************************************************************ * ============ empty_min.c - Produktion Line ============ * * * * Autor: Ali ASIK * * Date: 07.10.2019 **************************************************************
**************************** Header Files ****************************/
#include <stdint.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <stdbool.h>#include "inc/hw_ints.h"#include "inc/hw_memmap.h"#include "driverlib/debug.h"#include "driverlib/gpio.h"#include "driverlib/interrupt.h"#include "driverlib/pin_map.h"#include "driverlib/rom.h"#include "driverlib/rom_map.h"#include "driverlib/sysctl.h"#include "driverlib/ssi.h"#include <driverlib/uart.h> // Supplies UART
// driver library for SPI peripheraluint32_t g_ui32SysClock; // system clock in Hzuint8_t font[10] = {0x7E, 0x0A, 0xB6, 0x9E, 0xCA, 0xDC, 0xFC, 0x0E, 0xFE, 0xDE}; // 7-Segment font, letters 0 to 9
/* XDCtools Header files */#include <xdc/std.h>#include <xdc/runtime/System.h>
/* BIOS Header files */#include <ti/sysbios/BIOS.h>#include <ti/sysbios/knl/Task.h>#include <xdc/runtime/Error.h>#include <xdc/runtime/System.h>
/* TI-RTOS Header files */
#include <ti/drivers/GPIO.h>#include <ti/drivers/SPI.h>#include <ti/drivers/UART.h>#include <ti/drivers/USBMSCHFatFs.h>
#include <ti/sysbios/knl/Semaphore.h>//#include <ti/sysbios/knl/Mailbox.h>
/* Board Header file */#include "Board.h"#include "EK_TM4C1294XL.h"
/**************************** Compiler Commands ****************************/
#define TASKSTACKSIZE 512 // Max task size, see#define MAX_TASKS 10 // max possible tasks
/**************************** Global variables & Structs ****************************/
Error_Block eb; // Error Block
/* UART0 Handle, Parameters and uart0 Semaphore */UART_Handle uart0;UART_Params uart0Params;
Semaphore_Struct sem_uart0_write_struct; // Semaphore save the uart0Semaphore_Handle sem_uart0_write_handle;
/* Task Struct and Stacksize*/Task_Struct task_Manager_Struct;Char task_Manager_Stack[TASKSTACKSIZE];
Task_Struct taskStruct[MAX_TASKS];Char taskStack[MAX_TASKS][TASKSTACKSIZE];
Task_Struct taskDisplayManagerStruct;Char task_DisplayManager_Stack[TASKSTACKSIZE];
/* Global Variable */bool show = 1;int speed[MAX_TASKS]; // Task speed fieldunsigned char buf[1]; // buffer for reading data from uart0
/**************************** Function definitions ****************************/void itoc(int);int ctoi(char);/**************************** Tasks ****************************/
// Configuration of SPI (SSI3, on BoosterPack 2 connector, master mode, 9 Mbps)void InitSpi(void) {
// enable peripherals SysCtlPeripheralEnable(SYSCTL_PERIPH_SSI3); // enable SSI3 (for SPI) SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOQ); // enable port Q for SSI I/O-pins
// configure pins as SSI3 pins GPIOPinConfigure(GPIO_PQ0_SSI3CLK); // Q0 for Clk GPIOPinConfigure(GPIO_PQ3_SSI3XDAT1); // Q3 for Master Output Slave Input (MOSI) GPIOPinConfigure(GPIO_PQ2_SSI3XDAT0); // Q2 for Master Input Slave Output (MISO)
// configure pins for SSI3 GPIOPinTypeSSI(GPIO_PORTQ_BASE, GPIO_PIN_3 | GPIO_PIN_2 | GPIO_PIN_0);
// configure SSI3 communication // SSI base address (SSI3), SSI clk (120 MHz), data transfer protocol (Motorola Mode 0), // mode of operation (Master), SPI clock rate (9 Mbps), bits per frame (8) SSIConfigSetExpClk(SSI3_BASE, g_ui32SysClock, SSI_FRF_MOTO_MODE_0, SSI_MODE_MASTER, 9000000, 8);
SSIEnable(SSI3_BASE); // enable the SSI3 module
// Configure latch pin for 74HC595 (7seg click) SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOP); // enable port Q GPIOPinWrite(GPIO_PORTP_BASE, GPIO_PIN_5, GPIO_PIN_5); // set pin P5 to 1 GPIOPinTypeGPIOOutput(GPIO_PORTP_BASE, GPIO_PIN_5); // configure pin P5 for output}//****************************************************************************
//****************************************************************************// send byte over SPI on BoosterPack 2 connector, latch byte to outputs of 74HC595 (7seg click) after sendingvoid SpiSend (uint8_t data) { SSIDataPut(SSI3_BASE, data); // send byte over SPI SysCtlDelay(100); // wait until byte was sent
GPIOPinWrite(GPIO_PORTP_BASE, GPIO_PIN_5, 0); // latch byte to outputs of 74HC595 (7seg click) with 0 on P5 GPIOPinWrite(GPIO_PORTP_BASE, GPIO_PIN_5, GPIO_PIN_5); // set P5 back to 1 // pulse width with no delay and optimization 2 is about 100 ns (measured), slow enough}
void DisplayManager(UArg zehner, UArg einser){ SpiSend(font[einser]); // output next digit SpiSend(font[zehner]); //Task_sleep(10);}/**************************** Tasks ****************************/
/* Slave Task */int Slave_Task(UArg ID){ Semaphore_pend(sem_uart0_write_handle, BIOS_WAIT_FOREVER); // Save uart0, if uart0 is used, wait forever UART_write(uart0, "Task ", sizeof("Task ")); // write to uart0 itoc(ID); // itoc - int to char UART_write(uart0, buf, 1); UART_write(uart0, " Started!\r\n", sizeof(" Started!\r\n")); Semaphore_post(sem_uart0_write_handle); // Free uart0 Task_sleep(speed[ID]); // Task sleep for speed time
while(1) // infinity loop { if(show) // show products in terminal if true { Semaphore_pend(sem_uart0_write_handle, BIOS_WAIT_FOREVER); UART_write(uart0, "Task ", sizeof("Task ")); itoc(ID); UART_write(uart0, buf, 1); UART_write(uart0, " speed ", sizeof(" speed ")); itoc(speed[ID]/1000); UART_write(uart0, buf, 1); UART_write(uart0, " \r\n", sizeof(" \r\n")); Semaphore_post(sem_uart0_write_handle); } Task_sleep(speed[ID]); }}
/* Task Manager */void Task_Manager(void) // Task Manager, control all Tasks and the Interface{ Task_Params taskParams; // Task Parameter Task_Params DisplayParams; int i, ID = 0; // ID to identify the Task char choice; // choice - for the command comming from uart0 int durchschnitt = 0; // Variables
Semaphore_pend(sem_uart0_write_handle, BIOS_WAIT_FOREVER); // Save uart0 UART_write(uart0, "\r\nCreate Task ...\r\n", sizeof("\r\nCreate Task ...\r\n")); // write uart0 Semaphore_post(sem_uart0_write_handle); // Free uart0
while(1) { UART_read(uart0, &choice, 1); // read from uart0 and save it to "choice"
switch(choice) // switch case { /* t - changing last task speed */ case 's': if(ID==0) // if no Task, break break; Semaphore_pend(sem_uart0_write_handle, BIOS_WAIT_FOREVER); UART_write(uart0, "\r\nEdit last task speed: ", sizeof("\r\nEdit last task speed: ")); UART_read(uart0, &choice, 1);
if((int)(choice-48)<=0 || (int)(choice-48)>=9) // ASCII input -> integer output { UART_write(uart0, " invalid Speed, only 1 to 9 allowed.\r\n", sizeof(" iinvalid Speed, only 1 to 9 allowed.\r\n")); break; } speed[ID-1] = (int)(choice-48)*1000; //ASCII -> int (48 == 0)
UART_write(uart0, "\r\n", sizeof("\r\n")); Semaphore_post(sem_uart0_write_handle); break;
/* n - create new Task */ case 'n': if(ID>=10) // Max 10 Tasks (0-9) break; Semaphore_pend(sem_uart0_write_handle, BIOS_WAIT_FOREVER); UART_write(uart0, "Task speed: ", sizeof("Task speed: ")); UART_write(uart0, "\r\n", sizeof("\r\n")); Semaphore_post(sem_uart0_write_handle);
UART_read(uart0, &choice, 1); if((int)(choice-48)<=0 || (int)(choice-48)>=9) { UART_write(uart0, " invalid Speed, only 1 to 9 allowed.\r\n", sizeof(" invalid Speed, only 1 to 9 allowed.\r\n")); break; }
speed[ID] = (int)(choice-48)*1000; //ASCII -> int (48 == 0) Task_Params_init(&taskParams); taskParams.arg0 = ID; Task_construct(&taskStruct[ID], (Task_FuncPtr)Slave_Task, &taskParams, NULL); Task_Params_init(&DisplayParams); DisplayParams.arg0 = ID; DisplayParams.arg1 = ctoi(choice); Task_construct(&taskDisplayManagerStruct, (Task_FuncPtr)DisplayManager, &DisplayParams, NULL); ID++; break;
/* d - delete Task */ case 'd': if(ID<=0) // Max 10 Tasks (0-9) break; Semaphore_pend(sem_uart0_write_handle, BIOS_WAIT_FOREVER); UART_write(uart0, "\r\nDelete Task\r\n", sizeof("\r\nDelete Task\r\n")); Semaphore_post(sem_uart0_write_handle); ID--; // reset the Task ID speed[ID] = BIOS_WAIT_FOREVER; // Task should wait forever break;
/* a - avg. speed */ case 'a': durchschnitt = 0;
for(i=0; i<10; i++) { durchschnitt += 10/(speed[i]/1000); }
Semaphore_pend(sem_uart0_write_handle, BIOS_WAIT_FOREVER); UART_write(uart0, "Average \r\n", sizeof("Average \r\n")); itoc((int)durchschnitt/10); UART_write(uart0, buf, 1); UART_write(uart0, " Product per Second\r\n", sizeof(" Product per Second\r\n")); Semaphore_post(sem_uart0_write_handle);
durchschnitt = 0; break;
/* l - show list with all Tasks */ case 'l': Semaphore_pend(sem_uart0_write_handle, BIOS_WAIT_FOREVER); UART_write(uart0, "Task list: \r\n", sizeof("Task list: \r\n")); UART_write(uart0, "Task: 0 1 2 3 4 5 6 7 8 9\r\n", sizeof("Task: 0 1 2 3 4 5 6 7 8 9\r\n")); UART_write(uart0, "---------------------------\r\nSpeed: ", sizeof("---------------------------\r\nSpeed: ")); for(i=0; i<10; i++) { itoc(speed[i]/1000); UART_write(uart0, buf, 4); UART_write(uart0, " ", sizeof(" ")); } UART_write(uart0, "\r\n", sizeof("\r\n")); Semaphore_post(sem_uart0_write_handle); break;
/* r - return how much tasks are running (producing) */ case 'r': Semaphore_pend(sem_uart0_write_handle, BIOS_WAIT_FOREVER); UART_write(uart0, "Total Running Tasks: ", sizeof("Total Running Tasks: ")); itoc(ID); UART_write(uart0, buf, 1); UART_write(uart0, "\r\n", sizeof("\r\n")); Semaphore_post(sem_uart0_write_handle);
DisplayParams.arg0 = 0; DisplayParams.arg1 = ID; Task_construct(&taskDisplayManagerStruct, (Task_FuncPtr)DisplayManager, &DisplayParams, NULL); break;
/* h - Help list */ case 'h': Semaphore_pend(sem_uart0_write_handle, BIOS_WAIT_FOREVER); UART_write(uart0, "----------------------- Task Factory -----------------------\r\n" " n -> Create Task\r\n" " d -> Delete Task\r\n" " r -> Show Total Running Tasks\r\n" " l -> Speed List\r\n" " a -> Average Production Speed\r\n" " s -> Edit Last Task Speed\r\n" " h -> HELP\r\n" "---------------------------------------------------------\r\n", sizeof("----------------------- Task Factory -----------------------\r\n" " n -> Create Task\r\n" " d -> Delete Task\r\n" " r -> Show Total Running Tasks\r\n" " l -> Speed List\r\n" " a -> Average Production Speed\r\n" " s -> Edit Last Task Speed\r\n" " h -> HELP\r\n" "---------------------------------------------------------\r\n")); Semaphore_post(sem_uart0_write_handle); break;
/* default - no character math */ default: Semaphore_pend(sem_uart0_write_handle, BIOS_WAIT_FOREVER); UART_write(uart0, "Invalid Command, Enter 'h' for HELP!\r\n", sizeof("Invalid Command, Enter 'h' for HELP!\r\n")); Semaphore_post(sem_uart0_write_handle); break; } }}
/**************************** Functions ****************************/
/* itoc - Change a integer to a global char field (string)*/void itoc(int z){ if(z==0) buf[0]='0'; if(z==1) buf[0]='1'; if(z==2) buf[0]='2'; if(z==3) buf[0]='3'; if(z==4) buf[0]='4'; if(z==5) buf[0]='5'; if(z==6) buf[0]='6'; if(z==7) buf[0]='7'; if(z==8) buf[0]='8'; if(z==9) buf[0]='9';}
int ctoi(char c){ switch(c) { case '1': return 1; break; case '2': return 2; break; case '3': return 3; break; case '4': return 4; break; case '5': return 5; break; case '6': return 6; break; case '7': return 7; break; case '8': return 8; break; case '9': return 9; break; }}
/**************************** main ****************************/
int main(void){ Task_Params taskParams; // Task Parameter Semaphore_Params semParams; // Semaphore Parameter
Error_init(&eb); // Error Function
/* Call board init functions */ Board_initGeneral(); Board_initGPIO(); Board_initUART();
// configure CPU clock to 120 MHz g_ui32SysClock = SysCtlClockFreqSet(( SYSCTL_XTAL_25MHZ | SYSCTL_OSC_MAIN | SYSCTL_USE_PLL | SYSCTL_CFG_VCO_480), 120000000);
InitSpi(); // SPI configuration /* Create a UART for text reading/writing to the terminal */ UART_Params_init(&uart0Params); uart0Params.writeDataMode = UART_DATA_TEXT; uart0Params.readDataMode = UART_DATA_TEXT; uart0Params.readReturnMode = UART_RETURN_FULL; uart0Params.readEcho = UART_ECHO_ON; uart0Params.baudRate = 115200; uart0 = UART_open(Board_UART0, &uart0Params);
/* Construct a Semaphore object to be used as a resource lock for the uart0 port */ Semaphore_Params_init(&semParams); Semaphore_construct(&sem_uart0_write_struct, 0, &semParams); /* Obtain instance handle */ sem_uart0_write_handle = Semaphore_handle(&sem_uart0_write_struct); Semaphore_post(sem_uart0_write_handle);
Semaphore_pend(sem_uart0_write_handle, BIOS_WAIT_FOREVER); UART_writePolling(uart0, "\r\n\r\n ************************ Task Factory ************************\r\n", sizeof("\r\n\r\n ************************ Task Factory ************************\r\n")); Semaphore_post(sem_uart0_write_handle);
/* Initialize & Construct Task_Manager */ Task_Params_init(&taskParams); taskParams.stackSize = TASKSTACKSIZE; taskParams.stack = &task_Manager_Stack; Task_construct(&task_Manager_Struct, (Task_FuncPtr)Task_Manager, &taskParams, NULL);
/* Turn on user LED */ //GPIO_write(Board_LED0, Board_LED_ON);
/* Start BIOS */ BIOS_start();
return (0);}
Here also i found the heart beat function to blink LEDs on this board but i couldnt achive how to implement this code.
Void heartBeatFxn1(UArg arg0, UArg arg1){ while (1) { Task_sleep((unsigned int)arg0); GPIO_toggle(Board_LED0); }}
/* Construct heartBeat Task thread */ Task_Params_init(&taskParams); taskParams.arg0 = 500; taskParams.stackSize = TASKSTACKSIZE; taskParams.stack = &task0Stack; Task_construct(&task0Struct, (Task_FuncPtr)heartBeatFxn, &taskParams, NULL);
Task_Struct task0Struct;
Char task0Stack[TASKSTACKSIZE];
Anybody can give advices that i how i can implement this to my project.
Thanks for your help.