- LPC1788 as above
- FreeRTOS included with LPCOpen (FreeRTOS version 7.3.0 – yep I know it’s old)
- Keil uVision v4.71.2.0
CANBUS example for LPC17xx
Hi folks,
I’m looking to try utilising FreeRTOS with a NXP LPC1788 MPU (Specifically the HY-LPC1788-CORE board), however I’ve had difficulties getting the CAN IRQ to fire or read any usable data.
My setup is as follows;
CANBUS example for LPC17xx
Am I right in thinking from your description that the CAN ISR is
executing correctly in an application that is running without FreeRTOS,
but is not executing when you are running FreeRTOS? If so, are you
trying the ISR after the scheduler has started, or before the scheduler
has started? As soon as you start using FreeRTOS API functions
interrupts will remain disabled until the scheduler is started – that is
done to prevent interrupts trying to use FreeRTOS calls prior to
FreeRTOS actually running.
Other than that – FreeRTOS does not do anything itself with interrupts,
and as long as you have the interrupt’s priority set at or below
configMAXSYSCALLINTERRUPT_PRIORITY if you want to use an API function,
then you should not notice any difference with or without FreeRTOS.
If the ISR is being called, but the code in the ISR is not doing what
you want or expect, then please post the code.
Regards.
CANBUS example for LPC17xx
Hi there,
I’ve had CANBUS working successfully on the LPC1788 platform for a good couple of years, using the standard CMSIS / LPCOpen frameworks.
I’m less inclined to believe it’s IRQ related as even when I manually trigger the IRQ using Keils debugger, the program will return gibberish. I know for a fact there should be something in the buffer because I’m firing data at it from an MBED LPC1768 which is received fine using non-RTOS code.
I honestly don’t know if it’s my setup, if I’m incorrectly initialising the CAN subsystem or what. Possibly the memory isn’t assigned properly. Attempting to send fails too with a transmission timeout.
Here’s a slimmed down code block (it may not compile as I’ve removed non-relevant blocks), it’s also hasn’t been touched in months as I took a break;
~~~
/*********************************
* Includes and required variables *
*********************************/
include “board.h”
include “FreeRTOS.h”
include “task.h”
include “queue.h”
include “semphr.h”
include <stdlib.h>
include <string.h>
// #include <stdarg.h> LPCCANT *CANPort; bool CANIRQInitialised; const unsigned char CAN_INTERFACE = 0;define CANBAUDRATE 500000UL
define CANFILTERFRAMES 0
xSemaphoreHandle xCANReceiveSemaphore; typedef struct { unsigned char length; char *data; } xMessage; /********************************* * Callable functions * *********************************/ /* Sets up the CAN controller */ void InitCAN(void) { if (CANIRQInitialised) { Chip_CAN_IntDisable(CANPort, CAN_IER_BITMASK); Chip_CAN_DeInit(CANPort); } if (CAN_INTERFACE == 1) CANPort = LPC_CAN2; else CANPort = LPC_CAN1; Chip_CAN_Init(CANPort); Chip_CAN_SetBitRate(CANPort, CAN_BAUD_RATE); Chip_CAN_SetAFMode(LPC_CANAF, CAN_AF_BYBASS_MODE); Chip_CAN_IntEnable(CANPort, CAN_IER_BITMASK); CANIRQInitialised = 1; } /* Sets up system hardware */ static void prvSetupHardware (void) { Board_Init(); InitCAN(); } /********************************* * Tasks * *********************************/ /* CAN receive task */ static void vTaskCANReceive (void *pvParameters) { xMessage message; portBASE_TYPE xQueueStatus; CAN_MSG_T canframe; xSemaphoreTake(xCANReceiveSemaphore, 0); while (1) { Chip_CAN_IntEnable(CANPort, CAN_IER_BITMASK); message.length = 12; message.data = (char *)calloc(12, 0x0); while (Chip_CAN_Receive(CANPort, &canframe)) { canframe.ID &= ~CAN_EXTEND_ID_USAGE; message.data[0] = ((canframe.ID >> 24) & 0xFF); message.data[1] = ((canframe.ID >> 16) & 0xFF); message.data[2] = ((canframe.ID >> 8) & 0xFF); message.data[3] = ((canframe.ID >> 0) & 0xFF); memcpy(message.data + 4, canframe.Data, 8); DEBUGOUT(“Received: %s”, &message); } } } /********************************* * Interrupt handlers * *********************************/ /* CAN IRQ handler */ void CAN_IRQHandler(void) { portBASE_TYPE xCurrentTaskInterrupted = pdFALSE; unsigned long IRQStatus = Chip_CAN_GetIntStatus(CANPort); DEBUGOUT(“CAN IRQ received: 0x%04Xrn”, IRQStatus); if (!(IRQStatus & CAN_ICR_RI)) return; NVIC_ClearPendingIRQ(CAN_IRQn); Chip_CAN_IntDisable(CANPort, CAN_IER_BITMASK); DEBUGOUT(“-“); xSemaphoreGiveFromISR(xCANReceiveSemaphore, &xCurrentTaskInterrupted); portEND_SWITCHING_ISR(xCurrentTaskInterrupted); } /********************************* * Main function * *********************************/ int main (void) { /* Init */ unsigned long i; prvSetupHardware();/* Queues and Semaphore */
vSemaphoreCreateBinary(xCANReceiveSemaphore); if (xCANReceiveSemaphore == NULL) { DEBUGOUT("Unable to create xCANReceiveSemaphorern"); return 1; }
/* IRQs */
Chip_UART_IntConfig(LPC_UART0, UART_INTCFG_RBR, ENABLE);
NVIC_SetPriority(UART0_IRQn, configKERNEL_INTERRUPT_PRIORITY);
NVIC_EnableIRQ(UART0_IRQn);
DEBUGOUT("Waiting for CAN init... ");
InitCAN();
for (i=0; i<50000000; i++) { }
NVIC_SetPriority(CAN_IRQn, configKERNEL_INTERRUPT_PRIORITY - 1);
NVIC_EnableIRQ(CAN_IRQn);
CANIRQInitialised = 1;
AddFrameToAFLUT(0, 0x600UL, 0x700UL);
InitCAN();
DEBUGOUT("Done!rn");
/* Tasks */
xTaskCreate(vTaskCANReceive, (signed char *) "CAN Receive", configMINIMAL_STACK_SIZE, NULL, (tskIDLE_PRIORITY + 1UL), (xTaskHandle *) NULL);
/* Start the scheduler */
vTaskStartScheduler();
/* Should never arrive here */
return 1;
}
~~~
CANBUS example for LPC17xx
What does DEBUGOUT() do? If it uses semihosting to output chars that could be your issue as it will interfere with FreeRTOS interrupts. Even if it is not using semihosting I would recommend trying without DEBUGOUT() as you are calling it from tasks and interrupts.
CANBUS example for LPC17xx
Hi MEdwards,
DEBUGOUT is a simple function to write a message (filtered through printf) to the debug UART so I can get some measure of feedback over what is exactly happening.
I’m unsure it’ll be tampering with much. I’m just firing up the code now to see exactly what was failing.