XBee sleep mode in API mode - xbee

I'm currently working on a project in which I use antennas such as XBee 2 mW Wire Antenna - Series 2 (ZigBee Mesh).
How can I configure my antenna to go sleep mode using software in API mode (without using XCTU)?
How am I supposed to wake up the antenna?

There are many ways to put your device to sleep. If you don't have access to X-CTU you can give the END-DEVICE antenna (it has to be an end device cause for obvious reasons routers and coordinators can't stop responding) a remote AT command through another antenna (usually the coordinator with the help of any microcontroller)
There are 4 types of sleep you can configure (SM) depending on the value you assign
0 - NO SLEEP
1 - PIN HIBERNATE //I believe this one will wake the device only
when Sleep_Rq, module pin 9, transitions from a high to a low
state.There is not much documentation on this mode
4 - Cyclic SLEEP //This mode depends on the SP and SN parameters.
SP (20 to AF0) is the period of sleep in milliseconds and SN (0000
to FFFF) is the number of periods to sleep before waking
5 - Cyclic SLEEP with pin
wake //same as before but you can wake the device also when Sleep_Rq,
module pin 9, transitions from a high to a low state.
This is a typical api message that configures your end device for sleep mode 4
7E //start delimiter
00 0F //length
17 //frame type identifier (remote AT message)
01 //frame ID
00 7D 33 A2 00 40 5C 42 //64bit END-DEVICE address
0C FF //16bit destination network address
02 //command options
83 77 //command name ( SM in ASCII )
04 //command data
** //checksum
In general X.CTU saves you a lot of time, if for some reason you can't use it check out this valid alternative Zigbee Operator

Related

Real time Linux: disable local timer interrupts

