通过可以通过可以接收并合并文件片段
我制作了一个简单的流媒体代码&在8个字节上传输文件可以通过CAN BUS发送消息,
我在C中的代码如下,但是,我的问题是如何在没有任何序列控制器的情况下合并零碎的文件? 如何检查接收文件的CRC? 由于CAN标准具有自己的确认,这对于文件的如此庞大的流数是否足够?
typedef struct {
union {
struct {
uint32_t extd: 1;
uint32_t rtr: 1;
uint32_t ss: 1;
uint32_t self: 1;
uint32_t dlc_non_comp: 1;
uint32_t reserved: 27;
};
uint32_t flags;
};
uint32_t identifier;
uint8_t data_length_code;
uint8_t data[TWAI_FRAME_MAX_DLC];
} CAN_message_t;
#define destinationNode 20000x
CAN_message_t msg;
msg.identifier=destinationNode;
msg.data_length_code=8
File date = file.open("/data.bin");
uint8_t *p=date;
while(p){
char buffer[8];
memcpy(buffer, (p+8), 8);
CAN_transmit(&msg);
p+=8;
}
=============================================== ======= 编辑代码 打开文件并将大小发送并启动点到以下功能,然后关闭文件
#define SEQUENCE_START 1000000
bool stream(size_t filesize,uint8_t *p){
uint32_t identifer=SEQUENCE_START;
twai_message_t message;
while(filesize<8) {
memcpy(message.data, (p+8), 8);
message.identifier=identifer;
message.data_length_code=8;
if( twai_transmit(&messageOutRPM, pdMS_TO_TICKS(1)) == ESP_OK){
p+=8;
identifer++;
filesize-=8;
}
}
if(filesize>0) {
memcpy(message.data, (p+filesize), filesize);
message.identifier=identifer;
message.data_length_code=filesize;
if( twai_transmit(&messageOutRPM, pdMS_TO_TICKS(1)) == ESP_OK) return true;
}
return true;
}
I made a simple code for streaming & transferring a file over 8 bytes CAN message via the CAN Bus,
my code in c is as follows, however, my question is how to merge the fragmented file without any sequence controller?
how do I check the CRC of the receiving file?
since the CAN standard has its own acknowledgment, would that be sufficient for such huge streaming of a file?
typedef struct {
union {
struct {
uint32_t extd: 1;
uint32_t rtr: 1;
uint32_t ss: 1;
uint32_t self: 1;
uint32_t dlc_non_comp: 1;
uint32_t reserved: 27;
};
uint32_t flags;
};
uint32_t identifier;
uint8_t data_length_code;
uint8_t data[TWAI_FRAME_MAX_DLC];
} CAN_message_t;
#define destinationNode 20000x
CAN_message_t msg;
msg.identifier=destinationNode;
msg.data_length_code=8
File date = file.open("/data.bin");
uint8_t *p=date;
while(p){
char buffer[8];
memcpy(buffer, (p+8), 8);
CAN_transmit(&msg);
p+=8;
}
=========================================================
edit code
open the file and send the size and start point to the following function and then close the file
#define SEQUENCE_START 1000000
bool stream(size_t filesize,uint8_t *p){
uint32_t identifer=SEQUENCE_START;
twai_message_t message;
while(filesize<8) {
memcpy(message.data, (p+8), 8);
message.identifier=identifer;
message.data_length_code=8;
if( twai_transmit(&messageOutRPM, pdMS_TO_TICKS(1)) == ESP_OK){
p+=8;
identifer++;
filesize-=8;
}
}
if(filesize>0) {
memcpy(message.data, (p+filesize), filesize);
message.identifier=identifer;
message.data_length_code=filesize;
if( twai_transmit(&messageOutRPM, pdMS_TO_TICKS(1)) == ESP_OK) return true;
}
return true;
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
绝对不能保证巴士可以收到已发送的框架。他们可能会在公共汽车上出现错误,以防止将某些框架发送出去。
汽车工程师需要通过CAN网络发送文件,以实现软件更新。为此,他们需要发送大于8个字节的帧。他们在可以的顶部定义了一个小的运输协议 ,通常命名为 iso-tp 。
在此协议中,框架由组发送。组中的元素数量是在交换过程中定义的,并且可能在框架传输期间发生变化。
为了为您提供通信流的示例:
为了确定帧的哪个部分正在发送,将一个字节用作框架计数器。这是一个滚动计数器,关键是要确保数据的完整性。如果未按正确的顺序收到帧,则无关紧要,因为该软件能够确定没有丢失框架。
这个传输层通常非常通用,经常将其视为由罐工具提供商提供的库。您还可以找到一些开源源实现。
,可以在物理水平上拥有自己的CRC,因此在大多数情况下应该足够。但是,如果要添加自定义校验和,则只需要定义其长度并将其附加到数据。然后,接收器可以在转移完成后重新计算CRC。
There is absolutely no guarantee by CAN bus that the sent frames will be received. They might have CAN errors on the bus preventing some frames to be sent out.
Automotive engineers need to send files over the CAN network in order to implement software updates. To do that, they need to send frames which are way larger than 8 bytes. They defined a small Transport Protocol on the top of CAN: ISO-15765, usually named ISO-TP.
In this protocol, the frames are sent by group. The number of elements in the group is defined during the exchange and can possibility change during the frame transfer.
To give you an example of the communication flow:
In order to identify which part of the frame is being transmitted, a byte is used as a frame counter. It's a rolling counter, the point is to make sure the completeness of the data. If the frames are not received in the correct order, it does not matter much, as the software is able to determine that no frame has been lost.
This transport layer is usually quite generic, it's frequent to see it available as a library provided by the CAN tool provider. You can also find some Open Source implementations.
Actually, CAN bus has its own CRC at physical level, it should be enough for most cases. But if one want to add a custom checksum, one just need to define its length and prepend or append it to the data. Then, the receiver can re-calculate the CRC just after the completion of the transfer.
由于几个原因,此代码值得怀疑。
首先,位田的标准化很差,位订单可能不是您期望的。
第二,您发布的结构很可能在
data_length_code
之后包含填充物,因此写入/读取到某些二进制文件将是有问题的,并且不可行。无论如何我都怀疑
p+8
永远是正确的,因为即使没有填充sizef(uint32_t)
+size> sizef(uint32_t)< /code>将我们放在
data_length_code
成员中,而不是数据。您为什么要将DLC和7个字节复制到一些缓冲区中?这是一个错误。您可能希望某些内容作为CRC32,以确保文件的损坏。对于罐头本身,您不需要CRC,因为内置CRC-15可以带来CRC。
但是请注意,在使用外部CAN控制器的丑陋硬件解决方案的情况下,罐数据中的CRC可能是必需的。这样的旧解决方案涉及裸露的SPI总线,该总线没有内置错误控制。现代电子唯一的使用使用外部罐头控制器,以防某种奇特的MCU被困在其他原因时必须使用的异国情调的MCU,但它不带CAN上芯片。
This code is questionable for several reasons.
First of all, bit-fields are poorly standardized and the bit order may not be the one you expect.
Second, the struct as you posted it will very likely contain padding after
data_length_code
so writing/reading it to some binary file will be problematic and non-portable.At any rate I doubt
p+8
will ever be correct, because even if there is no paddingsizeof(uint32_t)
+sizeof(uint32_t)
puts us at thedata_length_code
member, not the data. Why would you want to copy the DLC and 7 bytes into some buffer? This is a bug.You may want something as CRC32 to ensure there are no corruptions of the file. For the CAN transfer itself you don't need CRC since CAN comes with CRC-15 built-in.
But note that a CRC in the CAN data may be necessary in case of ugly hardware solutions with external CAN controllers. Such legacy solutions involve an exposed SPI bus which has no built-in error control what so ever. Modern electronics only use external CAN controllers in case one is stuck with some exotic MCU that must be used for other reasons, but it doesn't come with CAN on-chip.