Are unused bytes set to zero in response to SDO reads? - can-bus

I send and SDO request to read a 1 byte value like this:
|11 bit COD-ID | byte 0 | byte 1 | byte 2 | byte 3 | byte 4 | byte 5 | byte 6 | byte 7 |
| 0x0601 | 0x40 | index | subindex | 0x00 | 0x00 | 0x00 | 0x00 |
and the device responds with:
|11 bit COD-ID | byte 0 | byte 1 | byte 2 | byte 3 | byte 4 | byte 5 | byte 6 | byte 7 |
| 0x581 | 0x4F | index | subindex | 0xFF | 0x00 | 0x00 | 0x00 |
0x4F means that the returned value is only 8 bit wide, only byte 4 is set. What about byte 5, 6, and 7. Are they guaranteed to be zero by the standard?

Yes, CAN frames involved in SDO requests always have an 8-byte payload. Unused bytes are set to 0 and should be ignored by the recipient.
This is guaranteed by CiA 301 section 7.2.4.3, which describes the SDO protocol.

Related

Ymodem Buffer Start Address

I am looking this source codes to use Ymodem protocole,
https://github.com/STMicroelectronics/STM32CubeF4/blob/master/Projects/STM324xG_EVAL/Applications/IAP/IAP_Main/inc/ymodem.h
But I've a question about that,
Line 65 says to us as in below:
/* /-------- Packet in IAP memory ------------------------------------------\
* | 0 | 1 | 2 | 3 | 4 | ... | n+4 | n+5 | n+6 |
* |------------------------------------------------------------------------|
* | unused | start | number | !num | data[0] | ... | data[n] | crc0 | crc1 |
* \------------------------------------------------------------------------/
* the first byte is left unused for memory alignment reasons
According to this informaton PACKET_DATA_INDEX define 4. But I dont understand this because in the Ymodem includes data in 3th byte, why we choose the 4th byte or SOH is the 0th index of the frame, why we get this as a 1

Interleave two vectors

I'm trying my first steps with SIMD and I was wondering what the right approach is to the following problem. Consider two vectors:
+---+---+---+---+ +---+---+---+---+
| 0 | 1 | 2 | 3 | | 4 | 5 | 6 | 7 |
+---+---+---+---+ +---+---+---+---+
How to "interleave" the elements of those vectors so that they become:
+---+---+---+---+ +---+---+---+---+
| 0 | 4 | 1 | 5 | | 2 | 6 | 3 | 7 |
+---+---+---+---+ +---+---+---+---+
I was surprised I could not find an instruction for doing it, given the great many kinds of shuffles, broadcasts, permutes, ... Probably it could be done with some unpacklo and unpackhi and what not, but I was wondering if there is a canonical way of doing it as it seems to be quite common problem (SoA vs. AoS). For simplicity let's assume AVX(2) and vectors of four floats.
Edit:
Floats vs. doubles
The comment below (correctly) suggest I should use unpcklps and unpckhps for floats. Which instruction should I use to unpack vector of four doubles? I'm asking because _mm256_unpacklo_pd/_mm256_unpackhi_pd:
Unpack and interleave double-precision (64-bit) floating-point elements from the high half of each 128-bit lane in a and b, and store the results in dst.
DEFINE INTERLEAVE_HIGH_QWORDS(src1[127:0], src2[127:0]) {
dst[63:0] := src1[127:64]
dst[127:64] := src2[127:64]
RETURN dst[127:0]
}
dst[127:0] := INTERLEAVE_HIGH_QWORDS(a[127:0], b[127:0])
dst[255:128] := INTERLEAVE_HIGH_QWORDS(a[255:128], b[255:128])
dst[MAX:256] := 0
So what it apparently does is:
+---+---+---+---+ +---+---+---+---+
| 0 | 4 | 2 | 6 | | 1 | 5 | 3 | 7 |
+---+---+---+---+ +---+---+---+---+

Does endianness refer to ordering within a defined array or memory or also the actual memory used?

I'm having trouble expressing my question in words, but I think I can express it visually quite simply. Storing the string abcd, is the difference between Big and Little Endian this:
memory address | 0 | 1 | 2 | 3 | 4 | 5 | 6 | ...
little endian | d | c | b | a |
big endian | a | b | c | d |
Or this:
memory address | 0 | 1 | 2 | 3 | 4 | 5 | 6 | ...
little endian | d | c | b | a |
big endian | a | b | c | d |
My attempt in words: does "endianness" refer to the ordering of bytes within a specific memory "array", where in both cases the array begins at the same point in memory, or does it refer to both the ordering and the actual array used?
Endianness refers to the ordering of bytes used to store a single multi-byte numerical value. The "big endian" system in your second image is storing 4-byte integers unaligned, which no system would normally do.

Getting physical address when you don't have the page in physical memory

For the record, this is homework.
I have a problem, where I have a processor that uses 32 bit virtual addresses and 32 bit physical addresses, with 4Kb pages and a linear page table.
I am given the following assembly instruction (MIPS32)
lw $t0, 0x34c8($zero)
Since, this processor uses 4Kb pages, the offset in the virtual address is 12 bits long, and therefore the last nibble in the address is the VPN (3). Using that to query the page table, I found that the PTE is an empty entry:
VPN | Dirty | Present | PPN
----------------------------
0 | 1 | 0 | 0x1
----------------------------
1 | 0 | 1 | 0x0
----------------------------
2 | 1 | 1 | 0x6
----------------------------
3 | - | 0 | -
----------------------------
4 | 0 | 1 | 0x4
----------------------------
5 | 0 | 1 | 0x2
----------------------------
6 | 0 | 1 | 0x7
----------------------------
7 | 0 | 1 | 0x3
How do I find the physical address, then? I'm told all physical pages in memory are in use, but I don't know if that helps. Am I supposed to assume the PPN is going to be 0x5, since that's the only "missing" page number not in the table?
Thanks.

How to do a goedel numbering for bit strings?

I'm looking for a concept for doing a Gödel numbering for bit strings, i.e. for arbitrary binary data.
Approach 1 (failing): Simply interpret the binary data as data of an unsigned integer.
This fails, because e.g. the two different strings "01" and "001" both represent the same integer 1.
Is there a standard way of doing this? Is 0 usually included or excluded from the Gödel numbering?
The original Gödel numbering used prime numbers and unique encoding of symbols. If you want to do it for strings consisting of "0" and "1", you need positive codes for "0" (say 1) and "1" (say 2). Then numbering of "01" is
21 * 32
while numbering of "001" is
21 * 31 * 52
For longer strings use next prime numbers. However, note that Gödel numbering goals did not include any practical considerations, he simply needed numbering as a tool in the proof of his theorem. In practice for fairly short strings you will exceed range of integers in your language, so you need to use either a language with arbitrary large integers built-in (like Scheme) or a library supporting bignums in language without them built-in.
A super simple solution is to prepend a 1 to the binary data and then interpret the result as an unsigned integer value. This way, no 0-digits get lost at the left side of the bit string.
Illustration how well this works:
One obvious way to order bit strings is to order them first by length and then lexicographically:
+------------+
| bit string |
+------------+
| ε |
| 0 |
| 1 |
| 00 |
| 01 |
| 10 |
| 11 |
| 000 |
| 001 |
| 010 |
| 011 |
| 100 |
| 101 |
| 110 |
| ... |
+------------+
(ε denotes the empty string with no digits.)
Now we add an index number n to this table, starting with 1, and then look at the binary representation of the index number n. We will make a nice discovery there:
+------------+--------------+-------------+
| bit string | n in decimal | n in binary |
+------------+--------------+-------------+
| ε | 1 | 1 |
| 0 | 2 | 10 |
| 1 | 3 | 11 |
| 00 | 4 | 100 |
| 01 | 5 | 101 |
| 10 | 6 | 110 |
| 11 | 7 | 111 |
| 000 | 8 | 1000 |
| 001 | 9 | 1001 |
| 010 | 10 | 1010 |
| 011 | 11 | 1011 |
| 100 | 12 | 1100 |
| 101 | 13 | 1101 |
| 110 | 14 | 1110 |
| ... | ... | ... |
+------------+--------------+-------------+
This works out surprisingly well, because the binary representation of n (the index of each bit string when ordering in a very obvious way) is nothing else than a 1 prepended to the original bit string and then the whole thing interpreted as an unsigned integral value.
If you prefer a 0-based Goedel numbering, then subtract 1 from the resulting integer value.
Conversion formulas in pseudo code:
// for starting with 1
n_base1 = integer(prepend1(s))
s = removeFirstDigit(bitString(n_base1))
// for starting with 0
n_base0 = integer(prepend1(s)) - 1
s = removeFirstDigit(bitString(n_base0 + 1))

Resources