Hi!
The code had 2 task (T1 and T2), and worked fine. When I added a third task (T3), it does not run, even with highest priority. As you can see in the screen below, the task2 "moveTalon" has priority 3, and the others have max 2. The other tasks runs ok, but, "moveTalon" doesn't even launch.
There is the full code. I'm using TM4C1294XL board, with CCS V6.0.1 and the latest TI-RTOS platform.
Thanks!
/* * main.c * * Created on: 23/02/2015 * Author: Hk */ /* ******************************************************** * ** Universidade Tecnológica Federal do Paraná - UTFPR ** * ** Departamento Acadêmico de Eletrônica ** * ** Curso de Engenharia Eletrônica ** * ** Disciplina de Sistemas Operacionais ** * ** Prof.: L. F. Copetti ** * ** Aluno: H. C. Kaiser ** * ******************************************************** * * Este trabalho visa projetar um sistema de controle de braço robótico. * O braço será controlado por acelerômetro e botão de ação, e atuado por servomotores. * A programação embarcada utilizará a placa TI Tiva-C Connected Launchpad TM4C1294XL, com sistema * operacional RTOS. * Os códigos foram gerados no programa Code Composer Studio V6.0, com TI-RTOS instalado. * */ // -------------------------------------------------------- // Inclusões das bibliotecas usadas no programa // -------------------------------------------------------- // Bibliotecas SYS/BIOS #include <xdc/std.h> //mandatory - have to include first, for BIOS types #include <ti/sysbios/BIOS.h> //mandatory - if you call APIs like BIOS_start() #include <xdc/runtime/Log.h> //needed for any Log_info() call #include <xdc/cfg/global.h> //header file for statically defined objects/handles // Bibliotecas TIVAWARE #include <stdint.h> #include <stdbool.h> #include "inc/hw_gpio.h" #include "inc/hw_memmap.h" #include "inc/hw_types.h" #include "driverlib/debug.h" #include "driverlib/sysctl.h" #include "driverlib/gpio.h" #include "driverlib/adc.h" #include "driverlib/pwm.h" #include "driverlib/pin_map.h" // -------------------------------------------------------- // Definições estáticas // -------------------------------------------------------- #define PWM_FREQ 50 // Define a frequência de // funcionamento dos servomotores // -------------------------------------------------------- // Declaração de protótipos // -------------------------------------------------------- void hardware_init (void); void delay (void); void moveTalon (void); void moveServo (void); void readAcc (void); // -------------------------------------------------------- // Definição de estrutura para mailboxes // -------------------------------------------------------- typedef struct MsgObj { uint32_t AccX; uint32_t AccY; } MsgObj, *Msg; typedef struct TalonObj { int talonDir; // Último movimento registrado - 1 abre, -1 fecha uint32_t talonPos; // Posição final da garra } TalonObj, *Talon; // -------------------------------------------------------- // Código principal //--------------------------------------------------------- void main (void) { hardware_init(); // Inicialização do dispositivo BIOS_start(); // Inicia o agendador de BIOS } void hardware_init (void) { int i; // Variáveis para configuração do PWM volatile uint32_t ui32SysClkFreq; // Valor retornado por SysClockFreqSet() volatile uint32_t ui32PWMClock; // Frequência do clock do PWM volatile uint32_t ui32Load; // Período do PWM volatile uint32_t ui32Adjust; // Valor inicial de posição dos servos // Mailbox para acionamento da garra TalonObj talon; ui32SysClkFreq = SysCtlClockFreqSet ((SYSCTL_XTAL_25MHZ | SYSCTL_OSC_MAIN | SYSCTL_USE_PLL| SYSCTL_CFG_VCO_480), 120000000); // Habilitação da porta P4 para acionamento da garra SysCtlPeripheralEnable (SYSCTL_PERIPH_GPIOD); GPIOPinTypeGPIOInput (GPIO_PORTD_BASE, GPIO_PIN_0); GPIOPadConfigSet (GPIO_PORTD_BASE, GPIO_PIN_0, GPIO_STRENGTH_2MA, GPIO_PIN_TYPE_STD_WPD); // Habilitação do ADC SysCtlPeripheralEnable (SYSCTL_PERIPH_ADC0); SysCtlPeripheralEnable (SYSCTL_PERIPH_GPIOE); // Habilitação do PWM SysCtlPeripheralEnable (SYSCTL_PERIPH_PWM0); SysCtlPeripheralEnable (SYSCTL_PERIPH_GPIOF); SysCtlPeripheralEnable (SYSCTL_PERIPH_GPIOG); // Configurações do ADC ADCHardwareOversampleConfigure (ADC0_BASE, 64); GPIOPinTypeADC (GPIO_PORTE_BASE, GPIO_PIN_0 | // Pino PE0 GPIO_PIN_1 | // Pino PE1 GPIO_PIN_2 ); // Pino PE2 ADCSequenceConfigure (ADC0_BASE, 1, ADC_TRIGGER_PROCESSOR, 0); ADCSequenceStepConfigure (ADC0_BASE, 1, 0, ADC_CTL_CH3); ADCSequenceStepConfigure (ADC0_BASE, 1, 1, ADC_CTL_CH2); ADCSequenceStepConfigure (ADC0_BASE, 1, 2, ADC_CTL_CH1|ADC_CTL_IE|ADC_CTL_END); ADCSequenceEnable (ADC0_BASE, 1); // Configurações do PWM PWMClockSet (PWM0_BASE,PWM_SYSCLK_DIV_64); // CLK do PWM em 1.875 MHz GPIOPinConfigure (GPIO_PF1_M0PWM1); // Direciona saida do PWM da garra GPIOPinConfigure (GPIO_PF2_M0PWM2); // Direciona saida do PWM do pulso GPIOPinConfigure (GPIO_PF3_M0PWM3); // Direciona saida do PWM do cotovelo superior GPIOPinConfigure (GPIO_PG0_M0PWM4); // Direciona saida do PWM do cotovelo inferior GPIOPinConfigure (GPIO_PG1_M0PWM5); // Direciona saida do PWM da base GPIOPinTypePWM (GPIO_PORTF_BASE, GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3); // Configura porta F pinos 1~3 para PWM GPIOPinTypePWM (GPIO_PORTG_BASE, GPIO_PIN_0 | GPIO_PIN_1); // Configura porta G pinos 0~1 para PWM ui32PWMClock = ui32SysClkFreq / 64; // 120MHz/64 ui32Load = (ui32PWMClock / PWM_FREQ) - 1; // 1875000/55 - 1 ui32Adjust = 700; // Servos na posição central PWMGenConfigure (PWM0_BASE, PWM_GEN_0, PWM_GEN_MODE_DOWN | PWM_GEN_MODE_DBG_RUN); PWMGenConfigure (PWM0_BASE, PWM_GEN_1, PWM_GEN_MODE_DOWN | PWM_GEN_MODE_DBG_RUN); PWMGenConfigure (PWM0_BASE, PWM_GEN_2, PWM_GEN_MODE_DOWN | PWM_GEN_MODE_DBG_RUN); PWMGenPeriodSet (PWM0_BASE, PWM_GEN_0, ui32Load); PWMGenPeriodSet (PWM0_BASE, PWM_GEN_1, ui32Load); PWMGenPeriodSet (PWM0_BASE, PWM_GEN_2, ui32Load); PWMGenEnable (PWM0_BASE, PWM_GEN_0); PWMGenEnable (PWM0_BASE, PWM_GEN_1); PWMGenEnable (PWM0_BASE, PWM_GEN_2); PWMPulseWidthSet (PWM0_BASE, PWM_OUT_1, ui32Adjust * ui32Load / 10000); PWMPulseWidthSet (PWM0_BASE, PWM_OUT_2, ui32Adjust * ui32Load / 10000); PWMPulseWidthSet (PWM0_BASE, PWM_OUT_3, ui32Adjust * ui32Load / 10000); PWMPulseWidthSet (PWM0_BASE, PWM_OUT_4, ui32Adjust * ui32Load / 10000); PWMPulseWidthSet (PWM0_BASE, PWM_OUT_5, ui32Adjust * ui32Load / 10000); PWMOutputState (PWM0_BASE, PWM_OUT_1_BIT, true); PWMOutputState (PWM0_BASE, PWM_OUT_2_BIT, true); PWMOutputState (PWM0_BASE, PWM_OUT_3_BIT, true); PWMOutputState (PWM0_BASE, PWM_OUT_4_BIT, true); PWMOutputState (PWM0_BASE, PWM_OUT_5_BIT, true); talon.talonDir = 1; talon.talonPos = 700; Mailbox_post (Talon_Mbx, &talon, BIOS_WAIT_FOREVER); for (i = 0; i < 100; i++) delay(); } void delay (void) { SysCtlDelay(1200000); } void moveTalon (void) { // Estático para configuração do PWM static uint32_t ui32SysClkFreq = 120000000; // Variáveis para controle do punho uint32_t ui32AdjustTalon; uint32_t ui32Load; int talonLastDir; uint32_t flagMove = 0; // Mailbox para leitura do último valor da garra e direção TalonObj talon; ui32Load = (ui32SysClkFreq/64)/PWM_FREQ - 1; while (1){ Mailbox_pend (Talon_Mbx, &talon, BIOS_WAIT_FOREVER); ui32AdjustTalon = talon.talonPos; talonLastDir = talon.talonDir; flagMove = GPIOPinRead (GPIO_PORTD_BASE, GPIO_PIN_0); while (GPIOPinRead (GPIO_PORTD_BASE, GPIO_PIN_0) == 1){ if (ui32AdjustTalon > 400 && ui32AdjustTalon < 850){ if (talonLastDir == 1) ui32AdjustTalon -= 5; else ui32AdjustTalon += 5; PWMPulseWidthSet (PWM0_BASE, PWM_OUT_1, ui32AdjustTalon * ui32Load / 10000); delay(); } } if (ui32AdjustTalon <= 400) ui32AdjustTalon = 405; if (ui32AdjustTalon >= 850) ui32AdjustTalon = 845; if (flagMove == 1){ talonLastDir = -1*talonLastDir; flagMove = 0; } talon.talonDir = talonLastDir; talon.talonPos = ui32AdjustTalon; Mailbox_post (Talon_Mbx, &talon, BIOS_WAIT_FOREVER); } } void moveServo (void) { // Estático para configuração do PWM static uint32_t ui32SysClkFreq = 120000000; // Variáveis para controle dos servos uint32_t ui32AdjustWrist = 640; uint32_t ui32AdjustSupElbow; uint32_t ui32AdjustInfElbow = 1250; uint32_t ui32AdjustBase = 500; uint32_t ui32Load; // Variáveis diferenciais para controle do pulso uint32_t ui32BasePrev; int difBase; // Criação da caixa de mensagens MsgObj msg; ui32Load = (ui32SysClkFreq/64)/PWM_FREQ - 1; while (1) { // Leitura das mensagens na mailbox Mailbox_pend (MonCtl_Mbx, &msg, BIOS_WAIT_FOREVER); // Armazenamento de valores prévios para controle do pulso ui32BasePrev = ui32AdjustBase; // Carregamento dos valores ui32AdjustBase = msg.AccX/3 + 100; ui32AdjustInfElbow = msg.AccY/2 - 200; // Ajuste do pulso difBase = ui32AdjustBase - ui32BasePrev; if (difBase > 25) ui32AdjustWrist -= 50; else if (difBase < -25) ui32AdjustWrist += 50; else{ if (ui32AdjustWrist > 670) ui32AdjustWrist -= 14; if (ui32AdjustWrist > 640) ui32AdjustWrist -= 1; if (ui32AdjustWrist < 640) ui32AdjustWrist += 1; if (ui32AdjustWrist < 620) ui32AdjustWrist += 14; } // Ajuste do cotovelo superior if (ui32AdjustInfElbow > 650) ui32AdjustSupElbow = ui32AdjustInfElbow - 400; // Movimentação dos servos PWMPulseWidthSet(PWM0_BASE, PWM_OUT_2, ui32AdjustWrist * ui32Load / 10000); PWMPulseWidthSet(PWM0_BASE, PWM_OUT_3, ui32AdjustSupElbow * ui32Load / 10000); PWMPulseWidthSet(PWM0_BASE, PWM_OUT_4, ui32AdjustInfElbow * ui32Load / 10000); PWMPulseWidthSet(PWM0_BASE, PWM_OUT_5, ui32AdjustBase * ui32Load / 10000); } } void readAcc (void) { // Variáveis para leitura do acelerômetro uint32_t ui32ACCValues [4]; volatile uint32_t ui32AccX; volatile uint32_t ui32AccY; // Criação da caixa de mensagens MsgObj msg; // Leitura do ADC while (1){ ADCIntClear(ADC0_BASE, 1); ADCProcessorTrigger (ADC0_BASE, 1); while(!ADCIntStatus (ADC0_BASE, 1, false)) {} ADCSequenceDataGet (ADC0_BASE, 1, ui32ACCValues); ui32AccX = ui32ACCValues [0]; ui32AccY = ui32ACCValues [1]; // Envio dos valores para a caixa de mensagens msg.AccX = ui32AccX; msg.AccY = ui32AccY; Mailbox_post (MonCtl_Mbx, &msg, BIOS_WAIT_FOREVER); } }