RTX5/FreeRTOS全家桶源码工程综合实战模板集成CANopen组件(2024-10-30)

【前言】

之前的视频教程分享了两期CANopen的专题,配套的例子都是基于裸机的,为了方便大家在OS下使用,本期视频带OS下的支持。

CANopen协议栈专题,实战方式系统了解NMT,PDO,SDO,时间戳,同步报文,紧急报文等(2023-10-17)
BSP视频教程第27期:CANopen协议栈专题,实战方式系统了解NMT,PDO,SDO,时间戳,同步报文,紧急报文等(2023-10-17) - STM32H7 - 硬汉嵌入式论坛 - Powered by Discuz!

CANopen协议栈专题,CANopen主从机组网实战,CAN词典工具使用方法以及吃透PDO玩法(2023-11-01)
BSP视频教程第28期:CANopen协议栈专题,CANopen主从机组网实战,CAN词典工具使用方法以及吃透PDO玩法(2023-11-01) - STM32H7 - 硬汉嵌入式论坛 - Powered by Discuz!

【视频】

RTX5/FreeRTOS全家桶源码工程综合实战模板集成CANopen组件_哔哩哔哩_bilibili

【简介】

1、针对RTX5/FreeRTOS源码全家桶模板,已经更新了4期视频,这是第5期,来一期添加CANopen组件的视频教程。

第1期:RTX5全家桶源码综合模板发布,含FreeRTOS内核版本,将其打造成直接面向实际项目应用的综合框架
RTX5全家桶源码综合模板发布V3.0,含FreeRTOS内核版本,将其打造成直接面向实际项目应用的综合框架(2024-10-30) - STM32H7 - 硬汉嵌入式论坛 - Powered by Discuz!

第2期:RTX5源码全家桶集成emWin6.40, Modbus主从,含FreeRTOS版, 探讨一种移植第3方组件通用方法以及使用注意事项
RTX5源码全家桶集成emWin6.40, Modbus主从,含FreeRTOS版, 探讨一种移植第3方组件通用方法以及使用注意事项2024-08-30 - STM32H7 - 硬汉嵌入式论坛 - Powered by Discuz!

第3期:手把手AppWizard轻松制作一个emWin滑动主界面控制框架,任意跳转控制(2024-09-06)
【视频教程】手把手AppWizard轻松制作一个emWin滑动主界面控制框架,任意跳转控制(2024-09-06) - uCOS & uCGUI & emWin & embOS & TouchGFX & ThreadX - 硬汉嵌入式论坛 - Powered by Discuz!

第4期:【授人以渔】CMSIS-RTOS V2封装层专题视频,一期视频将常用配置和用法梳理清楚,适用于RTX5和FreeRTOS(2024-09-28)
【授人以渔】CMSIS-RTOS V2封装层专题视频,一期视频将常用配置和用法梳理清楚,适用于RTX5和FreeRTOS(2024-09-28) - STM32H7 - 硬汉嵌入式论坛 - Powered by Discuz!

2、CANopen常用的NMT,PDO,SDO,时间戳,同步报文,紧急报文都支持

3、移植CANopenNode协议栈到RTOS两个关键地方的处理

(1)开关中断的处理,裸机版的移植在开关中断的处理地方非常"暴力",直接就是大范围的全局开关中断处理,非常不合理

cs 复制代码
/* (un)lock critical section in CO_CANsend() */
#define CO_LOCK_CAN_SEND(CAN_MODULE)                                                                                   \
    do {                                                                                                               \
        (CAN_MODULE)->primask_send = __get_PRIMASK();                                                                  \
        __disable_irq();                                                                                               \
    } while (0)
#define CO_UNLOCK_CAN_SEND(CAN_MODULE) __set_PRIMASK((CAN_MODULE)->primask_send)
 
/* (un)lock critical section in CO_errorReport() or CO_errorReset() */
#define CO_LOCK_EMCY(CAN_MODULE)                                                                                       \
    do {                                                                                                               \
        (CAN_MODULE)->primask_emcy = __get_PRIMASK();                                                                  \
        __disable_irq();                                                                                               \
    } while (0)
#define CO_UNLOCK_EMCY(CAN_MODULE) __set_PRIMASK((CAN_MODULE)->primask_emcy)
 
