Developer Guides
Relevant source files
The following files were used as context for generating this wiki page:- README.md
- Firmware/App/Utils/Shell/Shell.h
- Firmware/App/Utils/Shell/Shell.c
- Firmware/App/Service/DataProc/DP_Shell.cpp
- Firmware/App/Version.h
- Firmware/App/Service/DataProc/Def/Version.h
- Firmware/App/Service/DataProc/DP_Version.cpp
- Firmware/App/Config/Config.h
- Firmware/Vendor/Artery/Application/HAL/HAL_Config.h
- Firmware/App/Service/DataProc/Def/Power.h
- Firmware/App/Service/DataProc/Def/_Template.h
This guide provides a technical overview of the DutyCycle firmware for developers. It covers the project's architecture, build process, command-line interface, and key configuration parameters. The information herein is derived exclusively from the source code to ensure accuracy for developers working on or extending the project.
The DutyCycle project is a "Work-Life Duty Cycle Clock" built on an AT32F421 microcontroller. The firmware is responsible for all core logic, including timekeeping, hardware control, and user interaction via a serial command-line interface.
1. Project Overview & Build Process
The project is structured as a firmware application developed using Keil MDK.
Sources: README.md, Firmware/App/Version.h
1.1. Version Information
The firmware versioning is defined in Version.h and exposed through the DP_Version data processing module.
| Property | Value | Source File |
|---|---|---|
| Firmware Name | DutyCycle | Firmware/App/Version.h:26 |
| Software Version | v1.2 | Firmware/App/Version.h:27 |
| Hardware Version | v1.3 | Firmware/App/Version.h:28 |
| Author | _VIFEXTech | Firmware/App/Version.h:29 |
| Website | `https://github.com/FASTSHIFT/DutyCycle%60 | Firmware/App/Version.h:30 |
The DP_Version module also captures and provides build-time information, such as the compiler version, build date, and time.
Sources: Firmware/App/Service/DataProc/DP_Version.cpp:32-47, 90-97
1.2. Getting the Source Code
To clone the repository, including all necessary submodules, use the --recursive flag.
git clone https://github.com/FASTSHIFT/DutyCycle.git --recursive
Sources: README.md:12-14
1.3. Compilation
The firmware is compiled using Keil MDK version 5.25 or higher. The project file is located at Firmware/Vendor/Artery/Platform/AT32F421/MDK-ARM/proj.uvprojx.
Sources: README.md:16-18
2. Firmware Architecture
The firmware is organized into several layers, including a Hardware Abstraction Layer (HAL), application services, and utilities. A key architectural pattern is the DataBroker, which facilitates communication between different modules using a publisher-subscriber model.
The diagram below illustrates the high-level interaction between the main firmware components.
3. Command-Line Interface (Shell)
The primary method for configuring and interacting with the device is through a serial command-line interface (CLI). The shell is implemented in Firmware/App/Utils/Shell/ and integrated into the system via the DP_Shell data processing module.
Sources: Firmware/App/Utils/Shell/Shell.h, Firmware/App/Utils/Shell/Shell.c, Firmware/App/Service/DataProc/DP_Shell.cpp
3.1. Initialization and Task Loop
The shell is initialized in the DP_Shell constructor. It requires three callback functions: a reader for serial input, a writer for serial output, and a tick getter for timing.
The main processing is handled by shell_task(), which is called continuously within the application's main loop, triggered by a GLOBAL_EVENT::APP_RUN_LOOP_BEGIN event.
The following diagram shows the shell's initialization and command processing flow.
3.2. Shell Commands
Commands are registered using shell_register() and implemented as static functions within DP_Shell.cpp. These command functions often use the DataBroker to interact with other system modules.
The following commands are available:
| Command | Description | Source File |
|---|---|---|
help | Lists all available commands. | Firmware/App/Service/DataProc/DP_Shell.cpp:277-281 |
loglevel <level> | Sets the HAL log level (0-4). | Firmware/App/Service/DataProc/DP_Shell.cpp:283-291 |
ps | Dumps memory usage information (stack and heap). | Firmware/App/Service/DataProc/DP_Shell.cpp:293-298 |
publish <topic> [data] | Publishes a message to a DataBroker topic. | Firmware/App/Service/DataProc/DP_Shell.cpp:300-313 |
clock [options] | Sets or gets the system time. Use -c SET to apply changes. | Firmware/App/Service/DataProc/DP_Shell.cpp:315-389 |
power -c <cmd> | Sends a power command (SHUTDOWN, REBOOT). | Firmware/App/Service/DataProc/DP_Shell.cpp:391-423 |
ctrl [options] | Controls the motor and display modes. | Firmware/App/Service/DataProc/DP_Shell.cpp:425-492 |
alarm [options] | Manages alarms and hourly chimes. | Firmware/App/Service/DataProc/DP_Shell.cpp:494-589 |
kvdb [options] | Manages the key-value database (DEL, LIST, SAVE). | Firmware/App/Service/DataProc/DP_Shell.cpp:591-623 |
3.3. Command Execution Flow (Example)
When a user issues a command like power -c REBOOT, the shell parses the input and triggers a series of interactions through the DataBroker to execute the action.
4. Data Processing and DataBroker
The DataBroker is a central message bus that decouples firmware modules. Modules, known as DataProc components, can publish, subscribe, pull, or be notified of data changes without direct dependencies on each other. The DP_Shell module is a prime example, acting as a bridge between the user and other DataProc modules.
4.1. ShellNodeHelper
The DP_Shell uses a helper class, ShellNodeHelper, to simplify interactions with other DataProc nodes. This helper handles subscribing to a node on creation and provides pull and notify methods.
// Example usage from DP_Shell.cpp
ShellNodeHelper<Power_Info_t, Power_Info_t> nodePower("Power");
// ...
if (!nodePower.notify(&info)) {
return SHELL_RET_FAILURE;
}
Sources: Firmware/App/Service/DataProc/DP_Shell.cpp:148-193
4.2. Data Structures
Communication between modules is done via standardized data structures. These are typically defined in the Firmware/App/Service/DataProc/Def/ directory.
Version_Info_t
This structure holds all version-related information for the firmware.
| Field | Type | Description |
|---|---|---|
name | const char* | Firmware name, e.g., "DutyCycle". |
software | const char* | Software version string. |
hardware | const char* | Hardware version string. |
author | const char* | Author's name. |
website | const char* | Project website URL. |
compiler | const char* | Compiler name and version. |
buildDate | const char* | Firmware build date. |
buildTime | const char* | Firmware build time. |
Sources: Firmware/App/Service/DataProc/Def/Version.h:30-47
Power_Info_t
This structure is used for both reporting power status and sending power-related commands.
| Field | Type | Description |
|---|---|---|
cmd | POWER_CMD | Command to execute (e.g., SHUTDOWN, REBOOT). |
isReady | bool | Power system status. |
isCharging | bool | true if the battery is charging. |
isBatteryLow | bool | true if the battery level is low. |
level | uint8_t | Battery level percentage. |
voltage | uint16_t | Battery voltage in mV. |
autoShutdownTime | int | Auto-shutdown timeout in seconds. |
Sources: Firmware/App/Service/DataProc/Def/Power.h:29-50
5. System Configuration
Key hardware and software parameters are defined in various configuration header files, allowing for easier adaptation to different hardware revisions or feature toggles.
5.1. Application Configuration
File: Firmware/App/Config/Config.h
| Macro | Default Value | Description |
|---|---|---|
CONFIG_WATCHDOG_TIMEOUT | 10 | Watchdog timeout in seconds. |
Sources: Firmware/App/Config/Config.h:26-28
5.2. HAL Configuration
File: Firmware/Vendor/Artery/Application/HAL/HAL_Config.h
This file defines pin mappings for various hardware components, with support for different hardware versions (v1.1 vs. v1.2).
| Macro | Pin (v1.2) | Pin (v1.1) | Description |
|---|---|---|---|
CONFIG_MOTOR_OUT1_PIN | PA2 | PA2 | Motor control pin 1. |
CONFIG_MOTOR_OUT2_PIN | PA3 | PA3 | Motor control pin 2. |
CONFIG_BUZZ_PIN | PB1 | PB2 | Buzzer control pin. |
CONFIG_BATT_DET_PIN | PB0 | PB1 | Battery voltage detection pin. |
CONFIG_PWR_EN_PIN | PA6 | PA7 | Power enable pin. |
CONFIG_BUTTON_SEL_PIN | PA7 | PB0 | Button input pin. |
Sources: Firmware/Vendor/Artery/Application/HAL/HAL_Config.h:29-50
5.3. MCU and Peripheral Configuration
File: Firmware/Vendor/Artery/Platform/AT32F421/Config/mcu_config.h
This file contains low-level configuration for MCU peripherals.
| Macro | Default Value | Description |
|---|---|---|
SYSTICK_TICK_FREQ | 1000 | System tick frequency in Hz. |
SERIAL_RX_BUFFER_SIZE | 64 | Size of the hardware serial receive buffer. |
WIRE_BUFF_SIZE | 32 | Buffer size for the I2C (Wire) library. |
PWM_RESOLUTION_DEFAULT | 1000 | Default resolution for PWM signals. |
PWM_FREQUENCY_DEFAULT | 10000 | Default frequency for PWM signals. |
Sources: Firmware/Vendor/Artery/Platform/AT32F421/Config/mcu_config.h:21, 24, 40, 70-71