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,31 @@
/*
* 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.
*/
#pragma once
/*
* chip_id.h
*
* This file specifies IDs for the different processors on our multi-processor devices.
* The IDs are used to differenetiate the source of system logs, core dumps, etc.
*
* The IDs must be unique within a platform and must fit in 2 bits.
* If we build a device with more than 4 log/core dump producing processors, this will need to be
* addressed.
*/
#define CORE_ID_MAIN_MCU 0
#define CORE_ID_BLE 1

View File

@@ -0,0 +1,59 @@
/*
* 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.
*/
#pragma once
/*
* core_dump_structs.h
*
* This file specifies core_dump structures previously defined in fw/kernel/core_dump_private.h
* This is so the Dialog BLE core_dump code can use the same structures.
*
*/
#include "portmacro.h"
#include "util/attributes.h"
// Structure of thread info stored within a CORE_DUMP_CHUNK_KEY_THREAD chunk in the core dump
#define CORE_DUMP_THREAD_NAME_SIZE 16
typedef struct PACKED {
int8_t name[CORE_DUMP_THREAD_NAME_SIZE]; // Name, includes null termination
uint32_t id; // thread id
uint8_t running; // true if this thread is running
uint32_t registers[portCANONICAL_REG_COUNT]; // registers [r0-r12, sp, lr, pc, xpsr]
} CoreDumpThreadInfo;
// Structure of extra registers stored within a CORE_DUMP_CHUNK_KEY_EXTRA_REG chunk in the
// core dump
typedef struct PACKED {
uint32_t msp;
uint32_t psp;
uint8_t primask;
uint8_t basepri;
uint8_t faultmask;
uint8_t control;
} CoreDumpExtraRegInfo;
// We save all the important registers on entry to core_dump_reset() in a structure of this type
// on the core_dump_reset() stack and save a pointer to it in the s_saved_registers global.
// IMPORTANT!: There is assembly code near the top of core_dump_reset() that makes assumptions
// about the order and packing of this structure.
typedef struct PACKED {
uint32_t core_reg[portCANONICAL_REG_COUNT];
CoreDumpExtraRegInfo extra_reg;
} CoreDumpSavedRegisters;

141
src/include/pebbleos/cron.h Normal file
View File

@@ -0,0 +1,141 @@
/*
* 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.
*/
#pragma once
#include <time.h>
#include "util/list.h"
//! @file cron.h
//! Wall-clock based timer system. Designed for use in things such as alarms, calendar events, etc.
//! Properly handles DST, etc.
typedef struct CronJob CronJob;
typedef void (*CronJobCallback)(CronJob *job, void* data);
//! Matches any possible value.
#define CRON_MINUTE_ANY (-1)
#define CRON_HOUR_ANY (-1)
#define CRON_MDAY_ANY (-1)
#define CRON_MONTH_ANY (-1)
#define WDAY_SUNDAY (1 << 0)
#define WDAY_MONDAY (1 << 1)
#define WDAY_TUESDAY (1 << 2)
#define WDAY_WEDNESDAY (1 << 3)
#define WDAY_THURSDAY (1 << 4)
#define WDAY_FRIDAY (1 << 5)
#define WDAY_SATURDAY (1 << 6)
#define WDAY_WEEKDAYS (WDAY_MONDAY | WDAY_TUESDAY | WDAY_WEDNESDAY | WDAY_THURSDAY | WDAY_FRIDAY)
#define WDAY_WEEKENDS (WDAY_SUNDAY | WDAY_SATURDAY)
#define WDAY_ANY (WDAY_WEEKENDS | WDAY_WEEKDAYS)
struct CronJob {
//! internal, no touchy
ListNode list_node;
//! Cached execution timestamp in UTC.
//! This is set by `cron_job_schedule`, and is required to never be changed once the job has been
//! added.
time_t cached_execute_time;
//! Callback that is called when the job fires.
CronJobCallback cb;
void* cb_data;
//! Occasionally, the system gets a clock change event for various reasons:
//! - User changed time-zones or a DST transition happened
//! - User changed the time
//! - Phone sent the current time and was different from ours, so we took theirs.
//! In the first case, the cron job's execute time will always be recalculated.
//! In the other two, we see if the time difference from the old time is >= this.
//! If it is, then we'll recalculate. Otherwise, we leave the calculated time alone.
//! In this way, 0 will always recalculate, and UINT32_MAX will never recalculate.
//!
//! Recalculating would essentially mean that a job that was "skipped over" will not fire until
//! the next match. If recalculation is not done, but the job was skipped over, it will fire
//! instantly.
//!
//! This value is specified in seconds.
uint32_t clock_change_tolerance;
int8_t minute; //!< 0-59, or CRON_MINUTE_ANY
int8_t hour; //!< 0-23, or CRON_HOUR_ANY
int8_t mday; //!< 0-30, or CRON_MDAY_ANY
int8_t month; //!< 0-11, or CRON_MONTH_ANY
//! Seconds to offset the cron execution time applied after regular cron job time calculation.
//! For example, a cron scheduled for Monday at 0:15 with an offset of negative 30min will fire
//! on Sunday at 23:45.
int32_t offset_seconds;
union {
uint8_t flags;
struct {
//! This should be any combination of WDAY_*. If zero, acts like WDAY_ANY.
uint8_t wday : 7;
//! If this flag is set, the resulting execution time may be equal to the local epoch.
//! Having it set could be used for some event that must happen at the specified time even if
//! that time is right now.
bool may_be_instant : 1;
};
};
};
//! Add a cron job. This will make the service hold a reference to the specified job, so it must
//! not leave scope or be destroyed until it is unscheduled.
//! The job only gets scheduled once. For re-scheduling, you can call this on the job again.
//! @params job pointer to the CronJob struct to be scheduled.
//! @returns time_t for when the job is destined to go off.
time_t cron_job_schedule(CronJob *job);
//! Schedule a cron job to run after another cron job.
//! This will make the service hold a reference to the new job, so it must
//! not leave scope or be destroyed until it is unscheduled.
//! @param job pointer to the CronJob after which we want our job to run. job must be scheduled.
//! @params new_job pointer to the CronJob struct to be scheduled. new_job must be unscheduled.
//! @returns time_t for when the job is destined to go off.
//! @note This API makes no guarantee that the two jobs will be scheduled back to back,
//! only that new_job will have the same scheduled time as job and that it will trigger
//! strictly after job.
time_t cron_job_schedule_after(CronJob *new_job, CronJob *job);
//! Remove a scheduled cron job.
//! @params job pointer to the CronJob struct to be unscheduled.
//! @return true if the job was successfully removed (false may indicate no job was
//! scheduled at all or the cb is currently executing)
bool cron_job_unschedule(CronJob *job);
//! Check if a cron job is scheduled.
//! @params job pointer to the CronJob struct to be checked for being scheduled.
//! @returns true if scheduled or pending deletion, false otherwise
bool cron_job_is_scheduled(CronJob *job);
//! Calculate cron job's destined execution time, from the current time.
//! @params job pointer to the CronJob struct to get the execution time for.
//! @returns time_t for when the job is destined to go off.
time_t cron_job_get_execute_time(const CronJob *job);
//! Calculate cron job's destined execution time if it were scheduled at the given time.
//! @params job pointer to the CronJob struct to get the execution time for.
//! @params local_epoch the epoch for getting the job's execution time.
//! @returns time_t for when the job is destined to go off.
time_t cron_job_get_execute_time_from_epoch(const CronJob *job, time_t local_epoch);

