Assigning MAC addresses from unbought oui - ethernet

I'm a freelancer. I have finished a project for a company that uses Ethernet (TCP+UDP) with a STM32F4 Device.
While I was testing I used MACs in the space 00:00:00:00:00:xx , but now we need to assign final MACs.
The question here is that the company that pays the project dont want to buy OUI mac space. They say that is it practically impossible to have 2 cards in the same network with the same MAC address.
Another reason that they are telling me is that they will use this ethernet device card in places where no more ethernet device except a WIFI router and maybe more of our cards would be connected.
I found on internet places telling that you can use FF:FF:FF:FF:FF:FF as null mac address, I have been testing it without any problem (i thought that ARP would fail but it is working), but they would not be able to connnect 2 cards together in this case.
I have some questions about this.
Is it legal to use MACs from other companies or even non assigned MACs addresses?
Is there any interval of MACs that they can use freely without paying
Any reason to convince them to buy the OUI space would be welcomed too.

I don't think using non-asigned OUI is good, but MAC addresses with second bit 1 are called "locally administered addresses" and can be used without registering to IEEE.
This mean that you can use MAC addresses like x2:xx:xx:xx:xx:xx, x6:xx:xx:xx:xx:xx, etc. to stand for your NIC.
Notr that MAC addresses with first bit 1 are for multicasting, not for standing fir single NIC, and that MAC address FF:FF:FF:FF:FF:FF is for broadcasting, not null.
MAC address - Wikipedia, the free encyclopedia

To clarify MikeCAT's answer - it is the two least significant bits of the 1st byte of the MAC address that are important - what I think of as the 7th and 8th bit:
??????XY:????????:???????? ????????:????????:????????
where ? represents any bit in the mac address, and X is the U/L bit and Y is the Uni/multi cast bit
If the the eighth bit of a MAC address is 1, devices may have trouble getting IP addresses using DHCP. If the eighth bit of a MAC address is 0, you may have more luck.
The 7th and 8th bit of MAC addresses are special:
Bit 8 == 0 for unicast
Bit 8 == 1 for multicast
Bit 7 is also special - 0 = globally unique (assigned to a manufacturer to use) and 1 = locally administered (we should use these addresses!)

Related

How to read Analog Output Holding Registers on Advantech ADAM 6717 through ModBus TCP

I've been exploring the ADAM 6717 from Advantech.
This is the ModBus address table for said device:
At first I wanted to modify the value of the Digital output channel 0(DO0), so, as can be seen from the picture above, such address is the 0x0017.
I succeed at this by using a ModBus tool and the following settings:
Sending either "On" or "Off", turns On and off a LED connected to that output. Everything runs smoothly according to my expectation up to this point.
The problem arises when I want to read the Analog Input channel 6 or equivalently, address 400431~40044.
Since that address lies on the Analog Output Holding Registers part of the address table, I though that the following settings would accomplish the job:
However, as can be seen above, the reading shows 0.0 when there is actually 6V connected to that input (a potentiometer)
It is worth mentioning that I've made sure to enable the AI6 channel as well as setting it to Voltage mode instead of current. Also, the web utility for the device shows the AI6 reading correctly as I change the potentiometer's resistance value.
So the problem doesn't lie in the connection from the potentiometer to the AI6 but somewhere else.
Out of nothing and leaving aside what I think I know on this topic, I though of changing the function from 0x03 to 0x04
However, the response is exactly the same.
It bugs me that I can read and write values to the output coils but not the Analog output holding registers.
Is there any configuration that I might be missing over here?
Thanks in advance.
Device settings:
IP address: 10.0.0.1
Port in which the ModBus service is running: 5020

Beagle Bone Black I2C2 Issues

I am having troubles using an I2C sensor with the Beagle Bone Black (BBB). The BBB is running a newly flashed 18.04 Ubuntu image specifically for the BBB.
I wired the sensor (VIN, GND, SCL, SDA) to the corresponding I2C2 pins (4, 2, 19, 20) on the BBB using the below pinout.
The sensor is supposed to be using address 0x40, but scanning I2C2 (using i2cdetect -r 2) does not show the sensor.
I have tested this with two separate sensors as I thought at first I may have fried the original sensor somehow, but the results are the same. In fact, running the I2C2 scan command yields the exact same results when nothing is connected at all.
I have read in many places that I2C2 may not be enabled by default, but I assume it is enabled in my case as I can scan I2C2 without getting an error. Is this assumption incorrect? Again, this is a freshly flashed BBB, and I have not enabled/disabled anything - it should be in the default state.
I have also verified the connectivity of my wires between the sensor and BBB. The voltage between VIN and GND on the chip is 3.3V, so it is definitely being powered.
Why can't I connect to my I2C sensors using the BBB?
it could be that the source you are using is outdated or not a viable entry for i2c.
Also, you could use this command to make sure i2c2 pins are available:
config-pin p9.21 i2c
config-pin p9.22 i2c
This may work, also. If this does not work, please reply with your entire source.
Seth
P.S. Also, if you have time, you may want to get an i2c library to use if your software falls short of setting up your own i2c library. They have smbus2 you can install with pip and other i2c libraries out there still.
Here are a few things you should check (in random order).
List all I2C buses wich i2cdetect -l and try them all. Depending on the platform, the i2c bus number in Linux may be different from the peripheral number used in the datasheet and pinout. E.g. "I2C2" might be bus i2c-1 or i2c-3 in Linux).
Use an oscilloscope or logical analyzer to see if the SCL and SDA lines are being driven. If they aren't check the bus number as above. If they are, then check whether the device gives an ACK; if it doesn't, anything else will never work: double-check the chip slave address. There are cheap logical analyzers that you can buy and user with pulseview.
Simply load the Linux driver for your chip (see the kernel docs on how to do it from userspace for a quick test). Then see check if the device appears or use dmesg to see any kernel error messages while probing.

Question about Message Signaled Interrupts (MSI) on x86 LAPIC system

Hi I'm writing a kernel and plan to use MSI interrupt for PCI devices.
However, I'm also quite confused by the documentations.
My understanding about MSI are as follow:
From PCI device point of view:
Documentations indicate that I
need to find Capabillty ID = 0x05 to locate 3 registers: Message control (MCR), Message Address (MAR) and Message Data (MDR) registers
MCR provide control functionality for MSI interrupt,
MAR provide the physical address the PCI device
will write once interrupt occurs
MDR forms out the actual data it will write into the physical address
From CPU point of view:
Documentation shows that Message Address register contains fixed top of 0xFEE, and following by destination ID (LAPIC ID) and other controlling bits as follow:
The Message Data register will contain the following information, including the interrupt vector:
After reading all of these, I am thinking if the APIC_ID is 0x0h would the Message Address conflict with the Local APIC memory mapping? Although the address of FEE00000~FEE00010 are reserved.
In addition, is it true that the vector number in MDR is corresponding to the IDT vector number. In other words, if I put MAR = 0xFEE0000C (Destination ID = 0, Using logical APIC ID) and MDR = 0x0032 (edge trigger, Vector = 50) and enable the MSI interrupt, then once the device issues an interrupt CPU would correspondingly run the function pointed by IDT[50]? After that I write 0h to EOI register to end it?
Finally, according to the documentation, the upper 32 bit of MAR is not used? Can anyone help on this?
Thanks a lot!
Your understanding of how to detect and program MSI in a PCI (or PCIe) device is correct.*
The message address controls the destination (which CPU the interrupt is sent to), while the message data contains the vector number. For normal interrupts, all bits of the message data should be 0 except for the low 8 bits, which contain the vector.
The vector is an index into the IDT, so if the message data is 0x0032, the interrupt is delivered through entry 50 of the IDT.**
If the Destination ID in an interrupt message is 0, the Message Address of the MSI does match the default address of the local APIC, but they do not conflict, because the APIC can only be written by the CPU and MSIs can only be written by devices.
On x86 platforms, the upper 32 bits of the message address must be 0. This can be done by setting the upper part of the message address to 0 or by programming the device to use a 32-bit message address (in which case the upper message address register is not used). The PCI spec was designed to work with systems where 64-bit MSI addresses are used, but x86 systems never use the upper 32 bits of the message address.
Reprogramming the APIC base address by writing to the APIC_BASE MSR does not affect the address range used for MSI; it is always 0xFEExxxxx.
* You should also look at the MSI-X capability, because some devices support MSI-X but not MSI. MSI-X is a bit more flexible, which inevitably makes it a bit more complicated.
** When using the MSI capability, the message data isn't exactly the value in the Message Data Register (MDR). The MSI capability allows the device to use several contiguous vectors. When the device sends an interrupt message, it replaces the low bits of the MDR with a different value depending on the interrupt cause within the device.

serial monitoring method to test communication via com ports without a serial communication device

