Import of the watch repository from Pebble

This commit is contained in:
Matthieu Jeanson 2024-12-12 16:43:03 -08:00 committed by Katharine Berry
commit 3b92768480
10334 changed files with 2564465 additions and 0 deletions

View file

@ -0,0 +1,238 @@
/*
* Copyright 2024 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "kernel/util/interval_timer.h"
#include "fakes/fake_rtc.h"
#include "clar.h"
void passert_failed_no_message(const char* filename, int line_number) {
}
void vPortEnterCritical(void) {
}
void vPortExitCritical(void) {
}
void test_interval_timer__initialize(void) {
fake_rtc_init(0, 0);
}
void test_interval_timer__simple(void) {
IntervalTimer timer;
interval_timer_init(&timer, 0, UINT32_MAX, 2);
uint32_t num_intervals;
uint32_t average_ms;
num_intervals = interval_timer_get(&timer, &average_ms);
cl_assert_equal_i(num_intervals, 0);
cl_assert_equal_i(average_ms, 0);
interval_timer_take_sample(&timer);
num_intervals = interval_timer_get(&timer, &average_ms);
cl_assert_equal_i(num_intervals, 0);
cl_assert_equal_i(average_ms, 0);
fake_rtc_increment_time_ms(1000);
interval_timer_take_sample(&timer);
num_intervals = interval_timer_get(&timer, &average_ms);
cl_assert_equal_i(num_intervals, 1);
cl_assert_equal_i(average_ms, 1000);
fake_rtc_increment_time_ms(1000);
interval_timer_take_sample(&timer);
num_intervals = interval_timer_get(&timer, &average_ms);
cl_assert_equal_i(num_intervals, 2);
cl_assert_equal_i(average_ms, 1000);
fake_rtc_increment_time_ms(1030);
interval_timer_take_sample(&timer);
// = 1000 + (0.5 * (1030 - 1000))
// = 1000 + (0.5 * 30)
// = 1015
num_intervals = interval_timer_get(&timer, &average_ms);
cl_assert_equal_i(num_intervals, 3);
cl_assert_equal_i(average_ms, 1015);
}
void test_interval_timer__invalid_samples(void) {
IntervalTimer timer;
interval_timer_init(&timer, 800, 1200, 2);
uint32_t num_intervals;
uint32_t average_ms;
interval_timer_take_sample(&timer);
fake_rtc_increment_time_ms(1000);
interval_timer_take_sample(&timer);
num_intervals = interval_timer_get(&timer, &average_ms);
cl_assert_equal_i(num_intervals, 1);
cl_assert_equal_i(average_ms, 1000);
// valid interval
fake_rtc_increment_time_ms(1020);
interval_timer_take_sample(&timer);
num_intervals = interval_timer_get(&timer, &average_ms);
cl_assert_equal_i(num_intervals, 2);
cl_assert_equal_i(average_ms, 1010);
// invalid interval, too high
fake_rtc_increment_time_ms(1220);
interval_timer_take_sample(&timer);
num_intervals = interval_timer_get(&timer, &average_ms);
cl_assert_equal_i(num_intervals, 2);
cl_assert_equal_i(average_ms, 1010);
// invalid interval, too low
fake_rtc_increment_time_ms(780);
interval_timer_take_sample(&timer);
num_intervals = interval_timer_get(&timer, &average_ms);
cl_assert_equal_i(num_intervals, 2);
cl_assert_equal_i(average_ms, 1010);
// valid interval
fake_rtc_increment_time_ms(1010);
interval_timer_take_sample(&timer);
num_intervals = interval_timer_get(&timer, &average_ms);
cl_assert_equal_i(num_intervals, 3);
cl_assert_equal_i(average_ms, 1010);
}
// Make sure we don't run into any issues when our internals are close to UINT32_MAX
void test_interval_timer__big_interval(void) {
IntervalTimer timer;
interval_timer_init(&timer, 0, UINT32_MAX, 2);
uint32_t num_intervals;
uint32_t average_ms;
interval_timer_take_sample(&timer);
fake_rtc_increment_time_ms(3000000000);
interval_timer_take_sample(&timer);
num_intervals = interval_timer_get(&timer, &average_ms);
cl_assert_equal_i(num_intervals, 1);
cl_assert_equal_i(average_ms, 3000000000);
fake_rtc_increment_time_ms(3000000000);
interval_timer_take_sample(&timer);
num_intervals = interval_timer_get(&timer, &average_ms);
cl_assert_equal_i(num_intervals, 2);
cl_assert_equal_i(average_ms, 3000000000);
fake_rtc_increment_time_ms(3000000000);
interval_timer_take_sample(&timer);
num_intervals = interval_timer_get(&timer, &average_ms);
cl_assert_equal_i(num_intervals, 3);
cl_assert_equal_i(average_ms, 3000000000);
}
void test_interval_timer__moving_average(void) {
IntervalTimer timer;
interval_timer_init(&timer, 0, UINT32_MAX, 4);
uint32_t num_intervals;
uint32_t average_ms;
interval_timer_take_sample(&timer);
fake_rtc_increment_time_ms(1000);
interval_timer_take_sample(&timer);
num_intervals = interval_timer_get(&timer, &average_ms);
cl_assert_equal_i(num_intervals, 1);
cl_assert_equal_i(average_ms, 1000);
fake_rtc_increment_time_ms(1020);
interval_timer_take_sample(&timer);
// = 1000 + (0.25 * (1020 - 1000))
// = 1000 + (0.25 * 20)
// = 1005
num_intervals = interval_timer_get(&timer, &average_ms);
cl_assert_equal_i(num_intervals, 2);
cl_assert_equal_i(average_ms, 1005);
fake_rtc_increment_time_ms(1010);
interval_timer_take_sample(&timer);
// = 1005 + (0.25 * (1010 - 1005))
// = 1005 + (0.25 * 5)
// = 1006
num_intervals = interval_timer_get(&timer, &average_ms);
cl_assert_equal_i(num_intervals, 3);
cl_assert_equal_i(average_ms, 1006);
fake_rtc_increment_time_ms(1010);
interval_timer_take_sample(&timer);
num_intervals = interval_timer_get(&timer, &average_ms);
cl_assert_equal_i(num_intervals, 4);
cl_assert_equal_i(average_ms, 1007);
fake_rtc_increment_time_ms(1030);
interval_timer_take_sample(&timer);
// = 1007 + (0.25 * (1030 - 1007))
// = 1007 + (0.25 * 23)
// = 1007 + 5
// = 1012
num_intervals = interval_timer_get(&timer, &average_ms);
cl_assert_equal_i(num_intervals, 5);
cl_assert_equal_i(average_ms, 1012);
fake_rtc_increment_time_ms(1030);
interval_timer_take_sample(&timer);
num_intervals = interval_timer_get(&timer, &average_ms);
cl_assert_equal_i(num_intervals, 6);
cl_assert_equal_i(average_ms, 1016);
// Take a bunch of samples to make sure the moving average moves up to the new interval
for (int i = 0; i < 10; ++i) {
fake_rtc_increment_time_ms(1030);
interval_timer_take_sample(&timer);
}
num_intervals = interval_timer_get(&timer, &average_ms);
cl_assert_equal_i(num_intervals, 16);
// Close enough, rounding issues will prevent us from every actually hitting 1030
// = 1027 + (0.25 * (1030 - 1027))
// = 1027 + (0.25 * 3)
// = 1027
cl_assert_equal_i(average_ms, 1027);
}

View file

@ -0,0 +1,223 @@
/*
* Copyright 2024 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "clar.h"
#include "kernel/pulse_logging.h"
// How many bytes are in a log message before the actual message content in pulse log messages
const int LOG_METADATA_LENGTH = 29;
// Stubs
///////////////////////////////////////////////////////////
#include "kernel/events.h"
#include "kernel/pebble_tasks.h"
#include "FreeRTOS.h"
#include "task.h"
static int s_num_event_puts;
static PebbleEvent s_last_event;
bool event_put_isr(PebbleEvent *e) {
cl_assert_equal_i(e->type, PEBBLE_CALLBACK_EVENT);
++s_num_event_puts;
s_last_event = *e;
return true;
}
char pbl_log_get_level_char(const uint8_t log_level) {
return 'L';
}
char pebble_task_get_char(PebbleTask task) {
return 'T';
}
PebbleTask pebble_task_get_current(void) {
return PebbleTask_Unknown;
}
void *pulse_best_effort_send_begin(uint16_t protocol) {
static char buffer[1024];
return buffer;
// todo
}
static int s_num_packets_sent = 0;
static int s_num_bytes_sent = 0;
static char s_log_message_buffer[256];
void pulse_best_effort_send(void *buf, size_t length) {
++s_num_packets_sent;
s_num_bytes_sent += length;
const size_t message_length = length - LOG_METADATA_LENGTH;
memcpy(s_log_message_buffer, ((char*) buf) + LOG_METADATA_LENGTH, message_length);
s_log_message_buffer[message_length] = '\0';
}
bool pulse_is_started(void) {
return true;
}
void rtc_get_time_ms(time_t* out_seconds, uint16_t* out_ms) {
*out_seconds = 0;
*out_ms = 0;
}
void vPortEnterCritical(void) {
}
void vPortExitCritical(void) {
}
bool s_in_critical_section;
bool vPortInCritical(void) {
return s_in_critical_section;
}
BaseType_t xTaskGetSchedulerState(void) {
return taskSCHEDULER_RUNNING;
}
// Tests
///////////////////////////////////////////////////////////
void test_pulse_logging__initialize(void) {
s_num_event_puts = 0;
s_last_event = (PebbleEvent) { 0 };
s_num_packets_sent = 0;
s_num_bytes_sent = 0;
s_log_message_buffer[0] = '\0';
s_in_critical_section = false;
pulse_logging_init();
}
void test_pulse_logging__simple(void) {
pulse_logging_log(LOG_LEVEL_DEBUG, "", 0, "Test");
cl_assert_equal_i(s_num_event_puts, 0);
cl_assert_equal_i(s_num_packets_sent, 1);
cl_assert_equal_i(s_num_bytes_sent, LOG_METADATA_LENGTH + 4);
cl_assert_equal_s(s_log_message_buffer, "Test");
s_num_bytes_sent = 0;
pulse_logging_log(LOG_LEVEL_DEBUG, "", 0, "TestTestTestTestTest");
cl_assert_equal_i(s_num_event_puts, 0);
cl_assert_equal_i(s_num_packets_sent, 2);
cl_assert_equal_i(s_num_bytes_sent, LOG_METADATA_LENGTH + 20);
cl_assert_equal_s(s_log_message_buffer, "TestTestTestTestTest");
}
void test_pulse_logging__simple_trucate(void) {
pulse_logging_log(LOG_LEVEL_DEBUG, "", 0, "TestTestTestTestTestTestTestTestTestTest"
"TestTestTestTestTestTestTestTestTestTest"
"TestTestTestTestTestTestTestTestTestTest"
"TestTestTestTestTestTestTestTestTestTest");
cl_assert_equal_i(s_num_event_puts, 0);
cl_assert_equal_i(s_num_packets_sent, 1);
cl_assert_equal_i(s_num_bytes_sent, LOG_METADATA_LENGTH + 128);
cl_assert_equal_s(s_log_message_buffer, "TestTestTestTestTestTestTestTestTestTest"
"TestTestTestTestTestTestTestTestTestTest"
"TestTestTestTestTestTestTestTestTestTest"
"TestTest");
}
void test_pulse_logging__isr_simple(void) {
s_in_critical_section = true;
pulse_logging_log(LOG_LEVEL_DEBUG, "", 0, "Test");
cl_assert_equal_i(s_num_event_puts, 1);
s_last_event.callback.callback(NULL);
cl_assert_equal_i(s_num_packets_sent, 1);
cl_assert_equal_i(s_num_bytes_sent, LOG_METADATA_LENGTH + 4);
cl_assert_equal_s(s_log_message_buffer, "Test");
s_num_bytes_sent = 0;
pulse_logging_log(LOG_LEVEL_DEBUG, "", 0, "TestTestTestTestTest");
cl_assert_equal_i(s_num_event_puts, 2);
s_last_event.callback.callback(NULL);
cl_assert_equal_i(s_num_packets_sent, 2);
cl_assert_equal_i(s_num_bytes_sent, LOG_METADATA_LENGTH + 20);
cl_assert_equal_s(s_log_message_buffer, "TestTestTestTestTest");
}
void test_pulse_logging__isr_trucate(void) {
s_in_critical_section = true;
pulse_logging_log(LOG_LEVEL_DEBUG, "", 0, "TestTestTestTestTestTestTestTestTestTest"
"TestTestTestTestTestTestTestTestTestTest"
"TestTestTestTestTestTestTestTestTestTest"
"TestTestTestTestTestTestTestTestTestTest");
cl_assert_equal_i(s_num_event_puts, 1);
s_last_event.callback.callback(NULL);
cl_assert_equal_i(s_num_packets_sent, 1);
cl_assert_equal_i(s_num_bytes_sent, LOG_METADATA_LENGTH + 128);
cl_assert_equal_s(s_log_message_buffer, "TestTestTestTestTestTestTestTestTestTest"
"TestTestTestTestTestTestTestTestTestTest"
"TestTestTestTestTestTestTestTestTestTest"
"TestTest");
}
void test_pulse_logging__isr_buffer_full(void) {
s_in_critical_section = true;
pulse_logging_log(LOG_LEVEL_DEBUG, "", 0, "TestTestTestTestTestTestTestTestTestTestA");
cl_assert_equal_i(s_num_event_puts, 1);
cl_assert_equal_i(s_num_packets_sent, 0);
pulse_logging_log(LOG_LEVEL_DEBUG, "", 0, "TestTestTestTestTestTestTestTestTestTestB");
cl_assert_equal_i(s_num_event_puts, 1);
cl_assert_equal_i(s_num_packets_sent, 0);
pulse_logging_log(LOG_LEVEL_DEBUG, "", 0, "TestTestTestTestTestTestTestTestTestTestC");
cl_assert_equal_i(s_num_event_puts, 1);
cl_assert_equal_i(s_num_packets_sent, 0);
pulse_logging_log(LOG_LEVEL_DEBUG, "", 0, "TestTestTestTestTestTestTestTestTestTestD");
cl_assert_equal_i(s_num_event_puts, 1);
cl_assert_equal_i(s_num_packets_sent, 0);
pulse_logging_log(LOG_LEVEL_DEBUG, "", 0, "TestTestTestTestTestTestTestTestTestTestE");
cl_assert_equal_i(s_num_event_puts, 1);
cl_assert_equal_i(s_num_packets_sent, 0);
pulse_logging_log(LOG_LEVEL_DEBUG, "", 0, "TestTestTestTestTestTestTestTestTestTestF");
cl_assert_equal_i(s_num_event_puts, 1);
cl_assert_equal_i(s_num_packets_sent, 0);
pulse_logging_log(LOG_LEVEL_DEBUG, "", 0, "TestTestTestTestTestTestTestTestTestTestG");
s_last_event.callback.callback(NULL);
cl_assert_equal_i(s_num_packets_sent, 7);
cl_assert_equal_s(s_log_message_buffer, "ISR Message Dropped!");
}

14
tests/fw/kernel/wscript Normal file
View file

@ -0,0 +1,14 @@
from waftools.pebble_test import clar
def build(ctx):
clar(ctx,
sources_ant_glob =
" src/fw/kernel/pulse_logging.c",
test_sources_ant_glob="test_pulse_logging.c")
clar(ctx,
sources_ant_glob =
" src/fw/kernel/util/interval_timer.c"
" tests/fakes/fake_rtc.c",
test_sources_ant_glob="test_interval_timer.c")