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
  }
}
0 REPLIES 0