Last active
January 18, 2024 14:43
-
-
Save DanGdl/0fd3c3e6fb927c1f89b3e4cccfc4bc22 to your computer and use it in GitHub Desktop.
Embedded linux C
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Tasks for C course. | |
Common requirements: | |
- don't use external libraries (if something else not specified) | |
- build system make/cmake (must be in every task) | |
- compilation with options '-O0 -g3 -Wall -Wextra -Wpedantic -std=c11' | |
- error handling | |
- all task must be checked with valgrind for memory leaks: 'valgrind --leak-check=full --show-leak-kinds=all --track-origins=yes --verbose /path/to/your/executable' (or with log file: 'valgrind --leak-check=full --show-leak-kinds=all --track-origins=yes --verbose --log-file=valgrind-out.txt /path/to/your/executable') | |
!!!!! | |
COMMENTS: | |
Tasks 5, 6, 7, 8, 9 are same as in C cource in Otus (maybe need to replace or change) | |
Task 4 -> Otus uses zip-jpeg file for such task (file, that contains jpeg image and zip archive) | |
!!!!! | |
Task 1: Basics | |
Write a console application that accepts 2 strings as an input from user (text for anagram and text with filtering symbols). | |
If text with filtering symbols is empty, than ignored symbols are digits and non alphabetic symbols. | |
Program should reverse every word of input text and show result in console. | |
Symbol in word, which is contained in filter, must stay on original position. | |
Supported encoding - ASCII. | |
Example: | |
User didn't enter any text in filter | |
Input: “abcd efgh” -> Output: “dcba hgfe” | |
Input: “a1bcd efg!h” -> Output: “d1cba hgf!e” | |
User typed "ab" in filter | |
Input: “abcd efgh” -> Output: “abdc hgfe” | |
Input: “a1bcd efglh” -> Output: “adbc1 hgfle” | |
Task 1.1*: Add support for UTF-8 | |
Task 1.2: | |
Try write a unit test, which test your program using Cmoka and googletest (optional) | |
Example: https://github.com/PacktPublishing/Extreme-C/tree/master/ch22-unit-testing-and-debugging | |
Task 2: Structures, collections, generics, macros | |
Write a program, with implementation of ArrayList, LinkedList, HashSet, HashMap. | |
Explanation about hash table: https://www.youtube.com/watch?v=2Ti5yvumFTU | |
Task 2.1: | |
Make a header-only library with hash map and generic (https://gist.github.com/DanGdl/055d429ccbdde6e149ba46f4d6ab1274) | |
Task 3: work with text files | |
Write a program, which receives a path to text file and counts word frequency (or letter frequency). Supported encoding ASCII | |
Task 4: work with binary files | |
Write a program, which parses torrent file (or any other binary file) and prints it's content. | |
Task 5: static library, macros | |
Write a static libray for logging. It must print to file messages with specified level (debug, info, warning, error) and place in code (where a logging called from). | |
Print stack trace for errors. | |
Task 6: network programing | |
Write a program, which connects to telnet service https://telehack.com and sends a command figlet (with requred parameters) | |
Task 7: network programing and libraries | |
Write a program, which receives a name of city and prints a wheater forecast for this city. | |
Program must to access external api using libcurl and parse a response (you can use any json-parser library). | |
Task 8: memory mapping and work with big files | |
Write a program, which calculates CRC32 (https://en.wikipedia.org/wiki/Cyclic_redundancy_check#CRC-32_algorithm) of big files. | |
Program receives a path to file via parameters | |
Task 9: daemons | |
Write a daemon, which shows a size of specified file (via config in /etc). | |
Damon must work via UNIX sockets (local sockets), with daemonisation and without it. | |
Use file lock to avoid work of additional instances of daemon | |
Task 10: work with devices (DevFs) | |
Program writer reads a file splits it on 100 byte chuncks and sends it via serial device. | |
Program reader reads chunck from serial device, orders them and saves in file | |
Path to file is provided via arguments, if path is folder - send all files from folder | |
Create virtual serial device using socat: socat pty,raw,echo=0 pty,raw,echo=0 | |
Launch programs: | |
./receiver path_to_tty_to_read path_to_folder_to_store_all_data | |
./sender path_to_tty_to_send path_to_file_or_folder | |
Task 10: Binary files, multithreading, queues | |
Record a pcapng-file with wireshark | |
Write a program, that reads a pcapng file extracts from it packets with specific protocol and destination (IP + port) and sends a data from those packets to your server (something simple, that only receives data and does nothing with it. Build with python or whatever you want) | |
Task 11: Optimisation and speed-up | |
Part 1: Implement mock for DMA device | |
Create a mock device with such behavior: | |
- while initialization it provides to client a pointers to it's buffers. Size of each buffer - 4096 bytes, amount of buffers - 50-100 (or choose yourself) | |
- client requests from device an index of buffer, that device is filling now and if there is a full buffers - client handels them | |
- a structure of data in buffer - a list of structs as below (size of channel's sample - 20 bits, placeholder - 16 bits, micros - 32 bits (kind of timestamp)): | |
typedef struct Sample { | |
uint32_t channel4; | |
uint32_t channel3; | |
uint32_t channel2; | |
uint32_t channel1; | |
uint16_t placeholder; | |
uint32_t micros; | |
} Sample_t | |
- to fill values for every channel in sample use any cyclic function (sinus, cosinus, unsigned counter with overflow etc) | |
- device produce samples on frequency 2MHz (5000 channel's samples per 0.1 second) | |
Part 2: Handle full buffers | |
- convert channel's value to float: (sample.channelX / 63035.408) - 2.54 | |
- perform FFT | |
FFT: | |
- collect 8192 values of channel (that's a window) | |
- perform FFT on window (data type for FFT - complex double) | |
- normalize value (convert from complex double to double): | |
SIZE_WINDOW_HALF = SIZE_WINDOW / 2 + 1 | |
for (int i = 0; i < SIZE_WINDOW_HALF; i++) { | |
ComplexD = ComplexD / SIZE_WINDOW; | |
const double real = creal(ComplexD); | |
const double img = cimag(ComplexD); | |
double = real * real + img * img; | |
if (i != 0) { | |
double = double * 2; | |
} | |
} | |
- collect 12 windows and calculate average of SIZE_WINDOW_HALF elements. 12 windows - FFT chunk | |
- you can free result array and print timings. Timming must show: | |
total chunk time (from first sample in window till the end) | |
total FFT time (from FFT of first window till the end) | |
average FFT time of window in chunk | |
- total average timings: for example we handle 200 FFT chunks and when all done - print average time, as in previous paragraph, per chunk | |
- use 4-5 threads | |
Task 11.2: Try to improve performance of FFT this FFT block | |
Task 12: Linux Kernel Modules (LKM, https://www.youtube.com/watch?v=x1Y203vH-Dc&list=PLCGpd0Do5-I3b5TtyqeF1UdyD4C-S-dMa) | |
Create a simple loadable LKM, that create a device in DevFs and property in SysFs. Device allows to read and write some data, | |
size of buffer in driver specify via property in SysFs. | |
Also create a program, that uses this device |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment