| /** |
| * 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; |
| } |