TL;DR : Using Linux kernel real time with NO_HZ_FULL I need to isolate a process in order to have deterministic results but /proc/interrupts tell me there is still local timer interrupts (among other). How to disable it?
Long version :
I want to make sure my program is not being interrupt so I try to use a real time Linux kernel.
I'm using the real time version of arch Linux (linux-rt on AUR) and I modified the configuration of the kernel to selection the following options :
CONFIG_NO_HZ_FULL=y
CONFIG_NO_HZ_FULL_ALL=y
CONFIG_RCU_NOCB_CPU=y
CONFIG_RCU_NOCB_CPU_ALL=y
then I reboot my computer to boot on this real time kernel with the folowing options:
nmi_watchdog=0
rcu_nocbs=1
nohz_full=1
isolcpus=1
I also disable the following option in the BIOS :
C state
intel speed step
turbo mode
VTx
VTd
hyperthreading
My CPU (i7-6700 3.40GHz) has 4 cores (8 logical CPU with hyperthreading technology)
I can see CPU0, CPU1, CPU2, CPU3 in /proc/interrupts file.
CPU1 is isolated by isolcpus kernel parameter and I want to disable the local timer interrupts on this CPU.
I though real-time kernel with CONFIG_NO_HZ_FULL and CPU isolation (isolcpus) was enough to do it and I try to check by running theses command :
cat /proc/interrupts | grep LOC > ~/tmp/log/overload_cpu1
taskset -c 1 ./overload
cat /proc/interrupts | grep LOC >> ~/tmp/log/overload_cpu1
where the overload process is:
***overload.c:***
int main()
{
for(int i=0;i<100;++i)
for(int j=0;j<100000000;++j);
}
The file overload_cpu1 contains the result:
LOC: 234328 488 12091 11299 Local timer interrupts
LOC: 239072 651 12215 11323 Local timer interrupts
meanings 651-488 = 163 interrupts from local timer and not 0...
For comparison I do the same experiment but I change the core where my process overload run (I keep watching interrupts on CPU1):
taskset -c 0 : 8 interrupts
taskset -c 1 : 163 interrupts
taskset -c 2 : 7 interrupts
taskset -c 3 : 8 interrupts
One of my question is why there is no 0 interrupts ? why the number of interrupts is bigger when my process run on CPU1 ? (I mean I though NO_HZ_FULL will prevent interrupt if my process was alone : "The CONFIG_NO_HZ_FULL=y Kconfig option causes the kernel to avoid
sending scheduling-clock interrupts to CPUs with a single runnable task"(https://www.kernel.org/doc/Documentation/timers/NO_HZ.txt)
Maybe an explaination is there is other process running on CPU1.
I checked by using ps command :
CLS CPUID RTPRIO PRI NI CMD PID
TS 1 - 19 0 [cpuhp/1] 18
FF 1 99 139 - [migration/1] 20
TS 1 - 19 0 [rcuc/1] 21
FF 1 1 41 - [ktimersoftd/1] 22
TS 1 - 19 0 [ksoftirqd/1] 23
TS 1 - 19 0 [kworker/1:0] 24
TS 1 - 39 -20 [kworker/1:0H] 25
FF 1 1 41 - [posixcputmr/1] 28
TS 1 - 19 0 [kworker/1:1] 247
TS 1 - 39 -20 [kworker/1:1H] 501
As you can see, there is threads on the CPU1.
Is that possible to disable these processes ? I guess it is because if it is not the case, NO_HZ_FULL will never work right ?
Tasks with class TS doesn't disturb me because they didn't have priority among SCHED_FIFO and I can set this policy to my program.
Same things for tasks with class FF and priority less than 99.
However, you can see migration/1 that is in SCHED_FIFO and priority 99.
Maybe these process can causes interrupts when they run . This explain the few interrupts when my process in on CPU0, CPU2 and CPU3 (respectively 8,7 and 8 interrupts) but it also mean these processes are not running very often and then doesn't explain why there is many interrupts when my process run on CPU1 (163 interrupts).
I also do the same experiment but with the SCHED_FIFO of my overload process and I get:
taskset -c 0 : 1
taskset -c 1 : 4063
taskset -c 2 : 1
taskset -c 3 : 0
In this configuration there is more interrupts in the case my process use SCHED_FIFO policy on CPU1 and less on other CPU. do you know why ?
The thing is that a full-tickless CPU (a.k.a. adaptive-ticks, configured with nohz_full=) still receives some ticks.
Most notably the scheduler requires a timer on an isolated full tickless CPU for updating some state every second or so.
This is a documented limitation (as of 2019):
Some process-handling operations still require the occasional
scheduling-clock tick. These operations include calculating CPU
load, maintaining sched average, computing CFS entity vruntime,
computing avenrun, and carrying out load balancing. They are
currently accommodated by scheduling-clock tick every second
or so. On-going work will eliminate the need even for these
infrequent scheduling-clock ticks.
(source: Documentation/timers/NO_HZ.txt, cf. the LWN article (Nearly) full tickless operation in 3.10 from 2013 for some background)
A more accurate method to measure the local timer interrupts (LOC row in /proc/interrupts) is to use perf. For example:
$ perf stat -a -A -e irq_vectors:local_timer_entry ./my_binary
Where my_binary has threads pinned to the isolated CPUs that non-stop utilize the CPU without invoking syscalls - for - say 2 minutes.
There are other sources of additional local timer ticks (when there is just 1 runnable task).
For example, the collection of VM stats - by default they are collected each seconds. Thus, I can decrease my LOC interrupts by setting a higher value, e.g.:
# sysctl vm.stat_interval=60
Another source are periodic checks if the TSC on the different CPUs doesn't drift - you can disable those with the following kernel option:
tsc=reliable
(Only apply this option if you really know that your TSCs don't drift.)
You might find other sources by recording traces with ftrace (while your test binary is running).
Since it came up in the comments: Yes, the SMI is fully transparent to the kernel. It doesn't show up as NMI. You can only detect an SMI indirectly.

Getting data from an RFID reader

I have a an RFID reader with very scant documentation.
It has some wires hanging out and they come from a connector with "+12V", "GND", "NC" , "COM" (or CDM) , "NO", "SW", "D0" , "D1" pins.
I don't know what they are but "+12V" and "GND" are for voltage and ground. Probably D0 and D1 are for I2C communication.
The unit works fine (beeps while reading from RFID card etc) but I'd like to get the info of the cards to a laptop using a serial (COM) port. I don't want to damage the serial port of my laptop. How would I go about trying to receive data from the RFID reader. I can try on another Windows XP laptop which is expendable.
My guess is to connect the D0 and D1 to the serial port but which pins do I connect? What about the voltage? I am familiar with RX and TX port usage. I just want to know that I can get data off the RFID reader and if so I'll write a more robust com send/receive C program.
D0 stands for Data Low pin.
D1 stands for Data High pin.
From the description of yours, you might be using Wiegand based RFID reader. The pin connection present here RFID reader. The pins D0 and D1 are used to send data to controller.
When D0 and D1 are both Low or 0 that means no data is
transmitting.
When D0 is Low and D1 is high (1) then the output 0 is transmitting.
When D0 is High and D1 is Low then the output 1 is transmitting.
When D0 and D1 are both High or 1 that means no data is transmitting.
So when you connect these two pins to some controller, it has to monitor the data from these two pins and has to determine the output (logic 0 or 1) based on the above four points. After controller reading all the data from D0 and D1 (may be 96 or 128 consecutive bits), you need to decode that binary data into ASCII first and then you can extract card number from that data.
Well you'll first need to make the RS232 connector. Your pins are as follows:
+12V: Hot voltage supply
GND: Ground
^^Connect those to a power 12V power supply.
NC: Normally closed
COM: Common
NO: Normally open
SW: Switch
D0: Data 0
D1: Data 1
There should be at least some documentation with the device as to which pins communicate. Look up RS232 9 pin wiring to see what you should solder where.
Then you'll need a Serial communication program that can send or at least receive communications from the device. Putty would be your best bet.

System halt in linux

I was looking at reboot.c in the Linux kernel.
http://lxr.free-electrons.com/source/kernel/reboot.c
There is a call to kernel_halt it says that this function will
Shutdown everything and perform a clean system halt.
What does a clean system halt mean?
Can any one explain what this halt actually does?
I am also wondering about syscore what kind of operations are considered as syscore operation?
0 void kernel_halt(void)
161 {
162 kernel_shutdown_prepare(SYSTEM_HALT);
163 migrate_to_reboot_cpu();
164 syscore_shutdown();
165 pr_emerg("System halted\n");
166 kmsg_dump(KMSG_DUMP_HALT);
167 machine_halt();
168 }
syscore_shutdown() will check all registered syscore operations (drivers/base/syscore.c"Execute all the registered system core shutdown callbacks.") for non-NULL operation shutdown and will execute them. Syscore operations are registered using register_syscore_ops, and most drivers register only resume and suspend fields of syscore_ops.
There is partial list of syscore registrations with shutdown field as of linux kernel version 3.13 for x86/x86_64:
1) arch/x86/kernel/i8259.c: i8259A_shutdown
261 /* Put the i8259A into a quiescent state that
262 * the kernel initialization code can get it
263 * out of.
264 */
265 outb(0xff, PIC_MASTER_IMR); /* mask all of 8259A-1 */
266 outb(0xff, PIC_SLAVE_IMR); /* mask all of 8259A-2 */
2) arch/x86/kernel/cpu/mcheck/mce.c, mce_syscore_shutdown which calls mce_disable_error_reporting
2026 * Disable machine checks on suspend and shutdown. We can't really handle
2027 * them later.
....
2037 wrmsrl(MSR_IA32_MCx_CTL(i), 0);
3) kernel/irq/generic-chip.c irq_gc_shutdown: for each element in gc_list, try to run ct->chip.irq_pm_shutdown(data);; the "#irq_pm_shutdown: function called from core code on shutdown once per chip" (description)
4) drivers/leds/trigger/ledtrig-cpu.c:
84 static void ledtrig_cpu_syscore_shutdown(void)
85 {
86 ledtrig_cpu(CPU_LED_HALTED);
87 }
...
61 case CPU_LED_HALTED:
62 /* Will turn the LED off */
63 led_trigger_event(trig->_trig, LED_OFF);
What does a clean system halt mean?
Unmount cleanly everything, switch off all hardware.
I am also wondering about syscore what kind of operations are considered as syscore operation?
Syscore is used to register some functions to work at suspend/restore and shutdown. Very small number of drivers registers syscore shutdown virtual functions, for example: turning PC case LEDs (not keyboard's leds off, disabling interrupts, disabling machine checks (I think like ECC error, because there will be nobody to report them to system log), ...
Can any one explain what this halt actually does?
This halt: switches to the 0 CPU core, because only it can do reboot or shutdown, runs all registered pre-shutdown handlers, then prints "System halted" and and asks hardware to do actual poweroff.
162 kernel_shutdown_prepare(SYSTEM_HALT);
163 migrate_to_reboot_cpu();
164 syscore_shutdown();
165 pr_emerg("System halted\n");
166 kmsg_dump(KMSG_DUMP_HALT);
167 machine_halt();

What is triggering an 0x08 interrupt?

I'm trying to hijack the Timer interrupt. A colleague told me that interrupt 0x08 on the IDT (Interrupt Descriptor Table) is the timer. Of curse I checked and saw two possible answers: this which says that 8 is the real clock timer and this saying it's the Double Fault interrupt - I decided to believe him and not waste time on checking further. After finally having control over the IDT and replacing interrupt 8, nothing is happening.
So what is going on?
Did this interrupt change its purpose over time from timer to double fault?
Does this interrupt has different purposes on ARM/Intel/etc.?
My code is a kernel module, that hijacks the interrupt 8 and simply do a printk command every time the interrupt arrives. I ran it for about 25 minutes - No output in dmesg.
In case it matters: I run Linux Mint with kernel 3.8 on a VM. The host has an Intel i5.
You can find which interrupt is for timer by using this command: cat /proc/interrupt
Following is a sample output on a 6 core machine:
cat /proc/interrupts | egrep "timer|rtc"
0: 320745126 0 0 0 0 0 IO-APIC-edge timer
8: 1 0 0 0 0 0 IO-APIC-edge rtc0
LOC: 115447297 304097630 194770704 212244137 63864376 69243268 Local timer interrupts
Note, timer and rtc are different. Also there is only one rtc interrupt so far. (Lots of timer interrupts). Following is the uptime output.
uptime
14:14:20 up 13 days, 3:58, 9 users, load average: 0.47, 1.68, 1.38
I think you should check this before you hack IDT. Also, probably, you want to hack interrupt 0, not 8.
You have found two descriptions for the same IRQ because in protected mode the address range 0x0 - 0x1F are reserved for internal cpu interruptions use.
You have to remap IRQs to another address space without conflicts, in this article you can find it explained with all the source code needed:
https://alfaexploit.com/readArticle/416

Why is data sent across the network converted to network byte order?

I'm not sure how to use hton(). The theory is that any data sent over the network should be in network byte (i.e. big-endian) format. Suppose client A supports big-endian and B supports little-endian. I'm sending data from A to B and the data is read as multibyte. Then in the network we need to convert data to network byte order using htonl() and htons(). Since client A is already big-endian, htonl() and htons() return the same output. But B is little-endian, so those functions reverse the order. Given that, how can we say that adhering to a common format (i.e. big-endian) is a solution to the problem when big- and little-endian machines need to communicate?
I'll try it the other way, showing the whole flow:
Sending 0x44332211 over the wire always happens as 44 33 22 11. The sender's htonl() ensures that, either by reverting the order of the bytes (on LE machines) or by just leaving them the way they are (on BE machines). The receiver turns the 44 33 22 11 into 0x44332211 with ntohl() - again, either by reverting them or leaving them.
The mentionned functions {hton,ntoh}{l,s}() help programming in a portable way: no matter if the program tuns on a LE or BE machine, they always work the way they should. Thus, even on BE machines the functions should be called, even if they are noops.
Example:
A (BE) wants to send 0x44332211 to B (LE).
A has the number 0x44332211 in memory as 44 33 22 11.
A calls htonl() as the program has been written to be portable.
The number is still represented as 44 33 22 11 and sent over the wire.
B receives 44 33 22 11 and puts it through ntohl().
B gets the value represented by 11 22 33 44 from ntohl() and puts it into the respective variable - which then results to 0x44332211 as wanted.
Again, the need for always calling these function saves you from thinking about which kind of machine you are programming for - just program for all kinds of machines and call each of these function when they are needed.
The same example can be expressed without knowing if A or B are BE or LE:
A has the number 0x44332211 in memory.
A calls htonl() so that the number is sent as 44 33 22 11 over the wire.
Whether this is done by reverting or by leaving it is determined by the endianness of host B.
B receives 44 33 22 11 and puts it through ntohl(). This one reverses it or not, depending on the endianness of host B.
B gets the value 0x44332211 as wanted.
I think you're thinking that client B seeing the bytes in "reversed order" means that they're wrong. The bytes will be in reverse order compared to client A, but that's because client A interprets integers backwards from client B; both will still interpret it as the same number in the end. For example, one machine would represent the number 4 as 00 00 00 04. The other would represent it as 04 00 00 00, but both would still see it as a 4 -- if you add 1 to it you're going to get 00 00 00 05 and 05 00 00 00, respectively. The hton/ntoh functions exist because there's no way to look at a number and know if it's big- or little-endian, so the receiver can't be sure which way to interpret the bytes

Resources