View File

@@ -0,0 +1,138 @@
/*
* 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.
*/
#pragma once
/*
* firmware_metadata.h
*
* This file specifies the Firmware Metadata structure used in the .elf & .bin files to
* identify the build info, etc.
*/
#include "util/attributes.h"
#include <stdint.h>
#include <stdbool.h>
#define FW_METADATA_CURRENT_STRUCT_VERSION 0x1
#define FW_METADATA_VERSION_SHORT_BYTES 8
#define FW_METADATA_VERSION_TAG_BYTES 32
// NOTE: When adding new platforms, if they use the legacy defective CRC, the list in
// tools/fw_binary_info.py needs to be updated with the platform value.
typedef enum FirmwareMetadataPlatform {
FirmwareMetadataPlatformUnknown = 0,
FirmwareMetadataPlatformPebbleOneEV1 = 1,
FirmwareMetadataPlatformPebbleOneEV2 = 2,
FirmwareMetadataPlatformPebbleOneEV2_3 = 3,
FirmwareMetadataPlatformPebbleOneEV2_4 = 4,
FirmwareMetadataPlatformPebbleOnePointFive = 5,
FirmwareMetadataPlatformPebbleTwoPointZero = 6,
FirmwareMetadataPlatformPebbleSnowyEVT2 = 7,
FirmwareMetadataPlatformPebbleSnowyDVT = 8,
FirmwareMetadataPlatformPebbleSpaldingEVT = 9,
FirmwareMetadataPlatformPebbleBobbyDVT = 10,
FirmwareMetadataPlatformPebbleSpalding = 11,
FirmwareMetadataPlatformPebbleSilkEVT = 12,
FirmwareMetadataPlatformPebbleRobertEVT = 13,
FirmwareMetadataPlatformPebbleSilk = 14,
FirmwareMetadataPlatformPebbleOneBigboard = 0xff,
FirmwareMetadataPlatformPebbleOneBigboard2 = 0xfe,
FirmwareMetadataPlatformPebbleSnowyBigboard = 0xfd,
FirmwareMetadataPlatformPebbleSnowyBigboard2 = 0xfc,
FirmwareMetadataPlatformPebbleSpaldingBigboard = 0xfb,
FirmwareMetadataPlatformPebbleSilkBigboard = 0xfa,
FirmwareMetadataPlatformPebbleRobertBigboard = 0xf9,
FirmwareMetadataPlatformPebbleSilkBigboard2 = 0xf8,
FirmwareMetadataPlatformPebbleRobertBigboard2 = 0xf7,
} FirmwareMetadataPlatform;
// WARNING: changes in this struct must be reflected in:
// - iOS/PebblePrivateKit/PebblePrivateKit/PBBundle.m
struct PACKED FirmwareMetadata {
uint32_t version_timestamp;
char version_tag[FW_METADATA_VERSION_TAG_BYTES];
char version_short[FW_METADATA_VERSION_SHORT_BYTES];
bool is_recovery_firmware:1;
bool is_ble_firmware:1;
uint8_t reserved:6;
uint8_t hw_platform;
//! This should be the last field, since we put the meta data struct at the end of the fw binary.
uint8_t metadata_version;
};
typedef struct FirmwareMetadata FirmwareMetadata;
_Static_assert(sizeof(struct FirmwareMetadata) == (sizeof(uint32_t) +
FW_METADATA_VERSION_SHORT_BYTES + FW_METADATA_VERSION_TAG_BYTES + sizeof(uint8_t) +
sizeof(uint8_t) + sizeof(uint8_t)),
"FirmwareMetadata bitfields not packed correctly");
// Shared defines. Let's not duplicate this everywhere.
#ifdef RECOVERY_FW
#define FIRMWARE_METADATA_IS_RECOVERY_FIRMWARE (true)
#else
#define FIRMWARE_METADATA_IS_RECOVERY_FIRMWARE (false)
#endif
#if BOARD_BIGBOARD
#define FIRMWARE_METADATA_HW_PLATFORM (FirmwareMetadataPlatformPebbleOneBigboard)
#elif BOARD_BB2
#define FIRMWARE_METADATA_HW_PLATFORM (FirmwareMetadataPlatformPebbleOneBigboard2)
#elif BOARD_SNOWY_BB
#define FIRMWARE_METADATA_HW_PLATFORM (FirmwareMetadataPlatformPebbleSnowyBigboard)
#elif BOARD_SNOWY_BB2
#define FIRMWARE_METADATA_HW_PLATFORM (FirmwareMetadataPlatformPebbleSnowyBigboard2)
#elif BOARD_SNOWY_EVT2
#define FIRMWARE_METADATA_HW_PLATFORM (FirmwareMetadataPlatformPebbleSnowyEVT2)
#elif BOARD_SNOWY_DVT
#define FIRMWARE_METADATA_HW_PLATFORM (FirmwareMetadataPlatformPebbleSnowyDVT)
#elif BOARD_SNOWY_S3
#define FIRMWARE_METADATA_HW_PLATFORM (FirmwareMetadataPlatformPebbleBobbyDVT)
#elif BOARD_V2_0
#define FIRMWARE_METADATA_HW_PLATFORM (FirmwareMetadataPlatformPebbleTwoPointZero)
#elif BOARD_V1_5
#define FIRMWARE_METADATA_HW_PLATFORM (FirmwareMetadataPlatformPebbleOnePointFive)
#elif BOARD_EV2_4
#define FIRMWARE_METADATA_HW_PLATFORM (FirmwareMetadataPlatformPebbleOneEV2_4)
#elif BOARD_SPALDING_BB2
#define FIRMWARE_METADATA_HW_PLATFORM (FirmwareMetadataPlatformPebbleSpaldingBigboard)
#elif BOARD_SPALDING_EVT
#define FIRMWARE_METADATA_HW_PLATFORM (FirmwareMetadataPlatformPebbleSpaldingEVT)
#elif BOARD_SPALDING
#define FIRMWARE_METADATA_HW_PLATFORM (FirmwareMetadataPlatformPebbleSpalding)
#elif BOARD_SILK_EVT
#define FIRMWARE_METADATA_HW_PLATFORM (FirmwareMetadataPlatformPebbleSilkEVT)
#elif BOARD_SILK_BB
#define FIRMWARE_METADATA_HW_PLATFORM (FirmwareMetadataPlatformPebbleSilkBigboard)
#elif BOARD_SILK
#define FIRMWARE_METADATA_HW_PLATFORM (FirmwareMetadataPlatformPebbleSilk)
#elif BOARD_SILK_BB2
#define FIRMWARE_METADATA_HW_PLATFORM (FirmwareMetadataPlatformPebbleSilkBigboard2)
#elif BOARD_ROBERT_BB
#define FIRMWARE_METADATA_HW_PLATFORM (FirmwareMetadataPlatformPebbleRobertBigboard)
#elif BOARD_ROBERT_BB2
#define FIRMWARE_METADATA_HW_PLATFORM (FirmwareMetadataPlatformPebbleRobertBigboard2)
#elif BOARD_ROBERT_EVT
#define FIRMWARE_METADATA_HW_PLATFORM (FirmwareMetadataPlatformPebbleRobertEVT)
#else
#define FIRMWARE_METADATA_HW_PLATFORM (FirmwareMetadataPlatformUnknown)
#endif