cancel
Showing results for 
Search instead for 
Did you mean: 

HardFault (CANopenNodeSTM32, traditional CAN - not FDCAN, FreeRTOS, chip = STM32L452RE)

Scott_Kaplan
Visitor

The author of this how to get CANopenNodeSTM32 working video is very good (The length of the video is 3:31:33; The part that is pertinent to this post 57:05 - 1:18:22).  Unfortunately, this video targets FDCAN (but I don't have this available; my chip just supports plain CAN) and this video also targets bare metal (but I don't have this available; FreeRTOS is what I am using).  I tried to follow all of the author's steps but was unable to.  When I ran I got a HardFault with the CAN node never even coming online.

Executing this line is what causes the Hard fault
canopen_app_init(&canOpenNodeSTM32);

 

From the instructions in the video, there are numerous steps that are different between FDCAN and CAN and I don't know what the equivalent (plain) CAN steps are which I believe may be the root of the problem.
 
     Under the "Parameter Settings" tab
  • "FDCAN1" and "FDCAN2" are in the video at 1:00:55. Mine doesn't have these.  Mine just has "CAN1"
  • "Auto Retransmit" is in the video at 1:01:20.  Mine doesn't have this.  Nor do I see an equivalent setting.
  • "Transmit Pause"  is in the video at 1:01:22.  Mine doesn't have this.  Nor do I see an equivalent setting.
  • "Frame Format"  is in the video at 1:01:41.  Mine doesn't have this.  Nor do I see an equivalent setting.
  • The bit timing settings ("Nominal Prescaler", "Nominal Time S...", "Nominal Time S..") are in the video at 1:04:25.  Mine doesn't have quite the same.  Mine is "Prescaler (for Time Quantum)", "Time Quanta in Bit Segment 1", "Time Quanta in Bit Segment 2".  I set these to 40,12 Times, 4 Times respectively.  The numbers that the presenter set his to are 32,13,2 respectively.  His numbers were based on fields that he has that I don't have and so I am unclear as to whether it is comparing apples to apples or apples to oranges.  I don't know if my numbers are correct.
  • "Data Prescaler" is in the video at 1:04:36.  Mine doesn't have this.  Nor do I see an equivalent setting.
  • "Data Time Seg1"  is in the video at 1:04:36.  Mine doesn't have this.  Nor do I see an equivalent setting.
  • "Data Time Seg2"  is in the video at 1:04:36.  Mine doesn't have this.  Nor do I see an equivalent setting.
     Under "NVIC Settings" tab
  • "TIM16, FDCAN1_IT0 and FDCAN2_IT0 Interrupt"  is in the video at 1:05:58.  Mine doesn't have this.
  • " TIM17, FDCAN1_IT1 and FDCAN2_IT1 Interrupt" is in the video at 1:05:58.  Mine doesn't have this.
  • Mine shows only the following
    • "CAN1 TX interrupt"
    • "CAN1 RX0 interrupt"
    • "CAN1 RX1 interrupt"
    • Note:  I attempted to activate TIM16 on each of these to see what would happen and every time it disabled CAN on the pin; both the timer and CAN don't seem to be able to coexist.
    Under Timers
  • "TIM14" is in the video at 1:07:05.  Mine doesn't have this.  Nor do I see an equivalent.

 

Below is all of the 'CAN' related code per the author's recommendation on top of what was generated from the .ioc file.  Note: this is specifically the FreeRTOS implementation not bare metal, since I don't have an option to run bare metal.
 
Notes:
  • Double blank lines below means that I removed unreleated code/comments that was not 'CAN'.  I removed this so anyone looking through will just see the 'CAN' related code.  Maybe it will make it easier to spot an error (or multiple errors) that I made.
  • The commented out lines that appear below resulted from me not being able to follow the author's steps - Because I don't have FDCAN; I just have CAN.

All code that I modified/added below is just in one file - main.c (.../App/main.c)
#include "CO_app_STM32.h"
osThreadId_t canOpenNodeTaskHandle;
const osThreadAttr_t canOpenNodeTask_attributes = {
    .name = "task CAN",
    .stack_size = 192,
    .priority = (osPriority_t) osPriorityHigh,
};

static void MX_CAN1_Init(void);
void startCanOpenNodeTask(void *argument);

MX_CAN1_Init();

canOpenNodeTaskHandle = osThreadNew(startCanOpenNodeTask, NULL, &canOpenNodeTask_attributes);

static void MX_CAN1_Init(void)
{
  hcan1.Instance = CAN1;
  hcan1.Init.Prescaler = 40;
  hcan1.Init.Mode = CAN_MODE_NORMAL;
  hcan1.Init.SyncJumpWidth = CAN_SJW_1TQ;
  hcan1.Init.TimeSeg1 = CAN_BS1_12TQ;
  hcan1.Init.TimeSeg2 = CAN_BS2_4TQ;
  hcan1.Init.TimeTriggeredMode = DISABLE;
  hcan1.Init.AutoBusOff = DISABLE;
  hcan1.Init.AutoWakeUp = DISABLE;
  hcan1.Init.AutoRetransmission = DISABLE;
  hcan1.Init.ReceiveFifoLocked = DISABLE;
  hcan1.Init.TransmitFifoPriority = DISABLE;
  if (HAL_CAN_Init(&hcan1) != HAL_OK)
  {
    Error_Handler();
  }
}

__attribute__((noreturn)) void startCanOpenNodeTask(void *argument)
{
  CANopenNodeSTM32 canOpenNodeSTM32;
  //canOpenNodeSTM32.CANHandle = &hfdcan1;
  canOpenNodeSTM32.CANHandle = &hcan1;
  // canOpenNodeSTM32.HWInitFunction = MX_FDCAN1_Init;
  canOpenNodeSTM32.HWInitFunction = MX_CAN1_Init;
  // canOpenNodeSTM32.timerHandle = &htim17;
  canOpenNodeSTM32.desiredNodeID = 21;
  // canOpenNodeSTM32.baudrate = 125;
  canopen_app_init(&canOpenNodeSTM32); // Hard fault
  // never makes it to here because the line above Hard faults
  for(;;)
  {
    // it makes no difference what is in here yet, because a Hard fault occurs when executing the above line
  }
}
1 REPLY 1
SofLit
ST Employee

Hello,

Not obvious to watch a 3 hours video. 

You are using STM32L452 having CAN 2.0 and in the video I can see some devices having also CAN 2.0 like F0.

I suggest you to follow the steps in the video of one of the devices having CAN2.0 and start with baremetal. Don't start with RTOS at this stage. Or contact the Youtuber.

To give better visibility on the answered topics, please click on "Accept as Solution" on the reply which solved your issue or answered your question.