Random stuff I keep doing to learn about new topics, packages, languages, frameworks and whatever else is out there#
Table of Contents#
Branches:
mqtt-client-sub#
Theme: The requirement was to provide a firmware for testing EC20 Modem. The telematics device connects to test.mosquitto.org public broker and publishes packet of size 60kB (default, configurable) at interval of 30secs (default, configurable).
Features:
I had already used paho mqtt library on python and
mqtt_server.py
script would have been enough.I decided to work with the C version of paho mqtt. Compiled the paho.mqtt.c from source and as well as using vcpkg.
I learned to use CMake with different compilers such as Clang (
C:/Program Files (x86)/Microsoft Visual Studio/2022/BuildTools/VC/Tools/Llvm/bin/clang.exe
) and GCC (C:/msys64/ucrt64/bin/gcc.exe
)Wrote my own CMakeLists.txt.
File Details:
1. hexdump#
Contains a function to print or dump the content of a buffer in hex format. Compiling the hexdump.c file:
cl .\hexdump\hexdump.c /I .\hexdump\ /c /Fo.\hexdump\hexdump.o
clang -c .\hexdump\hexdump.c -o .\hexdump\hexdump.o
gcc -c hexdump/hexdump.c -o hexdump/hexdump.o
One can add default Pre-Processor macro value in CMakeLists.txt like this
# Define NUMCOLS during the build (default value is 24)
set(NUMCOLS 24 CACHE INTEGER "Number of columns in hexdump")
# Pass NUMCOLS as preprocessor definition
target_compile_definitions(${target_name} PRIVATE NUMCOLS=${NUMCOLS})
2. mkPktRand#
Creates a random buffer for given size using XOR Shift random number generator.
32 Bit XOR Shift RNG
static void generatRandomBuffer(uint8_t buffer[], size_t size)
{
uint32_t *ptr = (uint32_t *)buffer;
size_t numIterations = size / sizeof(uint32_t);
for (size_t i = 0; i < numIterations; ++i) {
g_randSeed ^= (g_randSeed << 13);
g_randSeed ^= (g_randSeed >> 17);
g_randSeed ^= (g_randSeed << 5);
ptr[i] = g_randSeed;
}
}
3. mqtt_client.c#
This is the main file that creates a client with(out) SSL, connetcs to broker and subcribes to a topic. This file uses the paho.mqtt.c library and the hexdump.
Also, \(\text{ceil}(\frac{a}{b}) = \frac{a+b-1}{b}\)
Logging to file as well as console.
/**
* The delay in log file updates may be due to output buffering. By default,
* `printf` buffers output, delaying the write to the console or file until the
* program exits. To address this, use `fflush(stdout)` and `fflush(logfile)`
* after printf and fprintf to ensure immediate writing to both console and file.
*/
#define PRINT(format, ...) do { printf(format, ##__VA_ARGS__); fprintf(logfile, format, ##__VA_ARGS__); fflush(stdout); fflush(logfile); } while (0)
Compiling mqtt_client.c file
- GCC
gcc mqtt_client.c -I eclipse-paho-mqtt-c/include/ -I hexdump/ -L eclipse-paho-mqtt-c/lib/ hexdump/hexdump.o -lpaho-mqtt3cs-static
- cl (MSVC)
cl .\mqtt_client.c /I .\hexdump\ /I C:\dev\vcpkg\packages\paho-mqtt_x64-windows\include\ /I C:\dev\vcpkg\packages\openssl_x64-windows\include\ /link C:\dev\vcpkg\packages\paho-mqtt_x64-windows\lib\paho-mqtt3cs.lib .\hexdump\hexdump.o
- Clang
clang .\mqtt_client.c -I 'C:\dev\vcpkg\packages\paho-mqtt_x64-windows\include\' -I .\hexdump\ -L C:\dev\vcpkg\packages\paho-mqtt_x64-windows\lib\ -l paho-mqtt3cs .\hexdump\hexdump.o -o .\mqtt_client.exe
Refernce: MQTTClient_subscribe.c
4. CMakeLists.txt#
Used to create my package. Also see CMakeLists.txt.bak wich uses vcpkg
cmake toolchain.
Also learned that PreLoad.cmake runs before running the CMakeLists.txt. (Ref: https://stackoverflow.com/a/45247784).
So PreLoad.cmake contains: set (CMAKE_GENERATOR "MSYS Makefiles" CACHE INTERNAL "" FORCE)
Running cmake:
cmake .. -DCMAKE_C_COMPILER='C:/Program Files (x86)/Microsoft Visual Studio/2022/BuildTools/VC/Tools/Llvm/bin/clang.exe'
cmake .. -G "MSYS Makefiles" -DCMAKE_C_COMPILER=C:/msys64/ucrt64/bin/gcc.exe -DCMAKE_AR=C:/msys64/ucrt64/bin/ar.exe
5. cmake_command_for_building_paho.bat/sh#
The command I used to build paho.mqtt.c
6. mqtt_server.py#
The first thing I wrote which satisfies the requirements in python file
server-fota-crc-multithreading#
# TODO: Add readme
tcu-2g-service-tool-dealer#
Created a replacement of a legacy flashing utility for 2G devices. Integrated the the original UART communication C program with Python based GUI using ctypes. Also used IPC for communication progress to GUI.
task-control-gtk3#
A tool created tool for enforcing strict work-hour boundaries. It uses a scheduled GTK3-based visual timer and app killer to automatically shut down your PC and close running applications at the end of a configured work session.
1. schedule_task.c
#
Auto-starts on Windows boot.
Asks user for confirmation or input of work start time.
Calculates shutdown time =
start_time + 9h30m - 15min
.Creates a scheduled task (
stop_tasks.exe
) at the calculated time usingschtasks
.
2. stop_tasks.c
#
Launches a warning popup (Window’s blue colored screen with text).
Starts a 15-minute GTK3 countdown timer.
When timer hits 0:
Kills specified applications (e.g., VSCode, Edge, etc.)
Shuts down the PC.
bootinfo-and-appcrc#
Performs post build tasks
Generate
bin
andhex
files fromelf
frile created from project compilationPuches CRC32 MPEG-2 at the end of the binary file.
Creates
boot_info_data.c
file with structure containing firmware related metadata such as BL start address, APP start address, lenght, crc, debug flags, etc.Provides a linker script and a make file to compile the boot information file into
boot_info.hex
Clang Format file
Important Files’ Details:
1. crc32_bootinfo.cpp#
CPP program that reads binary file, calculates CRC32 and appends it. Generates boot_info_data.c
file and also 3 other files, two srec commad files, crc32.bin (a 4 byte size file).
Using constexpr
to create a crc table
constexpr uint32_t POLYNOMIAL = 0x04C11DB7;
constexpr auto crc_table = [] {
std::array<uint32_t, 256> table{};
for (uint32_t i = 0; i < 256; i++) {
uint32_t crc = i << 24;
for (int j = 0; j < 8; j++)
crc = (crc << 1) ^ (crc & 0x80000000 ? POLYNOMIAL : 0);
table[i] = crc;
}
return table;
}();
Learnt about SFINAE and unnecessarily used std::enable_if
for crc function.
template <typename T>
using crc32_result_t = typename std::enable_if<std::is_integral<T>::value, uint32_t>::type;
template <typename T>
crc32_result_t<T> crc32(const T *data, size_t size);
template <typename T>
crc32_result_t<T> crc32(const T *data, size_t size)
{
uint32_t crc = 0xFFFFFFFF;
for (size_t i = 0; i < size; ++i) {
uint8_t index = ((crc >> 24) ^ static_cast<uint8_t>(data[i])) & 0xFF;
crc = crc_table[index] ^ (crc << 8);
}
return crc;
}
Compilation:
clang crc32_bootinfo.cpp \
-std=c++20 \
-Wall -Wpedantic -Wextra \
-O3 \
-o generate_bootinfo_file.exe
2. boot_info.mk#
Makefile that uses toochain compiler for making boot_info.hex.
{CG_TOOL_MAKE} -f boot_info.mk -k -j 8 all -O
3. linker.cmd#
Linker file to place boot_info strcture in proper memory address.
cmake-build-embedded#
Created a build system using CMake for OpenCPU based project on Quectel’s MC25 4G LTE module.
For more see cmake-build-embedded/README.md
network-library-bumblenet#
# TODO: Add Readme
data-structures-algorithms#
# TODO: Add Readme