头痛做什么检查| 半胱氨酸是什么| 上军校需要什么条件| 1939年属什么| 包饺子用什么面粉| 小猫吃什么| 马赛克是什么意思啊| 木樨是什么意思| 上焦火旺什么症状| 张紫妍为什么自杀| 占位是什么意思| 马的贵人是什么生肖| 肺结核咳血是什么程度| 卡西欧属于什么档次| acth是什么激素| 手指长倒刺是什么原因| 头发油性大是什么原因| 15岁可以做什么兼职| 不景气是什么意思| 月经不调去医院要做什么检查| 痛风吃什么药| 什么样的人容易得痛风| 金达莱是什么花| 住院送什么花好| 666代表什么意思| 小燕子吃什么| 女性什么时间是排卵期| 肾囊肿用什么药| 烂尾楼是什么意思| 扫码是什么意思| 尿素氮肌酐比值偏高是什么原因| 萨洛蒙什么档次| bc是什么牌子| 什么是甘油三酯| 超导是什么意思| 去医院看脚挂什么科| 祈福是什么意思| 月经量多是什么原因导致的| 草木皆兵什么意思| 韩国是什么民族| 骨癌有什么症状有哪些| hr是什么单位| 暗卫是什么意思| 小囡是什么意思| 阴霾是什么意思| 福泽深厚什么意思| 安慰的意思是什么| 医学上ca是什么意思| 孕酮低是什么原因造成的| 心理学是什么| 林心如什么学历| 芝五行属什么| 什么是物理学| 两鬓长白发是什么原因| 18岁属什么生肖| 一什么桃花| 海口有什么好玩的| 50公斤发什么物流便宜| fpu是什么意思| 夏天吃西瓜有什么好处| 吃什么东西越吃越饿| 打两个喷嚏代表什么| 五指姑娘是什么意思| 尿酸高要吃什么药| 1889年属什么生肖| rad是什么意思| 起灵是什么意思| 什么人不适合吃胃复春| 吃完狗肉不能吃什么| 什么是生物钟| 牙齿一吸就出血是什么原因| 脑瘫是什么症状| 背水一战什么意思| 实性结节是什么意思| 什么是幽门螺旋杆菌| 前胸后背疼挂什么科| 喝枸杞子泡水有什么好处和坏处| 子宫内膜异位症有什么症状表现| 阴道放屁是什么原因| 白萝卜煮水喝有什么功效| 梦见什么是怀孕的征兆| 什么球| 泰山石敢当什么意思| 睡美人最怕什么脑筋急转弯| 过敏是什么样子的| 真菌菌丝阳性什么意思| 虾皮是什么| 女生被操是什么感觉| 聊天是什么意思| NPY什么意思| 西施姓什么| 箱涵是什么| 红楼梦大结局是什么| 工会副主席是什么级别| 人体缺钙吃什么补最快| 四月是什么星座| 荔枝代表什么寓意| 丰富多腔的腔是什么意思| 生菜不能和什么一起吃| 丙烯颜料用什么洗掉| 相生什么意思| 因公殉职是什么意思| 六七是什么意思| 阳光是什么颜色| save什么意思| 农历8月是什么星座| 眼角发白是什么原因| 1970年属狗的是什么命| 看乳腺挂什么科| 山西属于什么地区| 人什么地灵| 阴茎疼是什么原因| 牙疼是什么原因导致的| 痛风可以吃什么食物表| 乙肝有抗体是显示什么结果| 右手小指戴戒指什么意思| 氨甲环酸又叫什么名| 角瓜念什么| 尿酸高有什么危害| 沙参长什么样子图片| 电压mv是什么意思| 有什么好听的网名| 大便粗大是什么原因| 秦王是什么生肖| 右脸长痣代表什么意思| 空调什么度数最省电| 端倪是什么意思| 平板支撑练什么| 绝户是什么意思| 痛风什么水果不能吃| ppt是什么意思| 脚后跟疼挂什么科| 不让他看我的朋友圈是什么效果| 龙和什么生肖相冲| 梦见生娃娃是什么意思| 柬埔寨为什么叫柬埔寨| 后果自负是什么意思| 凌晨一点半是什么时辰| 血糖高吃什么最好| 小蛮腰什么意思| 频繁流鼻血是什么原因| 脑梗输什么液效果最好| 与世隔绝的绝是什么意思| 什么叫四大皆空| 蝴蝶兰什么时候开花| 高压高低压正常是什么原因| 浔是什么意思| 怀孕初期吃什么蔬菜好| 黄色裤子配什么上衣| 如如不动是什么意思| 淡淡的什么| 什么是元素| 缺钾是什么原因| 狗是什么属性| 化纤是什么面料| 胃息肉是什么引起的| 为什么会流黄鼻涕| 释放天性是什么意思| ntc是什么| 梦见进监狱是什么兆头| 乳房挂什么科| 知柏地黄丸有什么作用| aed什么意思| 暂住证和居住证有什么区别| 皮肤暗黄是什么原因造成的| 腿血栓什么症状| 喉咙吞口水痛吃什么药| 扁桃体切除有什么影响| 胰岛是什么器官| 女生体毛多是什么原因| 叉烧是什么肉| 产假从什么时候开始算| 开塞露擦脸有什么效果| 脚趾头抽筋是什么原因| 索性是什么意思| 双肺纹理增多模糊是什么意思| 泰迪哼哼唧唧表示什么| 般若波罗蜜是什么意思| 肾结石看什么科| 春天的雨是什么| 什么不能带上高铁| 下腹痛挂什么科| dpl是什么意思| 压车是什么意思| 焦作有什么大学| 曼陀罗是什么意思| 3e是什么意思| 阿托伐他汀钙片治什么病| 颈椎痛挂什么科| 嘴苦嘴臭什么原因| hpv男性有什么症状| 侮辱什么意思| 肚子疼吃什么药管用| ader是什么牌子| 作精是什么意思| 半夜吃什么不会胖| 二院是什么医院| 肚脐眼上面是什么部位| 银花指什么生肖| 肋骨突出是什么原因| 御风是什么意思| 一什么湖面| rr过高是什么意思| 花嫁是什么意思| 拔了尿管尿不出来有什么好办法| 2017属什么| 下缘达宫颈内口是什么意思| 星标朋友是什么意思| 爱恨情仇是什么意思| 吃什么可以提升白细胞| 炖肉放山楂起什么作用| 门字五行属什么| 滑精是什么症状| 夏天为什么不能喝中药| 清水文是什么意思| 为什么被蚊子咬了会起包| 人的血压一天中什么时候最高| 什么是交际花| 国务院秘书长什么级别| 长白班什么意思| 牙龈肿了吃什么消炎药| 百香果有什么好处功效| 抑郁症有什么表现| 牛油果是什么味道| 什么是玫瑰痤疮| 梦见床是什么意思| 母亲节送婆婆什么礼物| 怀孕前期有什么症状| 卒中中心是什么意思| 什么叫化疗| 一切就绪是什么意思| 2013年是什么命| 胃癌早期有什么症状| 凤凰单丛属于什么茶| 睡着了流口水是什么原因| 春梦是什么| 梦见别人开车撞死人是什么意思| 属兔的婚配什么属相好| 女排精神是什么| 办理户口迁移需要什么材料| 托马斯是什么意思| 泸州老窖是什么香型| 十月6号是什么星座| 黑木耳是什么意思| 垚字是什么意思| 什么食物含叶酸多| 后背长痘痘用什么药膏| 金翅鸟吃什么| 二手房是什么意思| se是什么意思| 10万个为什么的作者| 木耳和什么不能一起吃| 假如时光倒流我能做什么| 2006年出生的是什么命| 用醋泡脚有什么好处| 总蛋白高是什么原因| 蟾蜍吃什么| 4.25什么日子| 覆盆子有什么作用| 45属什么| 不怕流氓什么就怕流氓有文化| 土中金是什么数字| 法身是什么意思| b超属于什么科室| 百度
打印
[APM32F4]

生理盐水是什么东西

[复制链接]
1021|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
a976209770|  楼主 | 2024-12-2 13:49 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
1. 背景介绍CANopen协议中的LSS(Layer Setting Services)是一种用于动态配置设备通信参数(如节点ID和波特率)的服务。在固件更新场景中,LSS服务的扩展可以用于让设备进入固件更新模式并接收新的程序代码。
在本技术文档中,我们将使用APM32F4xx的CAN外设实现一个支持LSS协议的固件更新功能。主要功能包括:
  • 设备通过LSS命令进入编程模式。
  • 接收主机发送的固件数据并存储到Flash中。
  • 验证固件数据的完整性,执行系统重启,运行新固件。

2. 功能实现流程


2.1 初始化CAN外设
  • 配置CAN波特率、过滤器及中断处理。
  • 配置为标准CAN通信模式。
2.2 实现LSS服务
  • 解析并处理LSS请求帧。
  • 支持以下LSS命令:
    • 进入编程模式:命令代码0x11。
    • 波特率切换:命令代码0x22。
2.3 接收固件数据并更新
  • 主站分片发送固件数据,接收后写入Flash存储。
  • 完成后校验数据完整性。
2.4 执行更新
  • 校验通过后,重启设备,运行新固件。

3. 详细步骤说明
通信流程图:

3.1. 进入编程模式
  • 主站发送:LSS请求帧(命令代码0x11)。
    • 数据帧格式:[0x11, Reserved, Reserved, Reserved, Reserved, Reserved, Reserved, Reserved]
  • 从站响应:ACK(命令代码0x11)。
    • 数据帧格式:[0x11]
  • 从站行为:切换到编程模式,准备接收固件数据。

3.2. 波特率切换
  • 主站发送:LSS请求帧(命令代码0x22 + 波特率值)。
    • 数据帧格式:[0x22, BaudRate_H, BaudRate_M, BaudRate_L, Reserved, Reserved, Reserved, Reserved]
    • 波特率值为32位,例如0x0004E200表示125 kbit/s。
  • 从站响应:ACK(命令代码0x22)。
    • 数据帧格式:[0x22]
  • 从站行为:更新波特率并重启CAN通信。

3.3. 接收固件数据
  • 主站发送:固件数据帧。
    • 数据帧格式:[0x01, Data_1, Data_2, ..., Data_N]
    • 每帧数据长度为8字节(CAN协议限制)。
  • 从站响应:ACK(命令代码0x01)。
    • 数据帧格式:[0x01]
  • 从站行为
    • 将数据写入Flash存储。
    • 准备接收下一帧。
3.4. 结束固件发送
  • 主站发送:结束命令(命令代码0xEE)。
    • 数据帧格式:[0xEE]
  • 从站行为:校验接收的固件完整性。
3.5. 校验结果
  • 校验成功
    • 从站响应:ACK(命令代码0x02)。
      • 数据帧格式:[0x02]
    • 从站行为:触发系统重启,运行新固件。
  • 校验失败
    • 从站响应:NACK(命令代码0xFF)。
      • 数据帧格式:[0xFF]
    • 从站行为:通知主站失败原因,等待进一步指令。

4. 代码实现
4.1 主程序和初始化

#include "apm32f4xx_can.h"
#include "apm32f4xx_rcm.h"
#include "flash.h" // 假设包含Flash操作的头文件
#include <string.h>

#define LSS_REQUEST_ID 0x7E5     // LSS请求帧ID
#define LSS_RESPONSE_ID 0x7E4    // LSS响应帧ID
#define FLASH_BASE_ADDRESS 0x08020000 // 固件更新存储地址

// 全局变量
CAN_RxMessage_T rxMessage;
uint8_t firmwareData[256];  // 固件数据缓冲区
uint32_t firmwareSize = 0;

// 函数声明
void CAN_Init(void);
void LSS_ProcessMessage(CAN_RxMessage_T* rxMessage);
void EnterProgrammingMode(void);
void ChangeBaudRate(uint32_t baudrate);
uint8_t ReceiveFirmwareChunk(void);
uint8_t VerifyFirmware(void);
void SystemReset(void);

int main(void)
{
    // 初始化系统时钟
    SystemInit();

    // 初始化CAN外设
    CAN_Init();

    // 主循环
    while (1)
    {
        // 检查是否有CAN消息接收
        if (CAN_MessagePending(CAN1, CAN_RX_FIFO_0) > 0)
        {
            CAN_ReceiveMessage(CAN1, CAN_RX_FIFO_0, &rxMessage);
            LSS_ProcessMessage(&rxMessage); // 处理LSS协议消息
        }
    }
}

4.2 CAN初始化

void CAN_Init(void)
{
    CAN_Config_T canConfig;
    CAN_FilterConfig_T filterConfig;

    // 使能CAN1时钟
    RCM_EnableAPB1PeriphClock(RCM_APB1_PERIPH_CAN1);

    // 配置CAN参数
    CAN_ConfigStructInit(&canConfig);
    canConfig.autoBusOffManage = ENABLE;
    canConfig.autoWakeUpMode = ENABLE;
    canConfig.nonAutoRetran = DISABLE;
    canConfig.rxFIFOLockMode = DISABLE;
    canConfig.txFIFOPriority = ENABLE;
    canConfig.mode = CAN_MODE_NORMAL;
    canConfig.syncJumpWidth = CAN_SJW_1;
    canConfig.timeSegment1 = CAN_TIME_SEGMENT1_12;
    canConfig.timeSegment2 = CAN_TIME_SEGMENT2_4;
    canConfig.prescaler = 6; // 设置波特率

    if (CAN_Config(CAN1, &canConfig) == ERROR)
    {
        // 初始化错误,进入死循环
        while (1);
    }

    // 配置CAN过滤器,接收LSS相关的帧
    filterConfig.filterNumber = 0;
    filterConfig.filterMode = CAN_FILTER_MODE_IDMASK;
    filterConfig.filterScale = CAN_FILTER_SCALE_32BIT;
    filterConfig.filterIdHigh = (LSS_REQUEST_ID << 5) & 0xFFFF;
    filterConfig.filterIdLow = 0;
    filterConfig.filterMaskIdHigh = 0xFFFF;
    filterConfig.filterMaskIdLow = 0xFFFF;
    filterConfig.filterFIFO = CAN_FILTER_FIFO_0;
    filterConfig.filterActivation = ENABLE;
    CAN_ConfigFilter(&filterConfig);
}
4.3 LSS协议消息处理