/* (un)lock critical section when accessing Object Dictionary */
#define CO_LOCK_OD(CAN_MODULE)                                                                                         \
    do {                                                                                                               \
        (CAN_MODULE)->primask_od = __get_PRIMASK();                                                                    \
        __disable_irq();                                                                                               \
    } while (0)
#define CO_UNLOCK_OD(CAN_MODULE) __set_PRIMASK((CAN_MODULE)->primask_od)
cs 复制代码
canopen_app_interrupt(void) {
    CO_LOCK_OD(CO->CANmodule);
    if (!CO->nodeIdUnconfigured && CO->CANmodule->CANnormal) {
        bool_t syncWas = false;
        /* get time difference since last function call */
        uint32_t timeDifference_us = 1000; // 1ms second
 
#if (CO_CONFIG_SYNC) & CO_CONFIG_SYNC_ENABLE
        syncWas = CO_process_SYNC(CO, timeDifference_us, NULL);
#endif
#if (CO_CONFIG_PDO) & CO_CONFIG_RPDO_ENABLE
        CO_process_RPDO(CO, syncWas, timeDifference_us, NULL);
#endif
#if (CO_CONFIG_PDO) & CO_CONFIG_TPDO_ENABLE
        CO_process_TPDO(CO, syncWas, timeDifference_us, NULL);
#endif
 
        /* Further I/O or nonblocking application code may go here. */
    }
    CO_UNLOCK_OD(CO->CANmodule);
}

现在修改为采用仅开关CAN中断,且支持嵌套调用

cs 复制代码
/* (un)lock critical section in CO_CANsend() */
#define CO_LOCK_CAN_SEND(CAN_MODULE)                                                                   \
    do {                                                                                               \
                HAL_NVIC_DisableIRQ(FDCAN1_IT0_IRQn);                                                               \
        (CAN_MODULE)->CriticalNesting++;                                                               \
    } while(0)
#define CO_UNLOCK_CAN_SEND(CAN_MODULE)                                                                 \
    do {                                                                                               \
                (CAN_MODULE)->CriticalNesting--;                                                                \
                if((CAN_MODULE)->CriticalNesting == 0)                                                         \
                {                                                                                              \
                  HAL_NVIC_EnableIRQ(FDCAN1_IT0_IRQn);                                                               \
                }                                                                                              \
    } while(0)        
 
/* (un)lock critical section in CO_errorReport() or CO_errorReset() */
#define CO_LOCK_EMCY(CAN_MODULE)                                                                       \
    do {                                                                                               \
                HAL_NVIC_DisableIRQ(FDCAN1_IT0_IRQn);                                                               \
        (CAN_MODULE)->CriticalNesting++;                                                               \
    } while(0)
#define CO_UNLOCK_EMCY(CAN_MODULE)                                                                     \
            do {                                                                                           \
                (CAN_MODULE)->CriticalNesting--;                                                               \
                if((CAN_MODULE)->CriticalNesting == 0)                                                         \
                {                                                                                              \
                  HAL_NVIC_EnableIRQ(FDCAN1_IT0_IRQn);                                                               \
                }                                                                                              \
    } while(0)        
 
/* (un)lock critical section when accessing Object Dictionary */
#define CO_LOCK_OD(CAN_MODULE)                                                                         \
    do {                                                                                               \
                HAL_NVIC_DisableIRQ(FDCAN1_IT0_IRQn);                                                               \
        (CAN_MODULE)->CriticalNesting++;                                                               \
    } while (0)
#define CO_UNLOCK_OD(CAN_MODULE)                                                                       \
         do {                                                                                              \
                (CAN_MODULE)->CriticalNesting--;                                                                \
                if((CAN_MODULE)->CriticalNesting == 0)                                                         \
                {                                                                                              \
                  HAL_NVIC_EnableIRQ(FDCAN1_IT0_IRQn);                                                               \
                }                                                                                              \
    } while(0)
 
#endif

(2)函数canopen_app_process和canopen_app_interrupt的调用处理,我们这里直接将其放在1ms执行一次的任务里面:

