18. September 2023 · Categories: Software

VMWare Fusion allows you to run Windows on a Mac, and one of the issues with it is that both deal with high resolution text scaling differently. Windows uses ClearType to adjust the glyphs to look best on the physical display. This gives excellent results on 1x scaling with 110 dpi or less, but only if the output is not scaled afterwards. MacOS on the other hand no longer does subpixel trickery and only does standard antialiasing. This approach provides worse results at 1x, but it preserves more information for a scaled display, and looks better with scaling.

When your external display is 1x, you should use ClearType and 1x on Windows. Make sure that you center a full screen window, and not scale it automatically. Automatic scaling has an unfortunate bug where the display dimensions are somehow off by a pixel, and so stretches the pixel a bit, making text look terrible. Pretty much the same for 2x, only that you activate retina resolution for your VM, and do 200% text scaling in Windows.

If you have something in-between, like 140dpi or 160dpi, you have two options:

  • dedicate your external monitor to Windows, run it at a native resolution in macOS, and use 125% or 150% display scaling on Windows. This gives nice text, but fixes the monitor to be used for Windows only

  • use a scaled resolution in macOS, activate retina resolution in VMWare, run Windows with 200% scaling, and deactivate ClearType in Windows. This gives better letters for scaling, and it gives reasonable text in Windows. The text is worse than the alternative above, but it makes it possible use macOS with a similar text size in parallel.

04. July 2023 · Categories: .NET

SharedSizeGroup is a great mechanism to align multiple columns or rows between Grids in WPF, but it can have unexpected performance implications. I recently came across this when I used it inside the ItemTemplate of a ListBox. A few items in there, and everything works as expected, but after putting in a few dozen, it became really sluggish, and the app was permanently burning CPU cycles.

I redid the design without the need for the size group, removed the Grid.IsSharedSizeScope from the list box, and performance was restored. This was with .net framework 4.8.1.

While researching the problem, I also learned:

  • ScrollViewer.CanContentScroll can be used to switch the scrolling between ensuring that the top element is aligned (true), and continuous scrolling (false)

  • SharedSizeGroup can also be used with multiple columns/rows in the same grid, if you want them equal.

26. February 2023 · Categories: Embedded

The nRF52840 from Nordic Semi has an issue with SPIM3, in that using it with a shared memory buffer could lead to data corruption (Erratum 198). The description describes a simultaneous access from CPU and DMA on the same RAM block as the cause, but after some testing I believe the explanation to be insufficient. The problem seems to only occur with the first byte transmitted, and then it is not corrupted, it is not loaded at all and the SPIM uses the last byte from the last transaction instead. My theory is that the DMA needs to feed two bytes at the start, and that it does not wait for the first transaction to finish before starting the DMA clock. So the first load has no tolerance to retrieve its data before the read for the second byte is issued, which also aborts the first read. On the other hand SPIM0-2 seem to wait: only after the first byte has been read will the module start with transmission, and the DMA start issuing reads for the following bytes. For all following bytes I assume that the read has, on all SPIM, at least half the byte time to get filled.

The best support for this thesis is that when we arrange for SPIM0 to SPIM2 to start at the same time, we see that with contention the times differ, while without they line up nicely.

It looks like it is only the CPU that can lead to corruption, at least a test with the 3 other SPIM could not cause an issue. This is surprising given that all other AHB Masters have higher priority than SPIM3, and so could cause a critical delay. Peripherals however work at 1/4th the speed of the CPU and RAM, and so I guess it needs more than four masters to saturate the bus.

20. May 2022 · Categories: .NET

Windows .NET WPF orders their controls in a visual tree, and this tree has the restraint that every element can only have one parent. This can trip you when define a control as a resource, and then reuse it from the item template of a container. You will see the control exactly once in the list. So never do this in your XAML:

Instead either use templates, with DataTemplate or ControlTemplate, or define a VisualBrush for reuse. The better performance for icons and similar uses is with a visual brush, as it is one item that can be reused and is optimized for painting. For example:

The alternative with ControlTemplate initiates more, but is more compact to describe:

I ran into these problems when I naively tried to use the Visual Studio Image Library for some basic icons for my app. All of their icons are defined as a Rectangle, so these techniques are useful if you want to use them inside of lists.

09. May 2022 · Categories: Embedded

