blob: 25d621429f640e1a66825b07ac4ecc6e1b41bd45 [file] [log] [blame]
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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 "os/mynewt.h"
#include <bsp/bsp.h>
#include <hal/hal_gpio.h>
#include <hal/hal_flash.h>
#include <console/console.h>
#include <log/log.h>
#include <stats/stats.h>
#include <config/config.h>
#if MYNEWT_VAL(SPLIT_LOADER)
#include "split/split.h"
#endif
#include <bootutil/image.h>
#include <imgmgr/imgmgr.h>
#include <mgmt/mgmt.h>
#include <oic/oc_api.h>
#include <assert.h>
#include <string.h>
#include <reboot/log_reboot.h>
#ifdef ARCH_sim
#include <mcu/mcu_sim.h>
#endif
/* Task 1 */
#define TASK1_PRIO (8)
#define TASK1_STACK_SIZE OS_STACK_ALIGN(192)
#define MAX_CBMEM_BUF 600
static struct os_task task1;
static volatile int g_task1_loops;
/* Task 2 */
#define TASK2_PRIO (9)
#define TASK2_STACK_SIZE OS_STACK_ALIGN(64)
static struct os_task task2;
static struct log my_log;
static volatile int g_task2_loops;
/* Global test semaphore */
static struct os_sem g_test_sem;
/* For LED toggling */
static int g_led_pin;
STATS_SECT_START(gpio_stats)
STATS_SECT_ENTRY(toggles)
STATS_SECT_END
static STATS_SECT_DECL(gpio_stats) g_stats_gpio_toggle;
static STATS_NAME_START(gpio_stats)
STATS_NAME(gpio_stats, toggles)
STATS_NAME_END(gpio_stats)
static char *test_conf_get(int argc, char **argv, char *val, int max_len);
static int test_conf_set(int argc, char **argv, char *val);
static int test_conf_commit(void);
static int test_conf_export(void (*export_func)(char *name, char *val),
enum conf_export_tgt tgt);
static struct conf_handler test_conf_handler = {
.ch_name = "test",
.ch_get = test_conf_get,
.ch_set = test_conf_set,
.ch_commit = test_conf_commit,
.ch_export = test_conf_export
};
static uint8_t test8;
static uint8_t test8_shadow;
static char test_str[32];
static uint32_t cbmem_buf[MAX_CBMEM_BUF];
static struct cbmem cbmem;
static char *
test_conf_get(int argc, char **argv, char *buf, int max_len)
{
if (argc == 1) {
if (!strcmp(argv[0], "8")) {
return conf_str_from_value(CONF_INT8, &test8, buf, max_len);
} else if (!strcmp(argv[0], "str")) {
return test_str;
}
}
return NULL;
}
static int
test_conf_set(int argc, char **argv, char *val)
{
if (argc == 1) {
if (!strcmp(argv[0], "8")) {
return CONF_VALUE_SET(val, CONF_INT8, test8_shadow);
} else if (!strcmp(argv[0], "str")) {
return CONF_VALUE_SET(val, CONF_STRING, test_str);
}
}
return OS_ENOENT;
}
static int
test_conf_commit(void)
{
test8 = test8_shadow;
return 0;
}
static int
test_conf_export(void (*func)(char *name, char *val), enum conf_export_tgt tgt)
{
char buf[4];
conf_str_from_value(CONF_INT8, &test8, buf, sizeof(buf));
func("test/8", buf);
func("test/str", test_str);
return 0;
}
void
task1_handler(void *arg)
{
struct os_task *t;
int prev_pin_state, curr_pin_state;
struct image_version ver;
/* Set the led pin for the E407 devboard */
g_led_pin = LED_BLINK_PIN;
hal_gpio_init_out(g_led_pin, 1);
if (imgr_my_version(&ver) == 0) {
console_printf("\nSlinky_OIC %u.%u.%u.%u\n",
ver.iv_major, ver.iv_minor, ver.iv_revision,
(unsigned int)ver.iv_build_num);
} else {
console_printf("\nSlinky\n");
}
while (1) {
t = os_sched_get_current_task();
assert(t->t_func == task1_handler);
++g_task1_loops;
/* Wait one second */
os_time_delay(OS_TICKS_PER_SEC);
/* Toggle the LED */
prev_pin_state = hal_gpio_read(g_led_pin);
curr_pin_state = hal_gpio_toggle(g_led_pin);
MODLOG_DFLT(INFO, "GPIO toggle from %u to %u",
prev_pin_state, curr_pin_state);
STATS_INC(g_stats_gpio_toggle, toggles);
/* Release semaphore to task 2 */
os_sem_release(&g_test_sem);
}
}
void
task2_handler(void *arg)
{
struct os_task *t;
while (1) {
/* just for debug; task 2 should be the running task */
t = os_sched_get_current_task();
assert(t->t_func == task2_handler);
/* Increment # of times we went through task loop */
++g_task2_loops;
/* Wait for semaphore from ISR */
os_sem_pend(&g_test_sem, OS_TIMEOUT_NEVER);
}
}
/*
* OIC platform/resource registration.
*/
static void
omgr_app_init(void)
{
oc_init_platform("MyNewt", NULL, NULL);
/*
oc_add_device("/oic/d", "oic.d.light", "MynewtLed", "1.0", "1.0", NULL,
NULL);
*/
}
static const oc_handler_t omgr_oc_handler = {
.init = omgr_app_init,
};
/**
* init_tasks
*
* Called by main.c after sysinit(). This function performs initializations
* that are required before tasks are running.
*
* @return int 0 success; error otherwise.
*/
static void
init_tasks(void)
{
os_stack_t *pstack;
/* Initialize global test semaphore */
os_sem_init(&g_test_sem, 0);
pstack = malloc(sizeof(os_stack_t)*TASK1_STACK_SIZE);
assert(pstack);
os_task_init(&task1, "task1", task1_handler, NULL,
TASK1_PRIO, OS_WAIT_FOREVER, pstack, TASK1_STACK_SIZE);
pstack = malloc(sizeof(os_stack_t)*TASK2_STACK_SIZE);
assert(pstack);
os_task_init(&task2, "task2", task2_handler, NULL,
TASK2_PRIO, OS_WAIT_FOREVER, pstack, TASK2_STACK_SIZE);
oc_main_init((oc_handler_t *)&omgr_oc_handler);
}
/**
* main
*
* The main task for the project. This function initializes the packages, calls
* init_tasks to initialize additional tasks (and possibly other objects),
* then starts serving events from default event queue.
*
* @return int NOTE: this function should never return!
*/
int
main(int argc, char **argv)
{
int rc;
#ifdef ARCH_sim
mcu_sim_parse_args(argc, argv);
#endif
sysinit();
rc = conf_register(&test_conf_handler);
assert(rc == 0);
cbmem_init(&cbmem, cbmem_buf, MAX_CBMEM_BUF);
log_register("log", &my_log, &log_cbmem_handler, &cbmem, LOG_SYSLEVEL);
/* Point the default module at the cbmem log just registered. */
rc = modlog_register(LOG_MODULE_DEFAULT, &my_log, LOG_LEVEL_DEBUG, NULL);
assert(rc == 0);
stats_init(STATS_HDR(g_stats_gpio_toggle),
STATS_SIZE_INIT_PARMS(g_stats_gpio_toggle, STATS_SIZE_32),
STATS_NAME_INIT_PARMS(gpio_stats));
stats_register("gpio_toggle", STATS_HDR(g_stats_gpio_toggle));
reboot_start(hal_reset_cause());
#if MYNEWT_VAL(SPLIT_LOADER)
{
void *entry;
rc = split_app_go(&entry, true);
if(rc == 0) {
hal_system_start(entry);
}
}
#endif
init_tasks();
while (1) {
os_eventq_run(os_eventq_dflt_get());
}
/* Never returns */
return rc;
}