cs 复制代码
/*
*********************************************************************************************************
*        函 数 名: AppTaskCANopen
*        功能说明: CANopen处理任务。
*        形    参: 无
*        返 回 值: 无
*   优 先 级: osPriorityNormal6  
*********************************************************************************************************
*/
extern void DemoCANFD(void);
void AppTaskCANopen(void *argument)
{
        const uint16_t usFrequency = 1; /* 延迟周期 */
        uint32_t tick;
         
        DemoCANFD();
 
        /* 获取当前时间 */
        tick = osKernelGetTickCount(); 
         
    while(1)
    {
                /* CAN处理 */
                canopen_app_process(); 
                canopen_app_interrupt();
                 
                /* 相对延迟 */
                tick += usFrequency;                          
                osDelayUntil(tick);
    }
}

工程目录

1、集成了CMSIS6.10,CMSIS-Driver,CMSIS-DSP,CMSIS-Viwer,CMSIS-Compiler,CMSIS-RTOS V2,CMSIS-FreeRTOS,CMSIS-RTX,CMSIS-MbedTLS等,全部采用的当前最新版。

2、网络协议栈,单网络协议栈同时管理DM9000和DM9162双网口。

3、文件系统,同时管理外挂U盘,NAND Flash和SD卡。

4、USB协议栈,RL-USB同时外挂USB FS和USB HS两个USB外设,USB FS接口用于外接电脑,实现SD卡和NAND模拟U盘,USB HS用于外挂U盘设备。

5、加密算法库使用的CMSIS-mbedTLS。

6、BSP外设驱动,部分是采用的CMSIS-Driver,其他都采用我们自己设计的。

7、Modbus RTU主从。

8、emWin6.46。

9、CANopen。

注意事项

使用的CANFD1,注意V7开发板上的跳线帽设置。另外就是如果使用了CANFD1引脚后,不能再使用MicroUSB的Device端口了

参考资料

1、案例下载,本次功能升级将emWin升级到最新的6.46版本。

FreeRTOS All In One(2024-10-30 V3.0).7z (30.53MB)

RTX5 All In One(2024-10-30 V3.0).7z (29.38MB)

2、RTX5全家桶源码综合模板发布V2.0,含FreeRTOS内核版本,将其打造成直接面向实际项目应用的综合框架(2024-08-30)

RTX5全家桶源码综合模板发布V3.0,含FreeRTOS内核版本,将其打造成直接面向实际项目应用的综合框架(2024-10-30) - STM32H7 - 硬汉嵌入式论坛 - Powered by Discuz!

3、H7-TOOL的CAN/CANFD助手CANopen协议解析操作说明V1.1,持续更新(2023-12-04)

H7-TOOL的CAN/CANFD助手CANopen协议解析操作说明V1.1,持续更新(2023-12-04) - H7-TOOL开发工具 - 硬汉嵌入式论坛 - Powered by Discuz!

相关推荐
PPPPickup36 分钟前
金证秋招笔试
java·开发语言
@insist1231 小时前
系统集成项目管理工程师-信息和文档管理
网络·数据库·软考·系统集成项目管理工程师·软考中项·软件水平考试
不正经学生1 小时前
C语言结构体:自定义数据类型,让变量打包出行
java·c语言·开发语言·数据结构·算法
极客互动API1 小时前
企业微信 iPad 协议服务搭建与 AI 回调实战
网络·汇编·人工智能·微信·企业微信·ipad
ycjunhua1 小时前
Spring AI 2.0 GA:ToolCallingAdvisor 重构与 Java Agent 新范式
java·人工智能·spring
开源必胜1 小时前
Future的异常处理以及CompletableFuture传播链、异常处理
java
QH139292318801 小时前
Keysight N5183B N5183B 微波模拟信号发生器
网络·单片机·嵌入式硬件·集成测试·信息与通信
LabVIEW开发1 小时前
基于原始套接字实现LabVIEW网络Ping检测的编程方法
网络·labview·labview知识·labview功能·labview程序
东莞和裕包装2 小时前
如何管控广州定制纸箱生产中的啤切精度与印刷色差质量问题
大数据·运维·网络·人工智能
林森lsjs2 小时前
队列 FIFO 原理 & 手撕两种队列实现(链表 + 循环数组)—数据结构陆
java·开发语言·数据结构·队列