{"id":21116642,"url":"https://github.com/canopennode/canopenstm32","last_synced_at":"2025-04-05T03:10:00.645Z","repository":{"id":38095171,"uuid":"402037441","full_name":"CANopenNode/CanOpenSTM32","owner":"CANopenNode","description":"CANopenNode on STM32 microcontrollers.","archived":false,"fork":false,"pushed_at":"2024-09-10T12:25:13.000Z","size":3568,"stargazers_count":333,"open_issues_count":33,"forks_count":128,"subscribers_count":21,"default_branch":"master","last_synced_at":"2025-03-29T02:07:27.380Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/CANopenNode.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2021-09-01T11:34:05.000Z","updated_at":"2025-03-24T03:05:14.000Z","dependencies_parsed_at":"2024-11-20T02:34:33.828Z","dependency_job_id":"de6d9609-7319-4582-af75-1e4c188ebacb","html_url":"https://github.com/CANopenNode/CanOpenSTM32","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/CANopenNode%2FCanOpenSTM32","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/CANopenNode%2FCanOpenSTM32/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/CANopenNode%2FCanOpenSTM32/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/CANopenNode%2FCanOpenSTM32/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/CANopenNode","download_url":"https://codeload.github.com/CANopenNode/CanOpenSTM32/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247280272,"owners_count":20912967,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-20T02:32:08.560Z","updated_at":"2025-04-05T03:10:00.622Z","avatar_url":"https://github.com/CANopenNode.png","language":"C","readme":"# CANopenNode STM32\n\nCANopenSTM32 is a CANopen stack running on STM32 microcontroller based on [CANOpenNode](https://github.com/CANopenNode/CANopenNode) stack.\n\n## How to run demos\n\nExamples are developed in [STM32CubeIDE](https://www.st.com/en/development-tools/stm32cubeide.html) tool,\nofficial ST development studio for any STM32 microcontroller.\nYou can directly open projects in the STM32CubeIDE and run examples on the relevant boards.\n\n## Repository directories\n\n- `.\\CANopenNode` : Includes the stack implemenation, for most of usecases you don't need to touch these files as they are constant between all the variations and ports (i.e. Linux, PIC, STM32 and etc.)\n- `.\\CANopenNodeSTM32` : Includes the implementation of low-level driver for STM32 microcontrollers, support both CAN based controllers and FDCAN without any changes. It automatically detect the controller type and activate the relevant calls to STM32 HAL libraries\n- `.\\examples` : It include many examples on various boards including STM32F4-Discovery, STM32G0C1 Evaluation board, STM32F076 Nucleo Board, STM32H735G-Development Kit.\n- `.\\Legacy` : It include an older version of CANOpenSTM32 implementation, specifically made for FDCAN controllers, however it was stable and include the FreeRTOS implementation. \n\n## Supported boards and MCUs\n \n\n### [STM32H735G-DK](https://www.st.com/en/evaluation-tools/stm32h735g-dk.html).\nIt has many features of STM32H7xx series and includes 3 CAN transceivers on the board.\nYou do not need any additional hardware to connect to existing CAN network.\nIt also includes built-in programmer and virtual COM port for communication, hence evaluation is quick and easy.\n\n\u003e CanOpen demo works at `FDCAN1` port. Use connector *CN18*.\n\n\u003e FDCAN IP block is same for any STM32H7xx MCU family, hence migration to your custom board should be straight-forward.\n\n* Runs out of the box on STM32H735G-DK board\n* Bare metal, and FreeRTOS operating system examples\n* `FDCAN1` (*CN18*) hardware is used for communication at 125kHz\n* CANopen LED control is well integrated\n* Debug messages are available through VCP COM port at `115200` bauds\n* Can be used as a reference code for end product\n\n\n\n### [STM32G0C1VE-EV](https://www.st.com/en/evaluation-tools/stm32g0c1e-ev.html)\nThe 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.\nYou don't need any additional hardware to connect to existing CAN network.\nIt also includes built-in programmer and virtual COM port for communication, hence evaluation is quick and easy.\n\u003e CanOpen demo works at `FDCAN1` port. Use connector *CN12*.\n\u003e FDCAN IP block is same for any STM32G0xx MCU family, hence migration to your custom board should be straight-forward.\n\n\n### [NUCLEO-F303ZE](https://www.st.com/en/evaluation-tools/nucleo-f303ze.html) / [NUCLEO-F072RB](https://www.st.com/en/evaluation-tools/nucleo-f072rb.html) + [MAX33040ESHLD](https://www.digikey.ie/en/products/detail/analog-devices-inc-maxim-integrated/MAX33040ESHLD/13558019)\n\nNucleo 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.\n\nThis 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).\n\n\n### [STM32F4DISCOVERY](https://www.st.com/en/evaluation-tools/stm32f4discovery.html) + Any CAN Bus Physical Layer Module\n\nHave a look at STM32CubeMX configuration file for pin mapping.\n\n\n## Video Tutorial\n\nTo 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.\n\n[![CANOpen Node STM32 From basics to coding](https://img.youtube.com/vi/R-r5qIOTjOo/0.jpg)](https://www.youtube.com/watch?v=R-r5qIOTjOo)\n\n\u003e[00:00](https://www.youtube.com/watch?v=R-r5qIOTjOo\u0026t=0s) Introduction and Overview [1:13](https://www.youtube.com/watch?v=R-r5qIOTjOo\u0026t=73s) Why CAN ? [4:51](https://www.youtube.com/watch?v=R-r5qIOTjOo\u0026t=291s) CAN Bus [8:55](https://www.youtube.com/watch?v=R-r5qIOTjOo\u0026t=535s) Why CANOpen ? [13:27](https://www.youtube.com/watch?v=R-r5qIOTjOo\u0026t=807s) CANOpen architecture [20:00](https://www.youtube.com/watch?v=R-r5qIOTjOo\u0026t=1200s) Object dictionary [21:38](https://www.youtube.com/watch?v=R-r5qIOTjOo\u0026t=1298s) Important CANOpen concepts [23:29](https://www.youtube.com/watch?v=R-r5qIOTjOo\u0026t=1409s) PDO [27:25](https://www.youtube.com/watch?v=R-r5qIOTjOo\u0026t=1645s) SDO [32:23](https://www.youtube.com/watch?v=R-r5qIOTjOo\u0026t=1943s) NMT [33:25](https://www.youtube.com/watch?v=R-r5qIOTjOo\u0026t=2005s) CANOpenNode Open-Source Stack [39:26](https://www.youtube.com/watch?v=R-r5qIOTjOo\u0026t=2366s) STM32 Practical implementation [40:29](https://www.youtube.com/watch?v=R-r5qIOTjOo\u0026t=2429s) CANOpen Tutorial code preparation [43:09](https://www.youtube.com/watch?v=R-r5qIOTjOo\u0026t=2589s) Importing examples to STM32CubeIDE and programming them [47:04](https://www.youtube.com/watch?v=R-r5qIOTjOo\u0026t=2824s) Examples explanation [57:00](https://www.youtube.com/watch?v=R-r5qIOTjOo\u0026t=3420s) Porting to custom STM32 board [1:18:20](https://www.youtube.com/watch?v=R-r5qIOTjOo\u0026t=4700s) EDS Editor (Object dictionary editor) [1:25:54](https://www.youtube.com/watch?v=R-r5qIOTjOo\u0026t=5154s) Creating a TPDO [1:39:55](https://www.youtube.com/watch?v=R-r5qIOTjOo\u0026t=5995s) Accessing OD Variables [1:54:08](https://www.youtube.com/watch?v=R-r5qIOTjOo\u0026t=6848s) Creating an RPDO [2:05:50](https://www.youtube.com/watch?v=R-r5qIOTjOo\u0026t=7550s) Using the SDOs [2:52:52](https://www.youtube.com/watch?v=R-r5qIOTjOo\u0026t=10372s) Node guarding [3:04:38](https://www.youtube.com/watch?v=R-r5qIOTjOo\u0026t=11078s) Transmitting PDOs manually\n\n\n\n## Porting to other STM32 microcontrollers checklist :\n- Create a new project in STM32CubeMXIDE\n- Configure CAN/FDCAN to your desired bitrate and map it to relevant tx/rx pins - Make sure yo activate Auto Bus recovery (bxCAN) / protocol exception handling (FDCAN)\n- Activate the RX and TX interrupt on the CAN peripheral\n- Enable a timer for a 1ms overflow interrupt and activate interrupt for that timer\n- Copy or clone `CANopenNode` and `CANopenNodeSTM32` into your project directory \n- Add `CANopenNode` and `CANopenNodeSTM32` to Source locations in `Project Properties -\u003e C/C++ General -\u003e Paths and Symbols -\u003e Source Locations`\n  - add an exclusion filter for `example/` folder for `CANopenNode` folder\n- Add `CANOpenNode` and `CANopenNodeSTM32` to `Project Properties -\u003e C/C++ General -\u003e Paths and Symbols -\u003e Includes` under `GNU C` items\n- In your main.c, add `#include \"CO_app_STM32.h\"`\n  ```c\n    /* Private includes ----------------------------------------------------------*/\n    /* USER CODE BEGIN Includes */\n    #include \"CO_app_STM32.h\"\n    /* USER CODE END Includes */\n  ```\n  - Make sure that you have the `HAL_TIM_PeriodElapsedCallback` function implmented with a call to `canopen_app_interrupt`.\n\n```c\nvoid HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)\n{\n  /* USER CODE BEGIN Callback 0 */\n\n  /* USER CODE END Callback 0 */\n  if (htim-\u003eInstance == TIM1) {\n    HAL_IncTick();\n  }\n  /* USER CODE BEGIN Callback 1 */\n  // Handle CANOpen app interrupts\n  if (htim == canopenNodeSTM32-\u003etimerHandle) {\n      canopen_app_interrupt();\n  }\n  /* USER CODE END Callback 1 */\n}\n\n```\n\n- Now based on your application, you'll take one of the following approaches :\n\n  ### In Baremetal application\n- In your main.c, add following codes to your USER CODE BEGIN 2\n  ```c\n    /* USER CODE BEGIN 2 */\n    CANopenNodeSTM32 canOpenNodeSTM32;\n    canOpenNodeSTM32.CANHandle = \u0026hcan;\n    canOpenNodeSTM32.HWInitFunction = MX_CAN_Init;\n    canOpenNodeSTM32.timerHandle = \u0026htim17;\n    canOpenNodeSTM32.desiredNodeID = 29;\n    canOpenNodeSTM32.baudrate = 125;\n    canopen_app_init(\u0026canOpenNodeSTM32);\n    /* USER CODE END 2 */\n  ```\n\n- In your main.c, add following codes to your USER CODE BEGIN WHILE\n  ```c\n  /* USER CODE BEGIN WHILE */\n  while (1)\n  {\n\t  canopen_app_process();\n    /* USER CODE END WHILE */\n\n  ```\n\n  ### In FreeRTOS Applications\n- You need to create a task for CANOpen, we call it `canopen_task` with a high priority and in that task use the following code : \n\n```c\n\nvoid canopen_task(void *argument)\n{\n  /* USER CODE BEGIN canopen_task */\n  CANopenNodeSTM32 canOpenNodeSTM32;\n  canOpenNodeSTM32.CANHandle = \u0026hfdcan1;\n  canOpenNodeSTM32.HWInitFunction = MX_FDCAN1_Init;\n  canOpenNodeSTM32.timerHandle = \u0026htim17;\n  canOpenNodeSTM32.desiredNodeID = 21;\n  canOpenNodeSTM32.baudrate = 125;\n  canopen_app_init(\u0026canOpenNodeSTM32);\n  /* Infinite loop */\n  for(;;)\n  {\n\t  //Reflect CANopenStatus on LEDs\n    HAL_GPIO_WritePin(LED1_GPIO_Port, LED1_Pin, !canOpenNodeSTM32.outStatusLEDGreen);\n    HAL_GPIO_WritePin(LED2_GPIO_Port, LED2_Pin, !canOpenNodeSTM32.outStatusLEDRed);\n    canopen_app_process();\n    // Sleep for 1ms, you can decrease it if required, in the canopen_app_process we will double check to make sure 1ms passed\n    vTaskDelay(pdMS_TO_TICKS(1));\n  }\n  /* USER CODE END canopen_task */\n}\n\n```\n\u003e 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`.\n\n- Run your project on the target board, you should be able to see bootup message on startup\n\n### Known limitations : \n\n- We have never tested the multi CANOpen on a single STM32 device, but the the original CANOpenNode has the capability to use multi modules, which you can develop yourself.\n\n### Clone or update\n\nClone the project from git repository and get submodules:\n\n```\ngit clone https://github.com/CANopenNode/CANopenSTM32\ncd CANopenSTM32\ngit submodule update --init --recursive\n```\n\nUpdate an existing project including submodules:\n\n```\ncd CANopenSTM32\ngit pull\ngit submodule update --init --recursive\n```\n\n## License\n\nThis 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/.\n\nLicensed 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\n\nhttp://www.apache.org/licenses/LICENSE-2.0\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcanopennode%2Fcanopenstm32","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcanopennode%2Fcanopenstm32","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcanopennode%2Fcanopenstm32/lists"}