I am writing an application using FreeRTOS V8.0.1 and the STM32F4 discovery board (Cortex-M4) in keil.
When powering and running a GPS reciever on USART2 after the IRQ is run no other tasks will resume. It was my understanding that with the Cortex-M4 processors no state saving functions need to be called during the ISR to preserve the system state and ISRs can be written as normal ensuring any rtos functions are *FromISR
In the code below I have an LCD initialise and display the some SD card information with another task updating the display with clock information. As soon as the gps
task runs and the chip recieves power (therefore transmitting NMEA strings) the IRQ will fire, the task run and then according to the debugger the application never leaves the gpstasks infinite while loop (even sleeping the task doesnt help).
I do not understand what could cause the other tasks (LED flag, Update time, etc) to no longer be scheduled.
MAIN.C
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
:::c++
int main(void)
{
prvSetupHardware();
usartGate = xSemaphoreCreateMutex();
lcdGate = xSemaphoreCreateMutex();
sdCardGate = xSemaphoreCreateMutex();
gpsMSG = xSemaphoreCreateMutex();
supremaMSG = xSemaphoreCreateMutex();
xTaskCreate(lcd_demo, (signed char*)"lcd", 512, NULL, 2, NULL);
xTaskCreate(alert_flash, (signed char*)"lcd", 512, NULL, 1, NULL);
xTaskCreate(update_time, (signed char*)"time", 512, NULL, 1, NULL);
xTaskCreate(gps_task, (signed char*)"gps", 512, NULL,1,NULL);
/* Start the scheduler. */
vTaskStartScheduler();
for( ;; );
}
/
———————————————————–/
/
———————————————————–/
void lcd_demo(void){
char buffer[40];
int row = 4;
if(xSemaphoreTake(lcdGate, 500)){
lcd_init();
GLCD_Clear();
GLCD_TextGoTo(0,row);
row++;
GLCD_WriteText("Power On");
//Begin Boot Message
GLCD_TextGoTo(0,row);
row++;
GLCD_WriteText("BETR V3.1 ");
GLCD_TextGoTo(0,row);
row++;
row++;
GLCD_WriteText("Acme PTY LTD");
GLCD_TextGoTo(0,row);
row++;
row++;
GLCD_WriteText(" Greetings Earthlings");
GLCD_TextGoTo(0,row);
row++;
if(xSemaphoreTake (sdCardGate, 500)){
GLCD_WriteText("Read SD Card Contents");
if(!disk_initialize(0)){
GLCD_TextGoTo(0,row);
row++;
GLCD_WriteText("Disc Initialised");
if(!f_mount(0, &FatFs)){
GLCD_TextGoTo(0,row);
row++;
GLCD_WriteText("Drive Mounted");
fResult = f_opendir(&workDir, "");
if(fResult == FR_OK){
GLCD_TextGoTo(0,row);
row++;
GLCD_WriteText("Opened Directory");
fResult = f_readdir(&workDir, &info);
while(fResult == FR_OK && info.fname[0] != NULL){
snprintf(buffer, 40, "Name: %s Size: %d Bytes",info.fname, info.fsize);
row++;
GLCD_TextGoTo(0,row);
GLCD_WriteText(buffer);
fResult = f_readdir(&workDir, &info);
}}}}}
xSemaphoreGive(lcdGate);
}
vTaskDelete(NULL);
while(1){
vTaskDelay(200);
}
}
/
———————————————————–/
/
———————————————————–/
void alert_flash(void){
while(1){
//alert_red(ON);
alert_green(OFF);
vTaskDelay(50);
//alert_red(OFF);
alert_green(ON);
vTaskDelay(20);
}
}
/
———————————————————–/
/
———————————————————–/
void update
time(void){
char dateString[40];
char timeString[40];
RTCDateTypeDef RTC
DateStructure;
RTCTimeTypeDef RTC_TimeStruct;
while(1){
RTC_GetDate(RTC_Format_BIN, &RTC_DateStructure); //retrieve date information, consider shifting to low priority task with higher interval
RTC_GetTime(RTC_Format_BIN, &RTC_TimeStruct); //retrieve time information
//Build display strings in preperation
snprintf(dateString, 40, "Date 20%02d/%02d/%02d", RTC_DateStructure.RTC_Year, RTC_DateStructure.RTC_Month, RTC_DateStructure.RTC_Date);
snprintf(timeString, 40, "Time %02d:%02d:%02d", RTC_TimeStruct.RTC_Hours, RTC_TimeStruct.RTC_Minutes, RTC_TimeStruct.RTC_Seconds);
if(xSemaphoreTake(lcdGate, 500)){
GLCD_TextGoTo(0,1);
GLCD_WriteText(" ");
GLCD_TextGoTo(0,2);
GLCD_WriteText(" ");
GLCD_TextGoTo(0,1);
GLCD_WriteText(dateString);
GLCD_TextGoTo(0,2);
GLCD_WriteText(timeString);
xSemaphoreGive(lcdGate);
}
vTaskDelay(500);
}
}
/
———————————————————–/
/
———————————————————–/
void USART2
IRQHandler(void){
alertred(ON);
}
void gps_task(void){
gps_init();
power_GPS(POWER_ON);
while(1){
vTaskDelay(1000);
}
}
/
———————————————————–/
/
———————————————————–/
static void prvSetupHardware( void )
{
/* Setup STM32 system (clock, PLL and Flash configuration) */
SystemInit();
/* Ensure all priority bits are assigned as preemption priority bits. */
NVIC_PriorityGroupConfig( NVIC_PriorityGroup_4 );
power_init();
alert_init();
power_LCD(POWER_ON);
print_usart_init();
App_RTC_Init();
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
gps_init
~~~~~~~~~~~~~~~~~~~~~
:::c++
void gps
init(void){
USARTInitTypeDef USART
InitStructure;
NVICInitTypeDef NVIC
InitStructure;
GPIOInitTypeDef GPIO_InitStructure;
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
RCC
APB1PeriphClockCmd(RCCAPB1Periph_USART2, ENABLE);
GPIO_PinAFConfig(GPIOA, GPIO_PinSource3, GPIO_AF_USART2);
GPIO
InitStructure.GPIOSpeed = GPIO
Speed50MHz;
GPIO
InitStructure.GPIOMode = GPIO
ModeAF;
GPIO
InitStructure.GPIOPuPd = GPIO
PuPdNOPULL;
GPIO
InitStructure.GPIOPin = GPIO
Pin3;
GPIO
Init(GPIOA, &GPIOInitStructure);
USART_InitStructure.USART_BaudRate = 4800;
USART
InitStructure.USARTWordLength = USART
WordLength8b;
USART
InitStructure.USARTStopBits = USART
StopBits1;
USART
InitStructure.USARTParity = USART
ParityNo;
USART
InitStructure.USARTHardwareFlowControl = USART
HardwareFlowControlNone;
USART
InitStructure.USARTMode = USART
ModeRx;
USART
Init(USART2, &USARTInitStructure);
/* Enable the USART Interrupt */
NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x0F;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x0F;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
/* Enable USART */
USART_Cmd(USART2, ENABLE);
USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);
// receiverState = waitForStart;
// parsedMsg.msg
valid = NOTVALID;
// lastKnowGoodPos.msg
valid = NOTVALID;
}
~~~~~~~~~~~~~~~~~~~~~~~~~~