I have a Verilog code simulated and synthesized on ISE design toolkit. I've got an FPGA spartan 6 device which is to be used for the implementation. But there is a problem with the device (probably a power issue) which makes the device unavailable in any of the COM ports when I connected it to my PC. So I want to check whether my Matlab code which I made for serial communication through the device does the desired job. So I need a method to test serial communication via any of the COM ports without connecting a serial com device to the PC. Is there any such method that I can Tx Rx serial data from Matlab to COM ports? Any software or any other method would be highly appreciated :)
I found a way to test Matlab serial communication using virtual serial ports.
Download "Freeware Virtual COM Ports Emulator" from: http://freevirtualserialports.com/
I installed it in Windows 10, and it's working (as trial).
Add a pair of two serial ports:
Execute the following Matlab code sample to verify it's working:
s3 = serial('COM3','BaudRate',115200);
s4 = serial('COM4','BaudRate',115200);
fopen(s3);
fopen(s4);
fwrite(s3, uint8([1, 2, 3, 4, 5]));
%fprintf(s3, '12345');
pause(0.1);
RxBuf = fread(s4, 5)
fclose(s3);
delete(s3);
clear s3
fclose(s4);
delete(s4);
clear s4
The output is:
RxBuf =
1
2
3
4
5
Bypassing the problem "it only stays for a single test session".
There is a problem when creating a pair of virtual ports using the software, it only stays for a single test session.
I guess it's a problem with the COM port emulation software.
The following solution, is not a good practice (and not a true solution).
Declare the serial object as global, keeping the object persistent.
Create the serial object only if it's not created.
Don't delete and don't clear the serial object.
See the following code sample:
global s3 s4
if isempty(s3)
s3 = serial('COM3','BaudRate',115200);
end
if isempty(s4)
s4 = serial('COM4','BaudRate',115200);
end
fopen(s3);
fopen(s4);
fwrite(s3, uint8([1, 2, 3, 4, 5]));
pause(0.1);
RxBuf = fread(s4, 5)
fclose(s3);
%delete(s3);
%clear s3
fclose(s4);
%delete(s4);
%clear s4
You can also look for a better virtual COM port software.
As Rotem suggested, if you need to communicate via serial line between 2 program of your PC you need a virtual COM port emulator.
It seems you are running on Windows OS so I would recommend a completely free emulator (not a trial one). For Windows I use com0com Null-modem emulator (from SourceForge).
In the example below I will show how to communicate with "another" device so Matlab will not handle both side of the communication. The other device will be simulated by a simple terminal. For windows I use RealTerm: Serial/TCP Terminal (also from SourceForge).
Setup:
Execute the setup of both program with all default options. by default com0com will create a virtual pair COM3/COM4 but if these port already exist on your system the program may assign other numbers. Check the numbers before you run the example. (it will also create a CNCA0/CNCB0 pair but you can ignore this one for now).
For RealTerm, once installed (don't forget to activate the server registration at the end of the setup, it should be ticked by default though), it will look like below. Keep all default options, just set the port number and the baud rate if they need to be changed.
Test MATLAB -> Terminal
You are ready to send Ascii characters or binary values from MATLAB to your device. The animation below shows you an example of both option:
you can click on the picture to see it full size. It is running in loop so you may want to wait until it restart from the beginning.
Test Terminal -> MATLAB
Below animation shows you how to test the communication in the other way:
Don't forget to tick [CR] [LF] on RealTerm when you send Ascii characters and want to use the '%s' format specifier on MATLAB, as it needs these characters to detect the end of the string.
Note:
If you have another terminal program that you are more used too, it
will work the same.
If the RealTerm option does not suit you, or if you want to handle
both sides of communication from Matlab, then you can use the code
provided by Rotem in his first answer. Just install com0com but
ignore all the RealTerm part.

What data type should I use to store an IP Address?

I suddenly just thought of this and got stuck deciding which data type should I use to store an IP Address?
I have thought of NSString; But if I would need the last digit for identifications, should I use float or double? And that is also another problem, since when can float or double have more than 1 decimal point?
I am probably asking the question wrongly, because I really don't know how to ask this.
The IP Address comes from an XML format <IP>192.168.1.1</IP>. Any idea how I should do this?
Use NSString. You are not going to do arithmetic with it. If you need the separate components you can use NSArray, but NSString will serve you well for just storing the IP address.
In response to your needs, you can always obtain the last character in your string using the NSString method:
NSString *lastCharacter = [ip_string substringFromIndex: [ip_string length] - 1];
Where ip_string is the string holding the IP address.
Edit in response to comment:
Logan's code is storing each element in the IP address separated by a period into an array. So if the IP address is 192.168.1.1, the array will equal (192, 168, 1, 1).
My code is storing the entire IP address in a string, and then obtaining the last character in that string. [ip_string substringFromIndex: [ip_string length] - 1] is just obtaining the last character in the string containing the IP address. The last character can be found at minus one character.
So if the IP address is 192.168.1.1, the lastCharacter string will just contain the number 1.
I suggested that code because you stated that you needed to do something with the last character in your IP address string, and my code shows how you can obtain the last character.
Use a string. You don't need to perform arithmetic on the IP do you?
It is typical to store IP addresses as strings, or arrays of integers. Another option is to store it as a 32 bit integer. It really comes down to what you want to do.
I would use NSString. If you need to get it piece by piece, use:
NSArray *pieces = [ipAddress componentsSeparatedByString: #"."];
192.168.1.1 is considered the default IP for numerous home high-speed wireless routers. It had been initially utilized by Linksys and yet has been seen used in a number of other home network products including some of those manufactured by Netgear and also Westell among others.
Even though IP address stands out as the default ip for a lot of high speed broadband wireless routers, this does not essentially has to be. A large number of producers set the default IP address to 192.168.1.1 as a way to market a standard precessing conditions and to make it simpler for very first time clients to setup their own networking systems simply and efficiently.
May only Linksys as well as other wireless routers operate using the 192.168.1.1 IP?
Certainly no, given that 192.168.1.1 is definitely a non-public IPv4 address, any type of laptop or computer, modem, switch, or another web system might be devised to work with this unique IP. Nonetheless, it's not in most cases advisable because there are lots of products which default to 192.168.1.1 which in turn interaction issues can occur soon after from many different products utilizing the same IP. It's also really important to consider that a single network equipment might have just one single Ip, if you own numerous units using private IP address, basically at least one has to be adjusted to an alternative location.