blob: 4da3eebc4e6795399679bd543574c0301c6287c6 [file] [log] [blame]
Fabio Utzigd7f6c762017-07-27 20:50:50 -03001/*
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing,
13 * software distributed under the License is distributed on an
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 * KIND, either express or implied. See the License for the
16 * specific language governing permissions and limitations
17 * under the License.
18 */
19
20#include "syscfg/syscfg.h"
21#include "sysinit/sysinit.h"
22#include "sysflash/sysflash.h"
23#include <os/os.h>
24#include <bsp/bsp.h>
25#include <hal/hal_gpio.h>
26#include <hal/hal_flash.h>
27#include <console/console.h>
28#include <shell/shell.h>
29#include <log/log.h>
30#include <stats/stats.h>
31#include <config/config.h>
Andrzej Puzdrowskib788c712018-04-12 12:42:49 +020032#include "flash_map_backend/flash_map_backend.h"
Fabio Utzigd7f6c762017-07-27 20:50:50 -030033#include <hal/hal_system.h>
34#if MYNEWT_VAL(SPLIT_LOADER)
35#include "split/split.h"
36#endif
37#include <newtmgr/newtmgr.h>
38#include <bootutil/image.h>
39#include <bootutil/bootutil.h>
40#include <imgmgr/imgmgr.h>
41#include <assert.h>
42#include <string.h>
43#include <reboot/log_reboot.h>
44#include <os/os_time.h>
45#include <id/id.h>
46
47#ifdef ARCH_sim
48#include <mcu/mcu_sim.h>
49#endif
50
51/* Task 1 */
52#define TASK1_PRIO (8)
53#define TASK1_STACK_SIZE OS_STACK_ALIGN(192)
54#define MAX_CBMEM_BUF 600
55static struct os_task task1;
56static volatile int g_task1_loops;
57
58/* Task 2 */
59#define TASK2_PRIO (9)
60#define TASK2_STACK_SIZE OS_STACK_ALIGN(64)
61static struct os_task task2;
62
63static struct log my_log;
64
65static volatile int g_task2_loops;
66
67/* Global test semaphore */
68static struct os_sem g_test_sem;
69
70/* For LED toggling */
71static int g_led_pin;
72
73STATS_SECT_START(gpio_stats)
74STATS_SECT_ENTRY(toggles)
75STATS_SECT_END
76
77static STATS_SECT_DECL(gpio_stats) g_stats_gpio_toggle;
78
79static STATS_NAME_START(gpio_stats)
80STATS_NAME(gpio_stats, toggles)
81STATS_NAME_END(gpio_stats)
82
83static char *test_conf_get(int argc, char **argv, char *val, int max_len);
84static int test_conf_set(int argc, char **argv, char *val);
85static int test_conf_commit(void);
86static int test_conf_export(void (*export_func)(char *name, char *val),
87 enum conf_export_tgt tgt);
88
89static struct conf_handler test_conf_handler = {
90 .ch_name = "test",
91 .ch_get = test_conf_get,
92 .ch_set = test_conf_set,
93 .ch_commit = test_conf_commit,
94 .ch_export = test_conf_export
95};
96
97static uint8_t test8;
98static uint8_t test8_shadow;
99static char test_str[32];
100static uint32_t cbmem_buf[MAX_CBMEM_BUF];
101static struct cbmem cbmem;
102
103static char *
104test_conf_get(int argc, char **argv, char *buf, int max_len)
105{
106 if (argc == 1) {
107 if (!strcmp(argv[0], "8")) {
108 return conf_str_from_value(CONF_INT8, &test8, buf, max_len);
109 } else if (!strcmp(argv[0], "str")) {
110 return test_str;
111 }
112 }
113 return NULL;
114}
115
116static int
117test_conf_set(int argc, char **argv, char *val)
118{
119 if (argc == 1) {
120 if (!strcmp(argv[0], "8")) {
121 return CONF_VALUE_SET(val, CONF_INT8, test8_shadow);
122 } else if (!strcmp(argv[0], "str")) {
123 return CONF_VALUE_SET(val, CONF_STRING, test_str);
124 }
125 }
126 return OS_ENOENT;
127}
128
129static int
130test_conf_commit(void)
131{
132 test8 = test8_shadow;
133
134 return 0;
135}
136
137static int
138test_conf_export(void (*func)(char *name, char *val), enum conf_export_tgt tgt)
139{
140 char buf[4];
141
142 conf_str_from_value(CONF_INT8, &test8, buf, sizeof(buf));
143 func("test/8", buf);
144 func("test/str", test_str);
145 return 0;
146}
147
148static void
149task1_handler(void *arg)
150{
151 struct os_task *t;
152 int prev_pin_state, curr_pin_state;
153 struct image_version ver;
154
155 /* Set the led pin for the E407 devboard */
156 g_led_pin = LED_BLINK_PIN;
157 hal_gpio_init_out(g_led_pin, 1);
158
159 if (imgr_my_version(&ver) == 0) {
160 console_printf("\nSlinky %u.%u.%u.%u\n",
161 ver.iv_major, ver.iv_minor, ver.iv_revision,
162 (unsigned int)ver.iv_build_num);
163 } else {
164 console_printf("\nSlinky\n");
165 }
166
167 while (1) {
168 t = os_sched_get_current_task();
169 assert(t->t_func == task1_handler);
170
171 ++g_task1_loops;
172
173 /* Wait one second */
174 os_time_delay(OS_TICKS_PER_SEC / MYNEWT_VAL(BLINKY_TICKS_PER_SEC));
175
176 /* Toggle the LED */
177 prev_pin_state = hal_gpio_read(g_led_pin);
178 curr_pin_state = hal_gpio_toggle(g_led_pin);
179 LOG_INFO(&my_log, LOG_MODULE_DEFAULT, "GPIO toggle from %u to %u",
180 prev_pin_state, curr_pin_state);
181 STATS_INC(g_stats_gpio_toggle, toggles);
182
183 /* Release semaphore to task 2 */
184 os_sem_release(&g_test_sem);
185 }
186}
187
188static void
189task2_handler(void *arg)
190{
191 struct os_task *t;
192
193 while (1) {
194 /* just for debug; task 2 should be the running task */
195 t = os_sched_get_current_task();
196 assert(t->t_func == task2_handler);
197
198 /* Increment # of times we went through task loop */
199 ++g_task2_loops;
200
201 /* Wait for semaphore from ISR */
202 os_sem_pend(&g_test_sem, OS_TIMEOUT_NEVER);
203 }
204}
205
206/**
207 * init_tasks
208 *
209 * Called by main.c after sysinit(). This function performs initializations
210 * that are required before tasks are running.
211 *
212 * @return int 0 success; error otherwise.
213 */
214static void
215init_tasks(void)
216{
217 os_stack_t *pstack;
218
219 /* Initialize global test semaphore */
220 os_sem_init(&g_test_sem, 0);
221
222 pstack = malloc(sizeof(os_stack_t)*TASK1_STACK_SIZE);
223 assert(pstack);
224
225 os_task_init(&task1, "task1", task1_handler, NULL,
226 TASK1_PRIO, OS_WAIT_FOREVER, pstack, TASK1_STACK_SIZE);
227
228 pstack = malloc(sizeof(os_stack_t)*TASK2_STACK_SIZE);
229 assert(pstack);
230
231 os_task_init(&task2, "task2", task2_handler, NULL,
232 TASK2_PRIO, OS_WAIT_FOREVER, pstack, TASK2_STACK_SIZE);
233}
234
235int read_random_data(void);
236
237/**
238 * main
239 *
240 * The main task for the project. This function initializes the packages, calls
241 * init_tasks to initialize additional tasks (and possibly other objects),
242 * then starts serving events from default event queue.
243 *
244 * @return int NOTE: this function should never return!
245 */
246int
247main(int argc, char **argv)
248{
249 int rc;
250
251#ifdef ARCH_sim
252 mcu_sim_parse_args(argc, argv);
253#endif
254
255 sysinit();
256
257 rc = conf_register(&test_conf_handler);
258 assert(rc == 0);
259
260 cbmem_init(&cbmem, cbmem_buf, MAX_CBMEM_BUF);
261 log_register("log", &my_log, &log_cbmem_handler, &cbmem, LOG_SYSLEVEL);
262
263 stats_init(STATS_HDR(g_stats_gpio_toggle),
264 STATS_SIZE_INIT_PARMS(g_stats_gpio_toggle, STATS_SIZE_32),
265 STATS_NAME_INIT_PARMS(gpio_stats));
266
267 stats_register("gpio_toggle", STATS_HDR(g_stats_gpio_toggle));
268
269 conf_load();
270
271 reboot_start(hal_reset_cause());
272
273 (void) read_random_data();
274
275 init_tasks();
276
277 /* If this app is acting as the loader in a split image setup, jump into
278 * the second stage application instead of starting the OS.
279 */
280#if MYNEWT_VAL(SPLIT_LOADER)
281 {
282 void *entry;
283 rc = split_app_go(&entry, true);
284 if(rc == 0) {
285 hal_system_restart(entry);
286 }
287 }
288#endif
289
290 /*
291 * As the last thing, process events from default event queue.
292 */
293 while (1) {
294 os_eventq_run(os_eventq_dflt_get());
295 }
296}