-
Notifications
You must be signed in to change notification settings - Fork 51
Expand file tree
/
Copy pathappmanager.h
More file actions
192 lines (164 loc) · 5.54 KB
/
appmanager.h
File metadata and controls
192 lines (164 loc) · 5.54 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
#pragma once
/* appmanager.h
* Routines for managing the loading of applications dynamically
* Each app is loaded with its own stack and heap.
* (https://github.com/pebble-dev)
* RebbleOS
*
* Author: Barry Carter <barry.carter@gmail.com>.
*/
#include "rebble_time.h"
#include "fs.h"
#include "FreeRTOS.h"
#include "task.h"
#include "qalloc.h"
#include "node_list.h"
#include <stdbool.h>
#include "uuid.h"
#include "rocky_js.h"
// TODO Make this dynamic. hacky
#define NUM_APPS 3
#define MAX_APP_STR_LEN 32
typedef struct CoreTimer
{
TickType_t when; /* ticks when this should fire, in ticks since boot */
void (*callback)(struct CoreTimer *); /* always called back on the app thread */
struct CoreTimer *next;
} CoreTimer;
typedef struct AppMessage
{
uint8_t thread_id;
uint8_t command;
void *data;
} AppMessage;
typedef struct ButtonMessage
{
void *callback;
void *clickref;
void *context;
} ButtonMessage;
typedef void (*AppMainHandler)(void);
typedef struct Version {
uint8_t major;
uint8_t minor;
} __attribute__((__packed__)) Version;
typedef struct ApplicationHeader {
char header[8]; // PBLAPP
Version header_version; // version of this header
Version sdk_version; // sdk it was compiled against it seems
Version app_version; // app version
uint16_t app_size; // size of app binary + app header (but not reloc)
uint32_t offset; // beginning of the app binary
uint32_t crc; // data's crc?
char name[MAX_APP_STR_LEN];
char company[MAX_APP_STR_LEN];
uint32_t icon_resource_id;
uint32_t sym_table_addr; // The system will poke the sdk's symbol table address into this field on load
uint32_t flags;
uint32_t reloc_entries_count; // reloc list count
Uuid uuid;
uint32_t resource_crc;
uint32_t resource_timestamp;
uint16_t virtual_size; // The total amount of memory used by the process (.text + .data + .bss)
} __attribute__((__packed__)) ApplicationHeader;
typedef struct App {
uint8_t type; // this will be in flags I presume <-- it is. TODO. Hook flags up
bool is_internal; // is the app baked into flash
struct file app_file;
struct file resource_file; // the file where we are keeping the resources for this app
char *name;
ApplicationHeader *header;
AppMainHandler main; // A shortcut to main
list_node node;
} App;
typedef struct AppTypeHeader {
char at;
char address[8];
char delim;
char type[3];
} AppTypeHeader;
#define APP_BUTTON 0
#define APP_QUIT 1
#define APP_TICK 2
#define APP_DRAW 3
#define APP_TYPE_SYSTEM 0
#define APP_TYPE_FACE 1
#define APP_TYPE_APP 2
/* Running App stuff */
/* Are we loading? */
typedef enum AppThreadState {
AppThreadUnloaded,
AppThreadLoading,
AppThreadLoaded,
AppThreadRunloop,
AppThreadUnloading,
} AppThreadState;
/* We have App
* we want an array of running threads
* These will all be running at the same time
* Here are the types
*/
typedef enum AppThreadType {
AppThreadMainApp,
AppThreadWorker,
AppThreadOverlay,
MAX_APP_THREADS
} AppThreadType;
#define THREAD_MANAGER_APP_LOAD 0
#define THREAD_MANAGER_APP_QUIT_CLEAN 1
/* This struct hold all information about the task that is executing
* There are many runing apps, such as main app, worker or background.
*/
typedef struct app_running_thread_t {
AppThreadType thread_type;
App *app;
AppThreadState status;
void *thread_entry;
TickType_t shutdown_at_tick;
const char *thread_name;
uint8_t thread_priority;
TaskHandle_t task_handle;
StaticTask_t static_task;
size_t stack_size;
size_t heap_size;
StackType_t *stack;
uint8_t *heap;
struct CoreTimer *timer_head;
qarena_t *arena;
struct n_GContext *graphics_context;
rocky_thread_state rocky_state;
} app_running_thread;
/* in appmanager.c */
uint8_t appmanager_init(void);
void appmanager_timer_add(CoreTimer *timer);
void appmanager_timer_remove(CoreTimer *timer);
void app_event_loop(void);
bool appmanager_post_generic_thread_message(AppMessage *am, TickType_t timeout);
app_running_thread *appmanager_get_current_thread(void);
App *appmanager_get_current_app(void);
bool appmanager_is_thread_system(void);
bool appmanager_is_thread_worker(void);
bool appmanager_is_thread_app(void);
bool appmanager_is_thread_overlay(void);
void appmanager_load_app(app_running_thread *thread, ApplicationHeader *header);
void appmanager_execute_app(app_running_thread *thread, uint32_t total_app_size);
app_running_thread *appmanager_get_thread(AppThreadType type);
AppThreadType appmanager_get_thread_type(void);
/* in appmanager_app_runloop.c */
void appmanager_app_runloop_init(void);
void appmanager_app_main_entry(void);
list_head *app_manager_get_apps_head();
void appmanager_post_button_message(ButtonMessage *bmessage);
void appmanager_post_draw_message(uint8_t force);
void appmanager_post_draw_display_message(uint8_t *draw_to_display);
void appmanager_app_start(char *name);
void appmanager_app_quit(void);
void appmanager_app_display_done(void);
bool appmanager_is_app_shutting_down(void);
void appmanager_post_generic_app_message(AppMessage *am, TickType_t timeout);
void appmanager_timer_expired(app_running_thread *thread);
TickType_t appmanager_timer_get_next_expiry(app_running_thread *thread);
/* in appmanager_app.c */
App *appmanager_get_app(char *app_name);
void appmanager_app_loader_init(void);
void timer_init(void);