• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

pybricks / pybricks-micropython / 19016791193

02 Nov 2025 06:40PM UTC coverage: 57.167% (-2.6%) from 59.744%
19016791193

Pull #406

github

laurensvalk
bricks/virtualhub: Replace with embedded simulation.

Instead of using the newly introduced simhub alongside the virtualhub, we'll just replace the old one entirely now that it has reached feature parity. We can keep calling it the virtualhub.
Pull Request #406: New virtual hub for more effective debugging

41 of 48 new or added lines in 7 files covered. (85.42%)

414 existing lines in 53 files now uncovered.

4479 of 7835 relevant lines covered (57.17%)

17178392.75 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

22.5
/lib/pbio/sys/command.c
1
// SPDX-License-Identifier: MIT
2
// Copyright (c) 2022-2023 The Pybricks Authors
3

4
#include <assert.h>
5
#include <stdint.h>
6

7
#include <pbdrv/reset.h>
8
#include <pbio/protocol.h>
9
#include <pbsys/command.h>
10
#include <pbsys/config.h>
11
#include <pbsys/host.h>
12
#include <pbsys/storage.h>
13

14
#include "./hmi.h"
15
#include "./storage.h"
16
#include "./program_stop.h"
17

18
static pbsys_command_write_app_data_callback_t write_app_data_callback = NULL;
19

20
/**
21
 * Sets callback for the write program data buffer command.
22
 *
23
 * @param [in]  callback  The callback to set or @c NULL to unset.
24
 */
25
void pbsys_command_set_write_app_data_callback(pbsys_command_write_app_data_callback_t callback) {
×
26
    write_app_data_callback = callback;
×
27
}
×
28

29
/**
30
 * Parses binary data for command and dispatches handler for command.
31
 * @param [in]  data    The raw command data.
32
 * @param [in]  size    The size of @p data in bytes.
33
 */
34
pbio_pybricks_error_t pbsys_command(const uint8_t *data, uint32_t size) {
1✔
35
    assert(data);
1✔
36
    assert(size);
1✔
37

38
    pbio_pybricks_command_t cmd = data[0];
1✔
39

40
    switch (cmd) {
1✔
41

UNCOV
42
        case PBIO_PYBRICKS_COMMAND_STOP_USER_PROGRAM:
×
UNCOV
43
            pbsys_program_stop(false);
×
UNCOV
44
            return PBIO_PYBRICKS_ERROR_OK;
×
45

46
        case PBIO_PYBRICKS_COMMAND_START_USER_PROGRAM: {
×
47
            if (size > 2) {
×
UNCOV
48
                return PBIO_PYBRICKS_ERROR_VALUE_NOT_ALLOWED;
×
49
            }
50
            // Use payload as program ID, otherwise use active user slot.
51
            return pbio_pybricks_error_from_pbio_error(
×
52
                pbsys_main_program_request_start((size == 2 ? data[1] : pbsys_status_get_selected_slot()), PBSYS_MAIN_PROGRAM_START_REQUEST_TYPE_REMOTE));
×
53
        }
54
        #if PBSYS_CONFIG_FEATURE_BUILTIN_USER_PROGRAM_REPL
55
        case PBIO_PYBRICKS_COMMAND_START_REPL:
56
            // Deprecated. For backwards compatibility with Pybricks
57
            // Profile < v1.4.0, make it work anyway.
58
            return pbio_pybricks_error_from_pbio_error(
59
                pbsys_main_program_request_start(PBIO_PYBRICKS_USER_PROGRAM_ID_REPL, PBSYS_MAIN_PROGRAM_START_REQUEST_TYPE_REMOTE));
60
        #endif // PBSYS_CONFIG_FEATURE_BUILTIN_USER_PROGRAM_REPL
61

62
        case PBIO_PYBRICKS_COMMAND_WRITE_USER_PROGRAM_META:
×
63
            return pbio_pybricks_error_from_pbio_error(pbsys_storage_set_program_size(
×
64
                pbio_get_uint32_le(&data[1])));
65

66
        case PBIO_PYBRICKS_COMMAND_WRITE_USER_RAM:
×
67
            return pbio_pybricks_error_from_pbio_error(pbsys_storage_set_program_data(
×
UNCOV
68
                pbio_get_uint32_le(&data[1]), &data[5], size - 5));
×
69

UNCOV
70
        case PBIO_PYBRICKS_COMMAND_REBOOT_TO_UPDATE_MODE:
×
UNCOV
71
            pbdrv_reset(PBDRV_RESET_ACTION_RESET_IN_UPDATE_MODE);
×
UNCOV
72
            return PBIO_PYBRICKS_ERROR_OK;
×
73

74
        case PBIO_PYBRICKS_COMMAND_WRITE_STDIN:
1✔
75
            #if PBSYS_CONFIG_HOST
76
            if (pbsys_host_stdin_get_free() < size - 1) {
1✔
UNCOV
77
                return PBIO_PYBRICKS_ERROR_BUSY;
×
78
            }
79
            pbsys_host_stdin_write(&data[1], size - 1);
1✔
80
            #endif
81
            // If no consumers are configured, goes to "/dev/null" without error
82
            return PBIO_PYBRICKS_ERROR_OK;
1✔
83

84
        case PBIO_PYBRICKS_COMMAND_WRITE_APP_DATA: {
×
85
            if (!write_app_data_callback) {
×
86
                // No errors when no consumer is configured. This avoids errors
87
                // when data is sent after the program ends.
UNCOV
88
                return PBIO_PYBRICKS_ERROR_OK;
×
89
            }
90

91
            // Requires at least the message type and data offset.
92
            if (size <= 3) {
×
UNCOV
93
                return PBIO_PYBRICKS_ERROR_VALUE_NOT_ALLOWED;
×
94
            }
95

96
            uint16_t offset = pbio_get_uint16_le(&data[1]);
×
97
            uint16_t data_size = size - 3;
×
98
            const uint8_t *data_to_write = &data[3];
×
99
            return pbio_pybricks_error_from_pbio_error(write_app_data_callback(offset, data_size, data_to_write));
×
100
        }
UNCOV
101
        default:
×
UNCOV
102
            return PBIO_PYBRICKS_ERROR_INVALID_COMMAND;
×
103
    }
104
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc