Ημερήσια αρχεία: 23 Νοεμβρίου 2016


C/C++: Set Affinity to process thread – Example Code 3

The following code sets the affinity of the process thread to a specific CPU core.
In this example, we define the CPU core id using the variable core_id.

Full source code available here [download id=”2363″]


#include <stdio.h>
#include <stdlib.h>
#define __USE_GNU
#include <sched.h>
#include <errno.h>
#include <unistd.h>

// The <errno.h> header file defines the integer variable errno, which is set by system calls and some library functions in the event of an error to indicate what went wrong.
#define print_error_then_terminate(en, msg) \
  do { errno = en; perror(msg); exit(EXIT_FAILURE); } while (0)


int main(int argc, char *argv[]) {

  // We want to camp on the 2nd CPU. The ID of that core is #1.
  const int core_id = 1;
  const pid_t pid = getpid();

  // cpu_set_t: This data set is a bitset where each bit represents a CPU.
  cpu_set_t cpuset;
  // CPU_ZERO: This macro initializes the CPU set set to be the empty set.
  CPU_ZERO(&cpuset);
  // CPU_SET: This macro adds cpu to the CPU set set.
  CPU_SET(core_id, &cpuset);

  // sched_setaffinity: This function installs the cpusetsize bytes long affinity mask pointed to by cpuset for the process or thread with the ID pid. If successful the function returns zero and the scheduler will in future take the affinity information into account. 
  const int set_result = sched_setaffinity(pid, sizeof(cpu_set_t), &cpuset);
  if (set_result != 0) {

    print_error_then_terminate(set_result, "sched_setaffinity");
  }

  // Check what is the actual affinity mask that was assigned to the thread.
  // sched_getaffinity: This functions stores the CPU affinity mask for the process or thread with the ID pid in the cpusetsize bytes long bitmap pointed to by cpuset. If successful, the function always initializes all bits in the cpu_set_t object and returns zero.
  const int get_affinity = sched_getaffinity(pid, sizeof(cpu_set_t), &cpuset);
  if (get_affinity != 0) {

    print_error_then_terminate(get_affinity, "sched_getaffinity");
  }

  // CPU_ISSET: This macro returns a nonzero value (true) if cpu is a member of the CPU set set, and zero (false) otherwise. 
  if (CPU_ISSET(core_id, &cpuset)) {

    fprintf(stdout, "Successfully set thread %d to affinity to CPU %d\n", pid, core_id);
  } else {

    fprintf(stderr, "Failed to set thread %d to affinity to CPU %d\n", pid, core_id);
  }

  return 0;
}

To compile we used the following command

gcc -Wall affinity.c -o affinity;

Full source code available here [download id=”2363″]

For a full pthread example please visit this link.


How to wrap text in an HTML pre tag using CSS

The <pre> tag element is often used when displaying code blocks because it preserves indentation and line breaks.
Text identified by a <pre> tag is rendered with all spaces and line breaks intact.
By default, <pre> does not support wrapping, so when you render a ‘large’ line, it will force your browser to show a horizontal scroll bar.
By using that scroll bar you will be able to to read the whole line part by part.
Having this feature enabled, the process of reading that line will not be as convenient as it would be after the line would wrap to the following lines like a book. It make sense as you will never be able to see the whole line in one screen.

To mitigate the problem we used the following css snippet, which will instruct most browsers to wrap the contents of all <pre> tags.

pre {
 overflow-x: auto;
 white-space: pre-wrap;
 white-space: -moz-pre-wrap !important;
 white-space: -pre-wrap;
 white-space: -o-pre-wrap;
 word-wrap: break-word;
}

How to search for specific filenames in .tar archives

The following commands will search in the .tar archives found in the specified folder and print on screen all files that their paths or filenames match our search token. We provide multiple solutions, each one for a different type of .tar archive depending on the compression used.

For .tar archives

find /media/repository/packages/ -type f -iname "*.tar" -exec tar -t -f '{}' \; | grep "configurations/arm-cortexa9";

For .tar.bz2 archives

find /media/repository/packages/ -type f -iname "*.tar.bz2" -exec tar -t -j -f '{}' \; | grep "configurations/arm-cortexa9";

For .tar.xz archives

find /media/repository/packages/ -type f -iname "*.tar.xz" -exec tar -t -J -f '{}' \; | grep "configurations/arm-cortexa9";

For .tar.gz and .tgz archives

Please note that this commands uses the -o (which is the logical or) parameter on find to search for multiple filename extensions.

find /media/repository/packages/ -type f \( -iname "*.tar.gz" -o -iname "*.tgz" \) -exec tar -t -z -f '{}' \; | grep "configurations/arm-cortexa9";

find Parameters Legend

  • -type f filters out any result which is not a regular file
  • -exec command '{}' \; runs the specified command on the results of find. The string '{}' is replaced by the current file name being processed.
  • -o is the logical Or operator. The second expression  is not evaluated if the first expression is true.

tar Parameters Legend

  • -z or --gzip instructs tar to filter the archive through gzip
  • -j or --bzip2 filters the archive through bzip2
  • -J or --xz filters the archive through xz
  • -t or --list lists the contents of an archive
  • -f or --file=INPUT uses the archive file or device named INPUT

ATEN – USB-to-Serial Converter (35cm) UC232A – Windows 10 (64bit) Drivers

Background

Recently we started using the UC232A USB-to-Serial Converter to connect to a board.
The software we used was TeraTerm on a 64bit Windows 10 without installing custom drivers.

Our serial port configuration was the following:

  • Baud rate: 115200
  • Data: 8 bit
  • Parity: none
  • Stop: 1 bit
  • Flow control: none
  • Transmit delay:
    5 msec/char
    5 msec/line

The problem

We noticed that something was wrong with the process as the terminal would not operate consistently.
Some times keystrokes did not appear on screen, in other times results would not appear correctly (they could be truncated or mixed with other data) and in general, the system acted like it was possessed by a ghost.

Troubleshooting

We played around with the configuration parameters, hoping that it was an issue like having the need to add large transmit delay but it did not change anything, the communication with the board was unstable.
Afterwards, we switched to another cable, of a different company, and everything worked as expected. The data on the screen was consistent and the ghost was banished. The UC232A was brand new so we tested that it works on a GNU/Linux machine, which turned out to be OK. Doing so, these two tests led us to the conclusion that since both the cable operates properly on GNU/Linux and the board operates properly using the other cable, that the issue we had was the automatically installed Windows 10 drivers.

Solution

While the cable was unplugged, we installed the official drivers we found here.
To find the drivers on that page, click on Support and Download tab at the bottom and then click on the Software & Drivers panel.
From the new table that will appear, under the category Windows Legacy Software & Driver we used the latest version that was available at the time that this post was written, which was v1.0.082 dated 2016-01-27 uc232a_windows_setup_v1.0.082.zip ([download id=”2357″] retrieved on the 23rd of November 2016).
After the download was finished, we restarted the machine, plugged in the cable and gave it another go.
The system was working as expected.

Following, you will find the screenshots from the device manager, after we got the cable working right.

uc232a-device-manager

uc232a-device-properties

uc232a-drive-file-details