-- First frame of data
RxFrame.Data <= (
1 => x"39", -- LSB
2 => x"38",
3 => x"37",
4 => x"36",
5 => x"35",
6 => x"34",
7 => x"33"
);
-- Second/last frame of data
RxFrame.Data <= (
1 => x"32",
2 => x"31", -- MSB
3 => xx, -- "xx" means irrelevant data, not part of CRC calculation.
4 => xx, -- This occurs only in the last frame, when it specified in
5 => xx, -- byte 0 which bytes contain data
6 => xx,
7 => xx
);
-- Calculated CRC should be 0x31C3
-- First incoming frame of data
RxFrame.Data <= (
1 => x"39", -- LSB
2 => x"38",
3 => x"37",
4 => x"36",
5 => x"35",
6 => x"34",
7 => x"33"
);
-- Second incoming frame of data
RxFrame.Data <= (
1 => x"32",
2 => x"31",
3 => x"21",
4 => x"83",
5 => x"04",
6 => x"FC",
7 => x"1C"
);
-- Third/last incoming frame of data
RxFrame.Data <= (
1 => x"9A",
2 => x"66",
3 => x"76",
4 => x"43", -- MSB
5 => xx, -- Irrelevant data, specified in byte 0
6 => xx,
7 => xx
);
-- Calculated CRC should be 0x2848
从CANopen标准验证SDO块传输的CRC计算算法
这里有一个C语言的示例,您可以对其进行修改。既然您提到了VHDL,这是一个适合于转换到门和触发器中的稍微明智的实现。然而,如果循环对您来说比内存和门更珍贵,那么还有一个字节式的表驱动版本,它将在1/8的循环数中运行。
这与正常的CRC计算相反。然后,它将相同大小的输入与正常CRC一起应用于零,以获得正常CRC在该输入上的值。运行零所需的周期数与逆CRC相同,即O(n),其中n是输入的大小。如果延迟太大,可以减少到O(log n)个循环,并在门上进行一些投资。
#include <stddef.h>
// Update crc with the CRC-16/XMODEM of n zero bytes. (This can be done in
// O(log n) time or cycles instead of O(n), with a little more effort.)
static unsigned crc16x_zeros_bit(unsigned crc, size_t n) {
for (size_t i = 0; i < n; i++)
for (int k = 0; k < 8; k++)
crc = crc & 0x8000 ? (crc << 1) ^ 0x1021 : crc << 1;
return crc & 0xffff;
}
// Update crc with the CRC-16/XMODEM of the len bytes at mem in reverse. If mem
// is NULL, then return the initial value for the CRC. When done,
// crc16x_zeros_bit() must be used to apply the total length of zero bytes, in
// order to get what the CRC would have been if it were calculated on the bytes
// fed in the opposite order.
static unsigned crc16x_inverse_bit(unsigned crc, void const *mem, size_t len) {
unsigned char const *data = mem;
if (data == NULL)
return 0;
crc &= 0xffff;
for (size_t i = 0; i < len; i++) {
for (int k = 0; k < 8; k++)
crc = crc & 1 ? (crc >> 1) ^ 0x8810 : crc >> 1;
crc ^= (unsigned)data[i] << 8;
}
return crc;
}
#include <stdio.h>
int main(void) {
// Do framed example.
unsigned crc = crc16x_inverse_bit(0, NULL, 0);
crc = crc16x_inverse_bit(crc, (void const *)"9876543", 7);
crc = crc16x_inverse_bit(crc, (void const *)"21", 2);
crc = crc16x_zeros_bit(crc, 9);
printf("%04x\n", crc);
// Do another one.
crc = crc16x_inverse_bit(0, NULL, 0);
crc = crc16x_inverse_bit(crc, (void const *)"9876543", 7);
crc = crc16x_inverse_bit(crc, (void const *)"21!\x83\x04\xfc\x1c", 7);
crc = crc16x_inverse_bit(crc, (void const *)"\x9a" "fvC", 4);
crc = crc16x_zeros_bit(crc, 18);
printf("%04x\n", crc);
return 0;
}
以下是crc16x_zeros_bit()
的O(log n)版本:
// Return a(x) multiplied by b(x) modulo p(x), where p(x) is the CRC
// polynomial. For speed, a cannot be zero.
static inline unsigned multmodp(unsigned a, unsigned b) {
unsigned p = 0;
for (;;) {
if (a & 1) {
p ^= b;
if (a == 1)
break;
}
a >>= 1;
b = b & 0x8000 ? (b << 1) ^ 0x1021 : b << 1;
}
return p & 0xffff;
}
// Return x^(8n) modulo p(x).
static unsigned x2nmodp(size_t n) {
unsigned p = 1; // x^0 == 1
unsigned q = 0x10; // x^2^2
while (n) {
q = multmodp(q, q); // x^2^k mod p(x), k = 3,4,...
if (n & 1)
p = multmodp(q, p);
n >>= 1;
}
return p;
}
// Update crc with the CRC-16/XMODEM of n zero bytes.
static unsigned crc16x_zeros_bit(unsigned crc, size_t n) {
return multmodp(x2nmodp(n), crc);
}
我想知道是否有可能找出服务器使用TCP连接发送给客户端的最后一个字节。具体来说,我有一个客户端和一个服务器,都是C语言。他们使用XMLRPC进行通信,连接是TCP。客户端可以向服务器发送一个大请求,由于一些计算,服务器可能需要一些时间才能回复。在连接的任何部分,如果断开连接,整个过程都应该从头开始,这会导致服务器容易受到DoS攻击。 我的问题是,我是否可以找出连接断开的位置,以便在重新建立连接(对
问题内容: 我在计算本月下一个最后一天何时发送预定的通知时遇到问题。 这是我的代码: 这是导致问题的线,我相信: 如何使用日历正确设置下个月的通知的最后一天? 问题答案: 这将返回当前月份的实际最大值。例如,现在是leap年的2月,因此它返回29作为。
问题内容: 我想学习最好/最简单的方法,将一个字符串转换为另一个字符串,但只有一个子集,从一个字符的开头到最后一个索引。 例如,将。什么样的代码片段会做到这一点,并且最快捷?(我希望这不会引起争论,但是我找不到关于如何在Swift中处理子字符串的好课程。 问题答案: 最好的方法是结合使用属性和全局功能。 寻找从背面开始的字符串 使用并设置为 没有扩展,纯真的Swift 雨燕2.0 现在是的一部分,
我有一组原点-终点坐标,我想计算它们之间的最短路径。 我的出发地坐标有时位于一条长直线道路的中间。然而,由OSMNX/NETWorkX计算的最短路径将不考虑中间边缘到最近的节点路径。 OSMnx或networkx中是否有任何现成的函数,我可以使用它来找到在道路中间起点/终点的最短路径? 如果没有这样的功能,我会考虑使用以下步骤。 获取起点和终点的最近边 获取这些最近边的节点:假设(a,b)为起点,
我正在写一个简单的日历课程。我正在尝试重载,以便使用它将日历移动到下个月。然而,我找到下个月开始日期的算法并不完全正确。 1月定义为0,12月为11,周日为0,周六为6。start Day、previousStartDay、nextStartDay、月份和年份都是私有类变量 当我在2013年进行测试时,日期直到3月都是正确的。在这一点上,它将下一个开始日定为周二,而不是周一。 我也试过: 然而,它
问题 你需要查找星期中某一天最后出现的日期,比如星期五。 解决方案 Python的 datetime 模块中有工具函数和类可以帮助你执行这样的计算。 下面是对类似这样的问题的一个通用解决方案: #!/usr/bin/env python # -*- encoding: utf-8 -*- """ Topic: 最后的周五 Desc : """ from datetime import dateti