|
@@ -1,82 +0,0 @@
|
|
|
-## Project
|
|
|
|
|
-
|
|
|
|
|
-GPStracker is a portable device used for acquiring GNSS data via a wireless module and saving tracks onto a memory card.
|
|
|
|
|
-
|
|
|
|
|
-## Main directory structure
|
|
|
|
|
-
|
|
|
|
|
-`optiboot` - An "arduino"-type bootloader, modified slightly to handle device's power circuits. Likely does not need any modifications.
|
|
|
|
|
-`PCB` - Altium Designer and mechanical files for project PCBs.
|
|
|
|
|
-`soft` - Main application code.
|
|
|
|
|
-`gps-test-tool` - PC program to process NMEA data just like the embedded device would do, using actual main project code. Used for manual reprocessing of already recorded data and for code testing.
|
|
|
|
|
-
|
|
|
|
|
-## Main Project source files
|
|
|
|
|
-
|
|
|
|
|
-Optimally, all program parts should have a `.c` and a corresponding `.h` file.
|
|
|
|
|
-`1wire`: Utility for communicating with a Dallas 1-Wire bus.
|
|
|
|
|
-`diskio.h`: Header file for memory card states.
|
|
|
|
|
-`display`: Main display routines.
|
|
|
|
|
-`ds18b20`: Utility for reading temperature sensor data using 1-Wire.
|
|
|
|
|
-`expander`: Utility for accessing I2C GPIO expander.
|
|
|
|
|
-`ff`: Utility for accessing FAT filesystem.
|
|
|
|
|
-`ffconf.h`: FAT configuration
|
|
|
|
|
-`ffunicode.c`: FAT helper functions for unicode support
|
|
|
|
|
-`gpx`: Handles GPX file generation and writes, also processes and filters location data.
|
|
|
|
|
-`HD44780-I2C`: Utility for writing data to an alphanumerical display.
|
|
|
|
|
-`I2C`: Utility for communicating with devices on the I2C bus.
|
|
|
|
|
-`integer.h`: Type definition header.
|
|
|
|
|
-`main`: Main loop, global data storage, device initialization and system utilities.
|
|
|
|
|
-`menu`: Utility for drawing nested menus with various item types.
|
|
|
|
|
-`mmc`: Utility for accessing a memory card.
|
|
|
|
|
-`nmea`: Utility for parsing and generating NMEA messages.
|
|
|
|
|
-`settings`: Device configuration and settings menu.
|
|
|
|
|
-`stime`: Manages UNIX time conversions.
|
|
|
|
|
-`timec`: Calculates local time and generates time and date strings.
|
|
|
|
|
-`uart*`: Initializes and handles serial port communication.
|
|
|
|
|
-`UC1601S-I2C':Utility for writing data to a graphic display.
|
|
|
|
|
-`working_modes`: Provides main display (`default_menu`), handles device state.
|
|
|
|
|
-`xprintf`: Utility providing printf-like API.
|
|
|
|
|
-
|
|
|
|
|
-## Build
|
|
|
|
|
-
|
|
|
|
|
-Two display types are supported. Always provide display type as `make` argument. Use `make clean` when changing display types. At the moment, both types display identical data.
|
|
|
|
|
-
|
|
|
|
|
-cd soft
|
|
|
|
|
-make clean
|
|
|
|
|
-make LCD=alnum
|
|
|
|
|
-make clean
|
|
|
|
|
-make LCD=graphic
|
|
|
|
|
-
|
|
|
|
|
-## Notes
|
|
|
|
|
-
|
|
|
|
|
-User facing (display) messages - always in Polish. Logging, code constructs and code comments always in English.
|
|
|
|
|
-Polish character support not available at the time.
|
|
|
|
|
-
|
|
|
|
|
-## Main Code guidelines
|
|
|
|
|
-
|
|
|
|
|
-This is a very restricted embedded environment. Minimize RAM and Flash usage, maximize code efficiency. Some of these guidelines may be deemed antipatterns in other environments, but are essential here.
|
|
|
|
|
-1. All const variables should be declared as `__flash const`, example `__flash const char _logging_active[] = "Zapis aktywny";`. Do not use `PROGMEM`.
|
|
|
|
|
-2. Const array of strings example:
|
|
|
|
|
-```
|
|
|
|
|
-__flash const char gnss_gps_glonass_galileo[] = "GPS+GL.NS+GAL.EO";
|
|
|
|
|
-__flash const char gnss_gps[] = "GPS";
|
|
|
|
|
-__flash const char gnss_gps_galileo[] = "GPS+GALILEO";
|
|
|
|
|
-__flash const char gnss_galileo[] = "GALILEO";
|
|
|
|
|
-__flash const char gnss_gps_beidou[] = "GPS+BEIDOU";
|
|
|
|
|
-__flash const char gnss_beidou[] = "BEIDOU";
|
|
|
|
|
-
|
|
|
|
|
-__flash const char *gnss_names[] = {
|
|
|
|
|
- gnss_gps_glonass_galileo,
|
|
|
|
|
- gnss_gps,
|
|
|
|
|
- gnss_gps_galileo,
|
|
|
|
|
- gnss_galileo,
|
|
|
|
|
- gnss_gps_beidou,
|
|
|
|
|
- gnss_beidou,
|
|
|
|
|
-};
|
|
|
|
|
-```
|
|
|
|
|
-3. When a constant is to be used as a function argument, also declare the parameter as `__flash const` to allow direct accesses without `pgm_read_XXX()`. If the function (or a struct field) is to support both RAM variables and Flash constants, declare it as `const` and add another function argument / structure member to determine the memory type. Then, RAM data can be accessed directly, and Flash consts with `pgm_read_XXX(addr)` (DON'T USE direct accesses if a passed `const` pointer without `__flash` is for Flash - it won't work!). It is recommended to create separate functions for const and variable parameters (these can, in turn, call a single helper).
|
|
|
|
|
-4. Avoid placing auto variables on stack. Don't declare auto (local) variables larger than 4 bytes (beware of structs). If such storage is needed, consider using `static` type instead - even if persistence is not needed. It will consume predictable amount of RAM and generate more efficient code. Only variables allowed on stack are arguments for variadic functions.
|
|
|
|
|
-5. Consider using global buffer variables (for example text buffers), to be later used locally by a function, if possible. Be sure other functions won't overwrite it when being in use.
|
|
|
|
|
-6. Use `struct system_s` structure, with its only `extern volatile struct system_s System` instance, to keep global state - both for "system" info and for output data from application logic. Ideally, store only "fully cooked" data here - no partial states and unprocessed data, unless needed globally in the application.
|
|
|
|
|
-7. For busy loops, use `_delay_ms()` and `_delay_us()` - watch out for watchdog timeouts.
|
|
|
|
|
-8. For non-precision delays, use `set_timer(timer_name, time_in_ms)`. Declare new timer names inside `struct timers` (always `unsigned int`!). To check whether time has passed, query `timer_expired(timer_name)`.
|
|
|
|
|
-9. Don't add static and global variables to store data which can be cheaply recomputed.
|
|
|