The gcc linker sensibly checks that all files use the same calling convention to prevent problems, but it provides an awful error message that left me confused. When I updated a Cortex‑M project to use floating point math (-float-abi=hard), the linker gave the following error

mylib.o uses VFP register arguments, build/program.elf does not

It sounds like I have to update some setting to tell the linker which calling convention to use for the output, but what it actually means is slightly different: When the first object file is added, its calling convention becomes the calling convention of the output, and when any following files do not match, it is an error, and you see that message.

The most likely cause is that your build system did not rebuild everything, and a full rebuild will fix it. If not, you will need to check your libraries, and then the build options for your object files to see why they were built with a different calling convention. Make sure you put an object file with the correct convention at the start.

31. March 2022 · Categories: .NET

I recently wanted a fast way on the command line to find all available COM ports, and after some searching I constructed the following:

This code searches for all active port devices, which nowadays should only be COM Ports, then sorts them numerically by port number, and finally displays them together with a description and the manufacturer (of the driver). The only tricky part is that the COM port number is not available directly, but must be extracted from the Name property.

My thanks to this overview by Mathew J Bray, which also includes different approaches.

17. January 2022 · Categories: .NET

When trying to read data from the USB Serial driver used on the Pico, it would not read anything in my C# program. It turned out that the Pico library also simulates the RTS and DTR signals in its CDC driver, unlike the typical FDTI chips, which simply ignore them. This gives us two options to deal with it in the SerialPort class of .NET:

  • Set DtrEnable to true, and keep the Handshake to None
    This ignores the RTS input, which could lead to overflow, but it is a setting that also works with ports that do not use RTS/DTR handshakes.

  • Set DtrEnable and RtsEnable to true, and the Handshake to RequestToSend
    This enables hardware handshaking, and behaves unpredictable when no HW handshake is implemented.

03. January 2022 · Categories: .NET

As a C# programmer, Icon DLLs are a leftover from Windows XP days, but I recently needed to create one. The process is non obvious, but quite simple.

  1. Create a new DLL project for the icons, and remove the default class. To keep things portable, all icons should be in the project folder.

  2. Create a stand alone “Native Resource Template” with File | New | File

  3. Insert a dummy resource, then use File Save As, with the file type “Win32 Resource File”, to move the template to your project folder, and delete the dummy resource again.

    This is needed because the Save As refuses to save a template without any resources

  4. Right click to “Add Resource” and import all your existing icons

  5. In the project properties, tab “Application”, choose Resource file for resources, and select your .res file

  6. Add a reference to your icon and res files into the project to make them easier to open, with build action “None”.

08. November 2021 · Categories: Embedded

When using maths on a Cortex-M project, I ran into the problem that the linker would not find the pow function, which should be available. It turned out that the make files I was using were not correctly configured, and I got a basic lesson in diagnosing linker problems.

First is to get some diagnostics to figure out the problem. These are basically the --verbose option to get info about the libraries being loaded, and then --trace-symbol=mysym asks the linker to tell you when a symbol is introduced. Then you can use nm -gC lib.a to figure out whether the symbol is actually defined. If you use gcc to invoke the linker, remember that you need to forward linker options, e.g., -Wl,--verbose.

Now if the symbol is defined, but still not found, the culprit could be the link order. The linker keeps a table of defined elements, and required references. When an object file is found, all exported elements are added to its defined list. But when a library is found, only elements that are already a required reference are added, which is then repeated within the same library to resolve dependencies. This means that libraries must be always behind the object files, and if they have dependencies, must be ordered highest abstraction level first. You can use --start-group archives --end-group to group multiple archives so that dependencies between them are recursively resolved, but it costs performance. With --undefined= and --require-defined=, you can force including symbols from libraries. It would help with resolving dependencies in one pass, but it is brittle and should be avoided.

18. October 2021 · Categories: .NET

In WPF/XAML, you will very often create your custom templates for containers, and one of the issues is to properly adjust the template contents with its container.

The most common problem is making the template fill the container completely. This is done with the properties HorizontalContentAlignment and VerticalContentAlignment of the container, setting them to Stretch. You can then use the Margin of your top level template element for positioning.

When we need more precise control, we can do calculations with a converter based on the actual layout parameters of the container. You get that info with a RelativeSource binding in FindAncestor mode.

This requires you to add a simple converter to your project to do the calculation:

and include it in your application resources