void LSS_ProcessMessage(CAN_RxMessage_T* rxMessage)
{
    if (rxMessage->id == LSS_REQUEST_ID)
    {
        uint8_t command = rxMessage->data[0];

        switch (command)
        {
        case 0x11: // 进入编程模式
            EnterProgrammingMode();
            break;

        case 0x22: // 更改波特率
        {
            uint32_t baudrate = (rxMessage->data[1] << 24) |
                                (rxMessage->data[2] << 16) |
                                (rxMessage->data[3] << 8) |
                                rxMessage->data[4];
            ChangeBaudRate(baudrate);
            break;
        }

        default:
            // 其他命令不处理
            break;
        }
    }
}

4.4 编程模式与固件接收

void EnterProgrammingMode(void)
{
    // 初始化Flash模块
    Flash_Init();

    CAN_TxMessage_T txMessage;
    txMessage.id = LSS_RESPONSE_ID;
    txMessage.rtr = CAN_RTXR_DATA;
    txMessage.dlc = 1;
    txMessage.data[0] = 0x11; // 应答ACK

    CAN_TxMessage(CAN1, &txMessage);

    // 开始接收固件数据
    while (ReceiveFirmwareChunk() == SUCCESS)
    {
        Flash_Write(FLASH_BASE_ADDRESS + firmwareSize, firmwareData, sizeof(firmwareData));
        firmwareSize += sizeof(firmwareData);
    }

    // 校验固件
    if (VerifyFirmware() == SUCCESS)
    {
        SystemReset(); // 重启运行新固件
    }
    else
    {
        // 固件错误处理逻辑
    }
}

4.5 辅助函数

void ChangeBaudRate(uint32_t baudrate)
{
    // 停止CAN外设
    CAN_Disable(CAN1);

    // 配置新的波特率
    CAN_InitTypeDef canConfig;
    canConfig.prescaler = SystemCoreClock / baudrate;

    CAN_Config(CAN1, &canConfig);

    // 重启CAN外设
    CAN_Enable(CAN1);
}

uint8_t ReceiveFirmwareChunk(void)
{
    // 模拟从CAN接收固件数据
    memset(firmwareData, 0xFF, sizeof(firmwareData)); // 假设成功接收数据
    return SUCCESS;
}

uint8_t VerifyFirmware(void)
{
    // 校验固件内容的完整性
    return SUCCESS; // 假设校验成功
}

void SystemReset(void)
{
    NVIC_SystemReset(); // 触发系统复位
}

4. 总结

以上代码完整实现了基于APM32F4xx的CANopen LSS协议,用于实现固件更新功能,内容包括CAN初始化、LSS服务的处理、固件接收与存储、以及最终的固件校验和重启操作。代码注释详细且可直接用于项目中。









发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

40

主题

43

帖子

1

粉丝
长江学者是什么级别 车加昆念什么 尿少是什么原因 鱼非念什么 ca125高是什么原因
暂住证和居住证有什么区别 口苦口干吃什么药 奕五行属性是什么 吃杏子有什么好处 酸菜鱼用什么鱼
西字五行属什么 好哒是什么意思 脸肿眼睛肿是什么原因引起的 蜂蜜和柠檬一起喝有什么作用 排卵期是什么时候开始算
海马体是什么 肠道紊乱的症状是什么 1996属鼠的是什么命 逍遥丸是治什么的 程门立雪是什么生肖
重返20岁韩国版叫什么hcv8jop3ns2r.cn 性感染有什么症状hcv8jop6ns7r.cn 肝虚火旺吃什么中成药xinjiangjialails.com opo是什么hcv9jop1ns6r.cn 11月出生是什么星座hcv9jop5ns3r.cn
胃息肉有什么危害hcv7jop5ns2r.cn 男孩叫什么名字sanhestory.com 怀孕什么时候打掉最好hcv8jop1ns6r.cn 什么药可以降肌酐hcv9jop5ns0r.cn b型和ab型生的孩子是什么血型hcv8jop6ns5r.cn
康膜的功效是什么hcv8jop5ns2r.cn 乘风破浪是什么生肖hcv8jop2ns3r.cn 体质指数是什么意思hcv8jop0ns5r.cn 石楠花是什么味道hcv9jop2ns5r.cn 毫无保留什么意思hcv9jop1ns5r.cn
为什么会得扁平疣hcv8jop5ns7r.cn 谷草转氨酶偏低是什么原因hcv8jop0ns4r.cn 中医调理身体挂什么科hcv8jop5ns7r.cn 老夫聊发少年狂什么意思hcv8jop6ns4r.cn 意味深长的意思是什么zhiyanzhang.com
百度