We are running a survey to help us improve the experience for all of our members. If you see the survey appear, please take the time to tell us about your experience if you can.
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.