AnsweredAssumed Answered

CAN Interrupt error when using FreeRtos

Question asked by huang tianxiang on May 19, 2018

Hi, 

    I am using CAN COM API provided by the official, I demonstrated the "callback" demo, it's no problem. However when I combined that with FreeRtos project, there is always an error at Callback function. I just learn FreeRtos for several days, so is there anyone can help me check the code, and give some suggestion.

 

this is my code:

 

 

/* FreeRTOS kernel includes. */
#include "FreeRTOS.h"
#include "task.h"
#include "queue.h"
#include "timers.h"
#include "event_groups.h"

/* Freescale includes. */
#include "fsl_device_registers.h"
#include "fsl_debug_console.h"
#include "board.h"

/* User include. */
#include "can.h"
#include "pin_mux.h"
#include <stdbool.h>
/*******************************************************************************
* Definitions
******************************************************************************/

#define B0 (1 << 0)
#define B1 (1 << 1)
#define TICKRATE_HZ (1000) /* 1000 ticks per second */
#define TRANSMIT_PERIOD (100) /* milliseconds between transmission */

#define ECHO_BUFFER_LENGTH 20

#define CAN0_IRQ CAN0_IRQ0_IRQn
#define CAN1_IRQ CAN1_IRQ0_IRQn

#define CAN0_NVIC_PRIO 0
/* The software timer period. */
#define SW_TIMER_PERIOD_MS (1000 / portTICK_PERIOD_MS)
/*******************************************************************************
* Variables
******************************************************************************/
can_handle_t g_canHandle0;
can_handle_t g_canHandle1;

volatile bool CAN0rxBufferEmpty = true;
volatile bool CAN0rxOnGoing = false;

/* handle for non-blocking receive for message buffer 0 */
static can_mb_transfer_t mb0rxfer;
/*******************************************************************************
* Prototypes
******************************************************************************/
static void write_task_1(void *pvParameters);


/* USART user callback */
void CAN0_Callback(CAN_Type *base, can_handle_t *handle, status_t status, uint32_t result, void *userData);
void SwTimerCallback(TimerHandle_t xTimer);
/*******************************************************************************
* Globals
******************************************************************************/

/*******************************************************************************
* Code
******************************************************************************/


