Thursday, December 31, 2015

APC Back-UPS ES 500 BE500U-CN fluctuation in reported battery voltage due to power switch

I first noticed the problem when the Cinnamon desktop in Linux reported the battery was critically low, and even inappropriately hibernated the system although AC power was available. After rebooting into Windows, PowerChute Personal Edition 3.0.2 also said the battery was at 0%, but failed to report this as a problem.

The UPS also reports battery voltage, but that can only be viewed via apcupsd apcaccess or HWMonitor in Windows. HWMonitor gives faster updates, but it can cause blue screen Windows crashes, even after quitting the program, so I recommend apcupsd. Both programs showed voltage fluctuations, from below 11.1V to 13.3V.

The real battery voltage, was 13.60V with the UPS off, and 13.55V with the UPS on. So, the battery and the charger were working properly, and the UPS was measuring an incorrect voltage. The UPS was functional, though the incorrectly low voltage measurements could lead to a short runtime.

I removed the circuit board from the UPS, and only powered it via the battery connections using a bench supply. This is a safe method for testing. The board does not have any high voltage capacitors, and it cannot produce high voltage without connection to the large transformer mounted elsewhere in the UPS case. The small transformer on the board is only used for powering the UPS circuit from AC and charging the battery.

The microcontroller on the board is the Microchip PIC16C745. It has an analog to digital converter, so it's reasonable to suspect that the battery is measured that way. According to the data sheet, only 5 pins are usable as ADC channels. By varying the bench supply voltage while measuring voltage at those pins I saw that pin 3 was probably used to measure battery voltage. R15 and R2 form a voltage divider, and C18 is used to smooth the measured voltage. Fluctuations were also happening on the other end of R15, which is the positive "12V" supply to lots of things on the board. The supply comes from the positive battery terminal via the power switch and one of the transistors above the microcontroller.

I removed C18 just to make sure it is fine, and it was, with extremely low leakage. The problem was the switch for turning on the UPS. Its resistance was unpredictable, sometimes a few ohms and sometimes a few tens of ohms. It only gave zero resistance while I was pushing it in hard.

Although it is a latching pushbutton, it works on the principle of a slide switch. It is DPDT, but is used as an SPST switch with the poles connected in parallel. The switch is hard to unsolder due to all the pins, but it is very easy to disassemble by prying the sides to release the bottom with the contacts. Be careful with the sliding contacts. They are tiny, light, delicate, and nothing is holding them in place. I cleaned them by passing paper moistened in isopropyl alcohol inside them. I also cleaned the stationary contacts that way, and cleaned them from the outside with a pen eraser. After that, the resistance was less than 0.1 Ω and the problem is fixed. I hope it stays fixed.

Further comments on the APC Back-UPS ES 500 BE500U-CN

Voltage at the battery terminals goes above 14V when the UPS is AC powered and turned off, and no battery is connected. This would be bad for a battery, but even a 10 kΩ resistor is enough to bring the voltage down within acceptable levels. I don't think this is a problem, because there's probably more than 1.4 mA flowing into a fully charged battery.

Note the big metal blocks on the circuit board near the power switch. Those are heat sinks for the inverter MOSFETs. A normal heat sink would have fins to radiate heat. The metal blocks mainly provide heat capacity. The run time of the UPS is limited by battery capacity and charging speed. It is okay if those blocks need an hour to cool down, because battery charging takes even longer. Those heat sinks would need to be replaced if you want to use a much higher capacity battery or use the UPS continuously as an inverter.

Monday, December 28, 2015

Not disabling cache before reinitializing TCC76X led to some weird things

My RCA RC3000A digital boombox port of Rockbox started getting unexpected shutdowns at startup after I upgraded it to a newer version of Rockbox. A binary search showed it happened when the audio thread starts, but that made no sense! Simply starting the thread and making it execute a loop which only sleeps was enough to cause shutdowns.

Then I saw that they didn't happen when I loaded via USB boot. It made me suspect that some initialization performed by the Rockbox bootloader caused problems later on when the chip is re-initialized by Rockbox. My first guess was cache, prompted by how ROLO flushes ARM cache but doesn't disable it. Disabling the cache fixed the problem when loading Rockbox via ROLO. It also had to be disabled in another place to fix the bootloader.

The TCC760 uses standard ARM940T cache. I'm not sure if this affects other similar ARM cores or other Telechips SoC families.

Wednesday, December 23, 2015

Switching to tmpfs and unmounting root in Raspbian

This describes how to make a Raspberry Pi running Raspbian use RAM for the root file system. This allows you do things which cannot be done while the root file system is mounted, such as shrinking it with resize2fs. It would also allow you to write a totally new image to the SD card, overwriting everything. It might also allow you to swap SD cards and write an image to a different card, but I'm not sure that the SD card driver allows it. Here is the script:

cp -r lib bin sbin etc /mnt
mkdir -p mnt/usr/lib/arm-linux-gnueabihf
cp usr/lib/arm-linux-gnueabihf/ mnt/usr/lib/arm-linux-gnueabihf
# Move other mounts
mkdir mnt/dev
mount --move dev mnt/dev
# Pivot root using instructions from pivot_root(8) man page
cd mnt
mkdir old_root
pivot_root . old_root
# The current directory now seems invalid, so fix it
cd /
# Old root can only be unmounted once sh running from old root finishes.
# If enough was copied, you could continue startup normally using init.
exec old_root/usr/sbin/chroot . bin/sh

First, save the script somewhere. To use it, add init=/bin/sh to /boot/cmdline.txt and reboot. When the boot text finishes, you may not see the # prompt because of kernel output, but the shell should be running, and you'll get another prompt if you press enter.

You must run the script in the shell which is running as init, not a shell spawned from it. That is because the final line needs to end that shell. You won't be able to unmount old_root if you're still running a shell from it. So, for example if the script is /root2ram, use . /root2ram to run it.

The final line is the place where any errors will manifest themselves. You would get a kernel panic if chroot or sh can't run. If you're experience a problem, comment out the last line and look at the state of the system at that point.

The script is intentionally minimalist. All of Raspbian won't fit into RAM, so it only copies some parts. Some binaries in /bin and /sbin require libraries from
/usr/lib/arm-linux-gnueabihf/, and only the most commonly used one gets copied. The script does not umount old_root at the end so you can test whatever you want to run and copy anything else you need before manually unmounting it.

This has been tested on a Raspberry Pi 2 B running Raspbian Jessie. If you want to run it on a Raspberry Pi with less RAM, you might need to be more specific when copying from /lib. It is big and there are un-needed things there.

When you are done and you want to boot normally, simply remove init=/bin/sh from /boot/cmdline.txt. You would need to mkdir boot && mount boot. Vi is in /usr/bin, but sed is in /bin and you can use sed -i 's,init=/bin/sh *,,' /boot/cmdline.txt to edit it. Normal rebooting won't work without init, so umount /boot ; sync && reboot -f.

Thursday, December 17, 2015

WM_SYSCOMMAND SC_SCREENSAVE doesn't work anymore for activating the screen saver?

I use HoeKey as my hotkey program in Windows 7. One hotkey is supposed to activate the screen saver:

=Msg|0|274|61760|0      ; start screensaver

This waits one second to avoid the key release event, and then sends a WM_SYSCOMMAND SC_SCREENSAVE message. It failed a few times in the past, but it generally worked. Now it fails all the time. I wonder why?

This doesn't seem to be a HoeKey problem, because a trivial C program can't activate a screen saver this way either. However, SC_MONITORPOWER always works in both HoeKey and the C program, shutting off the monitor when lParam is 2.

In the past when it failed I thought it was due to the adaptive screen saver timeout, but disabling that doesn't help.

Emscripten 1.34.2 and later can reveal more alignment problems

Em-DOSBox started getting graphical corruption when built with recent versions of Emscripten. This was due to improper alignment of a statically allocated variable, which was declared as 8 bit values but also accessed as 16 and 32 bit.

Here is the Emscripten change which triggered the problem. It changes the alignment of variables which are allocated at compile time. Previously, they were 64 bit aligned. Afterwards, they are aligned as appropriate for their data type. 8 bit values don't need any alignment, and so they can end up improperly aligned for 16 and 32 bit access. This change is in emscripten-fastcomp, between 1.34.1 and 1.34.2 tags. Variable alignment depends on the build used during the final Emscripten link.

This is not an Emscripten problem, but an issue in DOSBox which started causing problems after that Emscripten change. If you think you may be dealing with an alignment problem, link the program with -s SAFE_HEAP=1. That will cause misaligned access to report and alignment error and throw an exception. You may also want to use a lower level of optimization or at least --profiling-funcs, so it is easier to find where the problem is occurring.

Thursday, December 10, 2015

Western Digital PM2 (power up in standby) was not useful

I have a 1TB WD1002FAEX Western Digital Black which used to by my main drive but is now just a data drive. Operating systems and commonly used data can all fit on the PNY CS1211 240GB SSD. As a result, the 1TB drive doesn't really need to spin up every time the computer turns on. Enabling power up in standby seems like a good idea.

Western Digital drives support power up in standby via a jumper, which they document in a PDF. The drive did not support setting of the feature using software via hdparm -s. This is probably wise. If power up in standby is enabled via software, you could end up in a situation where your operating system doesn't recognize the drive and you can't disable the feature. Such a drive isn't bricked, but you may need to connect it to a different computer running a different operating system in order to rescue it. A jumper is very easy to remove.

