Thursday, July 23, 2020

converting between decimal and hex on the command line

I've never been on a *unix system without bc installed. (I was surprised recently as well that some Linux distributions do not include vi) Recently, I have had the need to convert decimal to hexadecimal and hexadecimal to decimal enough to warrant scripts.
#!/bin/sh
#dec2hex.sh
COMMAND=bc
if ! command -v $COMMAND &> /dev/null
then
    echo "$COMMAND could not be found"
    exit
fi 
echo "obase=16; $@" | $COMMAND

#!/bin/sh
#hex2dec.sh
COMMAND=bc
if ! command -v $COMMAND &> /dev/null
then
    echo "$COMMAND could not be found"
    exit
fi
echo "ibase=16; $@"|$COMMAND

Sunday, June 21, 2020

FreeCAD via Macports under MacOS 10.13.6

There were all sorts of errors getting FreeCAD to install, but I found a ticket:
https://trac.macports.org/ticket/60039
Sadly, it still took me a bit to sort it out. You need python2.7 and boost.
sudo port select python27
If you do not have python27, install it. (however, it'll probably come with boost)
sudo port install boost @no_single+no_static+python27
At this point, you should be able to build FreeCad
sudo port install freecad

Thursday, July 18, 2019

Find a file type, order by date.

Under MacOS, finding my .tex files and showing newest first:
find . -type f -name "*.tex" -exec stat -f "%Sm %N" -t /
      "%Y%y%m%d%H%M" {} \; | sort -r | less

Tuesday, January 22, 2019

Matlab Coder from Windows to *unix

One of the strange things about a platform is that people tend to support "the platform". If you ever get a look at a MATLAB Coder Makefile, you'll immediately see things like PERL is included due to the lack of grep on Windows.

I asked Mathworks if they could export both a Windows and *unix Makefile, but it's not supported: https://www.mathworks.com/matlabcentral/answers/440297-coder-create-a-makefile-for-linux-from-windows

The following script won't work for everyone, but it is a good start. Run "script.sh > Makefile" in the top directory of the Coder output and you'll compile to a static library.
Surprisingly (don't know why I am), Coder did a really good job of making C code that compiled on BSD-Lite, Solaris and AIX. I'm sure it'll work on Linux.

#!/bin/bash

## change OUTPUT to be the proper name
echo '
#-------------------------------------------------------------------------------
#       User-modifiable options
#-------------------------------------------------------------------------------

OUTPUT=rtprocessing
PREFIXINSTALL=/opt/local
ANSI_OPTS = -ansi -pedantic -Wno-long-long -fwrapv

#-------------------------------------------------------------------------------
#       User-modifiable options
#------------------------------------------------------------------------------=


UNIXTIME=$(shell date +%s)
WRTSIGNAL = ./signals/
WRTPARSERS = ./parsers/

# Compile for all memories available on the board (this sets $(MEMORIES))
# moved down to tools.

# Output directories
BIN = bin
OBJ = obj
SRC = src
'

echo '
#-------------------------------------------------------------------------------
#       Tools
#-------------------------------------------------------------------------------

# This is to generate SVN information into the binary.  0 is default.
SVNREV := 0

# Tool suffix when cross-compiling
#CROSS_COMPILE = arm-elf-
#CROSS_COMPILE =arm-none-eabi-
# Compilation tools
AR = $(CROSS_COMPILE)ar
CC = $(CROSS_COMPILE)clang
SIZE = $(CROSS_COMPILE)size
OBJCOPY = $(CROSS_COMPILE)objcopy
SVNREV := $(shell svnversion -n . | sed -e "s/.*://" -e "s/\([0-9]*\).*/\1/" | grep "[0-9]" )
#degs compile target
MEMORIES = flash


INCLUDES += -I.. -I. -I$(WRTPARSERS)
CFLAGS += $(OPTIMIZATION) $(INCLUDES)
ARFLAGS  = ruvs
CFLAGS  += -c $(ANSI_OPTS) -O0

#-------------------------------------------------------------------------------
#       Files
#-------------------------------------------------------------------------------


#VPATH is important for file location, which is basically the "INCLUDES"
VPATH += $(WRTSIGNAL) 
VPATH += $(WRTPARSERS)
VPATH += ./io
VPATH += ./examples

#C_OBJECTS = main.o
'

shopt -s nullglob
for file in *.c; do
    echo "C_source+=$file"
done

shopt -s nullglob
for file in *.c; do
    basefilename=$(echo "$file" | sed -e "s/c$//")
    #objectname = "$basefilename""o"
    #echo "$objectname"
    objectname="$basefilename""o" #create the .o list
    echo "C_OBJECTS+=$objectname"
done

echo '
OUTPUTDIR := $(BIN)/$(OUTPUT)
LIBOUTPUTDIR := $(BIN)/lib$(OUTPUT).a


all: clean $(BIN) $(OBJ) $(SRC) $(MEMORIES) 


$(BIN) $(OBJ) $(SRC):
    mkdir $@

define RULES
C_OBJECTS_$(1) = $(addprefix $(OBJ)/$(1)_, $(C_OBJECTS))
ASM_OBJECTS_$(1) = $(addprefix $(OBJ)/$(1)_, $(ASM_OBJECTS))

$(1): $$(ASM_OBJECTS_$(1)) $$(C_OBJECTS_$(1))
    $(AR) $(ARFLAGS) $(LIBOUTPUTDIR) $$^

$$(C_OBJECTS_$(1)): $(OBJ)/$(1)_%.o: %.c Makefile $(OBJ) $(BIN)
    $(CC) $(CFLAGS) -D$(1) -c -o $$@ $$<

$$(ASM_OBJECTS_$(1)): $(OBJ)/$(1)_%.o: %.S Makefile $(OBJ) $(BIN)
    $(CC) $(ASFLAGS) -D$(1) -c -o $$@ $$<


endef

$(foreach MEMORY, $(MEMORIES), $(eval $(call RULES,$(MEMORY))))
    
    
clean:
    -rm -f $(SRC)/*.s $(SRC)/*.i $(OBJ)/* $(BIN)/*
    -rm -f *.s
    -rm -f *.i
    -rm -f *.bc
    -rm -f a.out $(SRC)/*.out $(SRC)/*.out $(OBJ)/*.out $(BIN)/*.out $(BIN)/*.out $(WRTSIGNAL)/*.out $(WRTPARSERS)/*.out


'




Sunday, January 13, 2019

BASH script to update all SVN archives

I have a base root for my SVN repositories, such as:
./svn
./svn/project1
./svn/project2
In order to update everything, I made a script that will execute from any SVN repository and update all of the unrelated repos.

#!/bin/bash
#Before anything else, set the PATH_SCRIPT variable
    pushd `dirname $0` > /dev/null; PATH_SCRIPT=`pwd -P`; popd > /dev/null
    PROGNAME=${0##*/}; PROGVERSION=0.1.0 
##
## This program attempts to do a SVN update on all of the directories off an SVN_ROOT

SVN_ROOT=$(svn info | awk -F: '/Root Path: (.*)/ { print $2 }' | xargs)
SVN_ROOT=$(dirname $SVN_ROOT)
echo "$SVN_ROOT"

for svndir in $SVN_ROOT/* ; do
    BRANCH=`svn info ${svndir} 2> /dev/null | grep "^URL:" | cut -d" " -f2 `
     if [ -z "${BRANCH}" ]
    then
        #echo "Error: directory ${svndir} exists and is not part of a working copy."
        echo "skipping: ${svndir}"
    else
        #echo "$svndir"
        svn update $svndir
    fi
done


Tuesday, August 28, 2018

Multiple timers in MacOS/FreeBSD without timer_t.

POSIX extensions strike again, as I did not have timer_t. dispatch functions allow multiple timers in C under MacOS.
#include 
#include 
#include 

int i = 0;
dispatch_queue_t queue;
dispatch_source_t timer1;
dispatch_source_t timer2;


void sigtrap(int sig)
{
    dispatch_source_cancel(timer1);
    dispatch_source_cancel(timer2);
    printf("CTRL-C received, exiting program\n");
    exit(EXIT_SUCCESS);
}

void vector1(dispatch_source_t timer)
{
  printf("a: %d\n", i);
  i++;
  if (i >= 20) 
  {
   dispatch_source_cancel(timer);
  } 
}
void vector2(dispatch_source_t timer)
{
  printf("b: %d\n", i);
  i++;
  if (i >= 20)  //at 20 count cancel the 
  {
   dispatch_source_cancel(timer);
  } 
}

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

 signal(SIGINT, &sigtrap);   //catch the cntl-c
 queue = dispatch_queue_create("timerQueue", 0);

 // Create dispatch timer source
 timer1 = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, queue);
 timer2 = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, queue);
 
 // Set block for dispatch source when catched events
 dispatch_source_set_event_handler(timer1, ^{vector1(timer1);});
 dispatch_source_set_event_handler(timer2, ^{vector2(timer2);});

 // Set block for dispatch source when cancel source
 dispatch_source_set_cancel_handler(timer1, ^{
  dispatch_release(timer1);
  dispatch_release(queue);
  printf("end\n");
  exit(0);
 });
 dispatch_source_set_cancel_handler(timer2, ^{
  dispatch_release(timer2);
  dispatch_release(queue);
  printf("end\n");
  exit(0);
 }); 

 dispatch_time_t start = dispatch_time(DISPATCH_TIME_NOW, NSEC_PER_SEC); // after 1 sec

 // Set timer
 dispatch_source_set_timer(timer1, start, NSEC_PER_SEC / 5, 0);  // 0.2 sec
 dispatch_source_set_timer(timer2, start, NSEC_PER_SEC / 2, 0);  // 0.5 sec
 printf("start\n");

 dispatch_resume(timer1);
 dispatch_resume(timer2);
 dispatch_main();
 return 0;
}