/*!
* @brief Main function
*/
int main(void)
{
can_config_t config;
can_frame_t rxmb0msg;
TimerHandle_t SwTimerHandle = NULL;
/* Define the init structure for the output LED pin*/
gpio_pin_config_t led_config = {
kGPIO_DigitalOutput, 0,
};

/* Board pin, clock, debug console init */
/* attach 12 MHz clock to FLEXCOMM0 (debug console) */
CLOCK_AttachClk(BOARD_DEBUG_UART_CLK_ATTACH);
CLOCK_EnableClock(kCLOCK_Gpio0);
CLOCK_EnableClock(kCLOCK_Gpio1);
CLOCK_EnableClock(kCLOCK_Gpio2);
CLOCK_EnableClock(kCLOCK_Gpio3);

/* attach 12 MHz clock to FLEXCOMM0 (debug console) */
CLOCK_AttachClk(BOARD_DEBUG_UART_CLK_ATTACH);

BOARD_InitPins();
BOARD_BootClockFROHF96M();
BOARD_InitDebugConsole();

/* Init output LED GPIO. */
GPIO_PinInit(GPIO, BOARD_LED1_GPIO_PORT, BOARD_LED1_GPIO_PIN, &led_config);
GPIO_WritePinOutput(GPIO, BOARD_LED1_GPIO_PORT, BOARD_LED1_GPIO_PIN, 1);
GPIO_PinInit(GPIO, BOARD_LED2_GPIO_PORT, BOARD_LED2_GPIO_PIN, &led_config);
GPIO_WritePinOutput(GPIO, BOARD_LED2_GPIO_PORT, BOARD_LED2_GPIO_PIN, 1);
GPIO_PinInit(GPIO, BOARD_LED3_GPIO_PORT, BOARD_LED3_GPIO_PIN, &led_config);
GPIO_WritePinOutput(GPIO, BOARD_LED3_GPIO_PORT, BOARD_LED3_GPIO_PIN, 1);

/* configure for 4Mbps data 1Mbps nominal, CAN-FD */
CAN_GetDefaultConfig(&config);
config.baseAddress = 0x20010000;
config.nominalBaudRate = 1000000;
config.dataBaudRate = 4000000;
config.timestampClock_Hz = 100000;

/* Set CAN0 interrupt priority higher. */
NVIC_SetPriority(CAN0_IRQ, CAN0_NVIC_PRIO+1);
EnableIRQ(CAN0_IRQ);

CAN_Init(CAN0, &config, SystemCoreClock);

/* receive 0x100 in CAN0 rx message buffer 0 by setting mask 0 */
CAN_SetRxIndividualMask(CAN0, 0, CAN_RX_MB_STD(0x52, 0));
/* receive 0x100 in CAN0 rx message buffer 0 by setting mask 1 */
CAN_SetRxIndividualMask(CAN0, 1, CAN_RX_MB_STD(0x57, 0));
/* receive 0x00000200 (29-bit id) in CAN1 rx message buffer 1 by setting mask 3 */
CAN_SetRxExtIndividualMask(CAN0, 3, CAN_RX_MB_EXT_LOW(0x200, 1), CAN_RX_MB_EXT_HIGH(0x200, 1));

//Creat a handler to get Interrupt
CAN_TransferCreateHandle(CAN0, &g_canHandle0, CAN0_Callback, NULL);

/* enable CAN 0 */
CAN_Enable(CAN0, true);

mb0rxfer.frame = &rxmb0msg;
mb0rxfer.mbIdx = 0;
CAN_TransferReceiveNonBlocking(CAN0, &g_canHandle0, &mb0rxfer);

 

xTaskCreate(write_task_1, "WRITE_TASK_1", configMINIMAL_STACK_SIZE + 38, NULL, tskIDLE_PRIORITY + 2, NULL);

/* Start scheduling. */
vTaskStartScheduler();
for (;;)
;
}

void SwTimerCallback(TimerHandle_t xTimer){
GPIO_TogglePinsOutput(GPIO, BOARD_LED2_GPIO_PORT, 1u << BOARD_LED2_GPIO_PIN);
}

/* CAN user callback */
void CAN0_Callback(CAN_Type *base, can_handle_t *handle, status_t status, uint32_t result, void *userData)
{
can_frame_t *rxmsg;
BaseType_t reschedule;
//if handle from CAN0
if(handle == &g_canHandle0)
{
/* message received into message buffer */
if (status == (status_t)kStatus_CAN_RxIdle)
{
/* get received message */

 

rxmsg = handle->mbFrameBuf[result];
/* toggle LED3 */
GPIO_TogglePinsOutput(GPIO, BOARD_LED3_GPIO_PORT, 1u << BOARD_LED3_GPIO_PIN);
/* receive next message using this callback */
CAN_TransferReceiveNonBlocking(CAN0, &g_canHandle0, &mb0rxfer);
}
else if (status == (status_t)kStatus_CAN_RxFifoIdle)
{
/* result holds the fifo number */
/* get the message from handle->rxFifoFrameBuf[result] */
}
}

// xSemaphoreGiveFromISR(handle->semaphore, &reschedule);
// portYIELD_FROM_ISR(1);
xTaskResumeFromISR(write_task_1);

}

 

/*!
* @brief write_task_1 function work_task mean the
*/
static void write_task_1(void *pvParameters)
{
while (1)
{
GPIO_TogglePinsOutput(GPIO, BOARD_LED1_GPIO_PORT, 1u << BOARD_LED1_GPIO_PIN);
vTaskDelay(1000);
}
}

Outcomes