CANopenNode / CanOpenSTM32

CANopenNode on STM32 microcontrollers.
Other
275 stars 110 forks source link

CANopenNode STM32

CANopenSTM32 is a CANopen stack running on STM32 microcontroller based on CANOpenNode stack.

How to run demos

Examples are developed in STM32CubeIDE tool, official ST development studio for any STM32 microcontroller. You can directly open projects in the STM32CubeIDE and run examples on the relevant boards.

Repository directories

Supported boards and MCUs

STM32H735G-DK.

It has many features of STM32H7xx series and includes 3 CAN transceivers on the board. You do not need any additional hardware to connect to existing CAN network. It also includes built-in programmer and virtual COM port for communication, hence evaluation is quick and easy.

CanOpen demo works at FDCAN1 port. Use connector CN18.

FDCAN IP block is same for any STM32H7xx MCU family, hence migration to your custom board should be straight-forward.

STM32G0C1VE-EV

The STM32G0C1E-EV Evaluation board is a high-end development platform for the STM32G0C1VET6 microcontroller. It has many features including two CAN FD controller and physical layer on board. You don't need any additional hardware to connect to existing CAN network. It also includes built-in programmer and virtual COM port for communication, hence evaluation is quick and easy.

CanOpen demo works at FDCAN1 port. Use connector CN12. FDCAN IP block is same for any STM32G0xx MCU family, hence migration to your custom board should be straight-forward.

NUCLEO-F303ZE / NUCLEO-F072RB + MAX33040ESHLD

Nucleo includes an arduino compatible headers which can be used to add MAX33040ESHLD to it and this bundle provide the minimum required components to establish a CAN communication and CanOpenNode on top of that.

This project is tied to the CubeMX configuration, so it is up to the user to provide compatible configuration using CubeMX (bitrate, interrupt activiation and etc).

STM32F4DISCOVERY + Any CAN Bus Physical Layer Module

Have a look at STM32CubeMX configuration file for pin mapping.

Video Tutorial

To get a good grasp of CANOpenNode Stack and CANOpenNodeSTM32 stack, you can refer to this video, which explains from basics to implementation and porting of the CANOpenNode stack.

CANOpen Node STM32 From basics to coding

00:00 Introduction and Overview 1:13 Why CAN ? 4:51 CAN Bus 8:55 Why CANOpen ? 13:27 CANOpen architecture 20:00 Object dictionary 21:38 Important CANOpen concepts 23:29 PDO 27:25 SDO 32:23 NMT 33:25 CANOpenNode Open-Source Stack 39:26 STM32 Practical implementation 40:29 CANOpen Tutorial code preparation 43:09 Importing examples to STM32CubeIDE and programming them 47:04 Examples explanation 57:00 Porting to custom STM32 board 1:18:20 EDS Editor (Object dictionary editor) 1:25:54 Creating a TPDO 1:39:55 Accessing OD Variables 1:54:08 Creating an RPDO 2:05:50 Using the SDOs 2:52:52 Node guarding 3:04:38 Transmitting PDOs manually

Porting to other STM32 microcontrollers checklist :

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
  /* USER CODE BEGIN Callback 0 */

  /* USER CODE END Callback 0 */
  if (htim->Instance == TIM1) {
    HAL_IncTick();
  }
  /* USER CODE BEGIN Callback 1 */
  // Handle CANOpen app interrupts
  if (htim == canopenNodeSTM32->timerHandle) {
      canopen_app_interrupt();
  }
  /* USER CODE END Callback 1 */
}

void canopen_task(void *argument)
{
  /* USER CODE BEGIN canopen_task */
  CANopenNodeSTM32 canOpenNodeSTM32;
  canOpenNodeSTM32.CANHandle = &hfdcan1;
  canOpenNodeSTM32.HWInitFunction = MX_FDCAN1_Init;
  canOpenNodeSTM32.timerHandle = &htim17;
  canOpenNodeSTM32.desiredNodeID = 21;
  canOpenNodeSTM32.baudrate = 125;
  canopen_app_init(&canOpenNodeSTM32);
  /* Infinite loop */
  for(;;)
  {
      //Reflect CANopenStatus on LEDs
    HAL_GPIO_WritePin(LED1_GPIO_Port, LED1_Pin, !canOpenNodeSTM32.outStatusLEDGreen);
    HAL_GPIO_WritePin(LED2_GPIO_Port, LED2_Pin, !canOpenNodeSTM32.outStatusLEDRed);
    canopen_app_process();
    // Sleep for 1ms, you can decrease it if required, in the canopen_app_process we will double check to make sure 1ms passed
    vTaskDelay(pdMS_TO_TICKS(1));
  }
  /* USER CODE END canopen_task */
}

In RTOS applications, be very careful when accessing OD variables, CAN Send and EMCY variable. You should lock the these critical sections to make sure prevent race conditions. Have a look at CO_LOCK_CAN_SEND, CO_LOCK_OD and CO_LOCK_EMCY.

Known limitations :

Clone or update

Clone the project from git repository and get submodules:

git clone https://github.com/CANopenNode/CANopenSTM32
cd CANopenSTM32
git submodule update --init --recursive

Update an existing project including submodules:

cd CANopenSTM32
git pull
git submodule update --init --recursive

License

This file is part of CANopenNode, an opensource CANopen Stack. Project home page is https://github.com/CANopenNode/CANopenNode. For more information on CANopen see http://www.can-cia.org/.

Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0