After placing the jumper, the drive didn't spin up when I turned on my computer, as expected. The Gigabyte GA-P35-DS3R F13 BIOS identified a hard drive there, but didn't identify what kind and didn't spin up the drive. There was a long delay before booting, but Linux successfully booted from the SSD. Linux spun up the drive and mounted the partitions on there. It complained about failing to spin up the drive, but I didn't notice any actual problems. So far, that is all okay. Then I put the computer to sleep and woke it up, hoping the drive wasn't going to spin up. Unfortunately, Linux spun it up. So, the drive remains usable with Linux, but this feature is pointless because Linux spins up the drive anyways.

Next, I tested Windows 7. It acted as if the drive was totally non-existent. Since it wasn't detected, other software couldn't be used to spin up the drive. This means power up in standby is totally incompatible with Windows 7. It could only work if the BIOS or a 3rd party driver spun up the drive during boot and after waking from sleep.

Wednesday, December 09, 2015

Comparing an Olympus Li-10B battery to a "1400 mAh" replacement

Both of these batteries had to be discarded because they were swelling. The Li-10B was purchased along with my Olympus C-770 Ultra Zoom camera in May 2005. I'm pretty sure the replacement was purchased from DX (DealExtreme) in January 2011.

I wanted to open them up for two main reasons: to see if it's possible to replace the cell, and to examine deception in the replacement. Both batteries were easy to open up by cutting along the seam. There are tabs, but I think the cases were welded or glued. Here's what's inside:
The Olympus Li-10B has a Sony cell inside, and the "1400 mAh" replacement contains a 750 mAh cell. It's probably decent quality, because in June 2013, after almost two and a half years of use, I measured 760 mAh.  The part number seems to be 063040AL.

In the original Li-10B, the cell fills the case. There is only some very thin double-sided tape on one side, and a bit of very thin insulating tape. The replacement contains a thick foam rubber spacer, and a thinner paper spacer. The cell thickness difference is easy to see. This is at least part of why the "1400 mAh" battery was lighter than the Li-10B.

Finally, here are the protection boards. The top is the original, and the bottom is the replacement. In the original board, the small black square is the control chip, and the much larger component is a low Rds(on) MOSFET. I'm not sure about the components in the replacement, or why one of the chips is cracked in a corner.

The replacement never had as much battery life as the original when it was new, and it probably wasn't much better than the already worn out Li-10B. However, at $5.18 US I can't say it was a ripoff, and it was helpful.

Preserving order when importing Internet Explorer Favourites

Internet Explorer stores its favourites as individual shortcut files in %USERPROFILE%\Favourites. Folders of favourites correspond to directories there. This is all easy to deal with, and other browsers can easily import it.

Ordering of favourites within a folder is stored separately, in HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\MenuOrder\Favorites. It uses an undocumented binary format. If you want to import into Internet Explorer elsewhere, you can simply export that branch of the registry using regedit, and then import it to restore the order. Exporting the ordering into other browsers is more difficult.

A CodeProject article explains the registry format. The code there is compatible with Windows XP and Vista, but not later versions. I also had some other problems, which I listed in a comment over there. Nevertheless, the code there was a very helpful starting point and only a few changes were needed.

The problem then is using the bookmarks.xml file, which is in XBEL format. Firefox is incapable of reading that format, and the XBELFox extension didn't work either. Debian had some XBEL tools in the past, but those depend on Python 2.1. I eventually ended up installing Konqueror and exporting to Mozilla format from there. That may seem like a ridiculously inefficient method, but it's much faster than spending more time searching for a suitable format conversion utility. Afterwards, it was easy to use dpkg.log to purge Konqueror and all of the KDE stuff it installed.

Tuesday, December 01, 2015

Windows 7 won't let you delete a hard-linked read-only file

Normally, Windows 7 file management ignores the read-only attribute. You can delete read-only files in Explorer or in cmd.exe command prompt without any need to remove the attribute. There is no additional prompting or notification, so it's effectively as if the attribute wasn't set. Some attempts to overwrite the file can be stopped by the attribute, so the read-only attribute isn't totally pointless.

When a file has hard links (or in other words, is associated with multiple directory entries), weird things happen. It seems as if there is one read-only attribute for the file itself which affects all of the file's directory entries, and an attribute cache associated with directory entries (file names). When you change the attribute for one name, you change it for all names, but attrib will give you incorrect old information for other names. The cache is updated when you attempt to overwrite or delete the file, and attrib will then provide accurate results.

If you try to delete a read-only file with multiple directory entries in cmd.exe, it will fail with "Access is denied." Explorer may fail to delete the file in some situations, incorrectly telling you that the file is in use.